capdebug 0.2.0 → 0.3.0
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 +30 -0
- package/android/build/.transforms/105231053f5053e70f17f15178bed793/results.bin +1 -0
- package/android/build/.transforms/7c2b02c40854250ff97be5e9e723091e/results.bin +1 -0
- package/android/build/.transforms/ca1c0f6bb67b5238fd83a40c3a1c0ddd/results.bin +1 -0
- package/android/build/.transforms/ca1c0f6bb67b5238fd83a40c3a1c0ddd/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml +9 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/java_res/debug/out/META-INF/capdebug_debug.kotlin_module +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/R-def.txt +2 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt +11 -0
- package/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml +9 -0
- package/android/build/intermediates/navigation_json/debug/navigation.json +1 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt +1 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +20 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/capdebug_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/capdebug/plugin/CapDebugPlugin$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/capdebug/plugin/CapDebugPlugin.class +0 -0
- package/bin/capdebug.js +8 -0
- package/dist/capacitor/deep-link.d.ts +4 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/qr.d.ts +15 -0
- package/dist/cli/server.d.ts +34 -0
- package/dist/cli.js +1868 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/plugin.cjs.js +866 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +866 -0
- package/dist/plugin.js.map +1 -1
- package/dist/plugin.mjs +859 -1
- package/dist/plugin.mjs.map +1 -1
- package/dist/remote/buffer.d.ts +13 -0
- package/dist/remote/desktop-viewer-html.d.ts +10 -0
- package/dist/remote/pairing-page-html.d.ts +8 -0
- package/dist/remote/pairing.d.ts +34 -0
- package/dist/remote/protocol.d.ts +14 -0
- package/dist/remote/remote-manager.d.ts +19 -0
- package/dist/remote/signaling.d.ts +27 -0
- package/dist/remote/transport.d.ts +15 -0
- package/dist/remote/types.d.ts +69 -0
- package/dist/remote/webrtc-transport.d.ts +47 -0
- package/package.json +5 -1
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sources":["../src/remote/pairing.ts","../src/remote/desktop-viewer-html.ts","../src/remote/pairing-page-html.ts","../src/cli/server.ts","../src/cli/qr.ts","../src/cli/index.ts"],"sourcesContent":["import type { PairingSession } from './types';\n\nexport interface ParsedPairingInfo {\n sessionId: string;\n secret: string;\n signalingUrl?: string;\n rawUrl: string;\n}\n\nexport class PairingHelper {\n /**\n * Creates a new pairing session with given TTL (default 5 minutes).\n */\n public static createSession(ttlMs: number = 5 * 60 * 1000): PairingSession {\n const now = Date.now();\n return {\n id: this.generateSessionId(),\n createdAt: now,\n expiresAt: now + ttlMs,\n status: 'waiting',\n };\n }\n\n /**\n * Generates a short, human-readable session ID (e.g. \"K7P4-M2\" or \"7HQ2-9X\").\n */\n public static generateSessionId(): string {\n const chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';\n const bytes = this.getRandomBytes(4);\n let id = '';\n for (let i = 0; i < 4; i++) {\n id += chars[bytes[i] % chars.length];\n }\n const suffix = this.getRandomBytes(2);\n id += '-' + chars[suffix[0] % chars.length] + chars[suffix[1] % chars.length];\n return id;\n }\n\n /**\n * Generates a cryptographically strong 128-bit random secret string.\n */\n public static generateSecret(): string {\n const bytes = this.getRandomBytes(16); // 128 bits entropy\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n /**\n * Formats a web pairing URL where the secret is stored strictly in the URL fragment (#SECRET).\n */\n public static formatPairingUrl(baseUrl: string, sessionId: string, secret: string): string {\n const cleanBase = baseUrl.replace(/\\/+$/, '');\n return `${cleanBase}/pair?s=${encodeURIComponent(sessionId)}#${secret}`;\n }\n\n /**\n * Formats a Capacitor mobile deep link URL.\n */\n public static formatDeepLinkUrl(sessionId: string, secret: string, signalingUrl?: string): string {\n let url = `capdebug://pair?session=${encodeURIComponent(sessionId)}&secret=${encodeURIComponent(secret)}`;\n if (signalingUrl) {\n url += `&server=${encodeURIComponent(signalingUrl)}`;\n }\n return url;\n }\n\n /**\n * Parses a web pairing URL or Capacitor deep-link URL into session and secret components.\n */\n public static parseUrl(urlStr: string): ParsedPairingInfo | null {\n if (!urlStr || typeof urlStr !== 'string') return null;\n\n try {\n // 1. Check for custom scheme (capdebug://pair?...)\n if (urlStr.startsWith('capdebug://')) {\n const queryIdx = urlStr.indexOf('?');\n if (queryIdx === -1) return null;\n const search = urlStr.substring(queryIdx + 1);\n const params = new URLSearchParams(search);\n const sessionId = params.get('session') || params.get('s');\n const secret = params.get('secret') || params.get('sec') || '';\n const signalingUrl = params.get('server') || params.get('sig') || undefined;\n\n if (sessionId && secret) {\n return { sessionId, secret, signalingUrl, rawUrl: urlStr };\n }\n return null;\n }\n\n // 2. Standard HTTP/HTTPS URL\n const url = new URL(urlStr);\n let sessionId = url.searchParams.get('s') || url.searchParams.get('session');\n\n // Check path segment if not in searchParams (e.g. /s/K7P4-M2)\n if (!sessionId && url.pathname.includes('/s/')) {\n const parts = url.pathname.split('/s/');\n if (parts[1]) {\n sessionId = decodeURIComponent(parts[1].split('/')[0]);\n }\n }\n\n // Extract secret from hash fragment (preferred) or query param fallback\n let secret = url.hash.replace(/^#/, '');\n if (!secret) {\n secret = url.searchParams.get('secret') || url.searchParams.get('sec') || '';\n }\n\n const signalingUrl = url.searchParams.get('server') || `${url.protocol}//${url.host}`;\n\n if (sessionId && secret) {\n return {\n sessionId: sessionId.trim(),\n secret: secret.trim(),\n signalingUrl,\n rawUrl: urlStr,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n private static getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(bytes);\n } else {\n // Fallback for older environments\n for (let i = 0; i < length; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n return bytes;\n }\n}\n","/**\n * HTML template for the Desktop Remote Viewer (http://localhost:4783).\n * Contains full client-side WebRTC host logic, real-time log stream UI,\n * filtering, JSON inspection, and remote controls.\n */\nexport function getDesktopViewerHtml(options: {\n sessionId: string;\n secret: string;\n signalingUrl: string;\n}): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>CapDebug Remote Viewer</title>\n <style>\n :root {\n --bg: #0b0f19;\n --surface: #111827;\n --surface-elevated: #1f293d;\n --border: rgba(255, 255, 255, 0.08);\n --border-focus: rgba(56, 189, 248, 0.5);\n --accent: #38bdf8;\n --accent-glow: rgba(56, 189, 248, 0.2);\n --text: #f8fafc;\n --text-muted: #94a3b8;\n --text-dim: #64748b;\n --green: #10b981;\n --amber: #f59e0b;\n --rose: #f43f5e;\n --purple: #a855f7;\n --blue: #3b82f6;\n }\n * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif; }\n body {\n background-color: var(--bg);\n color: var(--text);\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* Header */\n header {\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n padding: 12px 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n flex-shrink: 0;\n }\n .brand-section {\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .logo {\n font-weight: 800;\n font-size: 16px;\n letter-spacing: -0.5px;\n display: flex;\n align-items: center;\n gap: 8px;\n color: #fff;\n }\n .logo-badge {\n background: rgba(56, 189, 248, 0.15);\n color: var(--accent);\n border: 1px solid rgba(56, 189, 248, 0.3);\n padding: 2px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.5px;\n }\n .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid var(--border);\n }\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--text-dim);\n }\n .status-dot.waiting { background: var(--amber); box-shadow: 0 0 8px var(--amber); animation: pulse 1.5s infinite; }\n .status-dot.connected { background: var(--green); box-shadow: 0 0 8px var(--green); }\n .status-dot.failed { background: var(--rose); box-shadow: 0 0 8px var(--rose); }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.4; transform: scale(1.3); }\n }\n\n .meta-metrics {\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: 12px;\n color: var(--text-muted);\n }\n .metric-pill {\n background: rgba(255, 255, 255, 0.04);\n border: 1px solid var(--border);\n padding: 3px 8px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n .metric-pill strong { color: var(--text); }\n\n .header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .btn {\n background: var(--surface-elevated);\n color: var(--text);\n border: 1px solid var(--border);\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s;\n }\n .btn:hover {\n background: rgba(255, 255, 255, 0.1);\n border-color: rgba(255, 255, 255, 0.2);\n }\n .btn-primary {\n background: linear-gradient(135deg, #0284c7, #38bdf8);\n color: white;\n border: none;\n }\n .btn-danger {\n background: rgba(244, 63, 94, 0.15);\n border-color: rgba(244, 63, 94, 0.3);\n color: #fda4af;\n }\n .btn-danger:hover {\n background: rgba(244, 63, 94, 0.3);\n }\n\n /* Subheader & Filters */\n .controls-bar {\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n padding: 8px 20px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n flex-shrink: 0;\n }\n .tabs-group {\n display: flex;\n align-items: center;\n gap: 4px;\n overflow-x: auto;\n }\n .tab-btn {\n background: transparent;\n border: none;\n color: var(--text-muted);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n white-space: nowrap;\n }\n .tab-btn:hover {\n color: var(--text);\n background: rgba(255, 255, 255, 0.04);\n }\n .tab-btn.active {\n color: var(--accent);\n background: rgba(56, 189, 248, 0.12);\n }\n\n .filter-group {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-input {\n background: var(--bg);\n border: 1px solid var(--border);\n color: var(--text);\n padding: 6px 12px;\n border-radius: 6px;\n font-size: 12px;\n width: 220px;\n outline: none;\n transition: border 0.15s;\n }\n .search-input:focus {\n border-color: var(--border-focus);\n }\n .level-select {\n background: var(--bg);\n border: 1px solid var(--border);\n color: var(--text);\n padding: 6px 10px;\n border-radius: 6px;\n font-size: 12px;\n outline: none;\n cursor: pointer;\n }\n\n /* Main Container */\n .main-content {\n flex: 1;\n display: flex;\n overflow: hidden;\n position: relative;\n }\n\n /* Waiting / Empty Overlay */\n .overlay-banner {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(11, 15, 25, 0.9);\n backdrop-filter: blur(8px);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n z-index: 50;\n text-align: center;\n padding: 24px;\n }\n .overlay-card {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 20px;\n padding: 36px 32px;\n max-width: 440px;\n width: 100%;\n box-shadow: 0 20px 50px rgba(0,0,0,0.5);\n }\n .overlay-card h2 {\n font-size: 22px;\n font-weight: 700;\n margin-bottom: 8px;\n }\n .overlay-card p {\n color: var(--text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin-bottom: 24px;\n }\n .session-code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 20px;\n font-weight: 700;\n color: var(--accent);\n background: rgba(56, 189, 248, 0.08);\n border: 1px solid rgba(56, 189, 248, 0.25);\n padding: 10px 16px;\n border-radius: 12px;\n margin-bottom: 20px;\n display: inline-block;\n letter-spacing: 2px;\n }\n\n /* Log Stream */\n .logs-container {\n flex: 1;\n overflow-y: auto;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 12px;\n }\n .log-row {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 8px 20px;\n border-bottom: 1px solid rgba(255, 255, 255, 0.03);\n transition: background 0.1s;\n cursor: pointer;\n }\n .log-row:hover {\n background: rgba(255, 255, 255, 0.02);\n }\n .log-row.selected {\n background: rgba(56, 189, 248, 0.08);\n }\n .log-time {\n color: var(--text-dim);\n white-space: nowrap;\n flex-shrink: 0;\n }\n .pill {\n font-size: 10px;\n font-weight: 700;\n padding: 2px 6px;\n border-radius: 4px;\n text-transform: uppercase;\n flex-shrink: 0;\n }\n .pill-source { background: rgba(255, 255, 255, 0.08); color: var(--text-muted); }\n .pill-level-debug { background: rgba(148, 163, 184, 0.15); color: #cbd5e1; }\n .pill-level-info { background: rgba(56, 189, 248, 0.15); color: #38bdf8; }\n .pill-level-warn { background: rgba(245, 158, 11, 0.15); color: #f59e0b; }\n .pill-level-error { background: rgba(244, 63, 94, 0.15); color: #f43f5e; }\n\n .log-msg {\n flex: 1;\n word-break: break-word;\n color: var(--text);\n }\n .log-duration {\n color: var(--accent);\n font-size: 11px;\n margin-left: 8px;\n }\n\n /* Detail Inspector Pane */\n .details-pane {\n width: 420px;\n border-left: 1px solid var(--border);\n background: var(--surface);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .details-header {\n padding: 12px 16px;\n border-bottom: 1px solid var(--border);\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-weight: 600;\n font-size: 13px;\n }\n .details-body {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n }\n .json-tree {\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 8px;\n padding: 12px;\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n font-size: 12px;\n color: #cbd5e1;\n white-space: pre-wrap;\n word-break: break-all;\n }\n\n /* Diagnostics Drawer */\n .diag-modal {\n display: none;\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 16px;\n padding: 24px;\n width: 500px;\n max-width: 90vw;\n box-shadow: 0 20px 60px rgba(0,0,0,0.7);\n z-index: 100;\n }\n .diag-modal.show { display: block; }\n .diag-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n margin-top: 16px;\n font-size: 13px;\n }\n .diag-item {\n background: var(--bg);\n border: 1px solid var(--border);\n padding: 10px 12px;\n border-radius: 8px;\n }\n .diag-label { color: var(--text-dim); font-size: 11px; text-transform: uppercase; margin-bottom: 4px; }\n .diag-val { font-weight: 600; color: var(--text); }\n </style>\n</head>\n<body>\n\n <!-- Top Bar -->\n <header>\n <div class=\"brand-section\">\n <div class=\"logo\">\n CapDebug\n <span class=\"logo-badge\">DESKTOP</span>\n </div>\n <div class=\"status-badge\">\n <span class=\"status-dot waiting\" id=\"statusDot\"></span>\n <span id=\"statusText\">Waiting for device...</span>\n </div>\n </div>\n\n <div class=\"meta-metrics\">\n <div class=\"metric-pill\">Device: <strong id=\"metricDevice\">—</strong></div>\n <div class=\"metric-pill\">Route: <strong id=\"metricRoute\">—</strong></div>\n <div class=\"metric-pill\">RTT: <strong id=\"metricRtt\">—</strong></div>\n <div class=\"metric-pill\">Events: <strong id=\"metricEvents\">0</strong></div>\n <div class=\"metric-pill\" id=\"droppedPill\" style=\"display:none; color:var(--amber);\">Dropped: <strong id=\"metricDropped\">0</strong></div>\n </div>\n\n <div class=\"header-actions\">\n <button class=\"btn\" id=\"btnPause\">⏸ Pause</button>\n <button class=\"btn\" id=\"btnClear\">🧹 Clear</button>\n <button class=\"btn\" id=\"btnSnapshot\">📸 Snapshot</button>\n <button class=\"btn\" id=\"btnDiag\">📊 Diag</button>\n </div>\n </header>\n\n <!-- Subheader Filters -->\n <div class=\"controls-bar\">\n <div class=\"tabs-group\" id=\"tabsGroup\">\n <button class=\"tab-btn active\" data-source=\"all\">All</button>\n <button class=\"tab-btn\" data-source=\"console\">Console</button>\n <button class=\"tab-btn\" data-source=\"errors\">Errors</button>\n <button class=\"tab-btn\" data-source=\"network\">Network</button>\n <button class=\"tab-btn\" data-source=\"native\">Native</button>\n <button class=\"tab-btn\" data-source=\"custom\">Custom</button>\n <button class=\"tab-btn\" data-source=\"bridge\">Bridge</button>\n </div>\n\n <div class=\"filter-group\">\n <input type=\"text\" class=\"search-input\" id=\"searchInput\" placeholder=\"Filter message or type...\">\n <select class=\"level-select\" id=\"levelSelect\">\n <option value=\"all\">All Levels</option>\n <option value=\"debug\">Debug</option>\n <option value=\"info\">Info</option>\n <option value=\"warn\">Warn</option>\n <option value=\"error\">Error</option>\n </select>\n </div>\n </div>\n\n <!-- Content -->\n <div class=\"main-content\">\n <!-- Waiting Overlay -->\n <div class=\"overlay-banner\" id=\"waitingOverlay\">\n <div class=\"overlay-card\">\n <h2>Scan Terminal QR Code</h2>\n <p>Point your mobile camera at the terminal to connect CapDebug via WebRTC DataChannel.</p>\n <div class=\"session-code\">${options.sessionId}</div>\n <p style=\"font-size:12px; margin-bottom:0;\">Session active for 5 minutes. Handshake will initiate automatically upon scan.</p>\n </div>\n </div>\n\n <!-- Logs Container -->\n <div class=\"logs-container\" id=\"logsContainer\"></div>\n\n <!-- Details Pane -->\n <div class=\"details-pane\" id=\"detailsPane\" style=\"display:none;\">\n <div class=\"details-header\">\n <span>Event Details</span>\n <button class=\"btn\" id=\"btnCloseDetails\">✕</button>\n </div>\n <div class=\"details-body\" id=\"detailsBody\"></div>\n </div>\n </div>\n\n <!-- Diagnostics Modal -->\n <div class=\"diag-modal\" id=\"diagModal\">\n <div style=\"display:flex; justify-content:space-between; align-items:center; margin-bottom:12px;\">\n <h3 style=\"font-size:16px;\">WebRTC Diagnostics</h3>\n <button class=\"btn\" id=\"btnCloseDiag\">✕</button>\n </div>\n <div class=\"diag-grid\">\n <div class=\"diag-item\"><div class=\"diag-label\">Session ID</div><div class=\"diag-val\">${options.sessionId}</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Transport</div><div class=\"diag-val\">WebRTC DataChannel</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">ICE State</div><div class=\"diag-val\" id=\"diagIceState\">new</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Signaling State</div><div class=\"diag-val\" id=\"diagSigState\">stable</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Route Type</div><div class=\"diag-val\" id=\"diagRoute\">Unknown</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Candidate</div><div class=\"diag-val\" id=\"diagCandidate\">Host</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Protocol</div><div class=\"diag-val\" id=\"diagProtocol\">UDP</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Latency (RTT)</div><div class=\"diag-val\" id=\"diagRtt\">—</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Events Received</div><div class=\"diag-val\" id=\"diagReceived\">0</div></div>\n <div class=\"diag-item\"><div class=\"diag-label\">Dropped (Backpressure)</div><div class=\"diag-val\" id=\"diagDropped\">0</div></div>\n </div>\n </div>\n\n <script>\n (function() {\n const sessionId = \"${options.sessionId}\";\n const secret = \"${options.secret}\";\n const signalingUrl = \"${options.signalingUrl}\";\n\n let pc = null;\n let eventsChannel = null;\n let controlChannel = null;\n let sse = null;\n\n let events = [];\n let selectedEvent = null;\n let activeSourceFilter = 'all';\n let activeLevelFilter = 'all';\n let searchQuery = '';\n let isPaused = false;\n let totalReceived = 0;\n let droppedCount = 0;\n let rttMs = 0;\n let pingInterval = null;\n\n // DOM Elements\n const statusDot = document.getElementById('statusDot');\n const statusText = document.getElementById('statusText');\n const metricDevice = document.getElementById('metricDevice');\n const metricRoute = document.getElementById('metricRoute');\n const metricRtt = document.getElementById('metricRtt');\n const metricEvents = document.getElementById('metricEvents');\n const metricDropped = document.getElementById('metricDropped');\n const droppedPill = document.getElementById('droppedPill');\n const waitingOverlay = document.getElementById('waitingOverlay');\n const logsContainer = document.getElementById('logsContainer');\n const detailsPane = document.getElementById('detailsPane');\n const detailsBody = document.getElementById('detailsBody');\n const btnCloseDetails = document.getElementById('btnCloseDetails');\n const btnPause = document.getElementById('btnPause');\n const btnClear = document.getElementById('btnClear');\n const btnSnapshot = document.getElementById('btnSnapshot');\n const btnDiag = document.getElementById('btnDiag');\n const diagModal = document.getElementById('diagModal');\n const btnCloseDiag = document.getElementById('btnCloseDiag');\n\n // --- WebRTC Host Negotiation ---\n function initSignaling() {\n const sseUrl = signalingUrl + '/api/pair/events/' + encodeURIComponent(sessionId) + '?secret=' + encodeURIComponent(secret);\n sse = new EventSource(sseUrl);\n\n sse.onmessage = function(e) {\n try {\n const msg = JSON.parse(e.data);\n handleSignaling(msg);\n } catch(err) {\n console.error('[Signaling] Parse error:', err);\n }\n };\n\n sse.onerror = function() {\n // SSE connection state\n };\n }\n\n async function sendSignaling(msg) {\n try {\n await fetch(signalingUrl + '/api/pair/signal', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n sessionId: sessionId,\n secret: secret,\n sender: 'host',\n ...msg\n })\n });\n } catch(err) {\n console.error('[Signaling] Send error:', err);\n }\n }\n\n async function handleSignaling(msg) {\n if (msg.type === 'peer-joined') {\n // Peer scanned QR and joined signaling session!\n // NOW we create RTCPeerConnection and offer (delayed handshake invariant)\n statusText.innerText = 'Peer joined! Negotiating...';\n await startWebRTCHandshake();\n } else if (msg.type === 'answer') {\n if (pc) {\n await pc.setRemoteDescription(new RTCSessionDescription(msg.payload));\n }\n } else if (msg.type === 'ice-candidate') {\n if (pc && msg.payload) {\n try {\n await pc.addIceCandidate(new RTCIceCandidate(msg.payload));\n } catch(e) {\n console.warn('ICE Candidate add error:', e);\n }\n }\n } else if (msg.type === 'disconnect') {\n setDisconnected();\n }\n }\n\n async function startWebRTCHandshake() {\n pc = new RTCPeerConnection({\n iceServers: [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:global.stun.twilio.com:3478' }\n ]\n });\n\n pc.onicecandidate = function(event) {\n if (event.candidate) {\n sendSignaling({\n type: 'ice-candidate',\n payload: event.candidate.toJSON()\n });\n }\n };\n\n pc.onconnectionstatechange = function() {\n document.getElementById('diagIceState').innerText = pc.iceConnectionState;\n document.getElementById('diagSigState').innerText = pc.signalingState;\n\n if (pc.connectionState === 'connected') {\n setConnected();\n } else if (pc.connectionState === 'failed' || pc.connectionState === 'closed') {\n setDisconnected();\n }\n };\n\n // Create DataChannels\n eventsChannel = pc.createDataChannel('events', { ordered: true });\n controlChannel = pc.createDataChannel('control', { ordered: true });\n\n setupDataChannels();\n\n const offer = await pc.createOffer();\n await pc.setLocalDescription(offer);\n\n await sendSignaling({\n type: 'offer',\n payload: offer\n });\n }\n\n function setupDataChannels() {\n eventsChannel.onopen = checkConnected;\n controlChannel.onopen = checkConnected;\n\n eventsChannel.onmessage = function(e) {\n if (typeof e.data !== 'string') return;\n try {\n const parsed = JSON.parse(e.data);\n if (parsed.type === 'event' && parsed.event) {\n appendEvent(parsed.event);\n } else if (parsed.type === 'events-batch' && Array.isArray(parsed.events)) {\n parsed.events.forEach(appendEvent);\n }\n } catch(err) {\n console.error('DataChannel parse error:', err);\n }\n };\n\n controlChannel.onmessage = function(e) {\n try {\n const parsed = JSON.parse(e.data);\n if (parsed.type === 'hello') {\n metricDevice.innerText = parsed.payload?.deviceName || 'Mobile Device';\n if (parsed.payload?.platform) {\n metricDevice.innerText += ' (' + parsed.payload.platform + ')';\n }\n controlChannel.send(JSON.stringify({ v: 1, type: 'hello-ack' }));\n } else if (parsed.type === 'pong') {\n const pingTime = parsed.payload?.pingTimestamp || parsed.timestamp;\n if (pingTime) {\n rttMs = Math.max(1, Date.now() - pingTime);\n metricRtt.innerText = rttMs + ' ms';\n document.getElementById('diagRtt').innerText = rttMs + ' ms';\n }\n }\n } catch(err) {\n console.error('Control message error:', err);\n }\n };\n }\n\n function checkConnected() {\n if (eventsChannel && eventsChannel.readyState === 'open' &&\n controlChannel && controlChannel.readyState === 'open') {\n setConnected();\n }\n }\n\n function setConnected() {\n statusDot.className = 'status-dot connected';\n statusText.innerText = 'Connected';\n waitingOverlay.style.display = 'none';\n\n // Query Stats\n updateStats();\n if (!pingInterval) {\n pingInterval = setInterval(function() {\n if (controlChannel && controlChannel.readyState === 'open') {\n controlChannel.send(JSON.stringify({ v: 1, type: 'ping', timestamp: Date.now() }));\n }\n updateStats();\n }, 2000);\n }\n }\n\n function setDisconnected() {\n statusDot.className = 'status-dot failed';\n statusText.innerText = 'Disconnected';\n if (pingInterval) {\n clearInterval(pingInterval);\n pingInterval = null;\n }\n }\n\n async function updateStats() {\n if (!pc) return;\n try {\n const stats = await pc.getStats();\n stats.forEach(function(report) {\n if (report.type === 'candidate-pair' && (report.selected || report.state === 'succeeded')) {\n const local = stats.get(report.localCandidateId);\n if (local) {\n const cType = local.candidateType || 'host';\n document.getElementById('diagCandidate').innerText = cType;\n document.getElementById('diagProtocol').innerText = local.protocol || 'UDP';\n const route = cType === 'host' ? 'Direct / LAN' : (cType === 'relay' ? 'Relay / TURN' : 'STUN / WAN');\n metricRoute.innerText = route;\n document.getElementById('diagRoute').innerText = route;\n }\n }\n });\n } catch(e) {}\n }\n\n // --- UI & Event Rendering ---\n function appendEvent(ev) {\n if (isPaused) return;\n totalReceived++;\n events.push(ev);\n metricEvents.innerText = totalReceived;\n document.getElementById('diagReceived').innerText = totalReceived;\n\n if (matchesFilter(ev)) {\n renderLogRow(ev);\n }\n }\n\n function matchesFilter(ev) {\n if (activeSourceFilter !== 'all') {\n if (activeSourceFilter === 'custom' && ev.source !== 'custom') return false;\n if (activeSourceFilter !== 'custom' && ev.source !== activeSourceFilter) return false;\n }\n if (activeLevelFilter !== 'all' && ev.level !== activeLevelFilter) {\n return false;\n }\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n const matchMsg = ev.message && ev.message.toLowerCase().includes(q);\n const matchType = ev.type && ev.type.toLowerCase().includes(q);\n if (!matchMsg && !matchType) return false;\n }\n return true;\n }\n\n function renderLogRow(ev) {\n const row = document.createElement('div');\n row.className = 'log-row';\n row.dataset.id = ev.id;\n\n const time = new Date(ev.timestamp).toLocaleTimeString();\n const durationHtml = ev.duration ? '<span class=\"log-duration\">(' + Math.round(ev.duration) + 'ms)</span>' : '';\n\n row.innerHTML = '<span class=\"log-time\">' + time + '</span>' +\n '<span class=\"pill pill-source\">' + (ev.source || 'web') + '</span>' +\n '<span class=\"pill pill-level-' + (ev.level || 'info') + '\">' + (ev.level || 'info') + '</span>' +\n '<span class=\"log-msg\"><strong>' + (ev.type ? ev.type + ': ' : '') + '</strong>' + escapeHtml(ev.message || '') + durationHtml + '</span>';\n\n row.addEventListener('click', function() {\n showDetails(ev, row);\n });\n\n logsContainer.appendChild(row);\n logsContainer.scrollTop = logsContainer.scrollHeight;\n }\n\n function refreshLogs() {\n logsContainer.innerHTML = '';\n events.filter(matchesFilter).forEach(renderLogRow);\n }\n\n function showDetails(ev, rowElem) {\n document.querySelectorAll('.log-row.selected').forEach(function(el) { el.classList.remove('selected'); });\n if (rowElem) rowElem.classList.add('selected');\n\n selectedEvent = ev;\n detailsPane.style.display = 'flex';\n\n detailsBody.innerHTML = '<div style=\"margin-bottom:12px;\">' +\n '<div style=\"font-size:11px; color:var(--text-dim); text-transform:uppercase;\">Type</div>' +\n '<div style=\"font-weight:700; font-size:14px; margin-top:2px;\">' + (ev.type || 'generic') + '</div>' +\n '</div>' +\n '<div style=\"margin-bottom:12px;\">' +\n '<div style=\"font-size:11px; color:var(--text-dim); text-transform:uppercase;\">Message</div>' +\n '<div style=\"margin-top:2px; font-size:13px; color:#cbd5e1;\">' + escapeHtml(ev.message || '') + '</div>' +\n '</div>' +\n '<div style=\"margin-bottom:12px;\">' +\n '<div style=\"font-size:11px; color:var(--text-dim); text-transform:uppercase;\">Payload Data</div>' +\n '<pre class=\"json-tree\">' + escapeHtml(JSON.stringify(ev.data || {}, null, 2)) + '</pre>' +\n '</div>';\n }\n\n function escapeHtml(str) {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n }\n\n // --- Button Handlers ---\n btnPause.addEventListener('click', function() {\n isPaused = !isPaused;\n btnPause.innerText = isPaused ? '▶ Resume' : '⏸ Pause';\n if (controlChannel && controlChannel.readyState === 'open') {\n controlChannel.send(JSON.stringify({\n v: 1,\n type: 'control',\n command: { type: isPaused ? 'pause' : 'resume' }\n }));\n }\n });\n\n btnClear.addEventListener('click', function() {\n events = [];\n logsContainer.innerHTML = '';\n metricEvents.innerText = '0';\n totalReceived = 0;\n if (controlChannel && controlChannel.readyState === 'open') {\n controlChannel.send(JSON.stringify({\n v: 1,\n type: 'control',\n command: { type: 'clear' }\n }));\n }\n });\n\n btnSnapshot.addEventListener('click', function() {\n if (controlChannel && controlChannel.readyState === 'open') {\n controlChannel.send(JSON.stringify({\n v: 1,\n type: 'control',\n command: { type: 'snapshot.request' }\n }));\n }\n });\n\n btnDiag.addEventListener('click', function() { diagModal.classList.add('show'); });\n btnCloseDiag.addEventListener('click', function() { diagModal.classList.remove('show'); });\n btnCloseDetails.addEventListener('click', function() { detailsPane.style.display = 'none'; });\n\n // Tab filtering\n document.getElementById('tabsGroup').addEventListener('click', function(e) {\n if (e.target.classList.contains('tab-btn')) {\n document.querySelectorAll('.tab-btn').forEach(function(btn) { btn.classList.remove('active'); });\n e.target.classList.add('active');\n activeSourceFilter = e.target.dataset.source;\n refreshLogs();\n }\n });\n\n // Search & Level\n document.getElementById('searchInput').addEventListener('input', function(e) {\n searchQuery = e.target.value;\n refreshLogs();\n });\n\n document.getElementById('levelSelect').addEventListener('change', function(e) {\n activeLevelFilter = e.target.value;\n refreshLogs();\n });\n\n // Start SSE signaling listener\n initSignaling();\n })();\n </script>\n</body>\n</html>`;\n}\n","/**\n * HTML template for the mobile pairing redirect page (/pair).\n * Served when the user scans the terminal QR code.\n */\nexport function getPairingPageHtml(options: {\n sessionId: string;\n signalingUrl: string;\n}): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">\n <title>CapDebug Remote Pairing</title>\n <style>\n :root {\n --bg: #090d16;\n --card-bg: rgba(22, 30, 49, 0.85);\n --border: rgba(255, 255, 255, 0.1);\n --accent: #38bdf8;\n --accent-glow: rgba(56, 189, 248, 0.25);\n --text: #f1f5f9;\n --text-muted: #94a3b8;\n --green: #10b981;\n }\n * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n body {\n background: radial-gradient(circle at top, #1e293b 0%, var(--bg) 100%);\n color: var(--text);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n text-align: center;\n }\n .card {\n background: var(--card-bg);\n border: 1px solid var(--border);\n border-radius: 24px;\n padding: 32px 24px;\n max-width: 400px;\n width: 100%;\n box-shadow: 0 20px 40px rgba(0,0,0,0.5), 0 0 40px var(--accent-glow);\n backdrop-filter: blur(12px);\n animation: fadeIn 0.4s ease-out;\n }\n @keyframes fadeIn {\n from { opacity: 0; transform: translateY(16px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .logo-badge {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px;\n background: rgba(56, 189, 248, 0.12);\n border: 1px solid rgba(56, 189, 248, 0.3);\n border-radius: 999px;\n color: var(--accent);\n font-weight: 700;\n font-size: 13px;\n letter-spacing: 0.5px;\n margin-bottom: 20px;\n }\n .pulse-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--accent);\n box-shadow: 0 0 10px var(--accent);\n animation: pulse 1.5s infinite;\n }\n @keyframes pulse {\n 0%, 100% { transform: scale(1); opacity: 1; }\n 50% { transform: scale(1.6); opacity: 0.6; }\n }\n h1 {\n font-size: 24px;\n font-weight: 800;\n margin-bottom: 8px;\n letter-spacing: -0.5px;\n }\n p {\n color: var(--text-muted);\n font-size: 14px;\n line-height: 1.5;\n margin-bottom: 24px;\n }\n .session-pill {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n background: rgba(0,0,0,0.4);\n border: 1px solid var(--border);\n padding: 10px 16px;\n border-radius: 12px;\n font-size: 18px;\n font-weight: 700;\n color: #38bdf8;\n letter-spacing: 2px;\n margin-bottom: 24px;\n display: inline-block;\n }\n .btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n padding: 14px 20px;\n border-radius: 14px;\n font-size: 15px;\n font-weight: 600;\n cursor: pointer;\n text-decoration: none;\n transition: all 0.2s;\n border: none;\n margin-bottom: 12px;\n }\n .btn-primary {\n background: linear-gradient(135deg, #0284c7, #38bdf8);\n color: white;\n box-shadow: 0 4px 16px rgba(56, 189, 248, 0.35);\n }\n .btn-primary:active {\n transform: scale(0.98);\n }\n .btn-secondary {\n background: rgba(255, 255, 255, 0.06);\n color: var(--text);\n border: 1px solid var(--border);\n }\n .status-text {\n font-size: 12px;\n color: var(--text-muted);\n margin-top: 16px;\n }\n </style>\n</head>\n<body>\n <div class=\"card\">\n <div class=\"logo-badge\">\n <span class=\"pulse-dot\"></span>\n CAPDEBUG REMOTE\n </div>\n <h1>Pairing with Desktop</h1>\n <p>Opening CapDebug session on your device...</p>\n\n <div class=\"session-pill\" id=\"sessionDisplay\">${options.sessionId}</div>\n\n <a id=\"deepLinkBtn\" href=\"#\" class=\"btn btn-primary\">Open in Capacitor App</a>\n <button id=\"browserBtn\" class=\"btn btn-secondary\">Connect in Browser</button>\n\n <div class=\"status-text\" id=\"statusMessage\">Redirecting to app...</div>\n </div>\n\n <script>\n (function() {\n const sessionId = \"${options.sessionId}\";\n const signalingUrl = \"${options.signalingUrl}\";\n const secret = window.location.hash ? window.location.hash.substring(1) : \"\";\n\n const deepLinkUrl = \"capdebug://pair?session=\" + encodeURIComponent(sessionId) +\n \"&secret=\" + encodeURIComponent(secret) +\n \"&signaling=\" + encodeURIComponent(signalingUrl);\n\n const deepLinkBtn = document.getElementById(\"deepLinkBtn\");\n const browserBtn = document.getElementById(\"browserBtn\");\n const statusMsg = document.getElementById(\"statusMessage\");\n\n deepLinkBtn.href = deepLinkUrl;\n\n // Auto redirect to deep link after short pause\n setTimeout(function() {\n window.location.href = deepLinkUrl;\n }, 400);\n\n // Handle in-browser pairing if user stays on page\n browserBtn.addEventListener(\"click\", function() {\n statusMsg.innerText = \"Connecting browser session...\";\n browserBtn.disabled = true;\n // In-browser mobile web session joining\n if (window.opener || window.parent) {\n window.postMessage({ type: \"capdebug:pair\", sessionId: sessionId, secret: secret }, \"*\");\n }\n statusMsg.innerText = \"If using Capacitor app, tap 'Open in Capacitor App' above.\";\n });\n })();\n </script>\n</body>\n</html>`;\n}\n","import * as http from 'http';\nimport * as os from 'os';\nimport { PairingHelper } from '../remote/pairing';\nimport type { PairingSession, SignalingMessage } from '../remote/types';\nimport { getDesktopViewerHtml } from '../remote/desktop-viewer-html';\nimport { getPairingPageHtml } from '../remote/pairing-page-html';\n\nexport interface ServerSessionInfo {\n session: PairingSession;\n secret: string;\n subscribers: Set<http.ServerResponse>;\n peerJoined: boolean;\n}\n\nexport class CapDebugCliServer {\n private server: http.Server | null = null;\n private sessions: Map<string, ServerSessionInfo> = new Map();\n private port: number;\n private host: string;\n\n constructor(options: { port?: number; host?: string } = {}) {\n this.port = options.port || 4783;\n this.host = options.host || '0.0.0.0';\n }\n\n public getLanIp(): string {\n const interfaces = os.networkInterfaces();\n for (const name of Object.keys(interfaces)) {\n for (const iface of interfaces[name] || []) {\n // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses\n if (iface.family === 'IPv4' && !iface.internal) {\n return iface.address;\n }\n }\n }\n return '127.0.0.1';\n }\n\n public getLocalViewerUrl(): string {\n return `http://localhost:${this.port}`;\n }\n\n public getMobilePairingUrl(sessionId: string, secret: string): string {\n const lanIp = this.getLanIp();\n return PairingHelper.formatPairingUrl(\n `http://${lanIp}:${this.port}`,\n sessionId,\n secret\n );\n }\n\n public createSession(): { session: PairingSession; secret: string } {\n const session = PairingHelper.createSession(5 * 60 * 1000); // 5 min TTL\n const secret = PairingHelper.generateSecret();\n\n this.sessions.set(session.id, {\n session,\n secret,\n subscribers: new Set(),\n peerJoined: false,\n });\n\n return { session, secret };\n }\n\n public getSession(id: string): ServerSessionInfo | undefined {\n const s = this.sessions.get(id);\n if (!s) return undefined;\n if (Date.now() > s.session.expiresAt) {\n s.session.status = 'expired';\n }\n return s;\n }\n\n public async start(): Promise<{ port: number; lanIp: string }> {\n return new Promise((resolve, reject) => {\n this.server = http.createServer((req, res) => {\n this.handleRequest(req, res);\n });\n\n this.server.listen(this.port, this.host, () => {\n const addr = this.server?.address();\n const actualPort = typeof addr === 'object' && addr ? addr.port : this.port;\n this.port = actualPort;\n resolve({ port: this.port, lanIp: this.getLanIp() });\n });\n\n this.server.on('error', (err) => {\n reject(err);\n });\n });\n }\n\n public stop(): Promise<void> {\n return new Promise((resolve) => {\n // Close all SSE streams\n for (const s of this.sessions.values()) {\n for (const sub of s.subscribers) {\n try {\n sub.end();\n } catch {\n // ignore\n }\n }\n s.subscribers.clear();\n }\n\n if (this.server) {\n this.server.close(() => {\n this.server = null;\n resolve();\n });\n } else {\n resolve();\n }\n });\n }\n\n private handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void {\n const parsedUrl = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n const pathname = parsedUrl.pathname;\n\n // CORS Headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // 1. GET / -> Desktop Viewer\n if (pathname === '/' && req.method === 'GET') {\n const sessionId = parsedUrl.searchParams.get('s') || Array.from(this.sessions.keys())[0] || '';\n const sessionInfo = this.getSession(sessionId) || Array.from(this.sessions.values())[0];\n\n const html = getDesktopViewerHtml({\n sessionId: sessionInfo ? sessionInfo.session.id : '',\n secret: sessionInfo ? sessionInfo.secret : '',\n signalingUrl: `http://localhost:${this.port}`,\n });\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(html);\n return;\n }\n\n // 2. GET /pair -> Mobile Pairing Page\n if (pathname === '/pair' && req.method === 'GET') {\n const sessionId = parsedUrl.searchParams.get('s') || '';\n const lanIp = this.getLanIp();\n\n const html = getPairingPageHtml({\n sessionId,\n signalingUrl: `http://${lanIp}:${this.port}`,\n });\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(html);\n return;\n }\n\n // 3. POST /api/pair/create\n if (pathname === '/api/pair/create' && req.method === 'POST') {\n const result = this.createSession();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, session: result.session, secret: result.secret }));\n return;\n }\n\n // 4. POST /api/pair/join\n if (pathname === '/api/pair/join' && req.method === 'POST') {\n this.readJsonBody(req, (err, body) => {\n if (err || !body?.sessionId || !body?.secret) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Invalid join payload' }));\n return;\n }\n\n const sessionInfo = this.getSession(body.sessionId);\n if (!sessionInfo) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Session not found' }));\n return;\n }\n\n if (sessionInfo.session.status === 'expired') {\n res.writeHead(410, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Session expired' }));\n return;\n }\n\n if (sessionInfo.secret !== body.secret) {\n res.writeHead(403, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Invalid secret' }));\n return;\n }\n\n // Mark as peer joined and broadcast to subscribers (CLI & Desktop)\n sessionInfo.session.status = 'peer-joined';\n sessionInfo.peerJoined = true;\n this.broadcast(sessionInfo, {\n sessionId: sessionInfo.session.id,\n secret: sessionInfo.secret,\n type: 'peer-joined',\n sender: 'peer',\n });\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, session: sessionInfo.session }));\n });\n return;\n }\n\n // 5. POST /api/pair/signal\n if (pathname === '/api/pair/signal' && req.method === 'POST') {\n this.readJsonBody(req, (err, body) => {\n if (err || !body?.sessionId || !body?.secret || !body?.type) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Invalid signal payload' }));\n return;\n }\n\n const sessionInfo = this.getSession(body.sessionId);\n if (!sessionInfo || sessionInfo.secret !== body.secret) {\n res.writeHead(403, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Invalid session or secret' }));\n return;\n }\n\n // Broadcast signaling message to other party\n this.broadcast(sessionInfo, body);\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true }));\n });\n return;\n }\n\n // 6. GET /api/pair/events/:sessionId (SSE endpoint)\n if (pathname.startsWith('/api/pair/events/') && req.method === 'GET') {\n const sessionId = pathname.replace('/api/pair/events/', '');\n const secret = parsedUrl.searchParams.get('secret') || '';\n\n const sessionInfo = this.getSession(sessionId);\n if (!sessionInfo || (secret && sessionInfo.secret !== secret)) {\n res.writeHead(403, { 'Content-Type': 'text/plain' });\n res.end('Unauthorized');\n return;\n }\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n res.write(': ok\\n\\n');\n\n sessionInfo.subscribers.add(res);\n\n req.on('close', () => {\n sessionInfo.subscribers.delete(res);\n });\n return;\n }\n\n // 7. GET /api/pair/status/:sessionId\n if (pathname.startsWith('/api/pair/status/') && req.method === 'GET') {\n const sessionId = pathname.replace('/api/pair/status/', '');\n const sessionInfo = this.getSession(sessionId);\n\n if (!sessionInfo) {\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Session not found' }));\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: true, session: sessionInfo.session }));\n return;\n }\n\n // 404 fallback\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not Found');\n }\n\n private broadcast(sessionInfo: ServerSessionInfo, message: SignalingMessage): void {\n const data = `data: ${JSON.stringify(message)}\\n\\n`;\n for (const sub of sessionInfo.subscribers) {\n try {\n sub.write(data);\n } catch {\n sessionInfo.subscribers.delete(sub);\n }\n }\n }\n\n private readJsonBody(\n req: http.IncomingMessage,\n cb: (err: Error | null, body: any) => void\n ): void {\n let raw = '';\n req.on('data', (chunk) => {\n raw += chunk;\n if (raw.length > 1024 * 1024) {\n req.destroy();\n }\n });\n req.on('end', () => {\n try {\n const parsed = JSON.parse(raw || '{}');\n cb(null, parsed);\n } catch (err: any) {\n cb(err, null);\n }\n });\n req.on('error', (err) => cb(err, null));\n }\n}\n","/**\n * Zero-dependency QR Code matrix generator and terminal ANSI renderer.\n * Encodes Byte Mode URLs and renders compact Unicode half-block characters.\n */\n\n// Galois Field (GF 256) tables for Reed-Solomon error correction\nconst EXP_TABLE = new Uint8Array(512);\nconst LOG_TABLE = new Uint8Array(256);\n\n(function initGF() {\n let x = 1;\n for (let i = 0; i < 255; i++) {\n EXP_TABLE[i] = x;\n EXP_TABLE[i + 255] = x;\n LOG_TABLE[x] = i;\n x = (x << 1) ^ (x >= 128 ? 0x11d : 0);\n }\n})();\n\nfunction gfMul(x: number, y: number): number {\n if (x === 0 || y === 0) return 0;\n return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]];\n}\n\nfunction polyMul(p: number[], q: number[]): number[] {\n const result: number[] = new Array(p.length + q.length - 1).fill(0);\n for (let i = 0; i < p.length; i++) {\n for (let j = 0; j < q.length; j++) {\n result[i + j] ^= gfMul(p[i], q[j]);\n }\n }\n return result;\n}\n\nfunction rsGeneratorPoly(degree: number): number[] {\n let g: number[] = [1];\n for (let i = 0; i < degree; i++) {\n g = polyMul(g, [1, EXP_TABLE[i]]);\n }\n return g;\n}\n\nfunction rsCompute(data: Uint8Array, ecCount: number): Uint8Array {\n const gen = rsGeneratorPoly(ecCount);\n const msg: number[] = new Array(data.length + ecCount).fill(0);\n for (let i = 0; i < data.length; i++) {\n msg[i] = data[i];\n }\n\n for (let i = 0; i < data.length; i++) {\n const lead = msg[i];\n if (lead !== 0) {\n for (let j = 0; j < gen.length; j++) {\n msg[i + j] ^= gfMul(gen[j], lead);\n }\n }\n }\n\n const out = new Uint8Array(ecCount);\n for (let i = 0; i < ecCount; i++) {\n out[i] = msg[data.length + i];\n }\n return out;\n}\n\n// Version table for QR Version 3 (29x29), 4 (33x33), 5 (37x37), 6 (41x41) with Error Correction Level L\ninterface QRVersionSpec {\n version: number;\n size: number;\n totalBytes: number;\n dataBytes: number;\n ecBytes: number;\n alignPos: number[];\n}\n\nconst QR_SPECS: QRVersionSpec[] = [\n { version: 2, size: 25, totalBytes: 44, dataBytes: 34, ecBytes: 10, alignPos: [6, 18] },\n { version: 3, size: 29, totalBytes: 70, dataBytes: 55, ecBytes: 15, alignPos: [6, 22] },\n { version: 4, size: 33, totalBytes: 100, dataBytes: 80, ecBytes: 20, alignPos: [6, 26] },\n { version: 5, size: 37, totalBytes: 134, dataBytes: 108, ecBytes: 26, alignPos: [6, 30] },\n { version: 6, size: 41, totalBytes: 172, dataBytes: 136, ecBytes: 36, alignPos: [6, 34] },\n];\n\nexport class TerminalQRCode {\n /**\n * Generates a 2D boolean grid (true = dark/black, false = light/white) for the given text.\n */\n public static generateMatrix(text: string): boolean[][] {\n const textBytes = new TextEncoder().encode(text);\n const spec = QR_SPECS.find((s) => textBytes.length + 3 <= s.dataBytes) || QR_SPECS[QR_SPECS.length - 1];\n\n const dataBits: number[] = [];\n // 1. Mode indicator: Byte Mode (0100)\n dataBits.push(0, 1, 0, 0);\n\n // 2. Character count indicator (8 bits for versions 1-9)\n const len = textBytes.length;\n for (let i = 7; i >= 0; i--) {\n dataBits.push((len >> i) & 1);\n }\n\n // 3. Data payload\n for (let i = 0; i < len; i++) {\n const b = textBytes[i];\n for (let bit = 7; bit >= 0; bit--) {\n dataBits.push((b >> bit) & 1);\n }\n }\n\n // 4. Terminator (up to 4 zeros)\n const totalDataBits = spec.dataBytes * 8;\n for (let i = 0; i < 4 && dataBits.length < totalDataBits; i++) {\n dataBits.push(0);\n }\n\n // 5. Pad to multiple of 8\n while (dataBits.length % 8 !== 0) {\n dataBits.push(0);\n }\n\n // 6. Pad bytes (0xEC, 0x11 alternating)\n const padBytes = [0xec, 0x11];\n let padIdx = 0;\n while (dataBits.length < totalDataBits) {\n const pad = padBytes[padIdx % 2];\n for (let bit = 7; bit >= 0; bit--) {\n dataBits.push((pad >> bit) & 1);\n }\n padIdx++;\n }\n\n // Convert bits to byte array\n const dataBytes = new Uint8Array(spec.dataBytes);\n for (let i = 0; i < spec.dataBytes; i++) {\n let b = 0;\n for (let bit = 0; bit < 8; bit++) {\n b = (b << 1) | dataBits[i * 8 + bit];\n }\n dataBytes[i] = b;\n }\n\n // 7. Compute Reed-Solomon Error Correction\n const ecBytes = rsCompute(dataBytes, spec.ecBytes);\n\n // 8. Interleave / Final codeword sequence\n const finalCodewords = new Uint8Array(spec.totalBytes);\n finalCodewords.set(dataBytes, 0);\n finalCodewords.set(ecBytes, spec.dataBytes);\n\n // 9. Build 2D matrix\n const size = spec.size;\n const matrix: (boolean | null)[][] = Array.from({ length: size }, () =>\n Array.from({ length: size }, () => null)\n );\n\n // Draw Function Patterns:\n // Finder Patterns (7x7) top-left, top-right, bottom-left\n drawFinder(matrix, 0, 0);\n drawFinder(matrix, size - 7, 0);\n drawFinder(matrix, 0, size - 7);\n\n // Timing Patterns\n for (let i = 8; i < size - 8; i++) {\n const val = i % 2 === 0;\n if (matrix[6][i] === null) matrix[6][i] = val;\n if (matrix[i][6] === null) matrix[i][6] = val;\n }\n\n // Alignment Patterns\n if (spec.alignPos.length > 0) {\n for (const r of spec.alignPos) {\n for (const c of spec.alignPos) {\n if (\n (r === 6 && c === 6) ||\n (r === 6 && c === size - 7) ||\n (r === size - 7 && c === 6)\n ) {\n continue;\n }\n drawAlignment(matrix, r, c);\n }\n }\n }\n\n // Dark Module\n matrix[size - 8][8] = true;\n\n // Format Info Reservation (around finders)\n reserveFormatInfo(matrix, size);\n\n // 10. Place Data & Error Correction Codewords in Zigzag Pattern\n placeDataBits(matrix, size, finalCodewords);\n\n // 11. Apply Mask (Mask Pattern 0: (row + col) % 2 === 0)\n applyMask(matrix, size);\n\n // 12. Write Format Information (Error Level L, Mask 0: 0x77c4 with BCH code)\n writeFormatInfo(matrix, size, 0x77c4);\n\n // Convert matrix to boolean[][]\n return matrix.map((row) => row.map((cell) => cell === true));\n }\n\n /**\n * Renders the matrix to terminal string using ANSI half-block characters (▀, ▄, █).\n * 2 vertical rows are packed into 1 line of terminal output for high compactness.\n */\n public static renderToString(text: string): string {\n const matrix = this.generateMatrix(text);\n const size = matrix.length;\n const quietZone = 2;\n const fullSize = size + quietZone * 2;\n\n // Create padded matrix with white/light quiet zone\n const padded: boolean[][] = Array.from({ length: fullSize }, (_, r) =>\n Array.from({ length: fullSize }, (_, c) => {\n const mr = r - quietZone;\n const mc = c - quietZone;\n if (mr >= 0 && mr < size && mc >= 0 && mc < size) {\n return matrix[mr][mc];\n }\n return false;\n })\n );\n\n const lines: string[] = [];\n\n // White background: inverted ANSI colors\n // In ANSI: \\x1b[47m\\x1b[30m is white bg, black fg\n // '▀' draws top pixel black (foreground), bottom pixel white (background)\n // '▄' draws bottom pixel black (foreground), top pixel white (background)\n // '█' draws both pixels black\n // ' ' draws both pixels white\n const reset = '\\x1b[0m';\n const bgWhiteFgBlack = '\\x1b[47m\\x1b[30m';\n\n for (let r = 0; r < fullSize; r += 2) {\n let line = bgWhiteFgBlack;\n for (let c = 0; c < fullSize; c++) {\n const topDark = padded[r][c];\n const bottomDark = r + 1 < fullSize ? padded[r + 1][c] : false;\n\n if (topDark && bottomDark) {\n line += '█';\n } else if (topDark && !bottomDark) {\n line += '▀';\n } else if (!topDark && bottomDark) {\n line += '▄';\n } else {\n line += ' ';\n }\n }\n line += reset;\n lines.push(line);\n }\n\n return lines.join('\\n');\n }\n}\n\n// Helpers for QR Matrix Construction\nfunction drawFinder(matrix: (boolean | null)[][], row: number, col: number) {\n for (let r = -1; r <= 7; r++) {\n for (let c = -1; c <= 7; c++) {\n const mr = row + r;\n const mc = col + c;\n if (mr >= 0 && mr < matrix.length && mc >= 0 && mc < matrix.length) {\n if (r === -1 || r === 7 || c === -1 || c === 7) {\n matrix[mr][mc] = false; // Separator\n } else if (r === 0 || r === 6 || c === 0 || c === 6) {\n matrix[mr][mc] = true;\n } else if (r === 1 || r === 5 || c === 1 || c === 5) {\n matrix[mr][mc] = false;\n } else {\n matrix[mr][mc] = true;\n }\n }\n }\n }\n}\n\nfunction drawAlignment(matrix: (boolean | null)[][], centerR: number, centerC: number) {\n for (let r = -2; r <= 2; r++) {\n for (let c = -2; c <= 2; c++) {\n const mr = centerR + r;\n const mc = centerC + c;\n if (matrix[mr][mc] !== null) continue;\n if (Math.abs(r) === 2 || Math.abs(c) === 2 || (r === 0 && c === 0)) {\n matrix[mr][mc] = true;\n } else {\n matrix[mr][mc] = false;\n }\n }\n }\n}\n\nfunction reserveFormatInfo(matrix: (boolean | null)[][], size: number) {\n for (let i = 0; i <= 8; i++) {\n if (matrix[8][i] === null) matrix[8][i] = false;\n if (matrix[i][8] === null) matrix[i][8] = false;\n if (matrix[8][size - 1 - i] === null) matrix[8][size - 1 - i] = false;\n if (matrix[size - 1 - i][8] === null) matrix[size - 1 - i][8] = false;\n }\n}\n\nfunction placeDataBits(matrix: (boolean | null)[][], size: number, codewords: Uint8Array) {\n let bitIdx = 0;\n const totalBits = codewords.length * 8;\n\n let right = size - 1;\n let upwards = true;\n\n while (right > 0) {\n if (right === 6) right--; // Skip vertical timing column\n\n for (let i = 0; i < size; i++) {\n const row = upwards ? size - 1 - i : i;\n for (let colOffset = 0; colOffset < 2; colOffset++) {\n const col = right - colOffset;\n if (matrix[row][col] === null) {\n let bitVal = false;\n if (bitIdx < totalBits) {\n const byte = codewords[Math.floor(bitIdx / 8)];\n const bit = 7 - (bitIdx % 8);\n bitVal = ((byte >> bit) & 1) === 1;\n bitIdx++;\n }\n matrix[row][col] = bitVal;\n }\n }\n }\n right -= 2;\n upwards = !upwards;\n }\n}\n\nfunction applyMask(matrix: (boolean | null)[][], size: number) {\n for (let r = 0; r < size; r++) {\n for (let c = 0; c < size; c++) {\n // Don't invert finders, timing, alignment, or format areas\n if (isProtectedModule(r, c, size)) continue;\n\n // Mask 0: (r + c) % 2 === 0\n if ((r + c) % 2 === 0) {\n matrix[r][c] = !matrix[r][c];\n }\n }\n }\n}\n\nfunction isProtectedModule(r: number, c: number, size: number): boolean {\n // Top-left finder & separator\n if (r <= 8 && c <= 8) return true;\n // Top-right finder & separator\n if (r <= 8 && c >= size - 8) return true;\n // Bottom-left finder & separator\n if (r >= size - 8 && c <= 8) return true;\n // Timing patterns\n if (r === 6 || c === 6) return true;\n return false;\n}\n\nfunction writeFormatInfo(matrix: (boolean | null)[][], size: number, formatBits: number) {\n // 15 bits format information\n for (let i = 0; i < 15; i++) {\n const bit = ((formatBits >> (14 - i)) & 1) === 1;\n\n // Around top-left finder\n if (i <= 5) {\n matrix[8][i] = bit;\n } else if (i === 6) {\n matrix[8][7] = bit;\n } else if (i === 7) {\n matrix[8][8] = bit;\n } else if (i === 8) {\n matrix[7][8] = bit;\n } else {\n matrix[14 - i][8] = bit;\n }\n\n // Around other finders\n if (i < 8) {\n matrix[size - 1 - i][8] = bit;\n } else {\n matrix[8][size - 15 + i] = bit;\n }\n }\n}\n","import { exec } from 'child_process';\nimport * as readline from 'readline';\nimport { CapDebugCliServer } from './server';\nimport { TerminalQRCode } from './qr';\n\nexport async function runCli(argv: string[] = process.argv.slice(2)): Promise<void> {\n // Parse command line arguments\n let port = 4783;\n let host = '0.0.0.0';\n let shouldOpen = true;\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === '--port' && argv[i + 1]) {\n port = parseInt(argv[i + 1], 10) || 4783;\n i++;\n } else if (arg.startsWith('--port=')) {\n port = parseInt(arg.split('=')[1], 10) || 4783;\n } else if (arg === '--host' && argv[i + 1]) {\n host = argv[i + 1];\n i++;\n } else if (arg === '--no-open') {\n shouldOpen = false;\n }\n }\n\n const server = new CapDebugCliServer({ port, host });\n await server.start();\n\n let sessionInfo = server.createSession();\n let pairingUrl = server.getMobilePairingUrl(sessionInfo.session.id, sessionInfo.secret);\n const viewerUrl = server.getLocalViewerUrl();\n\n // Open browser on start if requested\n if (shouldOpen) {\n openBrowser(viewerUrl);\n }\n\n // Terminal UI State\n let statusMessage = 'Waiting for device...';\n let countdownTimer: NodeJS.Timeout | null = null;\n\n function renderTerminalScreen(): void {\n // Clear terminal screen\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\n\n const remainingSec = Math.max(0, Math.floor((sessionInfo.session.expiresAt - Date.now()) / 1000));\n const mins = String(Math.floor(remainingSec / 60)).padStart(2, '0');\n const secs = String(remainingSec % 60).padStart(2, '0');\n\n const qrRendered = TerminalQRCode.renderToString(pairingUrl);\n\n console.log('\\x1b[1m\\x1b[36mCapDebug Remote\\x1b[0m\\n');\n console.log(`Desktop viewer:\\n\\x1b[4m\\x1b[34m${viewerUrl}\\x1b[0m\\n`);\n console.log(`Scan to connect with mobile:\\n`);\n console.log(qrRendered);\n console.log('');\n console.log(`Session: \\x1b[1m\\x1b[33m${sessionInfo.session.id}\\x1b[0m`);\n console.log(`Expires in: ${mins}:${secs}`);\n console.log(`LAN URL: ${pairingUrl.split('#')[0]}`);\n console.log('');\n console.log(`Status: \\x1b[32m${statusMessage}\\x1b[0m\\n`);\n console.log('Press:');\n console.log(' \\x1b[1mO\\x1b[0m Open desktop viewer in browser');\n console.log(' \\x1b[1mC\\x1b[0m Copy pairing URL to clipboard');\n console.log(' \\x1b[1mR\\x1b[0m Regenerate QR session');\n console.log(' \\x1b[1mQ\\x1b[0m Quit');\n }\n\n function setupCountdown(): void {\n if (countdownTimer) clearInterval(countdownTimer);\n countdownTimer = setInterval(() => {\n const remainingSec = Math.floor((sessionInfo.session.expiresAt - Date.now()) / 1000);\n if (remainingSec <= 0) {\n statusMessage = '\\x1b[31mSession expired. Press R to regenerate.\\x1b[0m';\n }\n renderTerminalScreen();\n }, 1000);\n }\n\n function regenerateSession(): void {\n sessionInfo = server.createSession();\n pairingUrl = server.getMobilePairingUrl(sessionInfo.session.id, sessionInfo.secret);\n statusMessage = 'Waiting for device...';\n setupCountdown();\n renderTerminalScreen();\n }\n\n // Interactive keyboard handler\n if (process.stdin.isTTY) {\n readline.emitKeypressEvents(process.stdin);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n process.stdin.on('keypress', (str, key) => {\n if (key.ctrl && key.name === 'c') {\n cleanupAndExit();\n }\n\n const k = (str || key.name || '').toLowerCase();\n if (k === 'q') {\n cleanupAndExit();\n } else if (k === 'o') {\n openBrowser(viewerUrl);\n } else if (k === 'c') {\n copyToClipboard(pairingUrl);\n statusMessage = 'Pairing URL copied to clipboard!';\n renderTerminalScreen();\n } else if (k === 'r') {\n regenerateSession();\n }\n });\n }\n\n async function cleanupAndExit(): Promise<void> {\n if (countdownTimer) clearInterval(countdownTimer);\n console.log('\\nStopping CapDebug Remote server...');\n await server.stop();\n process.exit(0);\n }\n\n process.on('SIGINT', cleanupAndExit);\n process.on('SIGTERM', cleanupAndExit);\n\n setupCountdown();\n renderTerminalScreen();\n}\n\nfunction openBrowser(url: string): void {\n const startCmd =\n process.platform === 'darwin'\n ? `open \"${url}\"`\n : process.platform === 'win32'\n ? `start \"\" \"${url}\"`\n : `xdg-open \"${url}\"`;\n\n exec(startCmd, () => {\n // Ignore errors opening browser\n });\n}\n\nfunction copyToClipboard(text: string): void {\n const copyCmd =\n process.platform === 'darwin'\n ? `printf \"%s\" \"${text}\" | pbcopy`\n : process.platform === 'win32'\n ? `printf \"%s\" \"${text}\" | clip`\n : `printf \"%s\" \"${text}\" | xclip -selection clipboard 2>/dev/null || printf \"%s\" \"${text}\" | xsel -b 2>/dev/null`;\n\n exec(copyCmd, () => {\n // Ignore clipboard error\n });\n}\n"],"names":["sessionId","secret","signalingUrl","os","http","_","readline","exec"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CapDebugEventInput, CapDebugOptions, NetworkCaptureOptions } from './types';
|
|
2
2
|
import { CapDebugStore } from './store';
|
|
3
|
+
import { RemoteManager } from './remote/remote-manager';
|
|
3
4
|
export * from './types';
|
|
4
5
|
export * from './definitions';
|
|
5
6
|
export * from './sanitizer';
|
|
@@ -13,10 +14,20 @@ export * from './collectors/browser-event.collector';
|
|
|
13
14
|
export * from './collectors/bridge.collector';
|
|
14
15
|
export * from './ui/viewer.element';
|
|
15
16
|
export * from './ui/json-viewer';
|
|
17
|
+
export * from './remote/types';
|
|
18
|
+
export * from './remote/protocol';
|
|
19
|
+
export * from './remote/buffer';
|
|
20
|
+
export * from './remote/pairing';
|
|
21
|
+
export * from './remote/transport';
|
|
22
|
+
export * from './remote/webrtc-transport';
|
|
23
|
+
export * from './remote/signaling';
|
|
24
|
+
export * from './remote/remote-manager';
|
|
25
|
+
export * from './capacitor/deep-link';
|
|
16
26
|
export declare class CapDebugManager {
|
|
17
27
|
private store;
|
|
18
28
|
private viewerElement;
|
|
19
29
|
private isMounted;
|
|
30
|
+
private remoteManager;
|
|
20
31
|
private customEventCollector;
|
|
21
32
|
private consoleCollector;
|
|
22
33
|
private errorCollector;
|
|
@@ -24,6 +35,8 @@ export declare class CapDebugManager {
|
|
|
24
35
|
private browserEventCollector;
|
|
25
36
|
private bridgeCollector;
|
|
26
37
|
constructor();
|
|
38
|
+
get remote(): RemoteManager;
|
|
39
|
+
handlePairingUrl(url: string): Promise<boolean>;
|
|
27
40
|
get native(): import("./definitions").CapDebugNativePlugin;
|
|
28
41
|
get currentStore(): CapDebugStore;
|
|
29
42
|
/**
|