@canaryai/cli 0.1.11 → 0.1.12
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/{chunk-HJ2JWIJ7.js → chunk-2T64Z2NI.js} +7 -1
- package/dist/chunk-2T64Z2NI.js.map +1 -0
- package/dist/{chunk-G2X3H7AM.js → chunk-L26U3BST.js} +231 -132
- package/dist/chunk-L26U3BST.js.map +1 -0
- package/dist/{chunk-VYBCH4ZP.js → chunk-V7U52ISX.js} +2 -2
- package/dist/{feature-flag-PN5IFFQR.js → feature-flag-MFTRYRYX.js} +2 -2
- package/dist/index.js +17 -16
- package/dist/index.js.map +1 -1
- package/dist/{knobs-DAG7HD2F.js → knobs-T3O4Z3ZB.js} +2 -2
- package/dist/{local-browser-VOBIUIGT.js → local-browser-SYPTG6IQ.js} +3 -3
- package/dist/{mcp-I6FCGDDR.js → mcp-TMD2R5Z6.js} +4 -4
- package/dist/{psql-A3BADRQN.js → psql-6IFVXM3A.js} +2 -2
- package/dist/{redis-N2DSDDQU.js → redis-HZC32IEO.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-G2X3H7AM.js.map +0 -1
- package/dist/chunk-HJ2JWIJ7.js.map +0 -1
- /package/dist/{chunk-VYBCH4ZP.js.map → chunk-V7U52ISX.js.map} +0 -0
- /package/dist/{feature-flag-PN5IFFQR.js.map → feature-flag-MFTRYRYX.js.map} +0 -0
- /package/dist/{knobs-DAG7HD2F.js.map → knobs-T3O4Z3ZB.js.map} +0 -0
- /package/dist/{local-browser-VOBIUIGT.js.map → local-browser-SYPTG6IQ.js.map} +0 -0
- /package/dist/{mcp-I6FCGDDR.js.map → mcp-TMD2R5Z6.js.map} +0 -0
- /package/dist/{psql-A3BADRQN.js.map → psql-6IFVXM3A.js.map} +0 -0
- /package/dist/{redis-N2DSDDQU.js.map → redis-HZC32IEO.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/local-browser/host.ts"],"sourcesContent":["/**\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 */\ntype ContextSlot = {\n context: BrowserContext;\n page: Page;\n pendingDialogs: Dialog[];\n};\n\nexport class LocalBrowserHost {\n private options: LocalBrowserHostOptions;\n private ws: WebSocket | null = null;\n private browser: Browser | null = null;\n private contexts = new Map<string, ContextSlot>();\n private static DEFAULT_CONTEXT_ID = \"__default__\";\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 for (const [id, slot] of this.contexts) {\n try {\n await slot.context.close();\n } catch {}\n }\n this.contexts.clear();\n\n if (this.browser) {\n try {\n await this.browser.close();\n } catch {}\n this.browser = null;\n }\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 existingContexts = this.browser.contexts();\n const ctx = existingContexts[0] ?? (await this.browser.newContext());\n const pages = ctx.pages();\n const pg = pages[0] ?? (await ctx.newPage());\n const slot: ContextSlot = { context: ctx, page: pg, pendingDialogs: [] };\n pg.on(\"dialog\", (dialog) => slot.pendingDialogs.push(dialog));\n this.contexts.set(LocalBrowserHost.DEFAULT_CONTEXT_ID, slot);\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 const ctx = await this.browser.newContext(contextOptions);\n const pg = await ctx.newPage();\n const slot: ContextSlot = { context: ctx, page: pg, pendingDialogs: [] };\n pg.on(\"dialog\", (dialog) => slot.pendingDialogs.push(dialog));\n this.contexts.set(LocalBrowserHost.DEFAULT_CONTEXT_ID, slot);\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 const contextId = command.contextId;\n this.log(\"debug\", `Executing command: ${command.method}`, { id: command.id, contextId });\n\n try {\n const result = await this.executeMethod(command.method, command.args, contextId);\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 contextId,\n };\n this.ws?.send(JSON.stringify(response));\n\n this.log(\"debug\", `Command completed: ${command.method}`, {\n id: command.id,\n contextId,\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 contextId,\n };\n this.ws?.send(JSON.stringify(response));\n\n this.log(\"error\", `Command failed: ${command.method}`, {\n id: command.id,\n contextId,\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 getSlot(contextId?: string): ContextSlot {\n const id = contextId ?? LocalBrowserHost.DEFAULT_CONTEXT_ID;\n const slot = this.contexts.get(id);\n if (!slot) throw new Error(`Context not found: ${id}`);\n return slot;\n }\n\n private async createContextSlot(\n contextId: string,\n options?: { storageState?: unknown }\n ): Promise<void> {\n if (!this.browser) throw new Error(\"No browser available\");\n if (this.contexts.has(contextId)) throw new Error(`Context already exists: ${contextId}`);\n\n const contextOptions: { viewport: { width: number; height: number }; storageState?: string } = {\n viewport: { width: 1920, height: 1080 },\n };\n\n if (options?.storageState) {\n const tmpPath = `/tmp/storage-state-${crypto.randomUUID()}.json`;\n await Bun.write(tmpPath, JSON.stringify(options.storageState));\n contextOptions.storageState = tmpPath;\n this.log(\"info\", \"Loaded inline storage state for new context\", { contextId });\n }\n\n const ctx = await this.browser.newContext(contextOptions);\n const pg = await ctx.newPage();\n const slot: ContextSlot = { context: ctx, page: pg, pendingDialogs: [] };\n pg.on(\"dialog\", (dialog) => slot.pendingDialogs.push(dialog));\n this.contexts.set(contextId, slot);\n this.log(\"info\", \"Created new context slot\", { contextId });\n }\n\n private async destroyContextSlot(contextId: string): Promise<void> {\n if (contextId === LocalBrowserHost.DEFAULT_CONTEXT_ID) {\n throw new Error(\"Cannot destroy the default context\");\n }\n const slot = this.contexts.get(contextId);\n if (!slot) throw new Error(`Context not found: ${contextId}`);\n\n try {\n await slot.context.close();\n } catch {}\n this.contexts.delete(contextId);\n this.log(\"info\", \"Destroyed context slot\", { contextId });\n }\n\n private async executeMethod(method: string, args: unknown[], contextId?: string): Promise<unknown> {\n // Context lifecycle commands\n switch (method) {\n case \"createContext\":\n return this.createContextSlot(args[0] as string, args[1] as any);\n case \"destroyContext\":\n return this.destroyContextSlot(args[0] as string);\n }\n\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, contextId);\n case \"navigateBack\":\n return this.navigateBack(args[0] as any, contextId);\n\n // Page Inspection\n case \"snapshot\":\n return this.snapshot(args[0] as any, contextId);\n case \"takeScreenshot\":\n return this.takeScreenshot(args[0] as any, contextId);\n case \"evaluate\":\n return this.evaluate(args[0] as string, args[1] as any, contextId);\n case \"runCode\":\n return this.runCode(args[0] as string, args[1] as any, contextId);\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, contextId);\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 contextId\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 contextId\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 contextId\n );\n case \"hover\":\n return this.hover(args[0] as string, args[1] as string, args[2] as any, contextId);\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 contextId\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 contextId\n );\n case \"pressKey\":\n return this.pressKey(args[0] as string, args[1] as any, contextId);\n case \"fillForm\":\n return this.fillForm(args[0] as any[], args[1] as any, contextId);\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 contextId\n );\n case \"fileUpload\":\n return this.fileUpload(args[0] as string[], args[1] as any, contextId);\n\n // Dialogs\n case \"handleDialog\":\n return this.handleDialog(args[0] as \"accept\" | \"dismiss\", args[1] as string, args[2] as any, contextId);\n\n // Waiting\n case \"waitFor\":\n return this.waitFor(args[0] as any, contextId);\n\n // Browser Management\n case \"close\":\n return this.closePage(args[0] as any, contextId);\n case \"resize\":\n return this.resize(args[0] as number, args[1] as number, args[2] as any, contextId);\n case \"tabs\":\n return this.tabs(args[0] as any, args[1] as number, args[2] as any, contextId);\n\n // Context Management\n case \"swapContext\":\n return this.handleSwapContext(args[0] as any, contextId);\n\n // Storage\n case \"getStorageState\":\n return this.getStorageState(args[0] as any, contextId);\n case \"getCurrentUrl\":\n return this.getCurrentUrl(args[0] as any, contextId);\n case \"getTitle\":\n return this.getTitle(args[0] as any, contextId);\n case \"getLinks\":\n return this.getLinks(args[0] as any, contextId);\n case \"getElementBoundingBox\":\n return this.getElementBoundingBox(args[0] as string, args[1] as any, contextId);\n\n // Tracing\n case \"startTracing\":\n return this.startTracing(args[0] as any, contextId);\n case \"stopTracing\":\n return this.stopTracing(args[0] as any, contextId);\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 async handleSwapContext(options: {\n storageState?: unknown;\n storageStatePath?: string;\n recordVideo?: boolean;\n }, contextId?: string): Promise<void> {\n if (!this.browser) throw new Error(\"No browser available\");\n\n const slotId = contextId ?? LocalBrowserHost.DEFAULT_CONTEXT_ID;\n const existing = this.contexts.get(slotId);\n\n // Close existing context (and its pages)\n if (existing) {\n await existing.context.close();\n this.contexts.delete(slotId);\n }\n\n // Build context options\n const contextOptions: { viewport: { width: number; height: number }; storageState?: string } = {\n viewport: { width: 1920, height: 1080 },\n };\n\n if (options.storageState) {\n const tmpPath = `/tmp/storage-state-${crypto.randomUUID()}.json`;\n await Bun.write(tmpPath, JSON.stringify(options.storageState));\n contextOptions.storageState = tmpPath;\n this.log(\"info\", \"Loaded inline storage state for context swap\");\n } else if (options.storageStatePath) {\n try {\n const exists = await Bun.file(options.storageStatePath).exists();\n if (exists) {\n contextOptions.storageState = options.storageStatePath;\n this.log(\"info\", \"Loading storage state from file for context swap\", {\n storageStatePath: options.storageStatePath,\n });\n }\n } catch {\n this.log(\"debug\", \"Storage state file not found, starting fresh context\");\n }\n }\n\n const ctx = await this.browser.newContext(contextOptions);\n const pg = await ctx.newPage();\n const slot: ContextSlot = { context: ctx, page: pg, pendingDialogs: [] };\n pg.on(\"dialog\", (dialog) => slot.pendingDialogs.push(dialog));\n this.contexts.set(slotId, slot);\n\n this.log(\"info\", \"Browser context swapped successfully\", { contextId: slotId });\n }\n\n private getPage(contextId?: string): Page {\n return this.getSlot(contextId).page;\n }\n\n private resolveRef(ref: string, contextId?: string) {\n return this.getPage(contextId).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, contextId?: string): Promise<string> {\n const page = this.getPage(contextId);\n await page.goto(url, { waitUntil: \"domcontentloaded\" });\n await page.waitForLoadState(\"load\", { timeout: 5000 }).catch(() => {});\n return this.captureSnapshot(contextId);\n }\n\n private async navigateBack(_opts?: any, contextId?: string): Promise<string> {\n await this.getPage(contextId).goBack();\n return this.captureSnapshot(contextId);\n }\n\n private async snapshot(_opts?: any, contextId?: string): Promise<string> {\n return this.captureSnapshot(contextId);\n }\n\n private async captureSnapshot(contextId?: string): Promise<string> {\n const page = this.getPage(contextId) as PageWithAISnapshot;\n this.lastSnapshotYaml = await page._snapshotForAI({ mode: \"full\" });\n return this.lastSnapshotYaml;\n }\n\n private async takeScreenshot(opts?: any, contextId?: string): Promise<string | null> {\n const page = this.getPage(contextId);\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, contextId?: string): Promise<T> {\n const page = this.getPage(contextId);\n return page.evaluate(new Function(`return (${fn})()`) as () => T);\n }\n\n private async runCode(code: string, _opts?: any, contextId?: string): Promise<unknown> {\n const page = this.getPage(contextId);\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 return \"Console message capture not implemented in CLI host\";\n }\n\n private async networkRequests(_opts?: any): Promise<string> {\n return \"Network request capture not implemented in CLI host\";\n }\n\n private async click(ref: string, _elementDesc?: string, opts?: any, contextId?: string): Promise<void> {\n const locator = this.resolveRef(ref, contextId);\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(contextId);\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 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 contextId?: string\n ): Promise<void> {\n const page = this.getPage(contextId);\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 contextId?: string\n ): Promise<void> {\n await this.getPage(contextId).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 contextId?: string\n ): Promise<void> {\n const page = this.getPage(contextId);\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, contextId?: string): Promise<void> {\n await this.resolveRef(ref, contextId).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 contextId?: string\n ): Promise<void> {\n const startLocator = this.resolveRef(startRef, contextId);\n const endLocator = this.resolveRef(endRef, contextId);\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 contextId?: string\n ): Promise<void> {\n const locator = this.resolveRef(ref, contextId);\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, contextId?: string): Promise<void> {\n await this.getPage(contextId).keyboard.press(key);\n }\n\n private async fillForm(fields: any[], opts?: any, contextId?: string): Promise<void> {\n for (const field of fields) {\n const locator = this.resolveRef(field.ref, contextId);\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 contextId?: string\n ): Promise<void> {\n await this.resolveRef(ref, contextId).selectOption(value, { timeout: opts?.timeoutMs ?? 30000 });\n }\n\n private async fileUpload(paths: string[], opts?: any, contextId?: string): Promise<void> {\n const fileChooser = await this.getPage(contextId).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 contextId?: string\n ): Promise<void> {\n const slot = this.getSlot(contextId);\n const dialog = slot.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, contextId?: string): Promise<void> {\n const page = this.getPage(contextId);\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, contextId?: string): Promise<void> {\n const slot = this.getSlot(contextId);\n await slot.page.close();\n // If context still has pages, use the first one\n const remaining = slot.context.pages();\n if (remaining.length > 0) {\n slot.page = remaining[0];\n }\n }\n\n private async resize(width: number, height: number, _opts?: any, contextId?: string): Promise<void> {\n await this.getPage(contextId).setViewportSize({ width, height });\n }\n\n private async tabs(action: string, index?: number, _opts?: any, contextId?: string): Promise<unknown> {\n const slot = this.getSlot(contextId);\n const pages = slot.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 slot.context.newPage();\n slot.page = newPage;\n newPage.on(\"dialog\", (dialog) => slot.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 slot.page.close();\n }\n slot.page = slot.context.pages()[0] ?? slot.page;\n break;\n case \"select\":\n if (index !== undefined && pages[index]) {\n slot.page = pages[index];\n }\n break;\n }\n return null;\n }\n\n private async getStorageState(_opts?: any, contextId?: string): Promise<unknown> {\n const slot = this.getSlot(contextId);\n return slot.context.storageState();\n }\n\n private async getCurrentUrl(_opts?: any, contextId?: string): Promise<string> {\n return this.getPage(contextId).url();\n }\n\n private async getTitle(_opts?: any, contextId?: string): Promise<string> {\n return this.getPage(contextId).title();\n }\n\n private async getLinks(_opts?: any, contextId?: string): Promise<string[]> {\n const page = this.getPage(contextId);\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 contextId?: string\n ): Promise<{ x: number; y: number; width: number; height: number } | null> {\n const locator = this.resolveRef(ref, contextId);\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, contextId?: string): Promise<void> {\n const slot = this.getSlot(contextId);\n await slot.context.tracing.start({ screenshots: true, snapshots: true });\n }\n\n private async stopTracing(_opts?: any, contextId?: string): Promise<{\n trace: string;\n network: string;\n resources: string;\n directory: string | null;\n legend: string | null;\n }> {\n const slot = this.getSlot(contextId);\n const tracePath = `/tmp/trace-${Date.now()}.zip`;\n await slot.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"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readStoredToken
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2T64Z2NI.js";
|
|
4
4
|
|
|
5
5
|
// src/local-run.ts
|
|
6
6
|
import process from "process";
|
|
@@ -331,4 +331,4 @@ export {
|
|
|
331
331
|
createTunnel,
|
|
332
332
|
connectTunnel
|
|
333
333
|
};
|
|
334
|
-
//# sourceMappingURL=chunk-
|
|
334
|
+
//# sourceMappingURL=chunk-V7U52ISX.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
readStoredApiUrl,
|
|
3
3
|
readStoredToken
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2T64Z2NI.js";
|
|
5
5
|
import "./chunk-DGUM43GV.js";
|
|
6
6
|
|
|
7
7
|
// src/feature-flag.ts
|
|
@@ -223,4 +223,4 @@ async function runFeatureFlag(argv) {
|
|
|
223
223
|
export {
|
|
224
224
|
runFeatureFlag
|
|
225
225
|
};
|
|
226
|
-
//# sourceMappingURL=feature-flag-
|
|
226
|
+
//# sourceMappingURL=feature-flag-MFTRYRYX.js.map
|
package/dist/index.js
CHANGED
|
@@ -4,14 +4,15 @@ import {
|
|
|
4
4
|
createTunnel,
|
|
5
5
|
runLocalTest,
|
|
6
6
|
runTunnel
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-V7U52ISX.js";
|
|
8
8
|
import {
|
|
9
9
|
ENV_URLS,
|
|
10
|
+
readAllStoredTokens,
|
|
10
11
|
readStoredApiUrl,
|
|
11
12
|
readStoredAuth,
|
|
12
13
|
readStoredToken,
|
|
13
14
|
saveAuth
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2T64Z2NI.js";
|
|
15
16
|
import {
|
|
16
17
|
__require
|
|
17
18
|
} from "./chunk-DGUM43GV.js";
|
|
@@ -956,8 +957,8 @@ function isSuperadminToken(token) {
|
|
|
956
957
|
// src/index.ts
|
|
957
958
|
var require2 = createRequire2(import.meta.url);
|
|
958
959
|
var pkg = require2("../package.json");
|
|
959
|
-
var loadMcp = () => import("./mcp-
|
|
960
|
-
var loadLocalBrowser = () => import("./local-browser-
|
|
960
|
+
var loadMcp = () => import("./mcp-TMD2R5Z6.js").then((m) => m.runMcp);
|
|
961
|
+
var loadLocalBrowser = () => import("./local-browser-SYPTG6IQ.js").then((m) => m.runLocalBrowser);
|
|
961
962
|
var canary = { run };
|
|
962
963
|
var baseDir = typeof __dirname !== "undefined" ? __dirname : path4.dirname(fileURLToPath2(import.meta.url));
|
|
963
964
|
var preloadPath = path4.join(baseDir, "runner", "preload.js");
|
|
@@ -1107,8 +1108,11 @@ function printTestHelp() {
|
|
|
1107
1108
|
);
|
|
1108
1109
|
}
|
|
1109
1110
|
var COMMANDS_WITH_HELP = /* @__PURE__ */ new Set(["test"]);
|
|
1110
|
-
async function
|
|
1111
|
-
|
|
1111
|
+
async function resolveIsSuperadmin() {
|
|
1112
|
+
const envToken = process7.env.CANARY_API_TOKEN;
|
|
1113
|
+
if (envToken) return isSuperadminToken(envToken);
|
|
1114
|
+
const tokens = await readAllStoredTokens();
|
|
1115
|
+
return tokens.some((t) => isSuperadminToken(t));
|
|
1112
1116
|
}
|
|
1113
1117
|
async function main(argv) {
|
|
1114
1118
|
if (argv.includes("--version") || argv.includes("-V")) {
|
|
@@ -1118,13 +1122,11 @@ async function main(argv) {
|
|
|
1118
1122
|
const [command, ...rest] = argv;
|
|
1119
1123
|
const hasHelpFlag = argv.includes("--help") || argv.includes("-h");
|
|
1120
1124
|
if (hasHelpFlag && (!command || !COMMANDS_WITH_HELP.has(command))) {
|
|
1121
|
-
|
|
1122
|
-
printHelp({ isSuperadmin: isSuperadminToken(token2) });
|
|
1125
|
+
printHelp({ isSuperadmin: await resolveIsSuperadmin() });
|
|
1123
1126
|
return;
|
|
1124
1127
|
}
|
|
1125
1128
|
if (!command || command === "help") {
|
|
1126
|
-
|
|
1127
|
-
printHelp({ isSuperadmin: isSuperadminToken(token2) });
|
|
1129
|
+
printHelp({ isSuperadmin: await resolveIsSuperadmin() });
|
|
1128
1130
|
return;
|
|
1129
1131
|
}
|
|
1130
1132
|
if (command === "version") {
|
|
@@ -1179,28 +1181,27 @@ async function main(argv) {
|
|
|
1179
1181
|
return;
|
|
1180
1182
|
}
|
|
1181
1183
|
if (command === "psql") {
|
|
1182
|
-
const { runPsql } = await import("./psql-
|
|
1184
|
+
const { runPsql } = await import("./psql-6IFVXM3A.js");
|
|
1183
1185
|
await runPsql(rest);
|
|
1184
1186
|
return;
|
|
1185
1187
|
}
|
|
1186
1188
|
if (command === "redis") {
|
|
1187
|
-
const { runRedis } = await import("./redis-
|
|
1189
|
+
const { runRedis } = await import("./redis-HZC32IEO.js");
|
|
1188
1190
|
await runRedis(rest);
|
|
1189
1191
|
return;
|
|
1190
1192
|
}
|
|
1191
1193
|
if (command === "feature-flag") {
|
|
1192
|
-
const { runFeatureFlag } = await import("./feature-flag-
|
|
1194
|
+
const { runFeatureFlag } = await import("./feature-flag-MFTRYRYX.js");
|
|
1193
1195
|
await runFeatureFlag(rest);
|
|
1194
1196
|
return;
|
|
1195
1197
|
}
|
|
1196
1198
|
if (command === "knobs") {
|
|
1197
|
-
const { runKnobs } = await import("./knobs-
|
|
1199
|
+
const { runKnobs } = await import("./knobs-T3O4Z3ZB.js");
|
|
1198
1200
|
await runKnobs(rest);
|
|
1199
1201
|
return;
|
|
1200
1202
|
}
|
|
1201
1203
|
console.log(`Unknown command "${command}".`);
|
|
1202
|
-
|
|
1203
|
-
printHelp({ isSuperadmin: isSuperadminToken(token) });
|
|
1204
|
+
printHelp({ isSuperadmin: await resolveIsSuperadmin() });
|
|
1204
1205
|
process7.exit(1);
|
|
1205
1206
|
}
|
|
1206
1207
|
if (import.meta.url === pathToFileURL2(process7.argv[1]).href) {
|