@runcofactor/cli 0.13.0 → 0.15.1

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.
Files changed (149) hide show
  1. package/dist/account-62I7FG5G.js +255 -0
  2. package/dist/account-62I7FG5G.js.map +1 -0
  3. package/dist/{api-catalog-7HLEN7C2.js → api-catalog-CAJUASVC.js} +5 -5
  4. package/dist/{attachment-OVNQD6Z2.js → attachment-RL4AZUJE.js} +5 -5
  5. package/dist/augmentor-GAF3MFY6.js +198 -0
  6. package/dist/augmentor-GAF3MFY6.js.map +1 -0
  7. package/dist/{auth-VUHL74FH.js → auth-DURHUZDW.js} +3 -3
  8. package/dist/{chunk-YN763NWQ.js → chunk-26U3DGUM.js} +10 -4
  9. package/dist/chunk-26U3DGUM.js.map +1 -0
  10. package/dist/{chunk-JZMJUPZP.js → chunk-32P26BZT.js} +3 -3
  11. package/dist/chunk-32P26BZT.js.map +1 -0
  12. package/dist/{chunk-QQVWGWPI.js → chunk-5R4HMSNX.js} +8561 -1511
  13. package/dist/chunk-5R4HMSNX.js.map +1 -0
  14. package/dist/{chunk-VGTKUOYS.js → chunk-AQPJQ5AE.js} +2 -2
  15. package/dist/{chunk-CQE46HSM.js → chunk-CFJXYPTF.js} +14 -8
  16. package/dist/chunk-CFJXYPTF.js.map +1 -0
  17. package/dist/{chunk-NL7CVG56.js → chunk-CJEKEW7R.js} +57 -10
  18. package/dist/chunk-CJEKEW7R.js.map +1 -0
  19. package/dist/{chunk-Z5LUTUDN.js → chunk-G5SXUXSU.js} +3 -3
  20. package/dist/{chunk-ZTOE3ND3.js → chunk-HKQ5XQAQ.js} +4 -4
  21. package/dist/{chunk-PZ4LCN6K.js → chunk-IGHDIWZU.js} +2 -2
  22. package/dist/{chunk-QGI4UCJX.js → chunk-IWKJQZJQ.js} +124 -74
  23. package/dist/chunk-IWKJQZJQ.js.map +1 -0
  24. package/dist/{chunk-ZD3KHESI.js → chunk-KRWRUU6R.js} +27 -7
  25. package/dist/chunk-KRWRUU6R.js.map +1 -0
  26. package/dist/{chunk-CRHPDPRS.js → chunk-PXFDH6YL.js} +63 -8
  27. package/dist/{chunk-CRHPDPRS.js.map → chunk-PXFDH6YL.js.map} +1 -1
  28. package/dist/{chunk-EJ4U242G.js → chunk-UZ2ZA5A6.js} +2 -2
  29. package/dist/{chunk-EEN2TZUQ.js → chunk-VKBTI5EF.js} +3 -3
  30. package/dist/{chunk-ENDHMYEJ.js → chunk-ZXRVFFCY.js} +3 -3
  31. package/dist/{credential-LO2SEEHU.js → credential-JGVSEGVH.js} +5 -5
  32. package/dist/{credential-template-ZN7W7734.js → credential-template-CWWMOKB2.js} +5 -5
  33. package/dist/{debug-workflow-R3RYYAXK.js → debug-workflow-BXRU72YZ.js} +5 -5
  34. package/dist/{docs-DIAFBDXQ.js → docs-PVBXPTGR.js} +95 -11
  35. package/dist/docs-PVBXPTGR.js.map +1 -0
  36. package/dist/{doctor-NZPUSCRE.js → doctor-RHMKD4W5.js} +3 -3
  37. package/dist/{environment-RQVU4P5M.js → environment-WZKIO3R3.js} +5 -5
  38. package/dist/{feature-flag-XG26RURR.js → feature-flag-K5REGGDY.js} +98 -12
  39. package/dist/feature-flag-K5REGGDY.js.map +1 -0
  40. package/dist/index.js +107 -51
  41. package/dist/index.js.map +1 -1
  42. package/dist/{init-EDNLKGPT.js → init-FFUZO5D7.js} +5 -5
  43. package/dist/{install-FYZ3HNZK.js → install-XRKEQAFZ.js} +5 -5
  44. package/dist/{issues-NNRVTJ4L.js → issues-I3V6GEXU.js} +5 -5
  45. package/dist/{knobs-A2BOBH22.js → knobs-6WLJMB44.js} +7 -6
  46. package/dist/knobs-6WLJMB44.js.map +1 -0
  47. package/dist/{list-F33VZ4BJ.js → list-PHC7VYNS.js} +5 -5
  48. package/dist/{local-DQDTM3XA.js → local-VGYRSW22.js} +7 -7
  49. package/dist/{login-BUMVIB36.js → login-QPU2BKG2.js} +5 -5
  50. package/dist/{mcp-B5Y5CDMQ.js → mcp-LA452TOA.js} +9 -9
  51. package/dist/{mcp-B5Y5CDMQ.js.map → mcp-LA452TOA.js.map} +1 -1
  52. package/dist/{pdf-extract-ABWV3L5X.js → pdf-extract-YHE54XU4.js} +2 -2
  53. package/dist/product-RSZV5HMB.js +346 -0
  54. package/dist/product-RSZV5HMB.js.map +1 -0
  55. package/dist/{property-NJ4SRXQG.js → property-YP4GHQAR.js} +5 -5
  56. package/dist/{psql-VBZFCMNR.js → psql-XGLBI6T7.js} +3 -3
  57. package/dist/{record-WAO36O7G.js → record-KWKHP2ZY.js} +6 -6
  58. package/dist/{redis-DHZXHL4S.js → redis-VJGCUJPV.js} +3 -3
  59. package/dist/redis-VJGCUJPV.js.map +1 -0
  60. package/dist/{release-STJKUKTE.js → release-NDRHPW6V.js} +5 -5
  61. package/dist/{sandbox-DWSGLY7B.js → sandbox-OOCANWOG.js} +51 -7
  62. package/dist/sandbox-OOCANWOG.js.map +1 -0
  63. package/dist/{scenarios-HCIDY725.js → scenarios-2HRLCGFY.js} +5 -5
  64. package/dist/{session-Y5RHU54D.js → session-M4ULYDYP.js} +8 -9
  65. package/dist/session-M4ULYDYP.js.map +1 -0
  66. package/dist/{skill-23WAHUOB.js → skill-4DGPRDUC.js} +10 -10
  67. package/dist/{skill-23WAHUOB.js.map → skill-4DGPRDUC.js.map} +1 -1
  68. package/dist/skills/debug-run/SKILL.md +7 -1
  69. package/dist/skills/debug-run/history/1.3.1.md +279 -0
  70. package/dist/skills/debug-run/version.json +1 -1
  71. package/dist/skills/optimize-cache/SKILL.md +41 -4
  72. package/dist/{spec-LM5XHOQ5.js → spec-XZ2TKUFZ.js} +5 -5
  73. package/dist/{src-BGDRMOKC.js → src-2FK3JHGW.js} +315 -104
  74. package/dist/src-2FK3JHGW.js.map +1 -0
  75. package/dist/{src-NCJPUAE6.js → src-CV57ZD6I.js} +10 -8
  76. package/dist/{src-22RI5VP2.js → src-HL7HEJIW.js} +2 -2
  77. package/dist/{src-Y3K7UJEF.js → src-OU7544PM.js} +6 -4
  78. package/dist/{start-SWY55CZX.js → start-IYKF3C3X.js} +5 -5
  79. package/dist/{tag-YSU2XXPI.js → tag-T45MMSCH.js} +6 -6
  80. package/dist/{task-NLBKLD7D.js → task-MCUHAVTD.js} +5 -5
  81. package/dist/{test-suite-QCPWZ2LS.js → test-suite-BICBRSBP.js} +10 -8
  82. package/dist/{test-suite-QCPWZ2LS.js.map → test-suite-BICBRSBP.js.map} +1 -1
  83. package/dist/trace-2BAPMYAS.js +16 -0
  84. package/dist/{triage-TT4BMDBU.js → triage-M3RZ2ASB.js} +6 -6
  85. package/dist/{upgrade-6ZUFETKX.js → upgrade-4QCRAUHP.js} +3 -3
  86. package/dist/{workflow-2CX3ZNOQ.js → workflow-4J23FV7K.js} +86 -15
  87. package/dist/workflow-4J23FV7K.js.map +1 -0
  88. package/dist/{workflow-cache-GXNE6SU2.js → workflow-cache-XPSK6KC7.js} +26 -13
  89. package/dist/workflow-cache-XPSK6KC7.js.map +1 -0
  90. package/dist/{workflow-debug-PRX3DWGD.js → workflow-debug-W4USZH35.js} +9 -9
  91. package/dist/{workflow-proposals-BW327WGL.js → workflow-proposals-5E3DTYZB.js} +5 -7
  92. package/dist/workflow-proposals-5E3DTYZB.js.map +1 -0
  93. package/package.json +5 -1
  94. package/dist/chunk-CQE46HSM.js.map +0 -1
  95. package/dist/chunk-JZMJUPZP.js.map +0 -1
  96. package/dist/chunk-NL7CVG56.js.map +0 -1
  97. package/dist/chunk-QGI4UCJX.js.map +0 -1
  98. package/dist/chunk-QQVWGWPI.js.map +0 -1
  99. package/dist/chunk-YN763NWQ.js.map +0 -1
  100. package/dist/chunk-ZD3KHESI.js.map +0 -1
  101. package/dist/docs-DIAFBDXQ.js.map +0 -1
  102. package/dist/feature-flag-XG26RURR.js.map +0 -1
  103. package/dist/knobs-A2BOBH22.js.map +0 -1
  104. package/dist/redis-DHZXHL4S.js.map +0 -1
  105. package/dist/sandbox-DWSGLY7B.js.map +0 -1
  106. package/dist/session-Y5RHU54D.js.map +0 -1
  107. package/dist/src-BGDRMOKC.js.map +0 -1
  108. package/dist/trace-A3ZY6K26.js +0 -16
  109. package/dist/workflow-2CX3ZNOQ.js.map +0 -1
  110. package/dist/workflow-cache-GXNE6SU2.js.map +0 -1
  111. package/dist/workflow-proposals-BW327WGL.js.map +0 -1
  112. /package/dist/{api-catalog-7HLEN7C2.js.map → api-catalog-CAJUASVC.js.map} +0 -0
  113. /package/dist/{attachment-OVNQD6Z2.js.map → attachment-RL4AZUJE.js.map} +0 -0
  114. /package/dist/{auth-VUHL74FH.js.map → auth-DURHUZDW.js.map} +0 -0
  115. /package/dist/{chunk-VGTKUOYS.js.map → chunk-AQPJQ5AE.js.map} +0 -0
  116. /package/dist/{chunk-Z5LUTUDN.js.map → chunk-G5SXUXSU.js.map} +0 -0
  117. /package/dist/{chunk-ZTOE3ND3.js.map → chunk-HKQ5XQAQ.js.map} +0 -0
  118. /package/dist/{chunk-PZ4LCN6K.js.map → chunk-IGHDIWZU.js.map} +0 -0
  119. /package/dist/{chunk-EJ4U242G.js.map → chunk-UZ2ZA5A6.js.map} +0 -0
  120. /package/dist/{chunk-EEN2TZUQ.js.map → chunk-VKBTI5EF.js.map} +0 -0
  121. /package/dist/{chunk-ENDHMYEJ.js.map → chunk-ZXRVFFCY.js.map} +0 -0
  122. /package/dist/{credential-LO2SEEHU.js.map → credential-JGVSEGVH.js.map} +0 -0
  123. /package/dist/{credential-template-ZN7W7734.js.map → credential-template-CWWMOKB2.js.map} +0 -0
  124. /package/dist/{debug-workflow-R3RYYAXK.js.map → debug-workflow-BXRU72YZ.js.map} +0 -0
  125. /package/dist/{doctor-NZPUSCRE.js.map → doctor-RHMKD4W5.js.map} +0 -0
  126. /package/dist/{environment-RQVU4P5M.js.map → environment-WZKIO3R3.js.map} +0 -0
  127. /package/dist/{init-EDNLKGPT.js.map → init-FFUZO5D7.js.map} +0 -0
  128. /package/dist/{install-FYZ3HNZK.js.map → install-XRKEQAFZ.js.map} +0 -0
  129. /package/dist/{issues-NNRVTJ4L.js.map → issues-I3V6GEXU.js.map} +0 -0
  130. /package/dist/{list-F33VZ4BJ.js.map → list-PHC7VYNS.js.map} +0 -0
  131. /package/dist/{local-DQDTM3XA.js.map → local-VGYRSW22.js.map} +0 -0
  132. /package/dist/{login-BUMVIB36.js.map → login-QPU2BKG2.js.map} +0 -0
  133. /package/dist/{pdf-extract-ABWV3L5X.js.map → pdf-extract-YHE54XU4.js.map} +0 -0
  134. /package/dist/{property-NJ4SRXQG.js.map → property-YP4GHQAR.js.map} +0 -0
  135. /package/dist/{psql-VBZFCMNR.js.map → psql-XGLBI6T7.js.map} +0 -0
  136. /package/dist/{record-WAO36O7G.js.map → record-KWKHP2ZY.js.map} +0 -0
  137. /package/dist/{release-STJKUKTE.js.map → release-NDRHPW6V.js.map} +0 -0
  138. /package/dist/{scenarios-HCIDY725.js.map → scenarios-2HRLCGFY.js.map} +0 -0
  139. /package/dist/{spec-LM5XHOQ5.js.map → spec-XZ2TKUFZ.js.map} +0 -0
  140. /package/dist/{src-NCJPUAE6.js.map → src-CV57ZD6I.js.map} +0 -0
  141. /package/dist/{src-22RI5VP2.js.map → src-HL7HEJIW.js.map} +0 -0
  142. /package/dist/{src-Y3K7UJEF.js.map → src-OU7544PM.js.map} +0 -0
  143. /package/dist/{start-SWY55CZX.js.map → start-IYKF3C3X.js.map} +0 -0
  144. /package/dist/{tag-YSU2XXPI.js.map → tag-T45MMSCH.js.map} +0 -0
  145. /package/dist/{task-NLBKLD7D.js.map → task-MCUHAVTD.js.map} +0 -0
  146. /package/dist/{trace-A3ZY6K26.js.map → trace-2BAPMYAS.js.map} +0 -0
  147. /package/dist/{triage-TT4BMDBU.js.map → triage-M3RZ2ASB.js.map} +0 -0
  148. /package/dist/{upgrade-6ZUFETKX.js.map → upgrade-4QCRAUHP.js.map} +0 -0
  149. /package/dist/{workflow-debug-PRX3DWGD.js.map → workflow-debug-W4USZH35.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/session/index.ts","../src/session/claude-settings.ts","../src/session/credentials.ts","../src/session/daemon.ts","../src/session/controller-badge.ts","../src/session/user-takeover.ts","../src/session/cdp-proxy/mcp-client.ts","../src/session/cdp-proxy/translators.ts","../src/session/cdp-proxy/index.ts"],"sourcesContent":["/**\n * CLI session command — `canary session <subcommand>`.\n *\n * Flat subcommands for session lifecycle and browser tool execution.\n * All commands delegate to the session daemon via HTTP.\n *\n * @module\n */\n\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { getArgValue, hasFlag, resolveConfig } from '../auth.js';\nimport {\n createSession,\n listSessions,\n getSession,\n deleteSession,\n deleteAllSessions,\n swapSessionContext,\n getSessionStorageState,\n callTool,\n resolveTargetSession,\n takeControl,\n resumeCloud,\n} from './daemon-client.js';\nimport {\n findClaudeSettingsDir,\n hasScreenshotPermission,\n addScreenshotPermission,\n getScreenshotReadPattern,\n} from './claude-settings.js';\nimport { selectCredential, uploadStorageState } from '../cli-helpers.js';\nimport { resolveCredential } from './credentials.js';\nimport { runDaemon } from './daemon.js';\nimport type { SessionInfo, ToolResponse } from './types.js';\n\n/** Predictable screenshot directory under the user's home. */\nfunction getScreenshotDir() {\n return path.join(os.homedir(), '.canary', 'screenshots');\n}\n\n/** Delete all screenshot files (but keep the directory). */\nfunction cleanupScreenshots() {\n const dir = getScreenshotDir();\n if (!fs.existsSync(dir)) return;\n for (const file of fs.readdirSync(dir)) {\n fs.unlinkSync(path.join(dir, file));\n }\n}\n\n/** Delete screenshot files older than 1 hour (stale from crashed sessions). */\nfunction cleanupStaleScreenshots() {\n const dir = getScreenshotDir();\n if (!fs.existsSync(dir)) return;\n const cutoff = Date.now() - 60 * 60 * 1000;\n for (const file of fs.readdirSync(dir)) {\n const filePath = path.join(dir, file);\n try {\n const stat = fs.statSync(filePath);\n if (stat.isFile() && stat.mtimeMs < cutoff) {\n fs.unlinkSync(filePath);\n }\n } catch {\n // Ignore races\n }\n }\n}\n\n/* ── Output formatting ───────────────────────────────────────────────── */\n\nfunction formatDuration(since: string): string {\n const seconds = Math.floor((Date.now() - new Date(since).getTime()) / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const secs = seconds % 60;\n if (minutes < 60) return `${minutes}m ${secs}s`;\n const hours = Math.floor(minutes / 60);\n const mins = minutes % 60;\n return `${hours}h ${mins}m`;\n}\n\nfunction printSessionTable(sessions: SessionInfo[]) {\n if (sessions.length === 0) {\n console.log('No active sessions.');\n return;\n }\n\n const header = ['ID', 'NAME', 'MODE', 'CREDENTIAL', 'URL', 'UPTIME', 'IDLE'];\n const rows = sessions.map((s) => [\n s.id,\n s.name,\n s.mode,\n s.credentialName ?? '(none)',\n s.url ?? '(none)',\n formatDuration(s.startedAt),\n formatDuration(s.lastActivityAt),\n ]);\n\n // Calculate column widths\n const widths = header.map((h, i) =>\n Math.max(h.length, ...rows.map((r) => r[i].length))\n );\n\n const pad = (str: string, width: number) => str.padEnd(width);\n console.log(header.map((h, i) => pad(h, widths[i])).join(' '));\n for (const row of rows) {\n console.log(row.map((cell, i) => pad(cell, widths[i])).join(' '));\n }\n}\n\nfunction printToolResult(result: ToolResponse, jsonMode: boolean) {\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n if (result.text) {\n console.log(result.text);\n }\n\n if (result.images?.length) {\n const screenshotDir = getScreenshotDir();\n fs.mkdirSync(screenshotDir, { recursive: true });\n for (const img of result.images) {\n const ext = img.mimeType === 'image/png' ? 'png' : 'jpg';\n const filePath = path.join(screenshotDir, `screenshot-${Date.now()}.${ext}`);\n fs.writeFileSync(filePath, Buffer.from(img.data, 'base64'));\n console.log(`Screenshot saved: ${filePath}`);\n }\n }\n}\n\n/* ── Subcommand: start ───────────────────────────────────────────────── */\n\nasync function handleStart(argv: string[]) {\n // Clean up stale screenshots from crashed/killed sessions\n cleanupStaleScreenshots();\n\n const headless = hasFlag(argv, '--headless');\n const name = getArgValue(argv, '--name');\n const url = getArgValue(argv, '--url');\n const storageStatePath = getArgValue(argv, '--storage-state');\n const jsonMode = hasFlag(argv, '--json');\n const attachRealChrome = hasFlag(argv, '--attach-real-chrome');\n\n if (attachRealChrome) {\n const conflicts: string[] = [];\n if (headless) conflicts.push('--headless');\n if (storageStatePath) conflicts.push('--storage-state');\n if (url) conflicts.push('--url');\n if (argv.includes('--credential')) conflicts.push('--credential');\n if (argv.includes('--cloud-relay')) conflicts.push('--cloud-relay');\n if (conflicts.length > 0) {\n console.error(\n `Error: --attach-real-chrome cannot be combined with: ${conflicts.join(', ')}`,\n );\n console.error('Attached mode uses the live browser\\'s profile and tabs.');\n process.exitCode = 1;\n return;\n }\n\n const result = await createSession({ attachRealChrome: true, name });\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n console.error(\n 'Hint: in your real Chrome, open chrome://inspect/#remote-debugging and approve remote debugging (Chrome 144+).',\n );\n process.exitCode = 1;\n return;\n }\n const session = result.data!;\n console.log(`Session \"${session.id}\" attached to your real Chrome (M144+).`);\n console.log(' Chrome is showing the \"controlled by automated test software\" banner.');\n console.log(` Stop with: canary session stop ${session.id}`);\n return;\n }\n\n // Credential handling\n const credentialIdx = argv.indexOf('--credential');\n let resolvedCred: { storageStatePath: string | undefined; credentialName: string } | null = null;\n\n if (credentialIdx !== -1) {\n // Check if next arg is a value or another flag\n const nextArg = argv[credentialIdx + 1];\n const credentialArg = nextArg && !nextArg.startsWith('--') ? nextArg : undefined;\n resolvedCred = await resolveCredential(argv, credentialArg);\n if (!resolvedCred) {\n process.exitCode = 1;\n return;\n }\n }\n\n // Cloud relay setup\n let cloudRelay: { apiUrl: string; token: string } | undefined;\n if (hasFlag(argv, '--cloud-relay')) {\n const config = await resolveConfig(argv);\n cloudRelay = { apiUrl: config.apiUrl, token: config.token };\n }\n\n const result = await createSession({\n headless,\n name,\n url,\n storageStatePath: resolvedCred?.storageStatePath ?? storageStatePath,\n credentialName: resolvedCred?.credentialName,\n cloudRelay,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const session = result.data!;\n console.log(`Session \"${session.id}\" started (${session.mode})`);\n if (session.credentialName) {\n console.log(` Credential: ${session.credentialName}`);\n }\n // Show the requested URL if provided, since the daemon responds before navigation completes\n const displayUrl = url ?? session.url;\n if (displayUrl) {\n console.log(` URL: ${displayUrl}`);\n }\n if (cloudRelay) {\n console.log(` Cloud relay: connecting...`);\n }\n\n // Hint about screenshot permissions for Claude Code users\n if (!jsonMode) {\n const settingsDir = findClaudeSettingsDir();\n if (settingsDir && !hasScreenshotPermission(settingsDir)) {\n console.log('');\n console.log(' Tip: Claude needs permission to read screenshots.');\n console.log(' Run: canary session allow-screenshots');\n }\n }\n}\n\n/* ── Subcommand: list ────────────────────────────────────────────────── */\n\nasync function handleList(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n const result = await listSessions();\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n printSessionTable(result.data ?? []);\n}\n\n/* ── Subcommand: status ──────────────────────────────────────────────── */\n\nasync function handleStatus(argv: string[]) {\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await getSession(target.id);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok || !result.data) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const s = result.data;\n console.log(`Session: ${s.id} (${s.name})`);\n console.log(` Mode: ${s.mode}`);\n console.log(` Credential: ${s.credentialName ?? '(none)'}`);\n console.log(` URL: ${s.url ?? '(none)'}`);\n console.log(` Controller: ${s.lock.controller}${s.lock.cloudPaused ? ' (cloud paused)' : ''}`);\n if (s.cloudRelay) {\n console.log(` Cloud relay: ${s.cloudRelay.connected ? 'connected' : 'disconnected'}`);\n }\n console.log(` Uptime: ${formatDuration(s.startedAt)}`);\n console.log(` Idle: ${formatDuration(s.lastActivityAt)}`);\n console.log(` Started: ${s.startedAt}`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Subcommand: stop ────────────────────────────────────────────────── */\n\nasync function handleStop(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n\n if (hasFlag(argv, '--all')) {\n const result = await deleteAllSessions();\n if (result.ok) cleanupScreenshots();\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n } else if (result.ok) {\n console.log('All sessions stopped.');\n } else {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n }\n return;\n }\n\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await deleteSession(target.id);\n\n if (result.ok) {\n // Clean up screenshots if no sessions remain\n const remaining = await listSessions();\n if (remaining.ok && (!remaining.data || remaining.data.length === 0)) {\n cleanupScreenshots();\n }\n }\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n } else if (result.ok) {\n console.log(`Session \"${target.id}\" stopped.`);\n } else {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Subcommand: load-credential ────────────────────────────────────── */\n\nasync function handleLoadCredential(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n\n // Resolve which session to target\n let target;\n try {\n target = await resolveTargetSession(sessionId);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n return;\n }\n\n // Credential selection (interactive by default, or --credential <name|id>)\n const credentialIdx = argv.indexOf('--credential');\n const nextArg = credentialIdx !== -1 ? argv[credentialIdx + 1] : undefined;\n const credentialArg = nextArg && !nextArg.startsWith('--') ? nextArg : undefined;\n\n // Also support --storage-state for local files\n const storageStatePath = getArgValue(argv, '--storage-state');\n\n let resolvedStorageStatePath: string | undefined;\n let credentialName: string | undefined;\n\n if (storageStatePath) {\n resolvedStorageStatePath = storageStatePath;\n credentialName = '(local storage state)';\n } else {\n // Interactive or named credential resolution\n const resolvedCred = await resolveCredential(argv, credentialArg);\n if (!resolvedCred) {\n process.exitCode = 1;\n return;\n }\n resolvedStorageStatePath = resolvedCred.storageStatePath;\n credentialName = resolvedCred.credentialName;\n }\n\n const result = await swapSessionContext(target.id, {\n storageStatePath: resolvedStorageStatePath,\n credentialName,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const session = result.data!;\n console.log(`Credential loaded into session \"${session.id}\".`);\n if (session.credentialName) {\n console.log(` Credential: ${session.credentialName}`);\n }\n if (session.url) {\n console.log(` URL: ${session.url}`);\n }\n}\n\n/* ── Subcommand: save-credential ───────────────────────────────────── */\n\nasync function handleSaveCredential(argv: string[]) {\n const jsonMode = hasFlag(argv, '--json');\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n\n let target: SessionInfo;\n try {\n target = await resolveTargetSession(sessionId);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n return;\n }\n\n const { apiUrl, token } = await resolveConfig(argv);\n const credentialIdx = argv.indexOf('--credential');\n const nextArg = credentialIdx !== -1 ? argv[credentialIdx + 1] : undefined;\n const credentialHint = nextArg && !nextArg.startsWith('--') ? nextArg : undefined;\n\n // If no --credential flag, fall back to the session's credential name\n const credential = await selectCredential(apiUrl, token, credentialHint ?? target.credentialName);\n if (!credential) {\n console.error('Could not resolve credential. Use --credential <name|id>.');\n process.exitCode = 1;\n return;\n }\n\n const storageResult = await getSessionStorageState(target.id);\n if (!storageResult.ok || !storageResult.data) {\n const msg = storageResult.error ?? 'Unknown error';\n if (jsonMode) {\n console.log(JSON.stringify({ ok: false, error: msg }));\n } else {\n console.error(`Failed to extract storage state: ${msg}`);\n }\n process.exitCode = 1;\n return;\n }\n\n const uploadResult = await uploadStorageState({\n apiUrl,\n token,\n propertyId: credential.propertyId,\n credentialId: credential.id,\n storageState: storageResult.data,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(uploadResult));\n return;\n }\n\n if (!uploadResult.ok) {\n console.error(`Failed to save: ${uploadResult.error ?? 'Unknown error'}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Credential \"${credential.name}\" storage state saved.`);\n}\n\n/* ── Subcommand: allow-screenshots ──────────────────────────────────── */\n\nfunction handleAllowScreenshots() {\n const settingsDir = findClaudeSettingsDir();\n if (!settingsDir) {\n console.error(\n 'Error: No .claude/ directory found. Run this inside a project with Claude Code configured.'\n );\n process.exitCode = 1;\n return;\n }\n\n const result = addScreenshotPermission(settingsDir);\n if (result.alreadyPresent) {\n console.log('Screenshot read permission already configured.');\n console.log(` Pattern: ${getScreenshotReadPattern()}`);\n } else {\n console.log('Added screenshot read permission to .claude/settings.local.json:');\n console.log(` ${result.added}`);\n }\n}\n\n/* ── Subcommand: take-control ───────────────────────────────────────── */\n\nasync function handleTakeControl(argv: string[]) {\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await takeControl(target.id);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n const session = result.data!;\n console.log(`CLI now controls session \"${session.id}\".`);\n if (session.lock.cloudPaused) {\n console.log(' Cloud execution paused. Resume with: canary session resume-cloud');\n }\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Subcommand: resume-cloud ──────────────────────────────────────── */\n\nasync function handleResumeCloud(argv: string[]) {\n const sessionId =\n getArgValue(argv, '--session') ||\n (argv[0] && !argv[0].startsWith('--') ? argv[0] : undefined);\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionId);\n const result = await resumeCloud(target.id);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (!result.ok) {\n console.error(`Error: ${result.error}`);\n process.exitCode = 1;\n return;\n }\n\n console.log(`Cloud execution resumed for session \"${result.data!.id}\".`);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\n/* ── Browser tool subcommands ────────────────────────────────────────── */\n\nasync function handleToolCommand(toolName: string, argv: string[]) {\n const sessionIdOrName = getArgValue(argv, '--session');\n const jsonMode = hasFlag(argv, '--json');\n\n try {\n const target = await resolveTargetSession(sessionIdOrName);\n const args = buildToolArgs(toolName, argv);\n const result = await callTool(target.id, toolName, args);\n printToolResult(result, jsonMode);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n}\n\nexport function buildToolArgs(toolName: string, argv: string[]): Record<string, unknown> {\n const args: Record<string, unknown> = {};\n\n switch (toolName) {\n case 'navigate':\n args.url = getArgValue(argv, '--url');\n break;\n\n case 'snapshot':\n args.search = getArgValue(argv, '--search');\n args.expand = getArgValue(argv, '--expand');\n args.mode = getArgValue(argv, '--mode') ?? 'tree';\n break;\n\n case 'screenshot':\n args.fullPage = hasFlag(argv, '--full-page');\n args.label = getArgValue(argv, '--label');\n args.returnImage = true;\n break;\n\n case 'evaluate':\n args.function = getArgValue(argv, '--js');\n break;\n\n case 'click': {\n const ref = getArgValue(argv, '--ref');\n const x = getArgValue(argv, '--x');\n const y = getArgValue(argv, '--y');\n if (ref) args.ref = ref;\n if (x) args.x = parseInt(x, 10);\n if (y) args.y = parseInt(y, 10);\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n }\n\n case 'type':\n args.ref = getArgValue(argv, '--ref');\n args.text = getArgValue(argv, '--text');\n args.element = getArgValue(argv, '--element') ?? '';\n args.submit = hasFlag(argv, '--submit');\n break;\n\n case 'fill_form': {\n const fieldsStr = getArgValue(argv, '--fields');\n if (fieldsStr) {\n try {\n args.fields = JSON.parse(fieldsStr);\n } catch {\n console.error('Error: --fields must be valid JSON');\n process.exitCode = 1;\n }\n }\n break;\n }\n\n case 'select_option':\n args.ref = getArgValue(argv, '--ref');\n args.value = getArgValue(argv, '--value');\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n\n case 'press_key':\n args.key = getArgValue(argv, '--key');\n break;\n\n case 'scroll':\n args.direction = getArgValue(argv, '--direction') ?? 'down';\n {\n const amount = getArgValue(argv, '--amount');\n if (amount) args.amount = parseInt(amount, 10);\n }\n break;\n\n case 'hover':\n args.ref = getArgValue(argv, '--ref');\n args.element = getArgValue(argv, '--element') ?? '';\n break;\n\n case 'drag': {\n // Two modes: refs (start-ref/end-ref) or coordinates (start-x/y, end-x/y).\n const startRef = getArgValue(argv, '--start-ref');\n const endRef = getArgValue(argv, '--end-ref');\n if (startRef) args.startRef = startRef;\n if (endRef) args.endRef = endRef;\n for (const [flag, key] of [\n ['--start-x', 'startX'],\n ['--start-y', 'startY'],\n ['--end-x', 'endX'],\n ['--end-y', 'endY'],\n ] as const) {\n const value = getArgValue(argv, flag);\n if (value) args[key] = parseInt(value, 10);\n }\n // startElement/endElement are required by the tool schema.\n args.startElement = getArgValue(argv, '--start-element') ?? '';\n args.endElement = getArgValue(argv, '--end-element') ?? '';\n break;\n }\n\n case 'tabs': {\n args.action = getArgValue(argv, '--action') ?? 'list';\n const index = getArgValue(argv, '--index');\n if (index) args.index = parseInt(index, 10);\n break;\n }\n\n case 'wait_for': {\n args.text = getArgValue(argv, '--text');\n const timeout = getArgValue(argv, '--timeout');\n if (timeout) args.timeout = parseInt(timeout, 10);\n break;\n }\n\n case 'console_messages':\n args.onlyErrors = hasFlag(argv, '--only-errors');\n break;\n\n case 'file_upload': {\n const paths = getArgValue(argv, '--paths');\n args.paths = paths\n ? paths\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean)\n : [];\n break;\n }\n\n case 'resize': {\n const width = getArgValue(argv, '--width');\n const height = getArgValue(argv, '--height');\n if (width) args.width = parseInt(width, 10);\n if (height) args.height = parseInt(height, 10);\n break;\n }\n\n case 'dismiss_overlay': {\n const strategy = getArgValue(argv, '--strategy');\n if (strategy) args.preferredStrategy = strategy;\n break;\n }\n\n case 'handle_dialog': {\n args.action = getArgValue(argv, '--action') ?? 'accept';\n const promptText = getArgValue(argv, '--prompt-text');\n if (promptText) args.promptText = promptText;\n break;\n }\n\n case 'read_download': {\n const id = getArgValue(argv, '--id');\n if (id) args.downloadId = parseInt(id, 10);\n break;\n }\n\n case 'pdf_read':\n args.url = getArgValue(argv, '--url');\n break;\n\n // navigate_back, network_requests, close, list_downloads\n // have no special args or use defaults\n }\n\n return args;\n}\n\n/* ── Command aliases ─────────────────────────────────────────────────── */\n\n/** Map flat CLI subcommands to browser tool names */\nconst TOOL_ALIASES: Record<string, string> = {\n navigate: 'navigate',\n back: 'navigate_back',\n snapshot: 'snapshot',\n screenshot: 'screenshot',\n evaluate: 'evaluate',\n click: 'click',\n type: 'type',\n fill: 'fill_form',\n select: 'select_option',\n press: 'press_key',\n scroll: 'scroll',\n hover: 'hover',\n drag: 'drag',\n tabs: 'tabs',\n wait: 'wait_for',\n console: 'console_messages',\n network: 'network_requests',\n upload: 'file_upload',\n resize: 'resize',\n dismiss: 'dismiss_overlay',\n dialog: 'handle_dialog',\n downloads: 'list_downloads',\n 'read-download': 'read_download',\n pdf: 'pdf_read',\n};\n\n/* ── Help ────────────────────────────────────────────────────────────── */\n\nfunction printHelp() {\n console.log(\n [\n 'Usage: canary session <subcommand> [options]',\n '',\n 'Session lifecycle:',\n ' start [options] Start a new browser session',\n ' list List active sessions',\n ' status [<id>] Show session details',\n ' stop [<id>] Stop a session (or --all)',\n ' load-credential Load a credential into a running session',\n ' save-credential Save session login state back to its credential',\n ' allow-screenshots Grant Claude auto-read access to session screenshots',\n '',\n 'Control:',\n ' take-control [<id>] Force CLI control (pauses cloud execution)',\n ' resume-cloud [<id>] Resume paused cloud execution',\n '',\n 'Browser actions:',\n ' navigate --url <url> Navigate to URL',\n ' back Navigate back',\n ' snapshot [--search <text>] [--expand <ref>] [--mode tree|screenshot|both]',\n ' screenshot [--full-page] [--label <text>]',\n ' evaluate --js <expression> Evaluate JavaScript',\n ' click --ref <ref> [--element <desc>]',\n ' click --x <n> --y <n> [--element <desc>]',\n ' type --ref <ref> --text <text> [--submit]',\n ' fill --fields \\'[{\"ref\":\"e1\",\"value\":\"test\"}]\\'',\n ' select --ref <ref> --value <val> [--element <desc>]',\n ' press --key <key> Press keyboard key',\n ' scroll --direction <dir> [--amount <n>]',\n ' hover --ref <ref> [--element <desc>]',\n ' drag --start-ref <ref> --end-ref <ref> [--start-element <desc>] [--end-element <desc>]',\n ' drag --start-x <n> --start-y <n> --end-x <n> --end-y <n>',\n ' tabs [--action list|new|close|select] [--index <n>]',\n ' wait --text <text> [--timeout <ms>]',\n ' console [--only-errors] Show console messages',\n ' network Show network requests',\n ' upload --paths <p1,p2,...> Upload one or more files',\n ' resize --width <n> --height <n> Resize the browser viewport',\n ' dialog --action accept|dismiss [--prompt-text <text>]',\n ' dismiss [--strategy escape|close_button|backdrop|auto]',\n ' downloads List files downloaded this session',\n ' read-download [--id <n>] Read a downloaded file (PDF text extracted)',\n ' pdf --url <url> Fetch a PDF and extract its text',\n '',\n 'Start options:',\n ' --credential [<name|id>] Use a credential (interactive if no value)',\n ' --storage-state <path> Use a local storage state file',\n ' --headless Run browser without visible UI',\n ' --url <url> Navigate to URL after launch',\n ' --name <label> Name the session',\n ' --cloud-relay Connect session to cloud API for remote control',\n ' --attach-real-chrome Attach to the user\\'s running Chrome via chrome-devtools-mcp.',\n ' Requires Chrome 144+ with remote debugging enabled at',\n ' chrome://inspect/#remote-debugging. Uses the live profile —',\n ' not compatible with --headless/--credential/--storage-state/--url.',\n '',\n 'Load-credential options:',\n ' --credential [<name|id>] Use a credential (interactive if no value)',\n ' --storage-state <path> Use a local storage state file',\n '',\n 'Save-credential options:',\n ' --credential [<name|id>] Target credential (defaults to session\\'s credential)',\n '',\n 'Common options:',\n ' --session <id|name> Target a specific session (when multiple)',\n ' --json Output raw JSON',\n ' --env <env> Environment for credential resolution',\n ' -h, --help Show this help',\n ].join('\\n')\n );\n}\n\n/* ── Main entry ──────────────────────────────────────────────────────── */\n\nexport async function runSession(argv: string[]) {\n const [subcommand, ...rest] = argv;\n\n if (!subcommand || subcommand === 'help' || hasFlag(argv, '-h', '--help')) {\n printHelp();\n return;\n }\n\n // Internal: daemon process mode\n if (subcommand === 'daemon') {\n await runDaemon();\n return;\n }\n\n switch (subcommand) {\n case 'start':\n await handleStart(rest);\n break;\n case 'list':\n await handleList(rest);\n break;\n case 'status':\n await handleStatus(rest);\n break;\n case 'stop':\n await handleStop(rest);\n break;\n case 'load-credential':\n await handleLoadCredential(rest);\n break;\n case 'save-credential':\n await handleSaveCredential(rest);\n break;\n case 'allow-screenshots':\n handleAllowScreenshots();\n break;\n case 'take-control':\n await handleTakeControl(rest);\n break;\n case 'resume-cloud':\n await handleResumeCloud(rest);\n break;\n default: {\n // Check for tool alias\n const toolName = TOOL_ALIASES[subcommand];\n if (toolName) {\n await handleToolCommand(toolName, rest);\n } else {\n console.error(`Unknown session subcommand: ${subcommand}`);\n printHelp();\n process.exitCode = 1;\n }\n }\n }\n}\n","/**\n * Utilities for finding and modifying `.claude/settings.local.json`\n * to grant screenshot read permissions.\n *\n * @module\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\n\n/** Walk up from `startDir` looking for a `.claude/` directory. */\nexport function findClaudeSettingsDir(startDir: string = process.cwd()): string | null {\n let dir = path.resolve(startDir);\n const root = path.parse(dir).root;\n\n while (dir !== root) {\n const candidate = path.join(dir, '.claude');\n if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {\n return candidate;\n }\n dir = path.dirname(dir);\n }\n return null;\n}\n\n/** The predictable screenshot directory path. */\nexport function getScreenshotDirPath(): string {\n return path.join(os.homedir(), '.canary', 'screenshots');\n}\n\n/** The Read permission pattern for the screenshot directory. */\nexport function getScreenshotReadPattern(): string {\n return `Read(${getScreenshotDirPath()}/**)`;\n}\n\n/** Check if the screenshot Read permission is already configured. */\nexport function hasScreenshotPermission(settingsDir: string): boolean {\n const filePath = path.join(settingsDir, 'settings.local.json');\n if (!fs.existsSync(filePath)) return false;\n\n try {\n const content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const allow: unknown[] = content?.permissions?.allow ?? [];\n const pattern = getScreenshotReadPattern();\n return allow.includes(pattern);\n } catch {\n return false;\n }\n}\n\n/** Add the screenshot Read permission to settings.local.json. Idempotent. */\nexport function addScreenshotPermission(settingsDir: string): {\n added: string | null;\n alreadyPresent: boolean;\n} {\n const filePath = path.join(settingsDir, 'settings.local.json');\n const pattern = getScreenshotReadPattern();\n\n let content: Record<string, unknown> = {};\n if (fs.existsSync(filePath)) {\n try {\n content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n } catch (err) {\n throw new Error(\n `Failed to parse ${filePath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // Ensure permissions.allow exists\n if (!content.permissions || typeof content.permissions !== 'object') {\n content.permissions = { allow: [], deny: [], ask: [] };\n }\n const permissions = content.permissions as Record<string, unknown>;\n if (!Array.isArray(permissions.allow)) {\n permissions.allow = [];\n }\n const allow = permissions.allow as string[];\n\n if (allow.includes(pattern)) {\n return { added: null, alreadyPresent: true };\n }\n\n allow.push(pattern);\n fs.writeFileSync(filePath, JSON.stringify(content, null, 2) + '\\n', 'utf-8');\n return { added: pattern, alreadyPresent: false };\n}\n","/**\n * Credential resolution and storage state download for session commands.\n *\n * Uses shared selectCredential from cli-helpers for interactive selection,\n * then downloads the storage state for the selected credential.\n *\n * @module\n */\n\nimport { resolveConfig } from '../auth.js';\nimport { selectCredential, downloadStorageState } from '../cli-helpers.js';\n\n/**\n * Resolve a credential and download its storage state.\n *\n * @param argv - CLI arguments (for --env, --token, --api-url resolution)\n * @param credentialArg - Credential name, ID, or undefined for interactive selection\n * @returns Object with storageStatePath and credentialName, or null if no match\n */\nexport async function resolveCredential(\n argv: string[],\n credentialArg: string | undefined\n): Promise<{ storageStatePath: string | undefined; credentialName: string } | null> {\n const { apiUrl, token } = await resolveConfig(argv);\n\n const credential = await selectCredential(apiUrl, token, credentialArg);\n if (!credential) {\n return null;\n }\n\n console.log(`Fetching credential \"${credential.name}\"...`);\n\n let storageStatePath: string | undefined;\n if (credential.storageStateS3Key) {\n storageStatePath = await downloadStorageState({\n apiUrl,\n token,\n propertyId: credential.propertyId,\n credentialId: credential.id,\n prefix: 'session-ss',\n });\n\n if (storageStatePath) {\n console.log('Downloaded storage state.');\n } else {\n console.warn('Warning: Could not download storage state. Starting without auth.');\n }\n } else {\n console.log('Credential has no storage state. Starting without auth.');\n }\n\n return {\n storageStatePath,\n credentialName: credential.name,\n };\n}\n","/**\n * Session daemon — lightweight HTTP server that owns all browser sessions.\n *\n * Runs on localhost with an OS-assigned port. Both CLI and MCP delegate\n * browser lifecycle and tool execution to this daemon.\n *\n * @module\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport os from 'node:os';\nimport {\n PlaywrightClient,\n BrowserToolExecutor,\n consoleLogger,\n dispatchBrowserToolWithTimeout,\n} from '@chatsdet/browser-core';\nimport { LocalBrowserHost } from '../local-browser/host.js';\nimport type {\n DaemonState,\n SessionInfo,\n SessionLock,\n CreateSessionRequest,\n SwapContextRequest,\n DaemonResponse,\n ToolResponse,\n} from './types.js';\nimport { USER_PAUSED_ERROR } from './types.js';\nimport { updateControllerBadge, INTERACTIVE_BADGE_SCRIPT } from './controller-badge.js';\nimport {\n checkPauseAndDrainEvents,\n discardCapturedEvents,\n startPauseEnrichment,\n stopPauseEnrichment,\n cleanupPauseTimer,\n injectCaptureScript,\n formatUserActionsSummary,\n type TakeoverSession,\n} from './user-takeover.js';\nimport { CdpProxyClient } from './cdp-proxy/index.js';\n\nconst PIDFILE_DIR = path.join(os.homedir(), '.config', 'canary-cli');\nconst PIDFILE_PATH = path.join(PIDFILE_DIR, 'daemon.json');\nconst IDLE_TIMEOUT_MS = 60_000;\n\n/** Auto-stop sessions that have had no activity for this long (default 1h). */\nconst SESSION_IDLE_TIMEOUT_MS = (() => {\n const env = process.env.CANARY_SESSION_IDLE_TIMEOUT_MS;\n if (env) {\n const n = Number(env);\n if (Number.isFinite(n) && n > 0) return n;\n }\n return 60 * 60 * 1000;\n})();\n/** How often the idle sweep runs. */\nconst SESSION_IDLE_SWEEP_INTERVAL_MS = 5 * 60 * 1000;\n\ninterface PlaywrightManagedSession extends TakeoverSession {\n kind: 'playwright';\n name: string;\n credentialName?: string;\n startedAt: string;\n lastActivityAt: string;\n lock: SessionLock;\n /** Cloud-relay WebSocket host (when connected to cloud API) */\n relayHost?: LocalBrowserHost;\n /** Cloud session ID (from /local-browser/sessions) */\n localBrowserSessionId?: string;\n}\n\ninterface AttachedManagedSession {\n kind: 'attached';\n id: string;\n name: string;\n mode: 'attached';\n startedAt: string;\n lastActivityAt: string;\n lock: SessionLock;\n cdpProxy: CdpProxyClient;\n}\n\ntype ManagedSession = PlaywrightManagedSession | AttachedManagedSession;\n\nfunction isAttached(s: ManagedSession): s is AttachedManagedSession {\n return s.kind === 'attached';\n}\n\nconst sessions = new Map<string, ManagedSession>();\nlet nextId = 1;\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\nlet idleSweepTimer: ReturnType<typeof setInterval> | null = null;\n\n/** Mark a session as having just had activity. Called on every action route. */\nfunction touch(s: ManagedSession) {\n s.lastActivityAt = new Date().toISOString();\n}\n\nfunction formatIdle(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${minutes % 60}m`;\n}\n\nfunction resetIdleTimer() {\n if (idleTimer) clearTimeout(idleTimer);\n if (sessions.size === 0) {\n idleTimer = setTimeout(async () => {\n if (sessions.size === 0) {\n await removePidfile();\n process.exit(0);\n }\n }, IDLE_TIMEOUT_MS);\n }\n}\n\nfunction generateId(): string {\n return `s${nextId++}`;\n}\n\nasync function getSessionUrl(session: ManagedSession): Promise<string | undefined> {\n if (isAttached(session)) {\n // Real Chrome — we'd have to query via the proxy; skip for now to keep\n // list/status cheap. The user knows what's in their browser.\n return undefined;\n }\n try {\n return await session.client.getCurrentUrl();\n } catch {\n return undefined;\n }\n}\n\nasync function toSessionInfo(s: ManagedSession): Promise<SessionInfo> {\n if (isAttached(s)) {\n return {\n id: s.id,\n name: s.name,\n mode: 'attached',\n credentialName: undefined,\n url: undefined,\n startedAt: s.startedAt,\n lastActivityAt: s.lastActivityAt,\n lock: s.lock,\n };\n }\n return {\n id: s.id,\n name: s.name,\n mode: s.mode,\n credentialName: s.credentialName,\n url: await getSessionUrl(s),\n startedAt: s.startedAt,\n lastActivityAt: s.lastActivityAt,\n lock: s.lock,\n cloudRelay: s.localBrowserSessionId\n ? { localBrowserSessionId: s.localBrowserSessionId, connected: !!s.relayHost }\n : undefined,\n };\n}\n\n/* ── Request parsing helpers ─────────────────────────────────────────── */\n\nasync function readBody(req: IncomingMessage): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nfunction parseJson(body: string): Record<string, unknown> {\n if (!body.trim()) return {};\n try {\n return JSON.parse(body);\n } catch {\n return {};\n }\n}\n\nfunction json(res: ServerResponse, status: number, data: unknown) {\n const body = JSON.stringify(data);\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Content-Length': Buffer.byteLength(body),\n });\n res.end(body);\n}\n\nfunction parseRoute(url: string): { path: string[]; query: Record<string, string> } {\n const [pathname] = url.split('?');\n const segments = pathname.split('/').filter(Boolean);\n return { path: segments, query: {} };\n}\n\n/* ── Cloud relay ────────────────────────────────────────────────────── */\n\ninterface CloudSessionResponse {\n ok: boolean;\n sessionId: string;\n wsToken: string;\n expiresAt: string;\n error?: string;\n}\n\nasync function setupCloudRelay(\n session: PlaywrightManagedSession,\n apiUrl: string,\n token: string\n): Promise<void> {\n // 1. Create cloud session\n const res = await fetch(`${apiUrl}/local-browser/sessions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ browserMode: 'playwright' }),\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to create cloud session: ${res.status} ${text}`);\n }\n\n const cloudSession = (await res.json()) as CloudSessionResponse;\n if (!cloudSession.ok) {\n throw new Error(`Cloud session creation failed: ${cloudSession.error}`);\n }\n\n session.localBrowserSessionId = cloudSession.sessionId;\n\n // 2. Create LocalBrowserHost with the session's existing PlaywrightClient\n const host = new LocalBrowserHost({\n apiUrl,\n wsToken: cloudSession.wsToken,\n sessionId: cloudSession.sessionId,\n browserMode: 'playwright',\n existingClient: session.client,\n skipBrowserLaunch: true,\n shouldExecute: () => session.lock.controller === 'cloud',\n onLog: (level, message, data) => {\n const fn =\n level === 'error'\n ? consoleLogger.error\n : level === 'warn'\n ? consoleLogger.warn\n : consoleLogger.info;\n fn(`[relay:${session.id}] ${message}`, data as Record<string, unknown>);\n },\n });\n\n await host.start();\n session.relayHost = host;\n}\n\n/* ── Route handlers ──────────────────────────────────────────────────── */\n\nasync function handleHealth(res: ServerResponse) {\n json(res, 200, { ok: true, sessions: sessions.size });\n}\n\nasync function handleCreateSession(body: string, res: ServerResponse) {\n const params = parseJson(body) as CreateSessionRequest;\n const id = generateId();\n const name = params.name ?? id;\n\n if (params.attachRealChrome) {\n // Mutex against options that only make sense for a fresh Playwright session.\n const conflicts: string[] = [];\n if (params.headless) conflicts.push('headless');\n if (params.credentialName) conflicts.push('credential');\n if (params.storageStatePath) conflicts.push('storage-state');\n if (params.url) conflicts.push('url');\n if (params.cloudRelay) conflicts.push('cloud-relay');\n if (conflicts.length > 0) {\n json(res, 400, {\n ok: false,\n error: `--attach-real-chrome cannot be combined with: ${conflicts.join(', ')} (attached mode uses the live browser's profile and tabs).`,\n } satisfies DaemonResponse);\n return;\n }\n for (const existing of sessions.values()) {\n if (existing.kind === 'attached') {\n json(res, 409, {\n ok: false,\n error: `Another attached session is already active (\"${existing.id}\"). Stop it first with: canary session stop ${existing.id}`,\n } satisfies DaemonResponse);\n return;\n }\n }\n\n try {\n const cdpProxy = new CdpProxyClient();\n await cdpProxy.start();\n const now = new Date().toISOString();\n const session: AttachedManagedSession = {\n kind: 'attached',\n id,\n name,\n mode: 'attached',\n startedAt: now,\n lastActivityAt: now,\n lock: { controller: 'cli', acquiredAt: now, cloudPaused: false },\n cdpProxy,\n };\n sessions.set(id, session);\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n json(res, 201, {\n ok: true,\n data: await toSessionInfo(session),\n } satisfies DaemonResponse<SessionInfo>);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies DaemonResponse);\n }\n return;\n }\n\n const mode = params.headless ? 'headless' : 'headed';\n\n try {\n const client = new PlaywrightClient({ logger: consoleLogger });\n await client.connect({\n browserMode: mode,\n storageStatePath: params.storageStatePath,\n cursorOverlay: mode === 'headed',\n });\n\n const executor = new BrowserToolExecutor(client, {\n autoSnapshotAfterAction: true,\n includeScreenshotWithSnapshot: true,\n clickValidation: true,\n logger: consoleLogger,\n });\n\n const now = new Date().toISOString();\n const session: PlaywrightManagedSession = {\n kind: 'playwright',\n id,\n name,\n mode,\n credentialName: params.credentialName,\n client,\n executor,\n startedAt: now,\n lastActivityAt: now,\n lock: { controller: 'cli', acquiredAt: now, cloudPaused: false },\n userPaused: false,\n userPausePollTimer: null,\n pauseEnrichedEvents: [],\n pauseResumeSnapshot: null,\n };\n\n // Inject interaction capture script and interactive badge for headed sessions.\n // Both use addInitScript so they survive page navigations.\n if (mode === 'headed') {\n await injectCaptureScript(client);\n const page = await client.getPageForReplay();\n if (page) {\n try {\n await page.addInitScript(INTERACTIVE_BADGE_SCRIPT);\n } catch {\n // Best effort — badge is non-critical\n }\n }\n await updateControllerBadge(client, 'cli', { interactive: true });\n }\n\n sessions.set(id, session);\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n\n // Set up cloud relay before responding so the caller gets the localBrowserSessionId\n if (params.cloudRelay) {\n try {\n await setupCloudRelay(session, params.cloudRelay.apiUrl, params.cloudRelay.token);\n } catch (err) {\n consoleLogger.warn(`Cloud relay setup failed: ${err}`);\n // Continue without relay — session is still usable for CLI control\n }\n }\n\n const result: DaemonResponse<SessionInfo> = {\n ok: true,\n data: await toSessionInfo(session),\n };\n json(res, 201, result);\n\n // Navigate after responding — navigation can take 30+ seconds and the\n // CLI intentionally does not wait so callers can issue commands in parallel.\n if (params.url) {\n client.navigate(params.url).catch((err) => {\n consoleLogger.warn(`Initial navigation to ${params.url} failed: ${err}`);\n });\n }\n } catch (err) {\n const result: DaemonResponse = {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n json(res, 500, result);\n }\n}\n\nasync function handleListSessions(res: ServerResponse) {\n const list = await Promise.all(Array.from(sessions.values()).map(toSessionInfo));\n json(res, 200, { ok: true, data: list } satisfies DaemonResponse<SessionInfo[]>);\n}\n\nasync function handleGetSession(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n json(res, 200, {\n ok: true,\n data: await toSessionInfo(session),\n } satisfies DaemonResponse<SessionInfo>);\n}\n\nasync function teardownSession(session: ManagedSession): Promise<void> {\n if (isAttached(session)) {\n try {\n await session.cdpProxy.shutdown();\n } catch {\n // Best effort\n }\n return;\n }\n cleanupPauseTimer(session);\n if (session.relayHost) {\n try {\n await session.relayHost.stop();\n } catch {\n // Best effort\n }\n }\n try {\n await session.client.disconnect();\n } catch {\n // Best effort\n }\n}\n\n/** Tear down and remove a session from the map. Shared by the DELETE route and the idle sweep. */\nasync function stopSession(\n sessionId: string,\n reason: 'manual' | 'idle' | 'all'\n): Promise<boolean> {\n const session = sessions.get(sessionId);\n if (!session) return false;\n if (reason === 'idle') {\n const idleMs = Date.now() - Date.parse(session.lastActivityAt);\n consoleLogger.info(\n `[daemon] auto-stopping session ${session.id} (${session.name}) — idle ${formatIdle(idleMs)}`\n );\n }\n await teardownSession(session);\n sessions.delete(sessionId);\n return true;\n}\n\nasync function handleDeleteSession(sessionId: string, res: ServerResponse) {\n const stopped = await stopSession(sessionId, 'manual');\n if (!stopped) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n json(res, 200, { ok: true } satisfies DaemonResponse);\n resetIdleTimer();\n}\n\nasync function handleDeleteAllSessions(res: ServerResponse) {\n const ids = Array.from(sessions.keys());\n for (const id of ids) {\n await stopSession(id, 'all');\n }\n json(res, 200, { ok: true } satisfies DaemonResponse);\n resetIdleTimer();\n}\n\n/** Sweep idle sessions and auto-stop any past the timeout. */\nasync function sweepIdleSessions() {\n const now = Date.now();\n const toStop: string[] = [];\n for (const [id, s] of sessions) {\n // Skip cloud-controlled sessions — cloud lifecycle owns them.\n if (s.lock.controller === 'cloud') continue;\n const idleMs = now - Date.parse(s.lastActivityAt);\n if (idleMs >= SESSION_IDLE_TIMEOUT_MS) toStop.push(id);\n }\n for (const id of toStop) {\n try {\n await stopSession(id, 'idle');\n } catch (err) {\n consoleLogger.warn(`[daemon] idle-stop failed for ${id}: ${err}`);\n }\n }\n if (toStop.length > 0) resetIdleTimer();\n}\n\nasync function handleSwapContext(sessionId: string, body: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'swap-context is not supported in attached mode (real Chrome owns the profile).',\n } satisfies DaemonResponse);\n return;\n }\n\n touch(session);\n const params = parseJson(body) as SwapContextRequest;\n\n try {\n await session.client.swapContext({\n storageStatePath: params.storageStatePath,\n });\n\n if (params.credentialName) {\n session.credentialName = params.credentialName;\n }\n\n json(res, 200, {\n ok: true,\n data: await toSessionInfo(session),\n } satisfies DaemonResponse<SessionInfo>);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies DaemonResponse);\n }\n}\n\nasync function handleGetStorageState(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'storage-state is not supported in attached mode.',\n } satisfies DaemonResponse);\n return;\n }\n\n try {\n const storageState = await session.client.getStorageState();\n json(res, 200, { ok: true, data: storageState } satisfies DaemonResponse);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies DaemonResponse);\n }\n}\n\nasync function handleToolCall(\n sessionId: string,\n toolName: string,\n body: string,\n res: ServerResponse\n) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, {\n ok: false,\n error: `Session \"${sessionId}\" not found`,\n } satisfies DaemonResponse);\n return;\n }\n\n // Enforce session lock — CLI tool calls are rejected when cloud has control\n if (session.lock.controller === 'cloud') {\n json(res, 423, {\n ok: false,\n error: 'Session is controlled by cloud. Use take-control to force CLI control.',\n } satisfies ToolResponse);\n return;\n }\n\n touch(session);\n\n // Attached (real Chrome) sessions proxy directly to chrome-devtools-mcp.\n // No pause/takeover flow — the user owns their browser directly.\n if (isAttached(session)) {\n const args = parseJson(body);\n const fullToolName = toolName.startsWith('browser_') ? toolName : `browser_${toolName}`;\n try {\n const result = await session.cdpProxy.callByCanaryName(fullToolName, args);\n if (!result.ok) {\n json(res, 500, { ok: false, error: result.error } satisfies ToolResponse);\n return;\n }\n json(res, 200, {\n ok: true,\n text: result.text,\n images: result.images,\n } satisfies ToolResponse);\n } catch (err) {\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies ToolResponse);\n }\n return;\n }\n\n // Combined check: read pause flag + drain user events in one evaluate round-trip\n const { paused, events: drainedEvents } = await checkPauseAndDrainEvents(session);\n\n if (paused) {\n // Start enrichment polling if not already running\n startPauseEnrichment(session);\n json(res, 423, {\n ok: false,\n error:\n 'User has taken control of the browser. They will resume when ready. ' +\n 'Do not retry — wait for the user to click \"Resume Agent\" in the browser.',\n errorCode: USER_PAUSED_ERROR,\n } satisfies ToolResponse);\n return;\n }\n\n // If we were in pause mode and user resumed, drain enriched events\n if (session.userPausePollTimer || session.pauseEnrichedEvents.length > 0) {\n await stopPauseEnrichment(session);\n }\n\n // Merge pause-period enriched events with events drained in the combined check\n const userEvents = [\n ...session.pauseEnrichedEvents,\n ...drainedEvents,\n ];\n session.pauseEnrichedEvents = [];\n const pauseSnapshot = session.pauseResumeSnapshot;\n session.pauseResumeSnapshot = null;\n\n const args = parseJson(body);\n const fullToolName = toolName.startsWith('browser_') ? toolName : `browser_${toolName}`;\n\n try {\n const result = await dispatchBrowserToolWithTimeout(session.executor, fullToolName, args);\n\n // Discard events generated by Claude's own Playwright action so they\n // aren't reported as \"user actions\" in the next tool call's drain.\n await discardCapturedEvents(session);\n\n let text: string;\n let images: Array<{ data: string; mimeType: string }> | undefined;\n\n if (typeof result === 'string') {\n text = result;\n } else {\n text = result.text ?? '';\n images = result.images;\n }\n\n if (userEvents.length > 0) {\n const summary = formatUserActionsSummary(userEvents, pauseSnapshot);\n if (summary) {\n text = summary + '\\n' + text;\n }\n }\n\n json(res, 200, { ok: true, text, images } satisfies ToolResponse);\n } catch (err) {\n await discardCapturedEvents(session);\n json(res, 500, {\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n } satisfies ToolResponse);\n }\n}\n\n/* ── Lock management ────────────────────────────────────────────────── */\n\nasync function handleGetLock(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, { ok: false, error: `Session \"${sessionId}\" not found` } satisfies DaemonResponse);\n return;\n }\n json(res, 200, { ok: true, data: session.lock } satisfies DaemonResponse<SessionLock>);\n}\n\nasync function handleTakeControl(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, { ok: false, error: `Session \"${sessionId}\" not found` } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'Cloud lock operations are not supported in attached mode.',\n } satisfies DaemonResponse);\n return;\n }\n\n touch(session);\n const wasClouded = session.lock.controller === 'cloud';\n session.lock = {\n controller: 'cli',\n acquiredAt: new Date().toISOString(),\n cloudPaused: wasClouded,\n };\n\n await updateControllerBadge(session.client, 'cli');\n json(res, 200, { ok: true, data: await toSessionInfo(session) } satisfies DaemonResponse<SessionInfo>);\n}\n\nasync function handleResumeCloud(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, { ok: false, error: `Session \"${sessionId}\" not found` } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'Cloud lock operations are not supported in attached mode.',\n } satisfies DaemonResponse);\n return;\n }\n\n if (!session.lock.cloudPaused) {\n json(res, 409, { ok: false, error: 'Cloud is not paused' } satisfies DaemonResponse);\n return;\n }\n\n touch(session);\n session.lock = {\n controller: 'cloud',\n acquiredAt: new Date().toISOString(),\n cloudPaused: false,\n };\n\n await updateControllerBadge(session.client, 'cloud');\n json(res, 200, { ok: true, data: await toSessionInfo(session) } satisfies DaemonResponse<SessionInfo>);\n}\n\nasync function handleAcquireCloud(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, { ok: false, error: `Session \"${sessionId}\" not found` } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'Cloud lock operations are not supported in attached mode.',\n } satisfies DaemonResponse);\n return;\n }\n\n touch(session);\n session.lock = {\n controller: 'cloud',\n acquiredAt: new Date().toISOString(),\n cloudPaused: false,\n };\n\n await updateControllerBadge(session.client, 'cloud');\n json(res, 200, { ok: true, data: await toSessionInfo(session) } satisfies DaemonResponse<SessionInfo>);\n}\n\nasync function handleReleaseCloud(sessionId: string, res: ServerResponse) {\n const session = sessions.get(sessionId);\n if (!session) {\n json(res, 404, { ok: false, error: `Session \"${sessionId}\" not found` } satisfies DaemonResponse);\n return;\n }\n if (isAttached(session)) {\n json(res, 400, {\n ok: false,\n error: 'Cloud lock operations are not supported in attached mode.',\n } satisfies DaemonResponse);\n return;\n }\n\n touch(session);\n session.lock = {\n controller: 'cli',\n acquiredAt: new Date().toISOString(),\n cloudPaused: false,\n };\n\n await updateControllerBadge(session.client, 'cli');\n json(res, 200, { ok: true, data: await toSessionInfo(session) } satisfies DaemonResponse<SessionInfo>);\n}\n\n/* ── Server routing ──────────────────────────────────────────────────── */\n\nasync function handleRequest(req: IncomingMessage, res: ServerResponse) {\n const method = req.method ?? 'GET';\n const { path: segments } = parseRoute(req.url ?? '/');\n const body = method === 'POST' || method === 'DELETE' ? await readBody(req) : '';\n\n try {\n // GET /health\n if (method === 'GET' && segments[0] === 'health') {\n await handleHealth(res);\n return;\n }\n\n // POST /sessions\n if (method === 'POST' && segments[0] === 'sessions' && segments.length === 1) {\n await handleCreateSession(body, res);\n return;\n }\n\n // GET /sessions\n if (method === 'GET' && segments[0] === 'sessions' && segments.length === 1) {\n await handleListSessions(res);\n return;\n }\n\n // GET /sessions/:id\n if (method === 'GET' && segments[0] === 'sessions' && segments.length === 2) {\n await handleGetSession(segments[1], res);\n return;\n }\n\n // DELETE /sessions (all)\n if (method === 'DELETE' && segments[0] === 'sessions' && segments.length === 1) {\n await handleDeleteAllSessions(res);\n return;\n }\n\n // DELETE /sessions/:id\n if (method === 'DELETE' && segments[0] === 'sessions' && segments.length === 2) {\n await handleDeleteSession(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/swap-context\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'swap-context' &&\n segments.length === 3\n ) {\n await handleSwapContext(segments[1], body, res);\n return;\n }\n\n // GET /sessions/:id/storage-state\n if (\n method === 'GET' &&\n segments[0] === 'sessions' &&\n segments[2] === 'storage-state' &&\n segments.length === 3\n ) {\n await handleGetStorageState(segments[1], res);\n return;\n }\n\n // GET /sessions/:id/lock\n if (\n method === 'GET' &&\n segments[0] === 'sessions' &&\n segments[2] === 'lock' &&\n segments.length === 3\n ) {\n await handleGetLock(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/take-control\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'take-control' &&\n segments.length === 3\n ) {\n await handleTakeControl(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/resume-cloud\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'resume-cloud' &&\n segments.length === 3\n ) {\n await handleResumeCloud(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/acquire-cloud (internal — called by relay)\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'acquire-cloud' &&\n segments.length === 3\n ) {\n await handleAcquireCloud(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/release-cloud (internal — called by relay)\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'release-cloud' &&\n segments.length === 3\n ) {\n await handleReleaseCloud(segments[1], res);\n return;\n }\n\n // POST /sessions/:id/tools/:toolName\n if (\n method === 'POST' &&\n segments[0] === 'sessions' &&\n segments[2] === 'tools' &&\n segments.length === 4\n ) {\n await handleToolCall(segments[1], segments[3], body, res);\n return;\n }\n\n json(res, 404, { ok: false, error: 'Not found' });\n } catch (err) {\n json(res, 500, { ok: false, error: err instanceof Error ? err.message : String(err) });\n }\n}\n\n/* ── Pidfile management ──────────────────────────────────────────────── */\n\nasync function writePidfile(port: number) {\n await fs.mkdir(PIDFILE_DIR, { recursive: true, mode: 0o700 });\n const state: DaemonState = {\n pid: process.pid,\n port,\n startedAt: new Date().toISOString(),\n };\n await fs.writeFile(PIDFILE_PATH, JSON.stringify(state, null, 2), { mode: 0o600 });\n}\n\nasync function removePidfile() {\n try {\n await fs.unlink(PIDFILE_PATH);\n } catch {\n // Already removed\n }\n}\n\n/* ── Cleanup ─────────────────────────────────────────────────────────── */\n\nasync function cleanup() {\n if (idleSweepTimer) {\n clearInterval(idleSweepTimer);\n idleSweepTimer = null;\n }\n for (const session of sessions.values()) {\n await teardownSession(session);\n }\n sessions.clear();\n await removePidfile();\n}\n\n/* ── Main entry ──────────────────────────────────────────────────────── */\n\nasync function startDaemon(): Promise<{ port: number }> {\n const server = createServer(handleRequest);\n\n return new Promise((resolve, reject) => {\n server.listen(0, '127.0.0.1', async () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n reject(new Error('Failed to get server address'));\n return;\n }\n\n const port = addr.port;\n await writePidfile(port);\n resetIdleTimer();\n\n idleSweepTimer = setInterval(() => {\n sweepIdleSessions().catch((err) => {\n consoleLogger.warn(`[daemon] idle sweep failed: ${err}`);\n });\n }, SESSION_IDLE_SWEEP_INTERVAL_MS);\n // Don't keep the event loop alive for the sweep alone.\n idleSweepTimer.unref?.();\n\n // Graceful shutdown\n process.on('SIGINT', async () => {\n await cleanup();\n process.exit(0);\n });\n process.on('SIGTERM', async () => {\n await cleanup();\n process.exit(0);\n });\n process.on('exit', () => {\n removePidfile().catch(() => {});\n });\n\n resolve({ port });\n });\n\n server.on('error', reject);\n });\n}\n\n/** CLI entry point: `canary session daemon` (internal, spawned by daemon-client) */\nexport async function runDaemon() {\n // Redirect all console output to stderr before starting anything.\n // The spawner destroys our stdout pipe after reading DAEMON_READY,\n // so any subsequent stdout writes (e.g. console.info/debug from\n // browser-core's consoleLogger) would crash the process with EPIPE.\n const { Console } = await import('node:console');\n global.console = new Console({ stdout: process.stderr, stderr: process.stderr }) as typeof console;\n\n const { port } = await startDaemon();\n process.stdout.write(`DAEMON_READY:${port}\\n`);\n}\n","/**\n * Controller badge — injects an interactive DOM overlay showing session control state.\n *\n * In headed sessions controlled by an agent (CLI MCP or cloud), the badge is\n * clickable: clicking it toggles `window.__canaryUserPaused` which the daemon\n * checks before executing tool calls. This lets the user \"tag out\" the agent,\n * interact with the browser, then hand control back.\n *\n * The badge survives page navigations via `addInitScript` and persists pause\n * state via `sessionStorage` (same-origin). For cross-origin navigations, the\n * daemon tracks pause state server-side as the authoritative source.\n *\n * @module\n */\n\nimport type { PlaywrightClient } from '@chatsdet/browser-core';\nimport type { SessionController } from './types.js';\n\nconst BADGE_ID = '__canary_controller_badge__';\nconst STORAGE_KEY = '__canaryUserPaused';\n\n/**\n * Script that creates the interactive agent/user badge.\n * Designed to work both via addInitScript (survives navigation) and evaluate.\n *\n * Uses DOMContentLoaded to ensure document.body exists when injected early.\n * Reads pause state from sessionStorage to survive same-origin navigations.\n */\nexport const INTERACTIVE_BADGE_SCRIPT = `(() => {\n function initBadge() {\n const BADGE_ID = '${BADGE_ID}';\n const STORAGE_KEY = '${STORAGE_KEY}';\n\n // Restore pause state from sessionStorage (survives same-origin nav)\n if (typeof window.__canaryUserPaused === 'undefined') {\n try {\n window.__canaryUserPaused = sessionStorage.getItem(STORAGE_KEY) === 'true';\n } catch { window.__canaryUserPaused = false; }\n }\n\n // Ensure keyframes exist\n if (!document.getElementById('canary-badge-keyframes')) {\n const style = document.createElement('style');\n style.id = 'canary-badge-keyframes';\n style.textContent = [\n '@keyframes canary-badge-pulse{0%,100%{opacity:.75}50%{opacity:.4}}',\n '#' + BADGE_ID + '{transition:background .2s,opacity .2s}',\n '#' + BADGE_ID + ':hover{opacity:1!important}',\n ].join('\\\\n');\n document.head.appendChild(style);\n }\n\n let el = document.getElementById(BADGE_ID);\n if (!el) {\n el = document.createElement('div');\n el.id = BADGE_ID;\n el.style.cssText = 'position:fixed;bottom:20px;right:20px;z-index:2147483647;'\n + 'padding:6px 12px;border-radius:6px;font:600 12px/1.2 system-ui,sans-serif;'\n + 'cursor:pointer;user-select:none;opacity:.75;color:#fff;'\n + 'display:flex;align-items:center;gap:6px;box-shadow:0 2px 8px rgba(0,0,0,.2);';\n document.body.appendChild(el);\n }\n\n function render() {\n if (!el) return;\n var paused = !!window.__canaryUserPaused;\n if (paused) {\n el.style.background = '#4DA6FF';\n el.style.animation = 'canary-badge-pulse 2s ease-in-out infinite';\n el.innerHTML = '<span style=\"font-size:8px;vertical-align:middle;\">\\\\u25CF</span> You'\n + '<span style=\"margin-left:4px;padding:2px 6px;background:rgba(255,255,255,.25);'\n + 'border-radius:3px;font-size:10px;\">Resume Agent</span>';\n el.title = 'Click to resume agent control';\n } else {\n el.style.background = '#FFBD0F';\n el.style.animation = '';\n el.innerHTML = 'Agent';\n el.title = 'Click to take control of the browser';\n }\n }\n\n el.onclick = function(e) {\n e.stopPropagation();\n e.preventDefault();\n window.__canaryUserPaused = !window.__canaryUserPaused;\n try { sessionStorage.setItem(STORAGE_KEY, String(window.__canaryUserPaused)); } catch {}\n render();\n };\n\n render();\n\n // Re-inject if the page removes the badge (e.g. framework DOM cleanup)\n try {\n var observer = new MutationObserver(function() {\n if (!document.getElementById(BADGE_ID)) {\n observer.disconnect();\n initBadge();\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n } catch {}\n }\n\n // Wait for body to exist (addInitScript runs before DOM is ready)\n if (document.body) {\n initBadge();\n } else if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initBadge);\n } else {\n initBadge();\n }\n})()`;\n\nfunction staticBadgeScript(controller: SessionController): string {\n const color = controller === 'cli' ? '#4DA6FF' : '#FFBD0F';\n const label = controller === 'cli' ? 'CLI' : 'Cloud';\n\n return `(() => {\n let el = document.getElementById('${BADGE_ID}');\n if (!el) {\n el = document.createElement('div');\n el.id = '${BADGE_ID}';\n el.style.cssText = 'position:fixed;bottom:20px;right:20px;z-index:2147483647;'\n + 'padding:6px 12px;border-radius:6px;font:600 12px/1.2 system-ui,sans-serif;'\n + 'pointer-events:none;opacity:.7;color:#fff;'\n + 'box-shadow:0 2px 8px rgba(0,0,0,.2);';\n document.body.appendChild(el);\n }\n el.style.background = '${color}';\n el.style.animation = '';\n el.style.cursor = 'default';\n el.style.pointerEvents = 'none';\n el.onclick = null;\n el.textContent = '${label}';\n el.title = '';\n })()`;\n}\n\n/**\n * Inject or update the controller badge in the browser page.\n *\n * For agent-controlled headed sessions, injects an interactive badge\n * that the user can click to pause/resume the agent. For CLI/cloud\n * modes, shows a static non-interactive badge.\n */\nexport async function updateControllerBadge(\n client: PlaywrightClient,\n controller: SessionController,\n options?: {\n interactive?: boolean;\n logger?: { debug?: (...args: unknown[]) => void };\n }\n): Promise<void> {\n try {\n const interactive = options?.interactive ?? false;\n if (interactive) {\n await client.evaluate(INTERACTIVE_BADGE_SCRIPT);\n } else {\n await client.evaluate(staticBadgeScript(controller));\n }\n } catch (err) {\n options?.logger?.debug?.('[badge] updateControllerBadge failed', {\n controller,\n interactive: options?.interactive ?? false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n","/**\n * User takeover recording — captures and summarizes user interactions\n * during headed browser sessions controlled by an AI agent.\n *\n * Two modes:\n * 1. **Always-on**: Between agent tool calls, user clicks/typing are captured\n * and summarized in the next tool result.\n * 2. **Pause mode**: User clicks the badge to pause the agent. During pause,\n * events are enriched with element info. On resume, a snapshot is taken\n * and the full summary is prepended to the next tool result.\n *\n * @module session/user-takeover\n */\n\nimport {\n captureElementAtPoint,\n dispatchBrowserTool,\n consoleLogger,\n} from '@chatsdet/browser-core';\nimport type { PlaywrightClient, BrowserToolExecutor } from '@chatsdet/browser-core';\nimport { INTERACTION_CAPTURE_SCRIPT } from '../record-interaction-script.js';\nimport type { TakeoverEvent } from './types.js';\n\n/* ── Constants ─────────────────────────────────────────────────────── */\n\nconst PAUSE_POLL_INTERVAL_MS = 500;\nconst MAX_PAUSE_EVENTS = 500;\nconst EVALUATE_TIMEOUT_MS = 3_000;\nconst MAX_STRING_LENGTH = 200;\n\n/* ── Session interface ─────────────────────────────────────────────── */\n\n/** Minimal session interface for user-takeover helpers. */\nexport interface TakeoverSession {\n id: string;\n mode: 'headed' | 'headless';\n client: PlaywrightClient;\n executor: BrowserToolExecutor;\n /**\n * Daemon-side pause state — latched to true when the page flag is detected,\n * cleared only by stopPauseEnrichment. Survives cross-origin navigations\n * where sessionStorage is lost and the page flag resets.\n */\n userPaused: boolean;\n /** Poll timer for enriching events during pause mode */\n userPausePollTimer: ReturnType<typeof setInterval> | null;\n /** Enriched events accumulated during a user pause period */\n pauseEnrichedEvents: TakeoverEvent[];\n /** Snapshot taken when user resumes from pause, consumed by next tool call */\n pauseResumeSnapshot: string | null;\n}\n\n/* ── Event validation & sanitization ───────────────────────────────── */\n\nfunction truncate(s: unknown, maxLen = MAX_STRING_LENGTH): string | undefined {\n if (typeof s !== 'string') return undefined;\n return s.length > maxLen ? s.slice(0, maxLen) : s;\n}\n\n/**\n * Validate and sanitize a raw event object from the page.\n * The page is untrusted — a hostile page can write arbitrary data\n * to window.__canaryRecordedEvents.\n */\nfunction sanitizeEvent(raw: unknown): TakeoverEvent | null {\n if (typeof raw !== 'object' || raw === null) return null;\n const evt = raw as Record<string, unknown>;\n const ts = typeof evt.ts === 'number' ? evt.ts : Date.now();\n\n switch (evt.type) {\n case 'click':\n if (typeof evt.x !== 'number' || typeof evt.y !== 'number') return null;\n return {\n type: 'click',\n ts,\n x: evt.x,\n y: evt.y,\n tagName: truncate(evt.tagName, 50) ?? 'UNKNOWN',\n id: truncate(evt.id, 100),\n testId: truncate(evt.testId, 100),\n ariaLabel: truncate(evt.ariaLabel),\n role: truncate(evt.role, 50),\n textContent: truncate(evt.textContent),\n className: truncate(evt.className),\n };\n\n case 'input':\n return {\n type: 'input',\n ts,\n tagName: truncate(evt.tagName, 50) ?? 'INPUT',\n id: truncate(evt.id, 100),\n inputType: truncate(evt.inputType, 50),\n ariaLabel: truncate(evt.ariaLabel),\n value: truncate(evt.value) ?? '',\n isFinal: evt.isFinal === true,\n };\n\n case 'change':\n return {\n type: 'change',\n ts,\n tagName: truncate(evt.tagName, 50) ?? 'INPUT',\n id: truncate(evt.id, 100),\n inputType: truncate(evt.inputType, 50),\n ariaLabel: truncate(evt.ariaLabel),\n value: truncate(evt.value) ?? '',\n };\n\n case 'keydown':\n if (typeof evt.key !== 'string') return null;\n return { type: 'keydown', ts, key: evt.key.slice(0, 20) };\n\n case 'navigation':\n if (typeof evt.url !== 'string') return null;\n try {\n const parsed = new URL(evt.url);\n const safeUrl = `${parsed.origin}${parsed.pathname}`.slice(0, 2048);\n return {\n type: 'navigation',\n ts,\n url: safeUrl,\n navigationType: truncate(evt.navigationType, 50),\n };\n } catch {\n return null;\n }\n\n default:\n return null;\n }\n}\n\n/* ── Page interaction helpers ──────────────────────────────────────── */\n\n/** Create a timeout promise that rejects after the given duration. */\nfunction timeoutReject(ms = EVALUATE_TIMEOUT_MS): Promise<never> {\n return new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('evaluate timed out')), ms)\n );\n}\n\n/** Discard any events currently in the page buffer (used after tool execution). */\nexport async function discardCapturedEvents(session: TakeoverSession): Promise<void> {\n if (session.mode !== 'headed') return;\n const page = await session.client.getPageForReplay();\n if (!page) return;\n try {\n await Promise.race([\n page.evaluate(() => {\n const w = window as unknown as {\n __canaryFlushAndDiscard?: () => void;\n __canaryRecordedEvents?: unknown[];\n };\n if (typeof w.__canaryFlushAndDiscard === 'function') {\n w.__canaryFlushAndDiscard();\n } else {\n w.__canaryRecordedEvents = [];\n }\n }),\n timeoutReject(),\n ]);\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] discardCapturedEvents failed`, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n/** Drain events from the page, sanitize, and return. Shared by both drain paths. */\nasync function drainAndSanitize(session: TakeoverSession): Promise<TakeoverEvent[]> {\n const page = await session.client.getPageForReplay();\n if (!page) return [];\n\n const raw = await Promise.race([\n page.evaluate(() => {\n const w = window as unknown as { __canaryRecordedEvents?: unknown[] };\n const evts = w.__canaryRecordedEvents ?? [];\n w.__canaryRecordedEvents = [];\n return evts;\n }),\n timeoutReject(),\n ]);\n\n if (!Array.isArray(raw)) return [];\n const events: TakeoverEvent[] = [];\n for (const e of raw) {\n const sanitized = sanitizeEvent(e);\n if (sanitized) events.push(sanitized);\n }\n return events;\n}\n\n/**\n * Combined check: read pause flag and drain user events in a single evaluate.\n * Reduces CDP round-trips on the tool-call hot path.\n */\nexport async function checkPauseAndDrainEvents(\n session: TakeoverSession\n): Promise<{ paused: boolean; events: TakeoverEvent[] }> {\n if (session.mode !== 'headed') return { paused: false, events: [] };\n\n // Daemon-side pause state is authoritative (survives cross-origin navigation)\n if (session.userPaused) return { paused: true, events: [] };\n\n const page = await session.client.getPageForReplay();\n if (!page) return { paused: false, events: [] };\n\n try {\n const raw = await Promise.race([\n page.evaluate(() => {\n const w = window as unknown as {\n __canaryRecordedEvents?: unknown[];\n __canaryUserPaused?: boolean;\n };\n const paused = !!w.__canaryUserPaused;\n const evts = w.__canaryRecordedEvents ?? [];\n w.__canaryRecordedEvents = [];\n return { paused, events: evts };\n }),\n timeoutReject(),\n ]);\n\n const paused = raw?.paused === true;\n if (paused) session.userPaused = true;\n\n const events: TakeoverEvent[] = [];\n if (Array.isArray(raw?.events)) {\n for (const e of raw.events) {\n const sanitized = sanitizeEvent(e);\n if (sanitized) events.push(sanitized);\n }\n }\n return { paused, events };\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] checkPauseAndDrain failed`, {\n error: err instanceof Error ? err.message : String(err),\n });\n return { paused: session.userPaused, events: [] };\n }\n}\n\n/**\n * Drain user events (standalone, used by pause enrichment poll).\n * For the tool-call hot path, prefer checkPauseAndDrainEvents.\n */\nasync function drainUserEvents(session: TakeoverSession): Promise<TakeoverEvent[]> {\n if (session.mode !== 'headed') return [];\n try {\n return await drainAndSanitize(session);\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] drainUserEvents failed`, {\n error: err instanceof Error ? err.message : String(err),\n });\n return [];\n }\n}\n\n/* ── Pause mode enrichment ─────────────────────────────────────────── */\n\n/**\n * Start a poll loop that drains and enriches user events during pause mode.\n * Click events get element info via captureElementAtPoint for richer summaries,\n * but only if the capture script didn't already provide identifying info.\n */\nexport function startPauseEnrichment(session: TakeoverSession): void {\n if (session.userPausePollTimer) return;\n session.pauseEnrichedEvents = [];\n\n session.userPausePollTimer = setInterval(async () => {\n try {\n if (session.pauseEnrichedEvents.length >= MAX_PAUSE_EVENTS) {\n consoleLogger.debug?.(`[takeover:${session.id}] Event cap reached, skipping drain`);\n return;\n }\n\n const events = await drainUserEvents(session);\n for (const evt of events) {\n if (session.pauseEnrichedEvents.length >= MAX_PAUSE_EVENTS) break;\n\n // Enrich click events that lack identifying info from the capture script\n if (evt.type === 'click' && !evt.ariaLabel && !evt.textContent) {\n try {\n const page = await session.client.getPageForReplay();\n if (page) {\n const info = await captureElementAtPoint(page, evt.x, evt.y);\n if (info) {\n evt.elementInfo = info as unknown as Record<string, unknown>;\n }\n }\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] captureElementAtPoint failed`, {\n error: err instanceof Error ? err.message : String(err),\n x: evt.x,\n y: evt.y,\n });\n }\n }\n session.pauseEnrichedEvents.push(evt);\n }\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] Pause poll error`, {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }, PAUSE_POLL_INTERVAL_MS);\n\n consoleLogger.info(`[takeover:${session.id}] Pause enrichment started`);\n}\n\n/** Stop the pause enrichment poll loop and do a final drain + snapshot. */\nexport async function stopPauseEnrichment(session: TakeoverSession): Promise<void> {\n if (session.userPausePollTimer) {\n clearInterval(session.userPausePollTimer);\n session.userPausePollTimer = null;\n }\n\n // Final drain\n const remaining = await drainUserEvents(session);\n for (const evt of remaining) {\n if (session.pauseEnrichedEvents.length >= MAX_PAUSE_EVENTS) break;\n session.pauseEnrichedEvents.push(evt);\n }\n\n // Take a snapshot of current page state for context\n if (session.pauseEnrichedEvents.length > 0) {\n try {\n const result = await dispatchBrowserTool(session.executor, 'browser_snapshot', {});\n session.pauseResumeSnapshot = typeof result === 'string' ? result : (result.text ?? null);\n } catch (err) {\n consoleLogger.debug?.(`[takeover:${session.id}] Resume snapshot failed`, {\n error: err instanceof Error ? err.message : String(err),\n });\n session.pauseResumeSnapshot = null;\n }\n }\n\n session.userPaused = false;\n\n consoleLogger.info(\n `[takeover:${session.id}] Pause enrichment stopped, ${session.pauseEnrichedEvents.length} events captured`\n );\n}\n\n/** Clean up pause poll timer on session delete. */\nexport function cleanupPauseTimer(session: TakeoverSession): void {\n if (session.userPausePollTimer) {\n clearInterval(session.userPausePollTimer);\n session.userPausePollTimer = null;\n }\n}\n\n/* ── Capture script injection ──────────────────────────────────────── */\n\n/**\n * Inject the interaction capture script into a headed session's page.\n * Uses addInitScript so it survives navigations.\n */\nexport async function injectCaptureScript(client: PlaywrightClient): Promise<void> {\n const page = await client.getPageForReplay();\n if (!page) return;\n try {\n await page.addInitScript(INTERACTION_CAPTURE_SCRIPT);\n await page.evaluate(INTERACTION_CAPTURE_SCRIPT);\n } catch (err) {\n consoleLogger.warn('[capture] Failed to inject interaction capture script', {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n/* ── Summary formatting ────────────────────────────────────────────── */\n\n/** Format user actions into a human-readable summary for the agent. */\nexport function formatUserActionsSummary(\n events: TakeoverEvent[],\n snapshot?: string | null\n): string {\n const lines: string[] = ['[User Actions]'];\n lines.push('The user performed the following actions since your last tool call:');\n\n let actionNum = 0;\n for (const evt of events) {\n switch (evt.type) {\n case 'click': {\n actionNum++;\n const info = evt.elementInfo as\n | { ariaLabel?: string; textContent?: string }\n | undefined;\n const target = evt.ariaLabel\n ? `\"${evt.ariaLabel}\"`\n : evt.textContent\n ? `\"${evt.textContent.slice(0, 60)}\"`\n : info?.ariaLabel\n ? `\"${info.ariaLabel}\"`\n : info?.textContent\n ? `\"${String(info.textContent).slice(0, 60)}\"`\n : evt.testId\n ? `[data-testid=\"${evt.testId}\"]`\n : evt.tagName;\n lines.push(`${actionNum}. Clicked ${target} (${evt.tagName})`);\n break;\n }\n case 'input': {\n if (!evt.isFinal) continue;\n actionNum++;\n const field = evt.ariaLabel ? `\"${evt.ariaLabel}\"` : evt.id ? `#${evt.id}` : evt.tagName;\n const displayValue = evt.inputType === 'password' ? '***' : `\"${evt.value}\"`;\n lines.push(`${actionNum}. Typed ${displayValue} in ${field}`);\n break;\n }\n case 'change': {\n actionNum++;\n const changeTarget = evt.ariaLabel ?? evt.id ?? evt.tagName;\n lines.push(`${actionNum}. Changed ${changeTarget} to \"${evt.value}\"`);\n break;\n }\n case 'keydown': {\n if (evt.key === 'Enter' || evt.key === 'Escape') {\n actionNum++;\n lines.push(`${actionNum}. Pressed ${evt.key}`);\n }\n break;\n }\n case 'navigation': {\n actionNum++;\n lines.push(`${actionNum}. Navigated to ${evt.url}`);\n break;\n }\n }\n }\n\n if (actionNum === 0) return '';\n\n if (snapshot) {\n lines.push('');\n lines.push('Current page state after user actions:');\n lines.push(snapshot);\n }\n\n lines.push('---');\n return lines.join('\\n');\n}\n","/**\n * Minimal MCP stdio client for chrome-devtools-mcp.\n *\n * We don't pull in a full MCP SDK — we only need `initialize`,\n * `notifications/initialized`, `tools/list`, and `tools/call`. JSON-RPC 2.0\n * over line-delimited stdout.\n *\n * Version pinned. Bump `CHROME_DEVTOOLS_MCP_VERSION` deliberately and re-run\n * the translator coverage checks whenever the upstream tool shapes change.\n *\n * @module\n */\n\nimport { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';\nimport { createInterface } from 'node:readline';\n\nexport const CHROME_DEVTOOLS_MCP_VERSION = '0.21.0';\n\nconst CALL_TIMEOUT_MS = 60_000;\nconst INITIALIZE_TIMEOUT_MS = 30_000;\nconst SHUTDOWN_GRACE_MS = 5_000;\n\nexport interface McpContent {\n type: string;\n text?: string;\n data?: string;\n mimeType?: string;\n}\n\nexport interface McpToolResult {\n content?: McpContent[];\n isError?: boolean;\n [k: string]: unknown;\n}\n\ninterface Pending {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n method: string;\n}\n\nexport interface McpClientLogger {\n info: (msg: string) => void;\n warn: (msg: string) => void;\n error: (msg: string) => void;\n}\n\nexport class ChromeDevtoolsMcpClient {\n private child: ChildProcessWithoutNullStreams | null = null;\n private pending = new Map<number, Pending>();\n private nextId = 1;\n private initialized = false;\n private readonly logger: McpClientLogger;\n\n constructor(logger?: McpClientLogger) {\n this.logger = logger ?? {\n info: (m) => console.log(`[cdp-proxy] ${m}`),\n warn: (m) => console.warn(`[cdp-proxy] ${m}`),\n error: (m) => console.error(`[cdp-proxy] ${m}`),\n };\n }\n\n async start(): Promise<void> {\n if (this.child) throw new Error('ChromeDevtoolsMcpClient already started');\n\n const child = spawn(\n 'npx',\n ['-y', `chrome-devtools-mcp@${CHROME_DEVTOOLS_MCP_VERSION}`, '--autoConnect'],\n {\n stdio: ['pipe', 'pipe', 'pipe'],\n shell: process.platform === 'win32',\n windowsHide: true,\n },\n );\n this.child = child;\n\n child.on('exit', (code, signal) => {\n this.logger.info(`chrome-devtools-mcp exited (code=${code} signal=${signal})`);\n for (const [, p] of this.pending) {\n clearTimeout(p.timer);\n p.reject(new Error(`chrome-devtools-mcp subprocess exited before responding to ${p.method}`));\n }\n this.pending.clear();\n this.child = null;\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n // chrome-devtools-mcp logs usage/telemetry notices here; keep at debug level\n const line = chunk.toString().trimEnd();\n if (line) this.logger.info(`[cdp-mcp stderr] ${line}`);\n });\n\n const rl = createInterface({ input: child.stdout });\n rl.on('line', (line) => this.onLine(line));\n\n await this.request('initialize', {\n protocolVersion: '2024-11-05',\n capabilities: {},\n clientInfo: { name: 'canary-cli', version: '0.0.0' },\n }, INITIALIZE_TIMEOUT_MS);\n\n this.notify('notifications/initialized', {});\n this.initialized = true;\n }\n\n async callTool(name: string, args: Record<string, unknown>): Promise<McpToolResult> {\n if (!this.initialized) throw new Error('ChromeDevtoolsMcpClient not initialized');\n const result = await this.request('tools/call', { name, arguments: args });\n return result as McpToolResult;\n }\n\n async listTools(): Promise<Array<{ name: string; description?: string }>> {\n if (!this.initialized) throw new Error('ChromeDevtoolsMcpClient not initialized');\n const result = (await this.request('tools/list', {})) as { tools?: Array<{ name: string; description?: string }> };\n return result.tools ?? [];\n }\n\n async shutdown(): Promise<void> {\n const child = this.child;\n if (!child) return;\n\n try {\n child.stdin.end();\n } catch {\n // ignore\n }\n\n await new Promise<void>((resolve) => {\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n child.once('exit', finish);\n setTimeout(() => {\n if (!done) {\n try {\n child.kill('SIGTERM');\n } catch {\n // ignore\n }\n }\n }, SHUTDOWN_GRACE_MS);\n setTimeout(() => {\n if (!done) {\n try {\n child.kill('SIGKILL');\n } catch {\n // ignore\n }\n finish();\n }\n }, SHUTDOWN_GRACE_MS * 2);\n });\n\n this.child = null;\n this.initialized = false;\n }\n\n private request(method: string, params: unknown, timeoutMs: number = CALL_TIMEOUT_MS): Promise<unknown> {\n const child = this.child;\n if (!child) return Promise.reject(new Error('chrome-devtools-mcp subprocess not running'));\n\n const id = this.nextId++;\n const payload = JSON.stringify({ jsonrpc: '2.0', id, method, params });\n\n return new Promise<unknown>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (this.pending.delete(id)) {\n reject(new Error(`Timeout waiting for ${method} (id=${id}) after ${timeoutMs}ms`));\n }\n }, timeoutMs);\n\n this.pending.set(id, { resolve, reject, timer, method });\n\n try {\n child.stdin.write(payload + '\\n');\n } catch (err) {\n this.pending.delete(id);\n clearTimeout(timer);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n private notify(method: string, params: unknown): void {\n const child = this.child;\n if (!child) return;\n try {\n child.stdin.write(JSON.stringify({ jsonrpc: '2.0', method, params }) + '\\n');\n } catch (err) {\n this.logger.warn(`notify ${method} failed: ${String(err)}`);\n }\n }\n\n private onLine(line: string): void {\n const trimmed = line.trim();\n if (!trimmed) return;\n let msg: { id?: number; result?: unknown; error?: { code: number; message: string }; method?: string };\n try {\n msg = JSON.parse(trimmed);\n } catch {\n this.logger.warn(`non-JSON line from chrome-devtools-mcp: ${trimmed.slice(0, 200)}`);\n return;\n }\n if (typeof msg.id === 'number' && this.pending.has(msg.id)) {\n const p = this.pending.get(msg.id)!;\n this.pending.delete(msg.id);\n clearTimeout(p.timer);\n if (msg.error) {\n p.reject(new Error(`${msg.error.code}: ${msg.error.message}`));\n } else {\n p.resolve(msg.result);\n }\n }\n // Server-initiated notifications/requests are ignored for now.\n }\n}\n","/**\n * Translation table: canary `browser_*` tool calls → chrome-devtools-mcp tool calls.\n *\n * For attached (user's real Chrome) sessions we proxy each canary tool to an\n * equivalent chrome-devtools-mcp tool. Refs are opaque tokens in both worlds\n * (canary uses `eN`, chrome-devtools-mcp uses `uid_N_M`) — we pass them through\n * verbatim. The snapshot text format differs between the two but is structured\n * similarly; Claude's skill guidance explains the difference.\n *\n * Gaps (not available in attached mode) return an error string; everything\n * else maps cleanly.\n *\n * @module\n */\n\nimport type { ChromeDevtoolsMcpClient, McpToolResult } from './mcp-client.js';\n\nexport type ProxyResult =\n | { ok: true; text: string; images?: Array<{ data: string; mimeType: string }> }\n | { ok: false; error: string };\n\nfunction textFromMcp(result: McpToolResult): string {\n if (!result.content) return '';\n return result.content\n .filter((c) => c.type === 'text' && typeof c.text === 'string')\n .map((c) => c.text as string)\n .join('\\n');\n}\n\nfunction imagesFromMcp(\n result: McpToolResult,\n): Array<{ data: string; mimeType: string }> | undefined {\n if (!result.content) return undefined;\n const images = result.content\n .filter((c) => c.type === 'image' && typeof c.data === 'string')\n .map((c) => ({ data: c.data as string, mimeType: c.mimeType ?? 'image/png' }));\n return images.length > 0 ? images : undefined;\n}\n\nfunction toResult(result: McpToolResult): ProxyResult {\n const text = textFromMcp(result);\n const images = imagesFromMcp(result);\n if (result.isError) {\n return { ok: false, error: text || 'chrome-devtools-mcp returned an error with no message' };\n }\n return { ok: true, text, images };\n}\n\n/**\n * Snapshots print refs as \"uid=2_3 ...\"; claude naturally copies the visible\n * form. chrome-devtools-mcp's tools want the bare value (e.g. \"2_3\"). Accept\n * either and normalize.\n */\nfunction normalizeUid(ref: string | undefined): string | undefined {\n if (!ref) return ref;\n return ref.startsWith('uid=') ? ref.slice(4) : ref;\n}\n\nfunction notSupportedInAttachedMode(canaryTool: string): ProxyResult {\n return {\n ok: false,\n error: `${canaryTool} is not supported in attached mode (real Chrome). Use a fresh session (--credential) if you need this.`,\n };\n}\n\ntype Translator = (\n mcp: ChromeDevtoolsMcpClient,\n args: Record<string, unknown>,\n) => Promise<ProxyResult>;\n\nconst translators: Record<string, Translator> = {\n browser_navigate: async (mcp, args) => {\n const url = args.url as string;\n return toResult(await mcp.callTool('navigate_page', { url }));\n },\n\n browser_navigate_back: async (mcp) => {\n return toResult(await mcp.callTool('navigate_page', { type: 'back' }));\n },\n\n browser_snapshot: async (mcp, args) => {\n const mode = args.mode as 'both' | 'screenshot' | 'tree' | undefined;\n if (mode === 'screenshot') {\n return toResult(await mcp.callTool('take_screenshot', {}));\n }\n const snap = await mcp.callTool('take_snapshot', {});\n const snapResult = toResult(snap);\n if (!snapResult.ok) return snapResult;\n\n // --search: client-side filter on the snapshot text\n const search = args.search as string | undefined;\n let filteredText = snapResult.text;\n if (search) {\n const terms = search.split('|').map((t) => t.trim().toLowerCase()).filter(Boolean);\n if (terms.length > 0) {\n const lines = filteredText.split('\\n');\n const matching = lines.filter((line) => {\n const low = line.toLowerCase();\n return terms.some((t) => low.includes(t));\n });\n filteredText =\n matching.length > 0\n ? `# Filtered snapshot (search=${JSON.stringify(search)}, ${matching.length} matches)\\n${matching.join('\\n')}`\n : `# No matches for search=${JSON.stringify(search)}\\n\\n${filteredText}`;\n }\n }\n\n if (mode === 'both' || mode === undefined) {\n const shot = await mcp.callTool('take_screenshot', {});\n const shotResult = toResult(shot);\n return {\n ok: true,\n text: filteredText,\n images: shotResult.ok ? shotResult.images : undefined,\n };\n }\n\n return { ok: true, text: filteredText };\n },\n\n browser_screenshot: async (mcp, args) => {\n return toResult(\n await mcp.callTool('take_screenshot', {\n uid: normalizeUid(args.ref as string | undefined),\n fullPage: args.fullPage as boolean | undefined,\n }),\n );\n },\n\n browser_evaluate: async (mcp, args) => {\n const fn = args.function as string;\n return toResult(await mcp.callTool('evaluate_script', { function: fn }));\n },\n\n browser_console_messages: async (mcp, args) => {\n const res = await mcp.callTool('list_console_messages', {});\n const result = toResult(res);\n if (!result.ok) return result;\n if (args.onlyErrors) {\n const filtered = result.text\n .split('\\n')\n .filter((l) => /error/i.test(l))\n .join('\\n');\n return { ok: true, text: filtered || '(no errors)' };\n }\n return result;\n },\n\n browser_network_requests: async (mcp) => {\n return toResult(await mcp.callTool('list_network_requests', {}));\n },\n\n browser_click: async (mcp, args) => {\n const ref = normalizeUid(args.ref as string | undefined);\n const x = args.x as number | undefined;\n const y = args.y as number | undefined;\n if (ref) {\n return toResult(\n await mcp.callTool('click', {\n uid: ref,\n dblClick: args.doubleClick as boolean | undefined,\n }),\n );\n }\n if (typeof x === 'number' && typeof y === 'number') {\n // chrome-devtools-mcp has no coord-click; fall back to evaluate.\n const dbl = args.doubleClick === true;\n const fn = `() => { const el = document.elementFromPoint(${x}, ${y}); if (!el) throw new Error('No element at (${x},${y})'); el.${dbl ? 'click(); el.click' : 'click'}(); return el.outerHTML.slice(0, 200); }`;\n return toResult(await mcp.callTool('evaluate_script', { function: fn }));\n }\n return { ok: false, error: 'browser_click requires either ref or (x, y)' };\n },\n\n browser_hover: async (mcp, args) => {\n return toResult(await mcp.callTool('hover', { uid: normalizeUid(args.ref as string) }));\n },\n\n browser_drag: async (mcp, args) => {\n const startRef = normalizeUid(args.startRef as string | undefined);\n const endRef = normalizeUid(args.endRef as string | undefined);\n if (!startRef || !endRef) {\n return {\n ok: false,\n error: 'browser_drag in attached mode requires startRef and endRef (coordinate drag not supported).',\n };\n }\n return toResult(await mcp.callTool('drag', { from_uid: startRef, to_uid: endRef }));\n },\n\n browser_type: async (mcp, args) => {\n const ref = normalizeUid(args.ref as string | undefined);\n const text = args.text as string;\n const submit = args.submit as boolean | undefined;\n if (ref) {\n const fill = await mcp.callTool('fill', { uid: ref, value: text });\n const fillResult = toResult(fill);\n if (!fillResult.ok || !submit) return fillResult;\n const press = await mcp.callTool('press_key', { key: 'Enter' });\n const pressResult = toResult(press);\n if (!pressResult.ok) return pressResult;\n return { ok: true, text: `${fillResult.text}\\n${pressResult.text}`.trim() };\n }\n // No ref: type into whatever's focused\n const typed = await mcp.callTool('type_text', {\n text,\n submitKey: submit ? 'Enter' : undefined,\n });\n return toResult(typed);\n },\n\n browser_press_key: async (mcp, args) => {\n return toResult(await mcp.callTool('press_key', { key: args.key as string }));\n },\n\n browser_fill_form: async (mcp, args) => {\n const fields = args.fields as Array<{ ref: string; element?: string; value: string }>;\n if (!Array.isArray(fields)) return { ok: false, error: 'browser_fill_form requires fields[]' };\n const elements = fields.map((f) => ({ uid: normalizeUid(f.ref), value: f.value }));\n return toResult(await mcp.callTool('fill_form', { elements }));\n },\n\n browser_select_option: async (mcp, args) => {\n // chrome-devtools-mcp uses `fill` for <select> too.\n return toResult(\n await mcp.callTool('fill', { uid: normalizeUid(args.ref as string), value: args.value as string }),\n );\n },\n\n browser_file_upload: async (mcp, args) => {\n const paths = args.paths as string[] | undefined;\n const ref = normalizeUid(args.ref as string | undefined);\n if (!paths || paths.length === 0 || !ref) {\n return { ok: false, error: 'browser_file_upload in attached mode requires ref and a single path' };\n }\n return toResult(await mcp.callTool('upload_file', { uid: ref, filePath: paths[0] }));\n },\n\n browser_scroll: async (mcp, args) => {\n const direction = args.direction as 'up' | 'down' | 'left' | 'right';\n const amount = (args.amount as number | undefined) ?? 3;\n // amount is the canary \"intensity\" (1-10); map to ~300px per unit.\n const pixels = amount * 300;\n let dx = 0;\n let dy = 0;\n if (direction === 'down') dy = pixels;\n else if (direction === 'up') dy = -pixels;\n else if (direction === 'right') dx = pixels;\n else if (direction === 'left') dx = -pixels;\n const fn = `() => { window.scrollBy(${dx}, ${dy}); return { scrollX: window.scrollX, scrollY: window.scrollY }; }`;\n return toResult(await mcp.callTool('evaluate_script', { function: fn }));\n },\n\n browser_handle_dialog: async (mcp, args) => {\n return toResult(\n await mcp.callTool('handle_dialog', {\n action: args.action as 'accept' | 'dismiss',\n promptText: args.promptText as string | undefined,\n }),\n );\n },\n\n browser_dismiss_overlay: async (mcp) => {\n // No direct chrome-devtools tool; press Escape as a best-effort fallback.\n return toResult(await mcp.callTool('press_key', { key: 'Escape' }));\n },\n\n browser_wait_for: async (mcp, args) => {\n const text = args.text as string | undefined;\n const timeSec = args.timeSec as number | undefined;\n const timeout = args.timeout as number | undefined;\n if (text) {\n return toResult(await mcp.callTool('wait_for', { text: [text], timeout }));\n }\n if (typeof timeSec === 'number') {\n const fn = `async () => { await new Promise(r => setTimeout(r, ${Math.round(timeSec * 1000)})); return 'waited ${timeSec}s'; }`;\n return toResult(await mcp.callTool('evaluate_script', { function: fn }));\n }\n return { ok: false, error: 'browser_wait_for in attached mode requires text or time' };\n },\n\n browser_close: async () => {\n // Never close the user's real Chrome tab — just a no-op success.\n return { ok: true, text: 'browser_close is a no-op in attached mode (the user owns the browser).' };\n },\n\n browser_resize: async (mcp, args) => {\n return toResult(\n await mcp.callTool('resize_page', {\n width: args.width as number,\n height: args.height as number,\n }),\n );\n },\n\n browser_tabs: async (mcp, args) => {\n const action = args.action as 'list' | 'new' | 'close' | 'select';\n const index = args.index as number | undefined;\n switch (action) {\n case 'list':\n return toResult(await mcp.callTool('list_pages', {}));\n case 'new':\n return toResult(await mcp.callTool('new_page', { url: 'about:blank' }));\n case 'close':\n if (typeof index !== 'number')\n return { ok: false, error: 'browser_tabs close requires an index' };\n return toResult(await mcp.callTool('close_page', { pageId: index }));\n case 'select':\n if (typeof index !== 'number')\n return { ok: false, error: 'browser_tabs select requires an index' };\n return toResult(await mcp.callTool('select_page', { pageId: index, bringToFront: true }));\n default:\n return { ok: false, error: `browser_tabs: unknown action \"${String(action)}\"` };\n }\n },\n\n browser_list_downloads: async () => notSupportedInAttachedMode('browser_list_downloads'),\n browser_read_download: async () => notSupportedInAttachedMode('browser_read_download'),\n browser_pdf_read: async () => notSupportedInAttachedMode('browser_pdf_read'),\n};\n\nexport async function translateAndCall(\n mcp: ChromeDevtoolsMcpClient,\n toolName: string,\n args: Record<string, unknown>,\n): Promise<ProxyResult> {\n const translator = translators[toolName];\n if (!translator) {\n return { ok: false, error: `Unknown browser tool: ${toolName}` };\n }\n try {\n return await translator(mcp, args);\n } catch (err) {\n return { ok: false, error: err instanceof Error ? err.message : String(err) };\n }\n}\n","/**\n * CdpProxyClient — facade the daemon uses to proxy a canary `browser_*` tool\n * call to chrome-devtools-mcp, which in turn drives the user's real Chrome.\n *\n * @module\n */\n\nimport { ChromeDevtoolsMcpClient, type McpClientLogger } from './mcp-client.js';\nimport { translateAndCall, type ProxyResult } from './translators.js';\n\nexport class CdpProxyClient {\n private readonly mcp: ChromeDevtoolsMcpClient;\n\n constructor(logger?: McpClientLogger) {\n this.mcp = new ChromeDevtoolsMcpClient(logger);\n }\n\n async start(): Promise<void> {\n await this.mcp.start();\n }\n\n async callByCanaryName(\n toolName: string,\n args: Record<string, unknown>,\n ): Promise<ProxyResult> {\n const fullName = toolName.startsWith('browser_') ? toolName : `browser_${toolName}`;\n return translateAndCall(this.mcp, fullName, args);\n }\n\n async shutdown(): Promise<void> {\n await this.mcp.shutdown();\n }\n}\n\nexport { CHROME_DEVTOOLS_MCP_VERSION } from './mcp-client.js';\nexport type { ProxyResult } from './translators.js';\n"],"mappings":"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","names":["fs","os","path","process","fs","path","os","paused","path","os","args","fullToolName","fs","path","os","fs","sessions","process","result","session","handleTakeControl","handleResumeCloud"]}