@canaryai/cli 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +6 -2055
- package/dist/bin.js.map +1 -1
- package/dist/chunk-55MFLJD7.js +673 -0
- package/dist/chunk-55MFLJD7.js.map +1 -0
- package/dist/chunk-7AP5KRVU.js +1083 -0
- package/dist/chunk-7AP5KRVU.js.map +1 -0
- package/dist/chunk-7OCVIDC7.js +12 -0
- package/dist/chunk-7OCVIDC7.js.map +1 -0
- package/dist/chunk-UBYYNMML.js +21 -0
- package/dist/chunk-UBYYNMML.js.map +1 -0
- package/dist/chunk-YA43CE6P.js +781 -0
- package/dist/chunk-YA43CE6P.js.map +1 -0
- package/dist/chunk-Z6I3ZXZL.js +335 -0
- package/dist/chunk-Z6I3ZXZL.js.map +1 -0
- package/dist/index.js +8 -2267
- package/dist/index.js.map +1 -1
- package/dist/local-browser-5LJ7UPOH.js +141 -0
- package/dist/local-browser-5LJ7UPOH.js.map +1 -0
- package/dist/mcp-P2B24MTM.js +385 -0
- package/dist/mcp-P2B24MTM.js.map +1 -0
- package/dist/runner/preload.js +13 -1078
- package/dist/runner/preload.js.map +1 -1
- package/dist/test.js +14 -1077
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/runner/common.ts","../src/run.ts","../src/local-run.ts","../src/auth.ts","../src/tunnel.ts","../src/login.ts","../src/run-local.ts","../src/mcp.ts","../src/local-browser/host.ts","../src/remote-test.ts","../src/local-browser/index.ts","../src/bin.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport process from \"node:process\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\nimport { run as runCanary } from \"./run\";\nimport { runLocalTest } from \"./local-run\";\nimport { runTunnel } from \"./tunnel\";\nimport { runLogin } from \"./login\";\nimport { runLocalSession } from \"./run-local\";\nimport { runMcp } from \"./mcp\";\nimport { runRemoteTest } from \"./remote-test\";\nimport { runLocalBrowser } from \"./local-browser/index\";\n\nexport const canary = { run: runCanary };\nexport { runCanary as run };\n\nconst baseDir =\n typeof __dirname !== \"undefined\" ? __dirname : path.dirname(fileURLToPath(import.meta.url));\nconst preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\nconst requireFn = makeRequire();\n\nfunction runPlaywrightTests(args: string[]) {\n // Resolve the local @playwright/test CLI directly (drop-in replacement)\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = {\n ...process.env,\n CANARY_ENABLED: process.env.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n ...(nodeOptions ? { NODE_OPTIONS: nodeOptions } : {}),\n };\n\n const result = spawnSync(runnerBin, [playwrightCli, \"test\", ...args], {\n env,\n stdio: \"inherit\",\n cwd: process.cwd(),\n });\n\n if (result.error) {\n console.error(\"canary failed to launch Playwright:\", result.error);\n process.exit(1);\n }\n\n process.exit(result.status ?? 1);\n}\n\nfunction printHelp() {\n console.log(\n [\n \"canary: Local and remote testing CLI\",\n \"\",\n \"Usage:\",\n \" canary test [playwright options] Run local Playwright tests\",\n \" canary test --remote [options] Run remote workflow tests\",\n \" canary local-run --tunnel-url <url> [options]\",\n \" canary tunnel --port <localPort> [options]\",\n \" canary run --port <localPort> [options]\",\n \" canary mcp\",\n \" canary browser [--mode playwright|cdp] [--cdp-url <url>] [--no-headless]\",\n \" canary login [--app-url https://app.trycanary.ai] [--no-open]\",\n \" canary help\",\n \"\",\n \"Remote test options:\",\n \" --token <key> API key (or set CANARY_API_TOKEN)\",\n \" --api-url <url> API URL (default: https://api.trycanary.ai)\",\n \" --tag <tag> Filter workflows by tag\",\n \" --name-pattern <pat> Filter workflows by name pattern\",\n \" --verbose, -v Show all events\",\n \"\",\n \"Browser options:\",\n \" --mode <playwright|cdp> Browser mode (default: playwright)\",\n \" --cdp-url <url> CDP endpoint for existing Chrome\",\n \" --no-headless Run browser with visible UI\",\n \" --storage-state <path> Path to storage state JSON\",\n \" --instructions <text> Instructions for the cloud agent\",\n \"\",\n \"Flags:\",\n \" -h, --help Show help\",\n ].join(\"\\n\")\n );\n}\n\nexport async function main(argv: string[]) {\n if (argv.includes(\"--help\") || argv.includes(\"-h\")) {\n printHelp();\n return;\n }\n\n const [command, ...rest] = argv;\n if (!command || command === \"help\") {\n printHelp();\n return;\n }\n\n if (command === \"test\") {\n // Check for --remote flag to run remote workflow tests\n if (rest.includes(\"--remote\")) {\n const remoteArgs = rest.filter((arg) => arg !== \"--remote\");\n await runRemoteTest(remoteArgs);\n return;\n }\n runPlaywrightTests(rest);\n return;\n }\n\n if (command === \"local-run\") {\n await runLocalTest(rest);\n return;\n }\n\n if (command === \"run\") {\n await runLocalSession(rest);\n return;\n }\n\n if (command === \"mcp\") {\n await runMcp(rest);\n return;\n }\n\n if (command === \"tunnel\") {\n await runTunnel(rest);\n return;\n }\n\n if (command === \"login\") {\n await runLogin(rest);\n return;\n }\n\n if (command === \"browser\") {\n await runLocalBrowser(rest);\n return;\n }\n\n console.log(`Unknown command \"${command}\".`);\n printHelp();\n process.exit(1);\n}\n\nif (import.meta.url === pathToFileURL(process.argv[1]).href) {\n void main(process.argv.slice(2));\n}\n","import { spawnSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { createRequire } from \"node:module\";\nimport { pathToFileURL } from \"node:url\";\n\nexport function makeRequire() {\n try {\n return createRequire(import.meta.url);\n } catch {\n try {\n return createRequire(process.cwd());\n } catch {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return typeof require !== \"undefined\" ? (require as any) : createRequire(\".\");\n }\n }\n}\n\nexport function resolveRunner(preloadPath?: string): { runnerBin: string; preloadFlag?: string } {\n const { bin, version } = pickNodeBinary();\n const supportsImport = typeof version === \"number\" && version >= 18;\n\n if (supportsImport && preloadPath && fs.existsSync(preloadPath)) {\n return { runnerBin: bin, preloadFlag: `--import=${pathToFileURL(preloadPath).href}` };\n }\n\n if (preloadPath) {\n console.warn(\"[canary] Warning: no preload module found; instrumentation may be disabled.\");\n }\n\n return { runnerBin: bin };\n}\n\nexport function pickNodeBinary(): { bin: string; version?: number } {\n const candidates = collectNodeCandidates();\n\n // Prefer the first viable candidate with version >=18; otherwise pick highest version found.\n let best: { bin: string; version?: number } | undefined;\n let fallback: { bin: string; version?: number } | undefined;\n\n for (const bin of candidates) {\n const version = getNodeMajor(bin);\n if (!version) continue;\n const current = { bin, version };\n if (version >= 18 && !fallback) {\n fallback = current;\n }\n if (!best || version > (best.version ?? 0)) {\n best = current;\n }\n }\n\n if (fallback) return fallback;\n if (best) return best;\n\n // Last resort\n return { bin: candidates[0] ?? \"node\" };\n}\n\nexport function collectNodeCandidates(): string[] {\n const seen = new Set<string>();\n const push = (value?: string) => {\n if (!value) return;\n if (seen.has(value)) return;\n seen.add(value);\n };\n\n const isBun = path.basename(process.execPath).includes(\"bun\");\n\n push(process.env.CANARY_NODE_BIN);\n push(isBun ? undefined : process.execPath);\n push(\"node\"); // default PATH lookup\n\n // Collect from `which -a node` if available.\n try {\n const which = spawnSync(\"which\", [\"-a\", \"node\"], { encoding: \"utf-8\" });\n which.stdout\n ?.toString()\n .split(\"\\n\")\n .map((line) => line.trim())\n .forEach((line) => push(line));\n } catch {\n // ignore\n }\n\n // NVM installations (grab highest versions)\n const nvmDir = process.env.NVM_DIR || (process.env.HOME ? path.join(process.env.HOME, \".nvm\") : undefined);\n if (nvmDir) {\n const versionsDir = path.join(nvmDir, \"versions\", \"node\");\n if (fs.existsSync(versionsDir)) {\n try {\n const versions = fs.readdirSync(versionsDir);\n versions\n .sort((a, b) => (a > b ? -1 : 1))\n .forEach((v) => push(path.join(versionsDir, v, \"bin\", \"node\")));\n } catch {\n // ignore\n }\n }\n }\n\n return Array.from(seen);\n}\n\nexport function getNodeMajor(bin: string): number | undefined {\n try {\n const result = spawnSync(bin, [\"-v\"], { encoding: \"utf-8\" });\n const output = (result.stdout || result.stderr || \"\").toString().trim();\n const match = output.match(/^v(\\d+)/);\n if (match) return Number(match[1]);\n } catch {\n // ignore\n }\n return undefined;\n}\n","import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { makeRequire, resolveRunner } from \"./runner/common\";\n\nexport type HealingOptions = {\n apiKey?: string;\n provider?: string;\n model?: string;\n timeoutMs?: number;\n maxActions?: number;\n vision?: boolean;\n dryRun?: boolean;\n warnOnly?: boolean;\n debug?: boolean;\n readOnly?: boolean;\n allowEvaluate?: boolean;\n allowRunCode?: boolean;\n maxPayloadBytes?: number;\n};\n\nexport type RunRequest = {\n projectRoot?: string;\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n env?: Record<string, string>;\n healing?: HealingOptions;\n reporter?: \"default\" | \"json\" | string;\n timeoutMs?: number;\n nodeBin?: string;\n stdio?: \"inherit\" | \"pipe\";\n};\n\nexport type RunResult = {\n ok: boolean;\n exitCode: number;\n summary: {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n healed?: number;\n warned?: number;\n durationMs: number;\n };\n artifactsDir?: string;\n rawOutput?: string;\n error?: Error;\n};\n\ntype JsonReport = {\n suites?: JsonSuite[];\n duration?: number;\n};\n\ntype JsonSuite = {\n suites?: JsonSuite[];\n tests?: Array<{\n title: string;\n results: Array<{\n status: \"passed\" | \"failed\" | \"timedOut\" | \"skipped\" | \"interrupted\";\n duration: number;\n errors?: unknown[];\n }>;\n }>;\n};\n\nexport async function run(request: RunRequest = {}): Promise<RunResult> {\n const cwd = request.projectRoot ?? process.cwd();\n const stdio = request.stdio ?? \"inherit\";\n const requireFn = makeRequire();\n const playwrightCli = requireFn.resolve(\"@playwright/test/cli\");\n const baseDir = path.dirname(fileURLToPath(import.meta.url));\n const preloadPath = path.join(baseDir, \"runner\", \"preload.js\");\n const { runnerBin, preloadFlag } = resolveRunner(preloadPath);\n\n const { jsonReportPath, eventLogPath, artifactsDir } = prepareArtifactsDir(cwd);\n const reporter = buildReporterArgs(request.reporter, jsonReportPath);\n const args = buildArgs({\n testDir: request.testDir,\n configFile: request.configFile,\n cliArgs: request.cliArgs,\n reporter,\n });\n\n const nodeOptions =\n process.env.NODE_OPTIONS && preloadFlag\n ? `${process.env.NODE_OPTIONS} ${preloadFlag}`\n : preloadFlag ?? process.env.NODE_OPTIONS;\n\n const env = buildEnv({\n base: process.env,\n overrides: request.env,\n healing: request.healing,\n eventLogPath,\n nodeOptions,\n });\n\n const runResult = await spawnPlaywright({\n bin: request.nodeBin ?? runnerBin,\n args: [playwrightCli, ...args],\n cwd,\n env,\n stdio,\n timeoutMs: request.timeoutMs,\n });\n\n const summary = summarize(jsonReportPath, eventLogPath, runResult.durationMs);\n\n return {\n ok: runResult.exitCode === 0,\n exitCode: runResult.exitCode,\n summary,\n artifactsDir,\n rawOutput: runResult.output,\n error: runResult.error,\n };\n}\n\nfunction buildArgs(opts: {\n testDir?: string | string[];\n configFile?: string;\n cliArgs?: string[];\n reporter: string;\n}): string[] {\n const args = [\"test\"];\n\n if (opts.testDir) {\n const dirs = Array.isArray(opts.testDir) ? opts.testDir : [opts.testDir];\n args.push(...dirs);\n }\n\n if (opts.configFile) {\n args.push(\"--config\", opts.configFile);\n }\n\n args.push(\"--reporter\", opts.reporter);\n\n if (opts.cliArgs?.length) {\n args.push(...opts.cliArgs);\n }\n\n return args;\n}\n\nfunction buildReporterArgs(requested: RunRequest[\"reporter\"], jsonReportPath: string): string {\n if (requested === \"json\") return `json=${jsonReportPath}`;\n if (requested && requested !== \"default\") return requested;\n // Default: keep list output plus JSON for programmatic summary\n return `list,json=${jsonReportPath}`;\n}\n\nfunction prepareArtifactsDir(cwd: string): { jsonReportPath: string; eventLogPath: string; artifactsDir: string } {\n const dir = fs.mkdtempSync(path.join(os.tmpdir(), \"canary-run-\"));\n const jsonReportPath = path.join(dir, \"report.json\");\n const eventLogPath = path.join(dir, \"events-worker-0.jsonl\");\n const artifactsDir = path.join(cwd, \"test-results\", \"ai-healer\");\n return { jsonReportPath, eventLogPath, artifactsDir: dir };\n}\n\nfunction buildEnv(params: {\n base: NodeJS.ProcessEnv;\n overrides?: Record<string, string>;\n healing?: HealingOptions;\n eventLogPath: string;\n nodeOptions?: string;\n}): NodeJS.ProcessEnv {\n const healing = params.healing ?? {};\n const env: NodeJS.ProcessEnv = {\n ...params.base,\n CANARY_ENABLED: params.base.CANARY_ENABLED ?? \"1\",\n CANARY_RUNNER: \"canary\",\n CANARY_EVENT_LOG: params.eventLogPath,\n ...(params.nodeOptions ? { NODE_OPTIONS: params.nodeOptions } : {}),\n ...(healing.apiKey ? { AI_API_KEY: healing.apiKey } : {}),\n ...(healing.provider ? { AI_PROVIDER: healing.provider } : {}),\n ...(healing.model ? { AI_MODEL: healing.model } : {}),\n ...(healing.timeoutMs ? { AI_TIMEOUT_MS: String(healing.timeoutMs) } : {}),\n ...(healing.maxActions ? { CANARY_MAX_ACTIONS: String(healing.maxActions) } : {}),\n ...(healing.vision ? { CANARY_VISION: \"1\" } : {}),\n ...(healing.dryRun ? { CANARY_DRY_RUN: \"1\" } : {}),\n ...(healing.warnOnly ? { CANARY_WARN_ONLY: \"1\" } : {}),\n ...(healing.debug ? { CANARY_DEBUG: \"1\" } : {}),\n ...(healing.readOnly ? { CANARY_READ_ONLY: \"1\" } : {}),\n ...(healing.allowEvaluate === false ? { CANARY_ALLOW_EVALUATE: \"0\" } : {}),\n ...(healing.allowRunCode ? { CANARY_ALLOW_RUN_CODE: \"1\" } : {}),\n ...(healing.maxPayloadBytes ? { CANARY_MAX_PAYLOAD_BYTES: String(healing.maxPayloadBytes) } : {}),\n ...params.overrides,\n };\n return env;\n}\n\nasync function spawnPlaywright(opts: {\n bin: string;\n args: string[];\n cwd: string;\n env: NodeJS.ProcessEnv;\n stdio: \"inherit\" | \"pipe\";\n timeoutMs?: number;\n}): Promise<{ exitCode: number; output?: string; durationMs: number; error?: Error }> {\n return new Promise((resolve) => {\n const started = Date.now();\n const child = spawn(opts.bin, opts.args, {\n cwd: opts.cwd,\n env: opts.env,\n stdio: opts.stdio === \"inherit\" ? \"inherit\" : [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let timer: NodeJS.Timeout | undefined;\n let output = \"\";\n let error: Error | undefined;\n\n if (opts.stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n if (opts.timeoutMs && opts.timeoutMs > 0) {\n timer = setTimeout(() => {\n error = new Error(`canary.run timed out after ${opts.timeoutMs}ms`);\n child.kill(\"SIGKILL\");\n }, opts.timeoutMs);\n }\n\n child.on(\"close\", (code) => {\n if (timer) clearTimeout(timer);\n resolve({ exitCode: code ?? 1, output: output || undefined, durationMs: Date.now() - started, error });\n });\n });\n}\n\nfunction summarize(jsonReportPath: string, eventLogPath: string, durationMs: number): RunResult[\"summary\"] {\n const base = {\n total: 0,\n passed: 0,\n failed: 0,\n flaky: 0,\n skipped: 0,\n durationMs,\n };\n\n const jsonReport = readJsonReport(jsonReportPath);\n if (jsonReport) {\n const counts = countTests(jsonReport);\n base.total = counts.total;\n base.passed = counts.passed;\n base.failed = counts.failed;\n base.flaky = counts.flaky;\n base.skipped = counts.skipped;\n base.durationMs = jsonReport.duration ?? durationMs;\n }\n\n const healed = countHealed(eventLogPath);\n if (healed) {\n return { ...base, healed };\n }\n return base;\n}\n\nfunction readJsonReport(reportPath: string): JsonReport | undefined {\n try {\n if (fs.existsSync(reportPath)) {\n const raw = fs.readFileSync(reportPath, \"utf-8\");\n return JSON.parse(raw) as JsonReport;\n }\n } catch {\n // ignore parse issues\n }\n return undefined;\n}\n\nfunction countTests(report: JsonReport): {\n total: number;\n passed: number;\n failed: number;\n flaky: number;\n skipped: number;\n} {\n let total = 0;\n let passed = 0;\n let failed = 0;\n let flaky = 0;\n let skipped = 0;\n\n const visitSuite = (suite?: JsonSuite) => {\n if (!suite) return;\n suite.tests?.forEach((test) => {\n total += 1;\n const statuses = test.results.map((r) => r.status);\n const hasFailed = statuses.includes(\"failed\") || statuses.includes(\"interrupted\");\n const hasPassed = statuses.includes(\"passed\");\n const hasTimedOut = statuses.includes(\"timedOut\");\n const allSkipped = statuses.every((s) => s === \"skipped\");\n\n if (allSkipped) {\n skipped += 1;\n } else if ((hasFailed || hasTimedOut) && hasPassed) {\n flaky += 1;\n } else if (hasFailed || hasTimedOut) {\n failed += 1;\n } else if (hasPassed && statuses.length > 1) {\n flaky += 1;\n } else if (hasPassed) {\n passed += 1;\n }\n });\n\n suite.suites?.forEach(visitSuite);\n };\n\n report.suites?.forEach(visitSuite);\n\n return { total, passed, failed, flaky, skipped };\n}\n\nfunction countHealed(eventLogPath: string): number | undefined {\n try {\n if (!fs.existsSync(eventLogPath)) return undefined;\n const raw = fs.readFileSync(eventLogPath, \"utf-8\").trim();\n if (!raw) return undefined;\n const lines = raw.split(\"\\n\");\n let healed = 0;\n for (const line of lines) {\n try {\n const event = JSON.parse(line);\n if (event?.healed === true) healed += 1;\n } catch {\n // ignore bad lines\n }\n }\n return healed;\n } catch {\n return undefined;\n }\n}\n\nexport const __internals = {\n buildArgs,\n buildReporterArgs,\n buildEnv,\n countTests,\n countHealed,\n summarize,\n};\n","import process from \"node:process\";\nimport { readStoredToken } from \"./auth\";\n\ntype LocalRunOptions = {\n apiUrl: string;\n token?: string;\n title?: string;\n featureSpec?: string;\n startUrl?: string;\n tunnelUrl?: string;\n};\n\ntype LocalRunResponse = {\n ok: boolean;\n runId?: string;\n watchUrl?: string;\n error?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nexport async function runLocalTest(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n const title = getArgValue(argv, \"--title\");\n const featureSpec = getArgValue(argv, \"--feature\");\n const startUrl = getArgValue(argv, \"--start-url\");\n const tunnelUrl = getArgValue(argv, \"--tunnel-url\");\n\n if (!tunnelUrl && !startUrl) {\n console.error(\"Missing --tunnel-url or --start-url\");\n process.exit(1);\n }\n\n if (!token) {\n console.error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n process.exit(1);\n }\n\n const result = await createLocalRun({\n apiUrl,\n token,\n title,\n featureSpec,\n startUrl,\n tunnelUrl,\n });\n\n console.log(`Local test queued: ${result.runId}`);\n if (result.watchUrl) {\n console.log(`Watch: ${result.watchUrl}`);\n }\n}\n\nexport async function createLocalRun(input: {\n apiUrl: string;\n token: string;\n title?: string;\n featureSpec?: string;\n startUrl?: string;\n tunnelUrl?: string;\n}): Promise<{ runId: string; watchUrl?: string }> {\n const body = {\n title: input.title ?? null,\n featureSpec: input.featureSpec ?? null,\n startUrl: input.startUrl ?? null,\n tunnelPublicUrl: input.tunnelUrl ?? null,\n };\n\n const response = await fetch(`${input.apiUrl}/local-tests/runs`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${input.token}`,\n },\n body: JSON.stringify(body),\n });\n\n const json = (await response.json()) as LocalRunResponse;\n if (!response.ok || !json.ok || !json.runId) {\n throw new Error(json.error ?? response.statusText);\n }\n\n return { runId: json.runId, watchUrl: json.watchUrl };\n}\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\ntype StoredAuth = {\n token?: string;\n};\n\nexport async function readStoredToken(): Promise<string | null> {\n try {\n const filePath = path.join(os.homedir(), \".config\", \"canary-cli\", \"auth.json\");\n const content = await fs.readFile(filePath, \"utf8\");\n const parsed = JSON.parse(content) as StoredAuth;\n return typeof parsed.token === \"string\" ? parsed.token : null;\n } catch {\n return null;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport os from \"node:os\";\nimport process from \"node:process\";\nimport { readStoredToken } from \"./auth\";\n\nexport type CreateTunnelResponse = {\n ok: boolean;\n tunnelId?: string;\n publicUrl?: string;\n token?: string;\n error?: string;\n};\n\ntype ProxyRequest = {\n type: \"http_request\";\n id: string;\n method: string;\n path: string;\n headers: Record<string, string>;\n bodyBase64?: string | null;\n};\n\ntype ProxyResponse = {\n type: \"http_response\";\n id: string;\n status: number;\n headers?: Record<string, string | string[]>;\n bodyBase64?: string | null;\n};\n\ntype WsOpen = {\n type: \"ws_open\";\n id: string;\n path: string;\n headers: Record<string, string>;\n};\n\ntype WsReady = {\n type: \"ws_ready\";\n id: string;\n};\n\ntype WsMessage = {\n type: \"ws_message\";\n id: string;\n dataBase64: string;\n isBinary: boolean;\n};\n\ntype WsClose = {\n type: \"ws_close\";\n id: string;\n code?: number;\n reason?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nfunction toWebSocketUrl(apiUrl: string): string {\n const url = new URL(apiUrl);\n url.protocol = url.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return url.toString();\n}\n\nfunction createFingerprint(): string {\n const raw = `${os.hostname()}-${os.userInfo().username}-${process.version}`;\n return createHash(\"sha256\").update(raw).digest(\"hex\").slice(0, 16);\n}\n\nexport async function runTunnel(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n const portRaw = getArgValue(argv, \"--port\") ?? process.env.CANARY_LOCAL_PORT;\n\n if (!portRaw) {\n console.error(\"Missing --port\");\n process.exit(1);\n }\n\n const port = Number(portRaw);\n if (Number.isNaN(port) || port <= 0) {\n console.error(\"Invalid --port value\");\n process.exit(1);\n }\n\n if (!token) {\n console.error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n process.exit(1);\n }\n\n const maxReconnectAttempts = 10;\n const baseReconnectDelayMs = 1000;\n let reconnectAttempts = 0;\n\n const connect = async (): Promise<void> => {\n try {\n const data = await createTunnel({\n apiUrl,\n token,\n port,\n });\n\n console.log(`Tunnel connected: ${data.publicUrl ?? data.tunnelId}`);\n if (data.publicUrl) {\n console.log(`Public URL: ${data.publicUrl}`);\n console.log(\"\");\n console.log(\"To use this tunnel for sandbox agent callbacks, add to apps/api/.env:\");\n console.log(` SANDBOX_AGENT_API_URL=${data.publicUrl}`);\n console.log(\"\");\n }\n\n const ws = connectTunnel({\n apiUrl,\n tunnelId: data.tunnelId,\n token: data.token,\n port,\n onReady: () => {\n reconnectAttempts = 0; // Reset on successful connection\n },\n });\n\n return new Promise<void>((resolve, reject) => {\n ws.onclose = (event) => {\n console.log(`Tunnel closed (code: ${event.code})`);\n\n if (reconnectAttempts < maxReconnectAttempts) {\n const delay = Math.min(baseReconnectDelayMs * Math.pow(2, reconnectAttempts), 30000);\n reconnectAttempts++;\n console.log(`Reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${maxReconnectAttempts})...`);\n setTimeout(() => {\n connect().then(resolve).catch(reject);\n }, delay);\n } else {\n console.error(\"Max reconnection attempts reached. Exiting.\");\n process.exit(1);\n }\n };\n\n ws.onerror = (event) => {\n console.error(\"Tunnel error:\", event);\n };\n });\n } catch (error) {\n if (reconnectAttempts < maxReconnectAttempts) {\n const delay = Math.min(baseReconnectDelayMs * Math.pow(2, reconnectAttempts), 30000);\n reconnectAttempts++;\n console.error(`Failed to create tunnel: ${error}`);\n console.log(`Retrying in ${delay}ms (attempt ${reconnectAttempts}/${maxReconnectAttempts})...`);\n await new Promise((resolve) => setTimeout(resolve, delay));\n return connect();\n } else {\n console.error(\"Max reconnection attempts reached. Exiting.\");\n process.exit(1);\n }\n }\n };\n\n await connect();\n}\n\nexport async function createTunnel(input: {\n apiUrl: string;\n token: string;\n port: number;\n}): Promise<{ tunnelId: string; publicUrl?: string; token: string }> {\n const response = await fetch(`${input.apiUrl}/local-tests/tunnels`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${input.token}`,\n },\n body: JSON.stringify({\n requestedPort: input.port,\n clientFingerprint: createFingerprint(),\n }),\n });\n\n const data = (await response.json()) as CreateTunnelResponse;\n if (!response.ok || !data.ok || !data.tunnelId || !data.token) {\n throw new Error(data.error ?? response.statusText);\n }\n\n return { tunnelId: data.tunnelId, publicUrl: data.publicUrl, token: data.token };\n}\n\nexport function connectTunnel(input: {\n apiUrl: string;\n tunnelId: string;\n token: string;\n port: number;\n onReady?: () => void;\n}): WebSocket {\n const wsUrl = toWebSocketUrl(\n `${input.apiUrl}/local-tests/tunnels/${input.tunnelId}/connect?token=${input.token}`\n );\n const ws = new WebSocket(wsUrl);\n const wsConnections = new Map<string, WebSocket>();\n const wsQueues = new Map<string, Array<WsMessage | WsClose>>();\n\n ws.onopen = () => {\n input.onReady?.();\n };\n\n ws.onerror = (event) => {\n console.error(\"Tunnel error\", event);\n };\n\n ws.onclose = () => {\n console.log(\"Tunnel closed\");\n };\n\n ws.onmessage = async (event) => {\n try {\n const raw =\n typeof event.data === \"string\"\n ? event.data\n : Buffer.from(event.data as ArrayBuffer).toString();\n const payload = JSON.parse(raw) as\n | ProxyRequest\n | WsOpen\n | WsMessage\n | WsClose\n | { type: string };\n if (payload.type === \"http_request\") {\n const request = payload as ProxyRequest;\n const targetUrl = `http://localhost:${input.port}${\n request.path.startsWith(\"/\") ? request.path : `/${request.path}`\n }`;\n const body = request.bodyBase64 ? Buffer.from(request.bodyBase64, \"base64\") : undefined;\n const headers = { ...request.headers };\n delete headers.host;\n delete headers[\"content-length\"];\n\n try {\n const res = await fetch(targetUrl, {\n method: request.method,\n headers,\n body: body ?? undefined,\n });\n\n const resBody = await res.arrayBuffer();\n const resHeaders: Record<string, string | string[]> = Object.fromEntries(res.headers.entries());\n delete resHeaders[\"set-cookie\"];\n\n const getSetCookie = (res.headers as Headers & { getSetCookie?: () => string[] })\n .getSetCookie;\n const setCookieValues =\n typeof getSetCookie === \"function\" ? getSetCookie.call(res.headers) : [];\n const fallbackSetCookie = res.headers.get(\"set-cookie\");\n if (setCookieValues.length === 0 && fallbackSetCookie) {\n setCookieValues.push(fallbackSetCookie);\n }\n if (setCookieValues.length > 0) {\n resHeaders[\"set-cookie\"] = setCookieValues;\n }\n\n const responsePayload: ProxyResponse = {\n type: \"http_response\",\n id: request.id,\n status: res.status,\n headers: resHeaders,\n bodyBase64: resBody.byteLength ? Buffer.from(resBody).toString(\"base64\") : null,\n };\n\n ws.send(JSON.stringify(responsePayload));\n } catch (error) {\n const responsePayload: ProxyResponse = {\n type: \"http_response\",\n id: request.id,\n status: 502,\n headers: { \"content-type\": \"text/plain\" },\n bodyBase64: Buffer.from(`Tunnel error: ${String(error)}`).toString(\"base64\"),\n };\n ws.send(JSON.stringify(responsePayload));\n }\n }\n if (payload.type === \"ws_open\") {\n const request = payload as WsOpen;\n const targetUrl = `ws://localhost:${input.port}${\n request.path.startsWith(\"/\") ? request.path : `/${request.path}`\n }`;\n const protocolsHeader =\n request.headers[\"sec-websocket-protocol\"] ?? request.headers[\"Sec-WebSocket-Protocol\"];\n const protocols = protocolsHeader\n ? protocolsHeader\n .split(\",\")\n .map((value) => value.trim())\n .filter(Boolean)\n : undefined;\n const localWs = new WebSocket(targetUrl, protocols);\n wsConnections.set(request.id, localWs);\n\n localWs.onopen = () => {\n ws.send(JSON.stringify({ type: \"ws_ready\", id: request.id } satisfies WsReady));\n const queued = wsQueues.get(request.id);\n if (queued) {\n for (const message of queued) {\n ws.send(JSON.stringify(message));\n }\n wsQueues.delete(request.id);\n }\n };\n\n localWs.onmessage = (event) => {\n const data =\n typeof event.data === \"string\"\n ? Buffer.from(event.data)\n : Buffer.from(event.data as ArrayBuffer);\n const response: WsMessage = {\n type: \"ws_message\",\n id: request.id,\n dataBase64: data.toString(\"base64\"),\n isBinary: typeof event.data !== \"string\",\n };\n ws.send(JSON.stringify(response));\n };\n\n localWs.onclose = (event) => {\n wsConnections.delete(request.id);\n const response: WsClose = {\n type: \"ws_close\",\n id: request.id,\n code: event.code,\n reason: event.reason,\n };\n ws.send(JSON.stringify(response));\n };\n\n localWs.onerror = () => {\n wsConnections.delete(request.id);\n const response: WsClose = {\n type: \"ws_close\",\n id: request.id,\n code: 1011,\n reason: \"local_ws_error\",\n };\n ws.send(JSON.stringify(response));\n };\n }\n if (payload.type === \"ws_message\") {\n const message = payload as WsMessage;\n const localWs = wsConnections.get(message.id);\n const data = Buffer.from(message.dataBase64, \"base64\");\n if (!localWs || localWs.readyState !== WebSocket.OPEN) {\n const queued = wsQueues.get(message.id) ?? [];\n queued.push(message);\n wsQueues.set(message.id, queued);\n return;\n }\n if (message.isBinary) {\n localWs.send(data);\n } else {\n localWs.send(data.toString());\n }\n }\n if (payload.type === \"ws_close\") {\n const message = payload as WsClose;\n const localWs = wsConnections.get(message.id);\n if (!localWs) {\n const queued = wsQueues.get(message.id) ?? [];\n queued.push(message);\n wsQueues.set(message.id, queued);\n return;\n }\n localWs.close(message.code ?? 1000, message.reason ?? \"\");\n wsConnections.delete(message.id);\n }\n if (payload.type === \"health_ping\") {\n ws.send(JSON.stringify({ type: \"health_pong\" }));\n }\n } catch (error) {\n console.error(\"Tunnel message error\", error);\n }\n };\n\n return ws;\n}\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\n\ntype StartResponse = {\n ok: boolean;\n deviceCode?: string;\n userCode?: string;\n verificationUrl?: string;\n expiresAt?: string;\n intervalSeconds?: number;\n error?: string;\n};\n\ntype PollResponse = {\n ok: boolean;\n status?: \"pending\" | \"approved\" | \"rejected\" | \"expired\";\n accessToken?: string;\n error?: string;\n};\n\nconst DEFAULT_APP_URL = \"https://app.trycanary.ai\";\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nfunction shouldOpenBrowser(argv: string[]): boolean {\n return !argv.includes(\"--no-open\");\n}\n\nfunction openUrl(url: string) {\n const platform = process.platform;\n if (platform === \"darwin\") {\n spawn(\"open\", [url], { stdio: \"ignore\" });\n return;\n }\n if (platform === \"win32\") {\n spawn(\"cmd\", [\"/c\", \"start\", \"\", url], { stdio: \"ignore\" });\n return;\n }\n spawn(\"xdg-open\", [url], { stdio: \"ignore\" });\n}\n\nasync function writeToken(token: string) {\n const dir = path.join(os.homedir(), \".config\", \"canary-cli\");\n const filePath = path.join(dir, \"auth.json\");\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(filePath, JSON.stringify({ token }, null, 2), \"utf8\");\n return filePath;\n}\n\nexport async function runLogin(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const appUrl = getArgValue(argv, \"--app-url\") ?? process.env.CANARY_APP_URL ?? DEFAULT_APP_URL;\n\n const startRes = await fetch(`${apiUrl}/cli-login/start`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ appUrl }),\n });\n\n const startJson = (await startRes.json()) as StartResponse;\n if (!startRes.ok || !startJson.ok || !startJson.deviceCode || !startJson.userCode) {\n console.error(\"Login start failed\", startJson.error ?? startRes.statusText);\n process.exit(1);\n }\n\n console.log(\"Login required.\");\n console.log(`User code: ${startJson.userCode}`);\n if (startJson.verificationUrl) {\n console.log(`Open: ${startJson.verificationUrl}`);\n if (shouldOpenBrowser(argv)) {\n try {\n openUrl(startJson.verificationUrl);\n } catch {\n console.log(\"Unable to open browser automatically. Please open the URL manually.\");\n }\n }\n }\n\n const intervalMs = (startJson.intervalSeconds ?? 3) * 1000;\n const expiresAt = startJson.expiresAt ? new Date(startJson.expiresAt).getTime() : null;\n\n while (true) {\n if (expiresAt && Date.now() > expiresAt) {\n console.error(\"Login code expired.\");\n process.exit(1);\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n\n const pollRes = await fetch(`${apiUrl}/cli-login/poll`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ deviceCode: startJson.deviceCode }),\n });\n\n const pollJson = (await pollRes.json()) as PollResponse;\n if (!pollRes.ok || !pollJson.ok) {\n console.error(\"Login poll failed\", pollJson.error ?? pollRes.statusText);\n process.exit(1);\n }\n\n if (pollJson.status === \"approved\" && pollJson.accessToken) {\n const filePath = await writeToken(pollJson.accessToken);\n console.log(`Login successful. Token saved to ${filePath}`);\n console.log(\"Set CANARY_API_TOKEN to use the CLI without re-login.\");\n return;\n }\n\n if (pollJson.status === \"rejected\") {\n console.error(\"Login rejected.\");\n process.exit(1);\n }\n\n if (pollJson.status === \"expired\") {\n console.error(\"Login expired.\");\n process.exit(1);\n }\n }\n}\n","import process from \"node:process\";\nimport { readStoredToken } from \"./auth\";\nimport { createLocalRun } from \"./local-run\";\nimport { connectTunnel, createTunnel } from \"./tunnel\";\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1) return undefined;\n return argv[index + 1];\n}\n\nexport async function runLocalSession(argv: string[]) {\n const apiUrl = getArgValue(argv, \"--api-url\") ?? process.env.CANARY_API_URL ?? \"https://api.trycanary.ai\";\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n if (!token) {\n console.error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n process.exit(1);\n }\n\n const portRaw = getArgValue(argv, \"--port\") ?? process.env.CANARY_LOCAL_PORT;\n const tunnelUrl = getArgValue(argv, \"--tunnel-url\");\n const title = getArgValue(argv, \"--title\");\n const featureSpec = getArgValue(argv, \"--feature\");\n const startUrl = getArgValue(argv, \"--start-url\");\n\n if (!tunnelUrl && !portRaw) {\n console.error(\"Missing --port or --tunnel-url\");\n process.exit(1);\n }\n\n let publicUrl = tunnelUrl;\n let ws: WebSocket | null = null;\n\n if (!publicUrl && portRaw) {\n const port = Number(portRaw);\n if (Number.isNaN(port) || port <= 0) {\n console.error(\"Invalid --port value\");\n process.exit(1);\n }\n\n const tunnel = await createTunnel({ apiUrl, token, port });\n publicUrl = tunnel.publicUrl;\n\n ws = connectTunnel({\n apiUrl,\n tunnelId: tunnel.tunnelId,\n token: tunnel.token,\n port,\n onReady: () => {\n console.log(`Tunnel connected: ${publicUrl ?? tunnel.tunnelId}`);\n },\n });\n }\n\n if (!publicUrl) {\n console.error(\"Failed to resolve tunnel URL\");\n process.exit(1);\n }\n\n const run = await createLocalRun({\n apiUrl,\n token,\n title,\n featureSpec,\n startUrl,\n tunnelUrl: publicUrl,\n });\n\n console.log(`Local test queued: ${run.runId}`);\n if (run.watchUrl) {\n console.log(`Watch: ${run.watchUrl}`);\n }\n\n if (ws) {\n console.log(\"Tunnel active. Press Ctrl+C to stop.\");\n process.on(\"SIGINT\", () => {\n ws?.close();\n process.exit(0);\n });\n await new Promise<void>(() => undefined);\n }\n}\n","import process from \"node:process\";\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { CallToolRequestSchema, ListToolsRequestSchema } from \"@modelcontextprotocol/sdk/types.js\";\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport { readStoredToken } from \"./auth\";\nimport { createLocalRun } from \"./local-run\";\nimport { connectTunnel, createTunnel } from \"./tunnel\";\nimport { LocalBrowserHost } from \"./local-browser/host\";\nimport type { LocalBrowserMode } from \"./local-browser/protocol\";\n\ntype RunLocalInput = {\n port: number;\n instructions: string;\n title?: string;\n};\n\ntype WaitForRunInput = {\n runId: string;\n};\n\ntype LocalBrowserStartInput = {\n mode?: LocalBrowserMode;\n cdpUrl?: string;\n headless?: boolean;\n storageStatePath?: string;\n instructions?: string;\n};\n\ntype LocalBrowserStopInput = {\n sessionId: string;\n};\n\ntype LocalBrowserStatusInput = {\n sessionId: string;\n};\n\ninterface BrowserSession {\n sessionId: string;\n host: LocalBrowserHost;\n startedAt: number;\n mode: LocalBrowserMode;\n}\n\n// Global browser sessions managed by MCP\nconst browserSessions = new Map<string, BrowserSession>();\n\nconst DEFAULT_API_URL = \"https://api.trycanary.ai\";\n\nfunction resolveApiUrl(input?: string): string {\n return input ?? process.env.CANARY_API_URL ?? DEFAULT_API_URL;\n}\n\nasync function resolveToken(): Promise<string> {\n const token = process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n if (!token) {\n throw new Error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n }\n return token;\n}\n\nfunction toolText(text: string) {\n return { content: [{ type: \"text\", text }] };\n}\n\nfunction toolJson(data: unknown) {\n return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n}\n\nexport async function runMcp(argv: string[]) {\n const server = new Server(\n { name: \"canary-cli\", version: \"0.1.0\" },\n { capabilities: { tools: {} } }\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: \"local_run_tests\",\n description:\n \"Start an async local test run. A tunnel is opened automatically. Returns runId and watchUrl.\",\n inputSchema: {\n type: \"object\",\n properties: {\n port: { type: \"number\" },\n instructions: { type: \"string\" },\n title: { type: \"string\" },\n },\n required: [\"port\", \"instructions\"],\n },\n },\n {\n name: \"local_wait_for_results\",\n description:\n \"Wait for a local test run to complete. Streams until completion and returns a compact report.\",\n inputSchema: {\n type: \"object\",\n properties: {\n runId: { type: \"string\" },\n },\n required: [\"runId\"],\n },\n },\n {\n name: \"local_browser_start\",\n description:\n \"Start a local browser session that connects to the cloud agent. The cloud agent can then control this browser to test local applications. Returns sessionId for tracking.\",\n inputSchema: {\n type: \"object\",\n properties: {\n mode: {\n type: \"string\",\n enum: [\"playwright\", \"cdp\"],\n description: \"Browser mode: 'playwright' for fresh browser, 'cdp' to connect to existing Chrome\",\n },\n cdpUrl: {\n type: \"string\",\n description: \"CDP endpoint URL when mode is 'cdp' (e.g. http://localhost:9222)\",\n },\n headless: {\n type: \"boolean\",\n description: \"Run browser headless (default: true for playwright mode)\",\n },\n storageStatePath: {\n type: \"string\",\n description: \"Path to Playwright storage state JSON for pre-authenticated sessions\",\n },\n instructions: {\n type: \"string\",\n description: \"Instructions for the cloud agent on what to test\",\n },\n },\n },\n },\n {\n name: \"local_browser_status\",\n description: \"Check the status of a local browser session.\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionId: { type: \"string\" },\n },\n required: [\"sessionId\"],\n },\n },\n {\n name: \"local_browser_stop\",\n description: \"Stop a local browser session and close the browser.\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionId: { type: \"string\" },\n },\n required: [\"sessionId\"],\n },\n },\n {\n name: \"local_browser_list\",\n description: \"List all active local browser sessions.\",\n inputSchema: {\n type: \"object\",\n properties: {},\n },\n },\n {\n name: \"local_browser_run\",\n description:\n \"Start a test run on an active local browser session. The cloud agent will control the local browser according to the instructions.\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionId: {\n type: \"string\",\n description: \"The session ID from local_browser_start\",\n },\n instructions: {\n type: \"string\",\n description: \"Instructions for the cloud agent on what to test\",\n },\n startUrl: {\n type: \"string\",\n description: \"Optional URL to navigate to before starting\",\n },\n },\n required: [\"sessionId\", \"instructions\"],\n },\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (req) => {\n const token = await resolveToken();\n const tool = req.params.name;\n\n if (tool === \"local_run_tests\") {\n const input = req.params.arguments as RunLocalInput;\n const apiUrl = resolveApiUrl();\n const tunnel = await createTunnel({ apiUrl, token, port: input.port });\n connectTunnel({\n apiUrl,\n tunnelId: tunnel.tunnelId,\n token: tunnel.token,\n port: input.port,\n });\n const tunnelUrl = tunnel.publicUrl;\n\n const run = await createLocalRun({\n apiUrl,\n token,\n title: input.title ?? \"Local MCP run\",\n featureSpec: input.instructions,\n startUrl: undefined,\n tunnelUrl,\n });\n\n return toolJson({\n runId: run.runId,\n watchUrl: run.watchUrl,\n tunnelUrl,\n note:\n \"Testing is asynchronous. Use local_wait_for_results with the runId to wait for completion.\",\n });\n }\n\n if (tool === \"local_wait_for_results\") {\n const input = req.params.arguments as WaitForRunInput;\n const apiUrl = resolveApiUrl();\n const report = await waitForResult({ apiUrl, token, runId: input.runId });\n return toolJson(report);\n }\n\n if (tool === \"local_browser_start\") {\n const input = req.params.arguments as LocalBrowserStartInput;\n const apiUrl = resolveApiUrl();\n const mode = input.mode ?? \"playwright\";\n\n // Create session with cloud API\n const sessionResponse = 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({\n browserMode: mode,\n instructions: input.instructions ?? null,\n }),\n });\n\n if (!sessionResponse.ok) {\n const text = await sessionResponse.text();\n return toolJson({ ok: false, error: `Failed to create session: ${text}` });\n }\n\n const session = (await sessionResponse.json()) as {\n ok: boolean;\n sessionId: string;\n wsToken: string;\n expiresAt: string;\n };\n\n // Start the local browser host\n const host = new LocalBrowserHost({\n apiUrl,\n wsToken: session.wsToken,\n sessionId: session.sessionId,\n browserMode: mode,\n cdpUrl: input.cdpUrl,\n headless: input.headless ?? true,\n storageStatePath: input.storageStatePath,\n onLog: (level, message) => {\n // Silent logging for MCP context\n if (level === \"error\") {\n console.error(`[LocalBrowser] ${message}`);\n }\n },\n });\n\n // Start in background\n host.start().catch((err) => {\n console.error(\"Failed to start local browser:\", err);\n browserSessions.delete(session.sessionId);\n });\n\n browserSessions.set(session.sessionId, {\n sessionId: session.sessionId,\n host,\n startedAt: Date.now(),\n mode,\n });\n\n return toolJson({\n ok: true,\n sessionId: session.sessionId,\n mode,\n expiresAt: session.expiresAt,\n note: \"Browser session started. The cloud agent can now control this browser. Use local_browser_stop to end the session.\",\n });\n }\n\n if (tool === \"local_browser_status\") {\n const input = req.params.arguments as LocalBrowserStatusInput;\n const session = browserSessions.get(input.sessionId);\n\n if (!session) {\n return toolJson({ ok: false, error: \"Session not found\", sessionId: input.sessionId });\n }\n\n return toolJson({\n ok: true,\n sessionId: session.sessionId,\n mode: session.mode,\n startedAt: new Date(session.startedAt).toISOString(),\n uptimeMs: Date.now() - session.startedAt,\n });\n }\n\n if (tool === \"local_browser_stop\") {\n const input = req.params.arguments as LocalBrowserStopInput;\n const session = browserSessions.get(input.sessionId);\n\n if (!session) {\n return toolJson({ ok: false, error: \"Session not found\", sessionId: input.sessionId });\n }\n\n await session.host.stop();\n browserSessions.delete(input.sessionId);\n\n return toolJson({\n ok: true,\n sessionId: input.sessionId,\n note: \"Browser session stopped and browser closed.\",\n });\n }\n\n if (tool === \"local_browser_list\") {\n const sessions = Array.from(browserSessions.values()).map((s) => ({\n sessionId: s.sessionId,\n mode: s.mode,\n startedAt: new Date(s.startedAt).toISOString(),\n uptimeMs: Date.now() - s.startedAt,\n }));\n\n return toolJson({\n ok: true,\n count: sessions.length,\n sessions,\n });\n }\n\n if (tool === \"local_browser_run\") {\n const input = req.params.arguments as {\n sessionId: string;\n instructions: string;\n startUrl?: string;\n };\n const apiUrl = resolveApiUrl();\n\n // Verify session is active locally\n const session = browserSessions.get(input.sessionId);\n if (!session) {\n return toolJson({\n ok: false,\n error: \"Session not found locally. Make sure you started it with local_browser_start.\",\n sessionId: input.sessionId,\n });\n }\n\n // Call the API to start the run\n const response = await fetch(`${apiUrl}/local-browser/sessions/${input.sessionId}/run`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({\n instructions: input.instructions,\n startUrl: input.startUrl ?? null,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n return toolJson({ ok: false, error: `Failed to start run: ${text}` });\n }\n\n const result = (await response.json()) as { ok: boolean; jobId: string; sessionId: string };\n\n return toolJson({\n ok: true,\n jobId: result.jobId,\n sessionId: result.sessionId,\n note: \"Test run started. The cloud agent is now controlling your local browser. You can watch the browser to see the test in action.\",\n });\n }\n\n return toolText(`Unknown tool: ${tool}`);\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n return new Promise<void>(() => undefined);\n}\n\nasync function waitForResult(input: { apiUrl: string; token: string; runId: string }) {\n await streamUntilComplete(input);\n const response = await fetch(`${input.apiUrl}/local-tests/runs/${input.runId}`, {\n credentials: \"include\",\n headers: { authorization: `Bearer ${input.token}` },\n });\n const data = await response.json();\n const run = data?.data?.run ?? data?.run ?? data?.data;\n const summary = run?.summaryJson;\n return formatReport({ run, summary });\n}\n\nasync function streamUntilComplete(input: { apiUrl: string; token: string; runId: string }) {\n const response = await fetch(`${input.apiUrl}/local-tests/runs/${input.runId}/stream`, {\n headers: { authorization: `Bearer ${input.token}` },\n });\n\n if (!response.body) return;\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (event.event === \"status\") {\n try {\n const payload = JSON.parse(event.data);\n if (payload?.status === \"completed\" || payload?.status === \"failed\") {\n reader.cancel().catch(() => undefined);\n }\n } catch {}\n }\n if (event.event === \"complete\" || event.event === \"error\") {\n reader.cancel().catch(() => undefined);\n }\n },\n });\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n}\n\nfunction formatReport(input: { run: any; summary: any }) {\n if (!input.summary) {\n return {\n runId: input.run?.id,\n status: input.run?.status ?? \"unknown\",\n summary: \"No final report available.\",\n };\n }\n\n const tested = Array.isArray(input.summary.testedItems) ? input.summary.testedItems : [];\n const status = input.summary.status ?? input.run?.status ?? \"unknown\";\n const issues =\n status === \"issues_found\"\n ? (input.summary.notes ? [input.summary.notes] : [\"Issues reported.\"])\n : [];\n\n return {\n runId: input.run?.id,\n status,\n summary: input.summary.summary ?? \"Run completed.\",\n testedItems: tested,\n issues,\n notes: input.summary.notes ?? null,\n };\n}\n","/**\n * Local Browser Host\n *\n * Manages a local browser instance and handles commands from the cloud API\n * via WebSocket. This enables cloud agents to control a browser running\n * on the user's local machine.\n */\n\nimport { chromium, type Browser, type BrowserContext, type Page, type Dialog } from \"playwright\";\nimport type {\n BrowserCommand,\n BrowserResponse,\n HeartbeatMessage,\n SessionMessage,\n LocalBrowserMode,\n} from \"./protocol\";\n\nconst HEARTBEAT_INTERVAL_MS = 30_000;\nconst RECONNECT_DELAY_MS = 1000;\nconst MAX_RECONNECT_DELAY_MS = 30_000;\nconst MAX_RECONNECT_ATTEMPTS = 10;\n\nexport interface LocalBrowserHostOptions {\n apiUrl: string;\n wsToken: string;\n sessionId: string;\n browserMode: LocalBrowserMode;\n cdpUrl?: string;\n headless?: boolean;\n storageStatePath?: string;\n onLog?: (level: \"info\" | \"warn\" | \"error\" | \"debug\", message: string, data?: unknown) => void;\n}\n\ninterface PageWithAISnapshot extends Page {\n _snapshotForAI(options: { mode: \"full\" | \"compact\" }): Promise<string>;\n}\n\n/**\n * LocalBrowserHost manages the browser and WebSocket connection to the cloud.\n */\nexport class LocalBrowserHost {\n private options: LocalBrowserHostOptions;\n private ws: WebSocket | null = null;\n private browser: Browser | null = null;\n private context: BrowserContext | null = null;\n private page: Page | null = null;\n private pendingDialogs: Dialog[] = [];\n private heartbeatTimer: NodeJS.Timeout | null = null;\n private reconnectAttempts = 0;\n private isShuttingDown = false;\n private lastSnapshotYaml = \"\";\n\n constructor(options: LocalBrowserHostOptions) {\n this.options = options;\n }\n\n private log(level: \"info\" | \"warn\" | \"error\" | \"debug\", message: string, data?: unknown) {\n if (this.options.onLog) {\n this.options.onLog(level, message, data);\n } else {\n const fn = level === \"error\" ? console.error : level === \"warn\" ? console.warn : console.log;\n fn(`[LocalBrowserHost] ${message}`, data ?? \"\");\n }\n }\n\n // =========================================================================\n // Lifecycle\n // =========================================================================\n\n async start(): Promise<void> {\n this.log(\"info\", \"Starting local browser host\", {\n browserMode: this.options.browserMode,\n sessionId: this.options.sessionId,\n });\n\n // Connect to WebSocket first\n await this.connectWebSocket();\n\n // Then launch browser\n await this.launchBrowser();\n\n // Notify cloud that browser is ready\n this.sendSessionEvent(\"browser_ready\");\n }\n\n async stop(): Promise<void> {\n this.isShuttingDown = true;\n this.log(\"info\", \"Stopping local browser host\");\n\n this.stopHeartbeat();\n\n if (this.ws) {\n try {\n this.ws.close(1000, \"Shutdown\");\n } catch {}\n this.ws = null;\n }\n\n if (this.context) {\n try {\n await this.context.close();\n } catch {}\n this.context = null;\n }\n\n if (this.browser) {\n try {\n await this.browser.close();\n } catch {}\n this.browser = null;\n }\n\n this.page = null;\n this.log(\"info\", \"Local browser host stopped\");\n }\n\n // =========================================================================\n // WebSocket Connection\n // =========================================================================\n\n private async connectWebSocket(): Promise<void> {\n return new Promise((resolve, reject) => {\n const wsUrl = `${this.options.apiUrl.replace(\"http\", \"ws\")}/local-browser/sessions/${this.options.sessionId}/connect?token=${this.options.wsToken}`;\n\n this.log(\"info\", \"Connecting to cloud API\", { url: wsUrl.replace(/token=.*/, \"token=***\") });\n\n const ws = new WebSocket(wsUrl);\n\n ws.onopen = () => {\n this.log(\"info\", \"Connected to cloud API\");\n this.ws = ws;\n this.reconnectAttempts = 0;\n this.startHeartbeat();\n resolve();\n };\n\n ws.onmessage = (event) => {\n this.handleMessage(event.data as string);\n };\n\n ws.onerror = (event) => {\n this.log(\"error\", \"WebSocket error\", event);\n };\n\n ws.onclose = () => {\n this.log(\"info\", \"WebSocket closed\");\n this.stopHeartbeat();\n this.ws = null;\n\n if (!this.isShuttingDown) {\n this.scheduleReconnect();\n }\n };\n\n // Timeout after 30 seconds\n setTimeout(() => {\n if (!this.ws) {\n reject(new Error(\"WebSocket connection timeout\"));\n }\n }, 30_000);\n });\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {\n this.log(\"error\", \"Max reconnection attempts reached, giving up\");\n this.stop();\n return;\n }\n\n const delay = Math.min(\n RECONNECT_DELAY_MS * Math.pow(2, this.reconnectAttempts),\n MAX_RECONNECT_DELAY_MS\n );\n\n this.reconnectAttempts++;\n this.log(\"info\", `Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})`);\n\n setTimeout(async () => {\n try {\n await this.connectWebSocket();\n this.sendSessionEvent(\"connected\");\n if (this.page) {\n this.sendSessionEvent(\"browser_ready\");\n }\n } catch (error) {\n this.log(\"error\", \"Reconnection failed\", error);\n this.scheduleReconnect();\n }\n }, delay);\n }\n\n // =========================================================================\n // Heartbeat\n // =========================================================================\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeatTimer = setInterval(() => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n const ping: HeartbeatMessage = {\n type: \"heartbeat\",\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n direction: \"pong\",\n };\n this.ws.send(JSON.stringify(ping));\n }\n }, HEARTBEAT_INTERVAL_MS);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // =========================================================================\n // Browser Management\n // =========================================================================\n\n private async launchBrowser(): Promise<void> {\n const { browserMode, cdpUrl, headless = true, storageStatePath } = this.options;\n\n if (browserMode === \"cdp\" && cdpUrl) {\n this.log(\"info\", \"Connecting to existing Chrome via CDP\", { cdpUrl });\n this.browser = await chromium.connectOverCDP(cdpUrl);\n const contexts = this.browser.contexts();\n this.context = contexts[0] ?? (await this.browser.newContext());\n const pages = this.context.pages();\n this.page = pages[0] ?? (await this.context.newPage());\n } else {\n this.log(\"info\", \"Launching new Playwright browser\", { headless });\n this.browser = await chromium.launch({\n headless,\n args: [\"--no-sandbox\"],\n });\n\n const contextOptions: { viewport: { width: number; height: number }; storageState?: string } =\n {\n viewport: { width: 1920, height: 1080 },\n };\n\n if (storageStatePath) {\n try {\n await Bun.file(storageStatePath).exists();\n contextOptions.storageState = storageStatePath;\n this.log(\"info\", \"Loading storage state\", { storageStatePath });\n } catch {\n this.log(\"debug\", \"Storage state file not found, starting fresh\");\n }\n }\n\n this.context = await this.browser.newContext(contextOptions);\n this.page = await this.context.newPage();\n }\n\n // Setup dialog handler\n this.page.on(\"dialog\", (dialog) => {\n this.pendingDialogs.push(dialog);\n });\n\n this.log(\"info\", \"Browser ready\");\n }\n\n // =========================================================================\n // Message Handling\n // =========================================================================\n\n private handleMessage(data: string): void {\n try {\n const message = JSON.parse(data);\n\n if (message.type === \"heartbeat\" && message.direction === \"ping\") {\n // Respond to ping with pong\n const pong: HeartbeatMessage = {\n type: \"heartbeat\",\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n direction: \"pong\",\n };\n this.ws?.send(JSON.stringify(pong));\n return;\n }\n\n if (message.type === \"command\") {\n this.handleCommand(message as BrowserCommand);\n return;\n }\n\n this.log(\"debug\", \"Received unknown message type\", message);\n } catch (error) {\n this.log(\"error\", \"Failed to parse message\", { error, data });\n }\n }\n\n private async handleCommand(command: BrowserCommand): Promise<void> {\n const startTime = Date.now();\n this.log(\"debug\", `Executing command: ${command.method}`, { id: command.id });\n\n try {\n const result = await this.executeMethod(command.method, command.args);\n const response: BrowserResponse = {\n type: \"response\",\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n requestId: command.id,\n success: true,\n result,\n };\n this.ws?.send(JSON.stringify(response));\n\n this.log(\"debug\", `Command completed: ${command.method}`, {\n id: command.id,\n durationMs: Date.now() - startTime,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const response: BrowserResponse = {\n type: \"response\",\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n requestId: command.id,\n success: false,\n error: errorMessage,\n stack: error instanceof Error ? error.stack : undefined,\n };\n this.ws?.send(JSON.stringify(response));\n\n this.log(\"error\", `Command failed: ${command.method}`, {\n id: command.id,\n error: errorMessage,\n });\n }\n }\n\n private sendSessionEvent(\n event: \"connected\" | \"disconnected\" | \"browser_ready\" | \"browser_closed\" | \"error\",\n error?: string\n ): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\n\n const message: SessionMessage = {\n type: \"session\",\n id: crypto.randomUUID(),\n timestamp: Date.now(),\n event,\n browserMode: this.options.browserMode,\n error,\n };\n this.ws.send(JSON.stringify(message));\n }\n\n // =========================================================================\n // Method Execution\n // =========================================================================\n\n private async executeMethod(method: string, args: unknown[]): Promise<unknown> {\n // Route to appropriate handler\n switch (method) {\n // Lifecycle\n case \"connect\":\n return this.connect(args[0] as any);\n case \"disconnect\":\n return this.disconnect();\n\n // Navigation\n case \"navigate\":\n return this.navigate(args[0] as string, args[1] as any);\n case \"navigateBack\":\n return this.navigateBack(args[0] as any);\n\n // Page Inspection\n case \"snapshot\":\n return this.snapshot(args[0] as any);\n case \"takeScreenshot\":\n return this.takeScreenshot(args[0] as any);\n case \"evaluate\":\n return this.evaluate(args[0] as string, args[1] as any);\n case \"runCode\":\n return this.runCode(args[0] as string, args[1] as any);\n case \"consoleMessages\":\n return this.consoleMessages(args[0] as any);\n case \"networkRequests\":\n return this.networkRequests(args[0] as any);\n\n // Interaction\n case \"click\":\n return this.click(args[0] as string, args[1] as string, args[2] as any);\n case \"clickAtCoordinates\":\n return this.clickAtCoordinates(\n args[0] as number,\n args[1] as number,\n args[2] as string,\n args[3] as any\n );\n case \"moveToCoordinates\":\n return this.moveToCoordinates(\n args[0] as number,\n args[1] as number,\n args[2] as string,\n args[3] as any\n );\n case \"dragCoordinates\":\n return this.dragCoordinates(\n args[0] as number,\n args[1] as number,\n args[2] as number,\n args[3] as number,\n args[4] as string,\n args[5] as any\n );\n case \"hover\":\n return this.hover(args[0] as string, args[1] as string, args[2] as any);\n case \"drag\":\n return this.drag(\n args[0] as string,\n args[1] as string,\n args[2] as string,\n args[3] as string,\n args[4] as any\n );\n case \"type\":\n return this.type(\n args[0] as string,\n args[1] as string,\n args[2] as string,\n args[3] as boolean,\n args[4] as any\n );\n case \"pressKey\":\n return this.pressKey(args[0] as string, args[1] as any);\n case \"fillForm\":\n return this.fillForm(args[0] as any[], args[1] as any);\n case \"selectOption\":\n return this.selectOption(\n args[0] as string,\n args[1] as string,\n args[2] as string,\n args[3] as any\n );\n case \"fileUpload\":\n return this.fileUpload(args[0] as string[], args[1] as any);\n\n // Dialogs\n case \"handleDialog\":\n return this.handleDialog(args[0] as \"accept\" | \"dismiss\", args[1] as string, args[2] as any);\n\n // Waiting\n case \"waitFor\":\n return this.waitFor(args[0] as any);\n\n // Browser Management\n case \"close\":\n return this.closePage(args[0] as any);\n case \"resize\":\n return this.resize(args[0] as number, args[1] as number, args[2] as any);\n case \"tabs\":\n return this.tabs(args[0] as any, args[1] as number, args[2] as any);\n\n // Storage\n case \"getStorageState\":\n return this.getStorageState(args[0] as any);\n case \"getCurrentUrl\":\n return this.getCurrentUrl(args[0] as any);\n case \"getTitle\":\n return this.getTitle(args[0] as any);\n case \"getLinks\":\n return this.getLinks(args[0] as any);\n case \"getElementBoundingBox\":\n return this.getElementBoundingBox(args[0] as string, args[1] as any);\n\n // Tracing\n case \"startTracing\":\n return this.startTracing(args[0] as any);\n case \"stopTracing\":\n return this.stopTracing(args[0] as any);\n\n // Video\n case \"isVideoRecordingEnabled\":\n return false; // Video not supported in CLI host currently\n case \"saveVideo\":\n return null;\n case \"getVideoPath\":\n return null;\n\n default:\n throw new Error(`Unknown method: ${method}`);\n }\n }\n\n // =========================================================================\n // IBrowserClient Method Implementations\n // =========================================================================\n\n private getPage(): Page {\n if (!this.page) throw new Error(\"No page available\");\n return this.page;\n }\n\n private resolveRef(ref: string) {\n return this.getPage().locator(`aria-ref=${ref}`);\n }\n\n private async connect(_options: any): Promise<void> {\n // Browser already launched in start()\n return;\n }\n\n private async disconnect(): Promise<void> {\n await this.stop();\n }\n\n private async navigate(url: string, _opts?: any): Promise<string> {\n const page = this.getPage();\n await page.goto(url, { waitUntil: \"domcontentloaded\" });\n await page.waitForLoadState(\"load\", { timeout: 5000 }).catch(() => {});\n return this.captureSnapshot();\n }\n\n private async navigateBack(_opts?: any): Promise<string> {\n await this.getPage().goBack();\n return this.captureSnapshot();\n }\n\n private async snapshot(_opts?: any): Promise<string> {\n return this.captureSnapshot();\n }\n\n private async captureSnapshot(): Promise<string> {\n const page = this.getPage() as PageWithAISnapshot;\n this.lastSnapshotYaml = await page._snapshotForAI({ mode: \"full\" });\n return this.lastSnapshotYaml;\n }\n\n private async takeScreenshot(opts?: any): Promise<string | null> {\n const page = this.getPage();\n const buffer = await page.screenshot({\n type: opts?.type ?? \"jpeg\",\n fullPage: opts?.fullPage ?? false,\n });\n const mime = opts?.type === \"png\" ? \"image/png\" : \"image/jpeg\";\n return `data:${mime};base64,${buffer.toString(\"base64\")}`;\n }\n\n private async evaluate<T>(fn: string, _opts?: any): Promise<T> {\n const page = this.getPage();\n return page.evaluate(new Function(`return (${fn})()`) as () => T);\n }\n\n private async runCode(code: string, _opts?: any): Promise<unknown> {\n const page = this.getPage();\n const fn = new Function(\"page\", `return (async () => { ${code} })()`) as (\n p: Page\n ) => Promise<unknown>;\n return fn(page);\n }\n\n private async consoleMessages(_opts?: any): Promise<string> {\n // Console messages would need to be captured over time\n return \"Console message capture not implemented in CLI host\";\n }\n\n private async networkRequests(_opts?: any): Promise<string> {\n // Network requests would need to be captured over time\n return \"Network request capture not implemented in CLI host\";\n }\n\n private async click(ref: string, _elementDesc?: string, opts?: any): Promise<void> {\n const locator = this.resolveRef(ref);\n await locator.scrollIntoViewIfNeeded({ timeout: 5000 }).catch(() => {});\n\n const box = await locator.boundingBox();\n if (box) {\n const centerX = box.x + box.width / 2;\n const centerY = box.y + box.height / 2;\n const page = this.getPage();\n\n if (opts?.modifiers?.length) {\n for (const mod of opts.modifiers) {\n await page.keyboard.down(mod);\n }\n }\n\n if (opts?.doubleClick) {\n await page.mouse.dblclick(centerX, centerY);\n } else {\n await page.mouse.click(centerX, centerY);\n }\n\n if (opts?.modifiers?.length) {\n for (const mod of opts.modifiers) {\n await page.keyboard.up(mod);\n }\n }\n } else {\n // Fallback to locator click\n if (opts?.doubleClick) {\n await locator.dblclick({ timeout: opts?.timeoutMs ?? 30000 });\n } else {\n await locator.click({ timeout: opts?.timeoutMs ?? 30000 });\n }\n }\n }\n\n private async clickAtCoordinates(\n x: number,\n y: number,\n _elementDesc: string,\n opts?: any\n ): Promise<void> {\n const page = this.getPage();\n if (opts?.doubleClick) {\n await page.mouse.dblclick(x, y);\n } else {\n await page.mouse.click(x, y);\n }\n }\n\n private async moveToCoordinates(\n x: number,\n y: number,\n _elementDesc: string,\n _opts?: any\n ): Promise<void> {\n await this.getPage().mouse.move(x, y);\n }\n\n private async dragCoordinates(\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n _elementDesc: string,\n _opts?: any\n ): Promise<void> {\n const page = this.getPage();\n await page.mouse.move(startX, startY);\n await page.mouse.down();\n await page.mouse.move(endX, endY);\n await page.mouse.up();\n }\n\n private async hover(ref: string, _elementDesc?: string, opts?: any): Promise<void> {\n await this.resolveRef(ref).hover({ timeout: opts?.timeoutMs ?? 30000 });\n }\n\n private async drag(\n startRef: string,\n _startElement: string,\n endRef: string,\n _endElement: string,\n opts?: any\n ): Promise<void> {\n const startLocator = this.resolveRef(startRef);\n const endLocator = this.resolveRef(endRef);\n await startLocator.dragTo(endLocator, { timeout: opts?.timeoutMs ?? 60000 });\n }\n\n private async type(\n ref: string,\n text: string,\n _elementDesc?: string,\n submit?: boolean,\n opts?: any\n ): Promise<void> {\n const locator = this.resolveRef(ref);\n await locator.clear();\n await locator.pressSequentially(text, {\n delay: opts?.delay ?? 0,\n timeout: opts?.timeoutMs ?? 30000,\n });\n if (submit) {\n await locator.press(\"Enter\");\n }\n }\n\n private async pressKey(key: string, _opts?: any): Promise<void> {\n await this.getPage().keyboard.press(key);\n }\n\n private async fillForm(fields: any[], opts?: any): Promise<void> {\n for (const field of fields) {\n const locator = this.resolveRef(field.ref);\n const fieldType = field.type ?? \"textbox\";\n\n switch (fieldType) {\n case \"checkbox\": {\n const isChecked = await locator.isChecked();\n const shouldBeChecked = field.value === \"true\";\n if (shouldBeChecked !== isChecked) {\n await locator.click({ timeout: opts?.timeoutMs ?? 30000 });\n }\n break;\n }\n case \"radio\":\n await locator.check({ timeout: opts?.timeoutMs ?? 30000 });\n break;\n case \"combobox\":\n await locator.selectOption(field.value, { timeout: opts?.timeoutMs ?? 30000 });\n break;\n default:\n await locator.fill(field.value, { timeout: opts?.timeoutMs ?? 30000 });\n }\n }\n }\n\n private async selectOption(\n ref: string,\n value: string,\n _elementDesc?: string,\n opts?: any\n ): Promise<void> {\n await this.resolveRef(ref).selectOption(value, { timeout: opts?.timeoutMs ?? 30000 });\n }\n\n private async fileUpload(paths: string[], opts?: any): Promise<void> {\n const fileChooser = await this.getPage().waitForEvent(\"filechooser\", {\n timeout: opts?.timeoutMs ?? 30000,\n });\n await fileChooser.setFiles(paths);\n }\n\n private async handleDialog(\n action: \"accept\" | \"dismiss\",\n promptText?: string,\n _opts?: any\n ): Promise<void> {\n const dialog = this.pendingDialogs.shift();\n if (dialog) {\n if (action === \"accept\") {\n await dialog.accept(promptText);\n } else {\n await dialog.dismiss();\n }\n }\n }\n\n private async waitFor(opts?: any): Promise<void> {\n const page = this.getPage();\n const timeout = opts?.timeout ?? opts?.timeoutMs ?? 30000;\n\n if (opts?.timeSec) {\n await page.waitForTimeout(opts.timeSec * 1000);\n return;\n }\n if (opts?.text) {\n await page.getByText(opts.text).first().waitFor({ state: \"visible\", timeout });\n return;\n }\n if (opts?.textGone) {\n await page.getByText(opts.textGone).first().waitFor({ state: \"hidden\", timeout });\n return;\n }\n if (opts?.selector) {\n await page.locator(opts.selector).waitFor({\n state: opts.state ?? \"visible\",\n timeout,\n });\n }\n }\n\n private async closePage(_opts?: any): Promise<void> {\n await this.getPage().close();\n this.page = null;\n }\n\n private async resize(width: number, height: number, _opts?: any): Promise<void> {\n await this.getPage().setViewportSize({ width, height });\n }\n\n private async tabs(action: string, index?: number, _opts?: any): Promise<unknown> {\n if (!this.context) throw new Error(\"No context available\");\n const pages = this.context.pages();\n\n switch (action) {\n case \"list\":\n return Promise.all(\n pages.map(async (p, i) => ({\n index: i,\n url: p.url(),\n title: await p.title().catch(() => \"\"),\n }))\n );\n case \"new\": {\n const newPage = await this.context.newPage();\n this.page = newPage;\n newPage.on(\"dialog\", (dialog) => this.pendingDialogs.push(dialog));\n return { index: pages.length };\n }\n case \"close\":\n if (index !== undefined && pages[index]) {\n await pages[index].close();\n } else {\n await this.page?.close();\n }\n this.page = this.context.pages()[0] ?? null;\n break;\n case \"select\":\n if (index !== undefined && pages[index]) {\n this.page = pages[index];\n }\n break;\n }\n return null;\n }\n\n private async getStorageState(_opts?: any): Promise<unknown> {\n if (!this.context) throw new Error(\"No context available\");\n return this.context.storageState();\n }\n\n private async getCurrentUrl(_opts?: any): Promise<string> {\n return this.getPage().url();\n }\n\n private async getTitle(_opts?: any): Promise<string> {\n return this.getPage().title();\n }\n\n private async getLinks(_opts?: any): Promise<string[]> {\n const page = this.getPage();\n return page.$$eval(\"a[href]\", (links) =>\n links\n .map((a) => (a as HTMLAnchorElement).href)\n .filter((h): h is string => !!h && (h.startsWith(\"http://\") || h.startsWith(\"https://\")))\n );\n }\n\n private async getElementBoundingBox(\n ref: string,\n _opts?: any\n ): Promise<{ x: number; y: number; width: number; height: number } | null> {\n const locator = this.resolveRef(ref);\n const box = await locator.boundingBox();\n if (!box) return null;\n return { x: box.x, y: box.y, width: box.width, height: box.height };\n }\n\n private async startTracing(_opts?: any): Promise<void> {\n if (!this.context) throw new Error(\"No context available\");\n await this.context.tracing.start({ screenshots: true, snapshots: true });\n }\n\n private async stopTracing(_opts?: any): Promise<{\n trace: string;\n network: string;\n resources: string;\n directory: string | null;\n legend: string | null;\n }> {\n if (!this.context) throw new Error(\"No context available\");\n const tracePath = `/tmp/trace-${Date.now()}.zip`;\n await this.context.tracing.stop({ path: tracePath });\n return {\n trace: tracePath,\n network: \"\",\n resources: \"\",\n directory: null,\n legend: `Trace saved to ${tracePath}`,\n };\n }\n}\n","/**\n * Remote Test Command\n *\n * Triggers workflow tests on the Canary platform and streams results via SSE.\n * Designed for CI/CD pipelines - exits with code 0 on success, 1 on failure.\n *\n * Usage:\n * canary test --remote [options]\n *\n * Options:\n * --token <key> API key (or set CANARY_API_TOKEN env var)\n * --api-url <url> API URL (default: https://api.trycanary.ai)\n * --tag <tag> Filter workflows by tag\n * --name-pattern <pat> Filter workflows by name pattern\n * --verbose, -v Show all events (not just results)\n */\n\nimport process from \"node:process\";\nimport { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport { readStoredToken } from \"./auth\";\n\ntype WorkflowTestStatus = \"queued\" | \"running\" | \"waiting\" | \"success\" | \"failed\";\n\ntype WorkflowTestEvent = {\n type: \"workflow-test\";\n suiteId: string;\n workflowId: string;\n testRunId: string;\n workflowRunId: string | null;\n status: WorkflowTestStatus;\n startedAt: string | null;\n finishedAt: string | null;\n durationMs: number | null;\n errorMessage?: string | null;\n linkedIssueId?: string | null;\n message?: string;\n resumeAt?: string | null;\n segmentIndex?: number | null;\n totalSegments?: number | null;\n};\n\ntype WorkflowTestSuiteEvent = {\n type: \"workflow-test-suite\";\n suiteId: string;\n status: \"running\" | \"completed\";\n startedAt: string;\n finishedAt: string | null;\n durationMs: number | null;\n totalWorkflows: number;\n completedWorkflows: number;\n failedWorkflows: number;\n successfulWorkflows: number;\n errorMessage?: string | null;\n message?: string;\n};\n\ntype TriggerResponse = {\n ok: boolean;\n jobId?: string;\n suiteId?: string;\n startedAt?: string;\n error?: string;\n};\n\nfunction getArgValue(argv: string[], key: string): string | undefined {\n const index = argv.indexOf(key);\n if (index === -1 || index >= argv.length - 1) return undefined;\n return argv[index + 1];\n}\n\nfunction hasFlag(argv: string[], ...flags: string[]): boolean {\n return flags.some((flag) => argv.includes(flag));\n}\n\nfunction buildQueryParams(tag?: string, namePattern?: string): string {\n const params = new URLSearchParams();\n if (tag) params.set(\"tag\", tag);\n if (namePattern) params.set(\"namePattern\", namePattern);\n return params.toString();\n}\n\nfunction extractWorkflowName(message: string | undefined, workflowId: string): string {\n if (!message) return workflowId;\n const match = message.match(/^Flow \"(.+?)\" /);\n return match ? match[1] : workflowId;\n}\n\nfunction formatSummary(stats: {\n totalWorkflows: number;\n successfulWorkflows: number;\n failedWorkflows: number;\n completedWorkflows: number;\n}): { message: string; exitCode: number } {\n const { totalWorkflows, successfulWorkflows, failedWorkflows, completedWorkflows } = stats;\n\n if (totalWorkflows === 0) {\n return { message: \"No workflows found matching the filter criteria.\", exitCode: 0 };\n }\n\n const passRate = Math.round((successfulWorkflows / totalWorkflows) * 100);\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n\n let message: string;\n let exitCode: number;\n\n if (failedWorkflows > 0) {\n message = `FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`;\n exitCode = 1;\n } else {\n message = `PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`;\n exitCode = 0;\n }\n\n if (waitingWorkflows > 0) {\n message += `\\nNote: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`;\n }\n\n return { message, exitCode };\n}\n\n// Export internals for testing\nexport const __internals = {\n getArgValue,\n hasFlag,\n buildQueryParams,\n extractWorkflowName,\n formatSummary,\n};\n\nexport async function runRemoteTest(argv: string[]): Promise<void> {\n const apiUrl =\n getArgValue(argv, \"--api-url\") ??\n process.env.CANARY_API_URL ??\n \"https://api.trycanary.ai\";\n\n const token =\n getArgValue(argv, \"--token\") ??\n process.env.CANARY_API_TOKEN ??\n (await readStoredToken());\n\n const tag = getArgValue(argv, \"--tag\");\n const namePattern = getArgValue(argv, \"--name-pattern\");\n const verbose = hasFlag(argv, \"--verbose\", \"-v\");\n\n if (!token) {\n console.error(\"Error: No API token found.\");\n console.error(\"\");\n console.error(\"Set CANARY_API_TOKEN environment variable or run:\");\n console.error(\" canary login\");\n console.error(\"\");\n console.error(\"Or create an API key in Settings > API Keys and pass it:\");\n console.error(\" canary test --remote --token cnry_...\");\n process.exit(1);\n }\n\n console.log(\"Starting remote workflow tests...\");\n if (tag) console.log(` Filtering by tag: ${tag}`);\n if (namePattern) console.log(` Filtering by name pattern: ${namePattern}`);\n console.log(\"\");\n\n // 1. Trigger test run\n const queryParams = new URLSearchParams();\n if (tag) queryParams.set(\"tag\", tag);\n if (namePattern) queryParams.set(\"namePattern\", namePattern);\n\n const triggerUrl = `${apiUrl}/workflows/test-runs${queryParams.toString() ? `?${queryParams}` : \"\"}`;\n\n let triggerRes: Response;\n try {\n triggerRes = await fetch(triggerUrl, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to API: ${err}`);\n process.exit(1);\n }\n\n if (!triggerRes.ok) {\n const errorText = await triggerRes.text();\n console.error(`Failed to start tests: ${triggerRes.status}`);\n console.error(errorText);\n process.exit(1);\n }\n\n const triggerData = (await triggerRes.json()) as TriggerResponse;\n if (!triggerData.ok || !triggerData.suiteId) {\n console.error(`Failed to start tests: ${triggerData.error ?? \"Unknown error\"}`);\n process.exit(1);\n }\n\n const { suiteId, jobId } = triggerData;\n if (verbose) {\n console.log(`Suite ID: ${suiteId}`);\n console.log(`Job ID: ${jobId}`);\n console.log(\"\");\n }\n\n // 2. Subscribe to SSE stream\n const streamUrl = `${apiUrl}/workflows/test-runs/stream?suiteId=${suiteId}`;\n\n let streamRes: Response;\n try {\n streamRes = await fetch(streamUrl, {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"text/event-stream\",\n },\n });\n } catch (err) {\n console.error(`Failed to connect to event stream: ${err}`);\n process.exit(1);\n }\n\n if (!streamRes.ok || !streamRes.body) {\n console.error(`Failed to connect to event stream: ${streamRes.status}`);\n process.exit(1);\n }\n\n // Track state\n let exitCode = 0;\n let hasCompleted = false;\n const workflowNames = new Map<string, string>();\n let totalWorkflows = 0;\n let completedWorkflows = 0;\n let failedWorkflows = 0;\n let successfulWorkflows = 0;\n\n // 3. Parse SSE events\n const parser = createParser({\n onEvent: (event: EventSourceMessage) => {\n if (!event.data) return;\n\n try {\n const data = JSON.parse(event.data) as\n | WorkflowTestEvent\n | WorkflowTestSuiteEvent\n | { error?: string };\n\n if (verbose) {\n console.log(`[${event.event}] ${JSON.stringify(data)}`);\n }\n\n if (event.event === \"workflow-test\") {\n const testEvent = data as WorkflowTestEvent;\n const { status, workflowId, message, errorMessage } = testEvent;\n const name = workflowNames.get(workflowId) || message?.replace(/^Flow \"(.+)\" .*$/, \"$1\") || workflowId;\n\n if (message?.startsWith('Flow \"')) {\n const match = message.match(/^Flow \"(.+?)\" /);\n if (match) workflowNames.set(workflowId, match[1]);\n }\n\n if (!verbose) {\n if (status === \"success\") {\n console.log(` \\u2713 ${name}`);\n } else if (status === \"failed\") {\n console.log(` \\u2717 ${name}`);\n if (errorMessage) {\n console.log(` Error: ${errorMessage.slice(0, 200)}`);\n }\n exitCode = 1;\n } else if (status === \"running\") {\n // Don't log running status in non-verbose mode\n } else if (status === \"waiting\") {\n console.log(` \\u23F3 ${name} (waiting for scheduled time)`);\n }\n }\n }\n\n if (event.event === \"workflow-test-suite\") {\n const suiteEvent = data as WorkflowTestSuiteEvent;\n totalWorkflows = suiteEvent.totalWorkflows;\n completedWorkflows = suiteEvent.completedWorkflows;\n failedWorkflows = suiteEvent.failedWorkflows;\n successfulWorkflows = suiteEvent.successfulWorkflows;\n\n if (suiteEvent.status === \"completed\") {\n hasCompleted = true;\n }\n }\n\n if (event.event === \"error\") {\n const errorData = data as { error?: string };\n console.error(`Stream error: ${errorData.error ?? \"Unknown error\"}`);\n exitCode = 1;\n }\n } catch {\n // Ignore parse errors for keepalive, etc.\n }\n },\n });\n\n const reader = streamRes.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (!hasCompleted) {\n const { done, value } = await reader.read();\n if (done) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n } finally {\n reader.releaseLock();\n }\n\n // 4. Print summary\n console.log(\"\");\n console.log(\"─\".repeat(50));\n\n if (totalWorkflows === 0) {\n console.log(\"No workflows found matching the filter criteria.\");\n process.exit(0);\n }\n\n const passRate = totalWorkflows > 0 ? Math.round((successfulWorkflows / totalWorkflows) * 100) : 0;\n\n if (failedWorkflows > 0) {\n console.log(`FAILED: ${failedWorkflows} of ${totalWorkflows} workflows failed (${passRate}% pass rate)`);\n exitCode = 1;\n } else {\n console.log(`PASSED: ${successfulWorkflows} of ${totalWorkflows} workflows passed`);\n }\n\n const waitingWorkflows = totalWorkflows - completedWorkflows;\n if (waitingWorkflows > 0) {\n console.log(`Note: ${waitingWorkflows} workflow(s) are still waiting (scheduled for later)`);\n }\n\n process.exit(exitCode);\n}\n","/**\n * Local Browser Command\n *\n * Starts a local browser that can be controlled by the cloud agent.\n *\n * Usage:\n * canary browser [options]\n *\n * Options:\n * --mode <playwright|cdp> Browser mode (default: playwright)\n * --cdp-url <url> CDP endpoint for existing Chrome\n * --headless Run headless (default: true for playwright)\n * --storage-state <path> Path to storage state JSON\n * --api-url <url> API URL (default: https://api.trycanary.ai)\n * --instructions <text> Instructions for the cloud agent\n */\n\nimport process from \"node:process\";\nimport { readStoredToken } from \"../auth\";\nimport { LocalBrowserHost } from \"./host\";\nimport type { LocalBrowserMode } from \"./protocol\";\n\nconst DEFAULT_API_URL = \"https://api.trycanary.ai\";\n\ninterface LocalBrowserOptions {\n mode: LocalBrowserMode;\n cdpUrl?: string;\n headless: boolean;\n storageStatePath?: string;\n apiUrl: string;\n instructions?: string;\n}\n\nfunction parseArgs(args: string[]): LocalBrowserOptions {\n const options: LocalBrowserOptions = {\n mode: \"playwright\",\n headless: true,\n apiUrl: process.env.CANARY_API_URL ?? DEFAULT_API_URL,\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n const nextArg = args[i + 1];\n\n switch (arg) {\n case \"--mode\":\n if (nextArg === \"playwright\" || nextArg === \"cdp\") {\n options.mode = nextArg;\n i++;\n }\n break;\n case \"--cdp-url\":\n options.cdpUrl = nextArg;\n options.mode = \"cdp\";\n i++;\n break;\n case \"--headless\":\n options.headless = true;\n break;\n case \"--no-headless\":\n options.headless = false;\n break;\n case \"--storage-state\":\n options.storageStatePath = nextArg;\n i++;\n break;\n case \"--api-url\":\n options.apiUrl = nextArg;\n i++;\n break;\n case \"--instructions\":\n options.instructions = nextArg;\n i++;\n break;\n }\n }\n\n return options;\n}\n\nasync function resolveToken(): Promise<string> {\n const token = process.env.CANARY_API_TOKEN ?? (await readStoredToken());\n if (!token) {\n throw new Error(\"Missing token. Run `canary login` first or set CANARY_API_TOKEN.\");\n }\n return token;\n}\n\ninterface CreateSessionResponse {\n ok: boolean;\n sessionId: string;\n wsToken: string;\n wsUrl: string;\n expiresAt: string;\n error?: string;\n}\n\nasync function createSession(\n apiUrl: string,\n token: string,\n options: LocalBrowserOptions\n): Promise<CreateSessionResponse> {\n const response = 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({\n browserMode: options.mode,\n instructions: options.instructions ?? null,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new Error(`Failed to create session: ${response.status} ${text}`);\n }\n\n return response.json();\n}\n\nexport async function runLocalBrowser(args: string[]): Promise<void> {\n const options = parseArgs(args);\n\n console.log(\"Starting local browser...\");\n console.log(` Mode: ${options.mode}`);\n if (options.cdpUrl) {\n console.log(` CDP URL: ${options.cdpUrl}`);\n }\n console.log(` Headless: ${options.headless}`);\n console.log(` API URL: ${options.apiUrl}`);\n console.log();\n\n // Get auth token\n const token = await resolveToken();\n\n // Create session with cloud API\n console.log(\"Creating session with cloud API...\");\n const session = await createSession(options.apiUrl, token, options);\n\n if (!session.ok) {\n throw new Error(`Failed to create session: ${session.error}`);\n }\n\n console.log(`Session created: ${session.sessionId}`);\n console.log(`Expires at: ${session.expiresAt}`);\n console.log();\n\n // Start the local browser host\n const host = new LocalBrowserHost({\n apiUrl: options.apiUrl,\n wsToken: session.wsToken,\n sessionId: session.sessionId,\n browserMode: options.mode,\n cdpUrl: options.cdpUrl,\n headless: options.headless,\n storageStatePath: options.storageStatePath,\n onLog: (level, message, data) => {\n const prefix = `[${level.toUpperCase()}]`;\n if (data) {\n console.log(prefix, message, data);\n } else {\n console.log(prefix, message);\n }\n },\n });\n\n // Handle shutdown\n const shutdown = async () => {\n console.log(\"\\nShutting down...\");\n await host.stop();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n try {\n await host.start();\n console.log();\n console.log(\"Local browser is ready and connected to cloud.\");\n console.log(\"Press Ctrl+C to stop.\");\n console.log();\n\n // Keep the process running\n await new Promise(() => {});\n } catch (error) {\n console.error(\"Failed to start local browser:\", error);\n await host.stop();\n process.exit(1);\n }\n}\n","import { main } from \"./index.js\";\n\nvoid main(process.argv.slice(2));\n"],"mappings":"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","names":["spawnSync","process","path","fileURLToPath","pathToFileURL","preloadPath","fs","path","process","fs","os","path","process","os","process","getArgValue","os","process","event","fs","os","path","process","spawn","getArgValue","process","getArgValue","process","run","process","process","run","process","createParser","getArgValue","getArgValue","process","createParser","process","DEFAULT_API_URL","process","resolveToken","path","fileURLToPath","process","spawnSync","pathToFileURL"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts"],"sourcesContent":["import { main } from \"./index.js\";\n\nvoid main(process.argv.slice(2));\n"],"mappings":";;;;;;;;;AAEA,KAAK,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC;","names":[]}
|