viyv-browser-mcp 0.3.2 → 0.3.4

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/index.js CHANGED
@@ -285,7 +285,7 @@ function startBridge(options) {
285
285
  import { randomUUID as randomUUID2 } from "crypto";
286
286
  import { chmodSync, existsSync as existsSync2, statSync, unlinkSync } from "fs";
287
287
  import http from "http";
288
- import { createServer } from "net";
288
+ import { createConnection as createConnection2, createServer } from "net";
289
289
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
290
290
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
291
291
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -2254,6 +2254,7 @@ async function startMcpServer(socketPath, agentName, options) {
2254
2254
  if (agentName) {
2255
2255
  setDefaultAgentId(agentName);
2256
2256
  }
2257
+ await evictExistingBridge(socketPath);
2257
2258
  const socketServer = createSocketServer(socketPath);
2258
2259
  if (options?.transport === "sse") {
2259
2260
  const sessions2 = /* @__PURE__ */ new Map();
@@ -2553,6 +2554,28 @@ function parseJsonBody(req) {
2553
2554
  });
2554
2555
  });
2555
2556
  }
2557
+ function evictExistingBridge(socketPath) {
2558
+ if (!existsSync2(socketPath)) return Promise.resolve();
2559
+ return new Promise((resolve2) => {
2560
+ const timeout = setTimeout(() => {
2561
+ tempSocket.destroy();
2562
+ resolve2();
2563
+ }, 2e3);
2564
+ const tempSocket = createConnection2(socketPath);
2565
+ tempSocket.on("connect", () => {
2566
+ process.stderr.write("[viyv-browser:mcp] Evicted bridge from previous MCP server\n");
2567
+ setTimeout(() => {
2568
+ tempSocket.destroy();
2569
+ clearTimeout(timeout);
2570
+ resolve2();
2571
+ }, 300);
2572
+ });
2573
+ tempSocket.on("error", () => {
2574
+ clearTimeout(timeout);
2575
+ resolve2();
2576
+ });
2577
+ });
2578
+ }
2556
2579
  function createSocketServer(socketPath) {
2557
2580
  cleanupSocket(socketPath);
2558
2581
  const server = createServer((socket) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/native-host/bridge.ts","../../shared/src/constants.ts","../src/native-host/compression.ts","../src/native-host/transport.ts","../src/server.ts","../src/agent-session.ts","../src/event-bridge.ts","../src/health.ts","../src/tools/index.ts","../src/tools/advanced/file-upload.ts","../src/tools/advanced/gif-creator.ts","../src/tools/advanced/resize-window.ts","../src/tools/advanced/shortcuts-execute.ts","../src/tools/advanced/shortcuts-list.ts","../src/tools/advanced/switch-browser.ts","../src/tools/advanced/update-plan.ts","../src/tools/advanced/upload-image.ts","../src/tools/core/click.ts","../src/tools/core/drag.ts","../src/tools/core/find.ts","../src/tools/core/form-input.ts","../src/tools/core/get-page-text.ts","../src/tools/core/handle-dialog.ts","../src/tools/core/hover.ts","../src/tools/core/javascript-exec.ts","../src/tools/core/key.ts","../src/tools/core/navigate.ts","../src/tools/core/read-page.ts","../src/tools/core/screenshot.ts","../src/tools/core/scroll.ts","../src/tools/core/type.ts","../src/tools/core/wait-for.ts","../src/tools/debug/read-console-messages.ts","../src/tools/debug/read-network-requests.ts","../src/tools/semantic/sm-add-action.ts","../src/tools/semantic/sm-add-fetch.ts","../src/tools/semantic/sm-add-target.ts","../src/tools/semantic/sm-capabilities.ts","../src/tools/semantic/sm-custom-view.ts","../src/tools/semantic/sm-delete.ts","../src/tools/semantic/sm-export.ts","../src/tools/semantic/sm-fetch.ts","../src/tools/semantic/sm-import.ts","../src/tools/semantic/sm-invoke.ts","../src/tools/semantic/sm-job-cancel.ts","../src/tools/semantic/sm-job-create.ts","../src/tools/semantic/sm-job-delete.ts","../src/tools/semantic/sm-job-history.ts","../src/tools/semantic/sm-job-list.ts","../src/tools/semantic/sm-job-report-export.ts","../src/tools/semantic/sm-job-report-get.ts","../src/tools/semantic/sm-job-run.ts","../src/tools/semantic/sm-job-update.ts","../src/tools/semantic/sm-register-page.ts","../src/tools/semantic/sm-report-delete.ts","../src/tools/semantic/sm-report-export.ts","../src/tools/semantic/sm-report-get.ts","../src/tools/semantic/sm-report-list.ts","../src/tools/semantic/sm-scenario-create.ts","../src/tools/semantic/sm-scenario-delete.ts","../src/tools/semantic/sm-scenario-list.ts","../src/tools/semantic/sm-scenario-run.ts","../src/tools/semantic/sm-scenario-update.ts","../src/tools/semantic/sm-status.ts","../src/tools/semantic/sm-test-target.ts","../src/tools/tabs/select-tab.ts","../src/tools/tabs/tab-close.ts","../src/tools/tabs/tabs-context.ts","../src/tools/tabs/tabs-create.ts","../src/tools/viyv/agent-tab-assign.ts","../src/tools/viyv/agent-tab-list.ts","../src/tools/viyv/artifact-from-page.ts","../src/tools/viyv/browser-event-subscribe.ts","../src/tools/viyv/browser-event-unsubscribe.ts","../src/tools/viyv/browser-health.ts","../src/tools/viyv/page-data-extract.ts","../src/setup.ts"],"sourcesContent":["/**\n * @viyv/browser-mcp CLI entry point.\n *\n * Modes:\n * viyv-browser-mcp → MCP Server (stdio | sse | streamable-http transport)\n * viyv-browser-mcp --native-host → Native Messaging Host mode (Chrome bridge)\n * viyv-browser-mcp setup → Register Native Messaging Host manifest\n */\n\nimport { existsSync, readdirSync } from 'node:fs'\nimport { startBridge } from './native-host/bridge.js'\nimport { startMcpServer } from './server.js'\nimport { runSetup } from './setup.js'\n\nconst args = process.argv.slice(2)\n\nif (args.includes('setup')) {\n // Setup mode: register Native Messaging Host\n const extensionIdIdx = args.indexOf('--extension-id')\n const extensionId = extensionIdIdx >= 0 ? args[extensionIdIdx + 1] : undefined\n runSetup({ extensionId })\n} else if (args.includes('--native-host')) {\n // Native Messaging Host mode: bridge Chrome ↔ MCP Server\n // Socket may not exist yet (MCP Server starts when AI client connects).\n // Wait and retry until the socket appears.\n const SOCKET_PATH = '/tmp/viyv-browser.sock'\n const POLL_INTERVAL = 2000\n const MAX_WAIT = 120_000\n\n function waitForSocket() {\n const start = Date.now()\n\n function poll() {\n const socketPath = findSocketPath()\n if (socketPath) {\n process.stderr.write(`[viyv-browser:native-host] Found socket at ${socketPath}\\n`)\n startBridge({\n socketPath,\n onError: (error) => {\n process.stderr.write(`[viyv-browser:native-host] Error: ${error.message}\\n`)\n },\n })\n return\n }\n\n if (Date.now() - start > MAX_WAIT) {\n process.stderr.write(\n `[viyv-browser:native-host] MCP server socket not found after ${MAX_WAIT / 1000}s. Exiting.\\n`,\n )\n process.exit(1)\n }\n\n process.stderr.write(\n `[viyv-browser:native-host] Waiting for MCP server socket (${SOCKET_PATH})...\\n`,\n )\n setTimeout(poll, POLL_INTERVAL)\n }\n\n poll()\n }\n\n waitForSocket()\n} else {\n // MCP Server mode (default) — fixed path so bridge can always find it on reconnect\n const socketPath = '/tmp/viyv-browser.sock'\n const agentNameIdx = args.indexOf('--agent-name')\n const agentName = agentNameIdx >= 0 ? args[agentNameIdx + 1] : undefined\n\n const transportIdx = args.indexOf('--transport')\n const transportMode = transportIdx >= 0 ? args[transportIdx + 1] : 'stdio'\n if (transportMode !== 'stdio' && transportMode !== 'sse' && transportMode !== 'streamable-http') {\n process.stderr.write(\n `[viyv-browser:mcp] Invalid transport: \"${transportMode}\". Must be \"stdio\", \"sse\", or \"streamable-http\".\\n`,\n )\n process.exit(1)\n }\n const portIdx = args.indexOf('--port')\n const port = portIdx >= 0 ? Number(args[portIdx + 1]) : undefined\n\n startMcpServer(socketPath, agentName, { transport: transportMode, port })\n}\n\nfunction findSocketPath(): string | null {\n const envSocket = process.env.VIYV_BROWSER_SOCKET\n if (envSocket) return envSocket\n\n // Check fixed socket path first\n const fixedPath = '/tmp/viyv-browser.sock'\n if (existsSync(fixedPath)) return fixedPath\n\n // Fallback: scan for legacy PID-based sockets\n try {\n const tmpFiles = readdirSync('/tmp')\n const socketFile = tmpFiles.find((f) => f.startsWith('viyv-browser-') && f.endsWith('.sock'))\n if (socketFile) return `/tmp/${socketFile}`\n } catch {\n // Ignore\n }\n\n return null\n}\n","/**\n * Bridge between Native Messaging Host and MCP Server via Unix socket.\n *\n * When running as --native-host:\n * Chrome <-> stdin/stdout (Native Messaging) <-> this bridge <-> Unix socket <-> MCP Server\n */\n\nimport { existsSync } from 'node:fs'\nimport { type Socket, createConnection } from 'node:net'\nimport { LIMITS, RECONNECT } from '@viyv-browser/shared'\nimport { compressPayload, decompressPayload } from './compression.js'\nimport { createMessageReader, writeMessage } from './transport.js'\n\nconst MAX_BUFFER_SIZE = 1000\n\nexport interface BridgeOptions {\n socketPath: string\n onError?: (error: Error) => void\n}\n\nexport function startBridge(options: BridgeOptions): void {\n const { socketPath, onError } = options\n let socket: Socket | null = null\n let reconnecting = false\n let retryCount = 0\n\n // FIX #2: Actual message buffer for messages received while socket is disconnected\n const pendingMessages: unknown[] = []\n\n function flushBuffer() {\n if (!socket || socket.destroyed) return\n while (pendingMessages.length > 0) {\n const msg = pendingMessages[0] // FIX NL3: Peek first, don't shift until write succeeds\n try {\n const written = socket.write(`${JSON.stringify(msg)}\\n`)\n pendingMessages.shift() // Safe to remove after successful write call\n if (!written) {\n // Backpressure: wait for drain before continuing flush\n socket.once('drain', () => flushBuffer())\n return\n }\n } catch (error) {\n // Message stays in buffer for retry on reconnection\n onError?.(error as Error)\n return\n }\n }\n }\n\n function scheduleReconnect() {\n if (reconnecting) return\n reconnecting = true\n\n // If socket file doesn't exist yet (MCP Server not started), poll for it\n // with a short fixed interval instead of exponential backoff\n const POLL_INTERVAL = 2000\n\n function attemptReconnect() {\n if (existsSync(socketPath)) {\n process.stderr.write(\n `[viyv-browser:native-host] Socket found, reconnecting (attempt ${retryCount + 1})\\n`,\n )\n reconnecting = false\n connectSocket()\n } else {\n retryCount++\n // Cap polling at ~120s total then give up polling, but keep alive\n if (retryCount > 60) {\n process.stderr.write(\n '[viyv-browser:native-host] Socket not found after 120s, slowing down polling\\n',\n )\n setTimeout(attemptReconnect, RECONNECT.MAX_DELAY)\n } else {\n setTimeout(attemptReconnect, POLL_INTERVAL)\n }\n }\n }\n\n // First attempt: use backoff delay if we had a live connection before\n const delay = retryCount === 0 ? RECONNECT.INITIAL_DELAY : POLL_INTERVAL\n setTimeout(attemptReconnect, delay)\n }\n\n function connectSocket() {\n socket = createConnection(socketPath)\n\n socket.on('connect', () => {\n process.stderr.write(`[viyv-browser:native-host] Connected to MCP server at ${socketPath}\\n`)\n retryCount = 0 // Reset backoff on successful connection\n flushBuffer()\n })\n\n // Messages from MCP Server -> Chrome (via stdout)\n // TCP stream fragmentation fix: line-based buffer\n let lineBuffer = ''\n\n socket.on('data', (data) => {\n lineBuffer += data.toString('utf-8')\n const lines = lineBuffer.split('\\n')\n lineBuffer = lines.pop() ?? '' // Keep incomplete last line\n for (const line of lines) {\n if (!line) continue\n try {\n let message = JSON.parse(line)\n // NM5: Decompress incoming compressed messages from MCP Server\n if (message.type === 'compressed' && typeof message.data === 'string') {\n const decompressed = decompressPayload(message.data, true)\n message = JSON.parse(decompressed)\n }\n writeMessage(process.stdout, message)\n } catch (error) {\n onError?.(error as Error)\n }\n }\n })\n\n socket.on('error', (error) => {\n process.stderr.write(`[viyv-browser:native-host] Socket error: ${error.message}\\n`)\n onError?.(error)\n })\n\n socket.on('close', () => {\n process.stderr.write('[viyv-browser:native-host] Socket closed\\n')\n socket = null\n scheduleReconnect()\n })\n }\n\n // Messages from Chrome (via stdin) -> MCP Server\n createMessageReader(\n process.stdin,\n (message) => {\n if (socket && !socket.destroyed) {\n // NM5: Compress large payloads (e.g., screenshots) before Unix socket transfer\n const json = JSON.stringify(message)\n if (json.length > LIMITS.CHUNK_SIZE) {\n const { compressed, wasCompressed } = compressPayload(json)\n if (wasCompressed) {\n socket.write(`${JSON.stringify({ type: 'compressed', data: compressed })}\\n`)\n } else {\n socket.write(`${json}\\n`)\n }\n } else {\n socket.write(`${json}\\n`)\n }\n } else {\n // Buffer messages while disconnected\n if (pendingMessages.length < MAX_BUFFER_SIZE) {\n pendingMessages.push(message)\n } else {\n process.stderr.write('[viyv-browser:native-host] Message buffer full, dropping message\\n')\n }\n }\n },\n onError,\n )\n\n connectSocket()\n\n // Clean shutdown handlers\n process.on('SIGINT', () => {\n socket?.destroy()\n process.exit(0)\n })\n\n process.on('SIGTERM', () => {\n socket?.destroy()\n process.exit(0)\n })\n\n process.stdin.on('end', () => {\n process.stderr.write('[viyv-browser:native-host] stdin closed, shutting down\\n')\n socket?.destroy()\n process.exit(0)\n })\n}\n","/** Protocol version for compatibility checks */\nexport const PROTOCOL_VERSION = '1.0.0'\n\n/** Native Messaging host name (must match manifest) */\nexport const NATIVE_HOST_NAME = 'com.viyv.browser'\n\n/** Extension ID (will be assigned by CWS) */\nexport const EXTENSION_ID = '' // Set after CWS registration\n\n// ── Timeouts (ms) ──\n\nexport const TIMEOUTS = {\n /** Overall MCP tool timeout */\n MCP_TOOL: 30_000,\n /** Native Messaging request timeout */\n NATIVE_MESSAGE: 15_000,\n /** CDP command timeout */\n CDP_COMMAND: 10_000,\n /** Screenshot capture timeout */\n SCREENSHOT: 5_000,\n /** Navigation timeout */\n NAVIGATION: 30_000,\n /** Chunk reassembly timeout */\n CHUNK_REASSEMBLY: 10_000,\n /** Default wait_for timeout */\n WAIT_FOR: 30_000,\n /** Heartbeat interval */\n HEARTBEAT: 30_000,\n /** CDP idle detach delay */\n CDP_IDLE_DETACH: 5_000,\n /** Tab lock TTL (deadlock prevention) */\n TAB_LOCK_TTL: 60_000,\n} as const\n\n// ── Limits ──\n\nexport const LIMITS = {\n /** Native Messaging max message size (Chrome limit) */\n NATIVE_MESSAGE_MAX_BYTES: 1024 * 1024,\n /** Chunk size for large payloads */\n CHUNK_SIZE: 768 * 1024,\n /** A11y tree max elements */\n A11Y_MAX_ELEMENTS: 5000,\n /** A11y tree default depth */\n A11Y_DEFAULT_DEPTH: 15,\n /** A11y tree default max chars */\n A11Y_DEFAULT_MAX_CHARS: 50_000,\n /** Event buffer max entries */\n EVENT_BUFFER_MAX: 1000,\n /** Event buffer max bytes */\n EVENT_BUFFER_MAX_BYTES: 10 * 1024 * 1024,\n /** Message buffer during disconnection */\n MESSAGE_BUFFER_MAX: 1000,\n /** Default screenshot JPEG quality */\n SCREENSHOT_JPEG_QUALITY: 80,\n /** Console buffer per tab */\n CONSOLE_BUFFER_MAX: 1000,\n /** Network buffer per tab */\n NETWORK_BUFFER_MAX: 1000,\n} as const\n\n// ── Reconnection ──\n\nexport const RECONNECT = {\n /** Initial delay (ms) */\n INITIAL_DELAY: 1000,\n /** Max delay (ms) */\n MAX_DELAY: 30_000,\n /** Backoff multiplier */\n MULTIPLIER: 2,\n} as const\n\n// ── Keep-alive ──\n\nexport const KEEP_ALIVE = {\n /** Alarm name for backup keep-alive */\n ALARM_NAME: 'viyv-browser-keepalive',\n /** Alarm period (minutes) - minimum for Chrome alarms */\n ALARM_PERIOD_MIN: 0.5,\n} as const\n\n// ── MCP Server ──\n\nexport const MCP_SERVER = {\n /** Server name for MCP protocol */\n NAME: 'viyv-browser',\n /** Server version */\n VERSION: '0.1.0',\n /** Unix socket path template */\n SOCKET_PATH_TEMPLATE: '/tmp/viyv-browser-{pid}.sock',\n} as const\n","/**\n * Compression utilities for large payloads.\n * Used when messages approach the 1MB Native Messaging limit.\n */\n\nimport { gunzipSync, gzipSync } from 'node:zlib'\nimport type { ChunkedMessage } from '@viyv-browser/shared'\n\nconst CHUNK_SIZE = 768 * 1024 // 768KB per chunk\n\n// Use shared ChunkedMessage as the canonical type\nexport type ChunkedPayload = ChunkedMessage\n\nexport function compressPayload(data: string): { compressed: string; wasCompressed: boolean } {\n const original = Buffer.from(data, 'utf-8')\n const gzipped = gzipSync(original)\n\n if (gzipped.length < original.length) {\n return { compressed: gzipped.toString('base64'), wasCompressed: true }\n }\n return { compressed: data, wasCompressed: false }\n}\n\nexport function decompressPayload(data: string, isCompressed: boolean): string {\n if (!isCompressed) return data\n const buf = Buffer.from(data, 'base64')\n return gunzipSync(buf).toString('utf-8')\n}\n\nexport function chunkPayload(\n requestId: string,\n agentId: string,\n data: string,\n compressed: boolean,\n): ChunkedPayload[] {\n const totalSize = data.length\n const totalChunks = Math.ceil(totalSize / CHUNK_SIZE)\n const chunks: ChunkedPayload[] = []\n\n for (let i = 0; i < totalChunks; i++) {\n chunks.push({\n type: 'chunk',\n requestId,\n agentId,\n chunkIndex: i,\n totalChunks,\n totalSize,\n compressed,\n data: data.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE),\n })\n }\n\n return chunks\n}\n\n// FIX #20: Guard against empty chunks array\nexport function reassembleChunks(chunks: ChunkedPayload[]): string {\n if (chunks.length === 0) {\n throw new Error('Cannot reassemble: no chunks provided')\n }\n\n const sorted = [...chunks].sort((a, b) => a.chunkIndex - b.chunkIndex)\n\n if (sorted.length !== sorted[0].totalChunks) {\n throw new Error(`Incomplete chunks: got ${sorted.length}, expected ${sorted[0].totalChunks}`)\n }\n\n const data = sorted.map((c) => c.data).join('')\n return decompressPayload(data, sorted[0].compressed)\n}\n","/**\n * Native Messaging transport: length-prefixed JSON over stdin/stdout.\n * Chrome Native Messaging uses 4-byte little-endian length prefix + UTF-8 JSON.\n */\n\nconst MAX_MESSAGE_SIZE = 1024 * 1024 // 1MB Chrome limit\n\nexport function encodeMessage(message: unknown): Buffer {\n const json = JSON.stringify(message)\n const body = Buffer.from(json, 'utf-8')\n\n if (body.length > MAX_MESSAGE_SIZE) {\n throw new Error(`Message too large: ${body.length} bytes (max ${MAX_MESSAGE_SIZE})`)\n }\n\n const header = Buffer.alloc(4)\n header.writeUInt32LE(body.length, 0)\n return Buffer.concat([header, body])\n}\n\nexport function createMessageReader(\n stream: NodeJS.ReadableStream,\n onMessage: (message: unknown) => void,\n onError?: (error: Error) => void,\n onClose?: () => void,\n) {\n let buffer = Buffer.alloc(0)\n let expectedLength: number | null = null\n\n stream.on('data', (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk])\n\n while (true) {\n // Read length header\n if (expectedLength === null) {\n if (buffer.length < 4) break\n expectedLength = buffer.readUInt32LE(0)\n buffer = buffer.subarray(4)\n\n if (expectedLength > MAX_MESSAGE_SIZE) {\n onError?.(new Error(`Message too large: ${expectedLength} bytes`))\n expectedLength = null\n buffer = Buffer.alloc(0)\n break\n }\n }\n\n // Read message body\n if (buffer.length < expectedLength) break\n\n const jsonBuffer = buffer.subarray(0, expectedLength)\n buffer = buffer.subarray(expectedLength)\n expectedLength = null\n\n try {\n const message = JSON.parse(jsonBuffer.toString('utf-8'))\n onMessage(message)\n } catch (error) {\n onError?.(new Error(`Invalid JSON: ${(error as Error).message}`))\n }\n }\n })\n\n // FIX #19: Handle stream close/error events\n stream.on('error', (error: Error) => {\n onError?.(new Error(`Stream error: ${error.message}`))\n })\n\n stream.on('end', () => {\n onClose?.()\n })\n\n stream.on('close', () => {\n onClose?.()\n })\n}\n\nexport function writeMessage(stream: NodeJS.WritableStream, message: unknown): void {\n const encoded = encodeMessage(message)\n stream.write(encoded)\n}\n","/**\n * MCP Server for viyv-browser.\n * Communicates with viyv Daemon via stdio (JSON-RPC), SSE (HTTP), or Streamable HTTP,\n * and with Chrome Extension via Unix socket <-> Native Messaging bridge.\n */\n\nimport { randomUUID } from 'node:crypto'\nimport { chmodSync, existsSync, statSync, unlinkSync } from 'node:fs'\nimport http from 'node:http'\nimport { type Server as NetServer, type Socket, createServer } from 'node:net'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { type BrowserEventType, MCP_SERVER, PROTOCOL_VERSION, TIMEOUTS } from '@viyv-browser/shared'\nimport { z } from 'zod'\nimport {\n closeSession,\n createSession,\n getDefaultAgentId,\n setDefaultAgentId,\n touchSession,\n} from './agent-session.js'\nimport {\n addEventListener,\n addSubscription,\n processEvent,\n removeEventListener,\n removeSubscription,\n removeSubscriptionsByAgent,\n} from './event-bridge.js'\nimport {\n getHealthStatus,\n isExtensionConnected,\n recordHeartbeat,\n setExtensionConnected,\n} from './health.js'\nimport { decompressPayload } from './native-host/compression.js'\nimport { allTools } from './tools/index.js'\n\ntype ToolContentItem =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n\ninterface PendingRequest {\n resolve: (result: Record<string, unknown>) => void\n reject: (error: Error) => void\n timer: ReturnType<typeof setTimeout>\n}\n\nconst pendingRequests = new Map<string, PendingRequest>()\nlet extensionSocket: Socket | null = null\n\nexport interface McpServerOptions {\n transport?: 'stdio' | 'sse' | 'streamable-http'\n port?: number\n}\n\ninterface StreamableHttpSession {\n transport: StreamableHTTPServerTransport\n server: McpServer\n lastActivity: number\n}\n\n/**\n * Coerce a single string value to its intended type (before Zod validation).\n * Some MCP clients (e.g. Claude Code deferred tools) send all params as strings.\n */\nfunction coerceValue(v: unknown): unknown {\n if (typeof v !== 'string') return v\n // JSON arrays and objects\n if ((v.startsWith('[') && v.endsWith(']')) || (v.startsWith('{') && v.endsWith('}'))) {\n try {\n return JSON.parse(v)\n } catch {\n /* keep as string */\n }\n }\n // Booleans (can't use z.coerce.boolean: Boolean(\"false\") === true)\n if (v === 'true') return true\n if (v === 'false') return false\n return v\n}\n\n/**\n * Wrap each field in a Zod shape with z.preprocess() so string-encoded\n * values are coerced BEFORE Zod validation runs.\n */\nfunction coerceShape(shape: Record<string, z.ZodType>): Record<string, z.ZodType> {\n const result: Record<string, z.ZodType> = {}\n for (const [key, schema] of Object.entries(shape)) {\n result[key] = z.preprocess(coerceValue, schema)\n }\n return result\n}\n\n/**\n * Creates a fully configured McpServer with all tools registered and event forwarding.\n * Each session (SSE / Streamable HTTP) needs its own instance (McpServer.connect() can only be called once).\n */\nfunction createConfiguredMcpServer(): McpServer {\n const server = new McpServer({\n name: MCP_SERVER.NAME,\n version: MCP_SERVER.VERSION,\n })\n\n // Register all tools -- pass Zod shape directly (FIX #1: MCP SDK expects Zod, not JSON Schema)\n for (const tool of allTools) {\n const def = tool.inputSchema._def as { shape?: () => Record<string, unknown> }\n const shape = def.shape?.() ?? {}\n server.tool(\n tool.name,\n tool.description,\n coerceShape(shape as Record<string, z.ZodType>),\n async (params: Record<string, unknown>) => {\n const result = await callExtensionTool(tool.name, params as Record<string, unknown>)\n\n // BUG-4 FIX: Sync event subscriptions with MCP server's event-bridge\n const first = result.content[0]\n if (tool.name === 'browser_event_subscribe' && first?.type === 'text') {\n try {\n const parsed = JSON.parse(first.text)\n if (parsed.subscriptionId) {\n const p = params as Record<string, unknown>\n addSubscription({\n id: parsed.subscriptionId,\n agentId: getDefaultAgentId(),\n eventTypes: (p.eventTypes as BrowserEventType[]) ?? [],\n urlPattern: p.urlPattern as string | undefined,\n createdAt: Date.now(),\n })\n }\n } catch {\n /* ignore parse errors */\n }\n } else if (tool.name === 'browser_event_unsubscribe' && first?.type === 'text') {\n try {\n const parsed = JSON.parse(first.text)\n if (parsed.subscriptionId) {\n removeSubscription(parsed.subscriptionId)\n }\n } catch {\n /* ignore parse errors */\n }\n }\n\n return result\n },\n )\n }\n\n // Forward browser events through MCP logging notification\n const listener = (event: Record<string, unknown>) => {\n server\n .sendLoggingMessage({\n level: 'info',\n data: event,\n })\n .catch(() => {\n // Ignore send errors for events (client may not be listening)\n })\n }\n addEventListener(listener)\n\n // Clean up listener when transport closes\n server.server.onclose = () => {\n removeEventListener(listener)\n }\n\n return server\n}\n\nexport async function startMcpServer(\n socketPath: string,\n agentName?: string,\n options?: McpServerOptions,\n): Promise<void> {\n if (agentName) {\n setDefaultAgentId(agentName)\n }\n\n // -- Unix Socket Server (for Native Host connections) -- shared by all transports\n const socketServer = createSocketServer(socketPath)\n\n if (options?.transport === 'sse') {\n // -- SSE mode: HTTP server, one McpServer per SSE session --\n const sessions = new Map<string, { transport: SSEServerTransport; server: McpServer }>()\n\n const httpServer = http.createServer()\n\n httpServer.on('request', (req, res) => {\n handleSseRequest(req, res, sessions).catch((error) => {\n process.stderr.write(`[viyv-browser:mcp] SSE request error: ${(error as Error).message}\\n`)\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n })\n })\n\n const listenPort = options.port ?? 0\n httpServer.listen(listenPort, '127.0.0.1', () => {\n const addr = httpServer.address()\n const port = typeof addr === 'object' ? addr?.port : listenPort\n process.stdout.write(`${JSON.stringify({ port })}\\n`)\n process.stderr.write(`[viyv-browser:mcp] SSE server listening on 127.0.0.1:${port}\\n`)\n })\n\n process.stderr.write(`[viyv-browser:mcp] MCP Server started (SSE), socket: ${socketPath}\\n`)\n\n // Graceful shutdown: close SSE sessions async, then sync cleanup\n let shuttingDown = false\n const shutdown = async () => {\n if (shuttingDown) return\n shuttingDown = true\n for (const { server: s } of sessions.values()) {\n await s.close().catch(() => {})\n }\n httpServer.close(() => {})\n socketServer.close(() => {})\n cleanupSocket(socketPath)\n process.exit(0)\n }\n process.on('SIGINT', () => {\n shutdown()\n })\n process.on('SIGTERM', () => {\n shutdown()\n })\n\n // Sync fallback for unexpected exit (e.g. uncaughtException)\n // shutdown() already handled close — only clean up socket file here\n process.on('exit', () => {\n cleanupSocket(socketPath)\n })\n } else if (options?.transport === 'streamable-http') {\n // -- Streamable HTTP mode: per-session McpServer with TTL --\n const sessions = new Map<string, StreamableHttpSession>()\n\n const SESSION_TTL = 30 * 60 * 1000 // 30 minutes\n const SWEEP_INTERVAL = 5 * 60 * 1000 // 5 minutes\n\n const sweepTimer = setInterval(() => {\n const now = Date.now()\n for (const [id, session] of sessions) {\n if (now - session.lastActivity > SESSION_TTL) {\n process.stderr.write(`[viyv-browser:mcp] Streamable HTTP session TTL expired: ${id}\\n`)\n // Delete from Map first to prevent concurrent requests hitting a closing transport\n sessions.delete(id)\n session.server.close().catch(() => {})\n }\n }\n }, SWEEP_INTERVAL)\n sweepTimer.unref()\n\n const httpServer = http.createServer()\n\n httpServer.on('request', (req, res) => {\n handleStreamableHttpRequest(req, res, sessions).catch((error) => {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP request error: ${(error as Error).message}\\n`,\n )\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n })\n })\n\n const listenPort = options.port ?? 0\n httpServer.listen(listenPort, '127.0.0.1', () => {\n const addr = httpServer.address()\n const port = typeof addr === 'object' ? addr?.port : listenPort\n process.stdout.write(`${JSON.stringify({ port })}\\n`)\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP server listening on 127.0.0.1:${port}\\n`,\n )\n })\n\n process.stderr.write(\n `[viyv-browser:mcp] MCP Server started (streamable-http), socket: ${socketPath}\\n`,\n )\n\n // Graceful shutdown\n let shuttingDown = false\n const shutdown = async () => {\n if (shuttingDown) return\n shuttingDown = true\n clearInterval(sweepTimer)\n for (const { server: s } of sessions.values()) {\n await s.close().catch(() => {})\n }\n httpServer.close(() => {})\n socketServer.close(() => {})\n cleanupSocket(socketPath)\n process.exit(0)\n }\n process.on('SIGINT', () => {\n shutdown()\n })\n process.on('SIGTERM', () => {\n shutdown()\n })\n\n process.on('exit', () => {\n cleanupSocket(socketPath)\n })\n } else {\n // -- stdio mode (default) --\n const server = createConfiguredMcpServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n process.stderr.write(`[viyv-browser:mcp] MCP Server started (stdio), socket: ${socketPath}\\n`)\n\n process.on('SIGINT', () => process.exit(0))\n process.on('SIGTERM', () => process.exit(0))\n\n process.on('exit', () => {\n socketServer.close()\n cleanupSocket(socketPath)\n })\n }\n}\n\nasync function handleSseRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n sessions: Map<string, { transport: SSEServerTransport; server: McpServer }>,\n): Promise<void> {\n if (req.method === 'GET' && req.url === '/sse') {\n // New SSE session\n const transport = new SSEServerTransport('/message', res)\n const mcpServer = createConfiguredMcpServer()\n\n transport.onclose = () => {\n sessions.delete(transport.sessionId)\n }\n\n // Fallback: clean up session if HTTP connection closes without transport.onclose\n res.on('close', () => {\n if (sessions.has(transport.sessionId)) {\n sessions.delete(transport.sessionId)\n transport.close()\n }\n })\n\n await mcpServer.connect(transport)\n\n // Register session only after connect succeeds\n sessions.set(transport.sessionId, { transport, server: mcpServer })\n } else if (req.method === 'POST' && req.url?.startsWith('/message')) {\n // Route POST to the correct session\n const url = new URL(req.url, `http://${req.headers.host ?? 'localhost'}`)\n const sessionId = url.searchParams.get('sessionId')\n const session = sessionId ? sessions.get(sessionId) : null\n\n if (session) {\n await session.transport.handlePostMessage(req, res)\n } else {\n res.writeHead(404).end('Session not found')\n }\n } else {\n res.writeHead(404).end()\n }\n}\n\nasync function handleStreamableHttpRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n sessions: Map<string, StreamableHttpSession>,\n): Promise<void> {\n let url: URL\n try {\n url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)\n } catch {\n res.writeHead(400).end('Bad request')\n return\n }\n\n if (url.pathname !== '/mcp') {\n res.writeHead(404).end('Not found')\n return\n }\n\n const rawSessionId = req.headers['mcp-session-id']\n const sessionId = typeof rawSessionId === 'string' ? rawSessionId : undefined\n const existingSession = sessionId ? sessions.get(sessionId) : undefined\n\n // Existing session: route request to its transport\n if (existingSession) {\n existingSession.lastActivity = Date.now()\n\n if (req.method === 'POST') {\n let body: unknown\n try {\n body = await parseJsonBody(req)\n } catch (parseError) {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP body parse failed: ${(parseError as Error).message}\\n`,\n )\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32700, message: 'Parse error' },\n id: null,\n }),\n )\n return\n }\n await existingSession.transport.handleRequest(req, res, body)\n } else {\n // GET (SSE stream) or DELETE (session termination) — SDK handles method routing\n await existingSession.transport.handleRequest(req, res)\n }\n return\n }\n\n // New session: only accept POST with initialize request\n if (!sessionId && req.method === 'POST') {\n let body: unknown\n try {\n body = await parseJsonBody(req)\n } catch (parseError) {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP body parse failed: ${(parseError as Error).message}\\n`,\n )\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32700, message: 'Parse error' },\n id: null,\n }),\n )\n return\n }\n\n if (!isInitializeRequest(body)) {\n const requestId =\n body && typeof body === 'object' && 'id' in body ? (body as { id: unknown }).id : null\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'First request must be an initialize request' },\n id: requestId ?? null,\n }),\n )\n return\n }\n\n const mcpServer = createConfiguredMcpServer()\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { transport, server: mcpServer, lastActivity: Date.now() })\n },\n })\n\n // Set onclose before server.connect() — Protocol wraps existing onclose\n transport.onclose = () => {\n const id = transport.sessionId\n if (id) sessions.delete(id)\n }\n\n let connected = false\n try {\n await mcpServer.connect(transport)\n connected = true\n await transport.handleRequest(req, res, body)\n } catch (error) {\n const stage = connected ? 'handleRequest' : 'connect'\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP session ${stage} failed: ${(error as Error).message}\\n`,\n )\n // Ensure event listener cleanup even if connect() didn't complete wrapping\n try {\n mcpServer.server.onclose?.()\n } catch {\n /* ignore */\n }\n await mcpServer.close().catch(() => {})\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n }\n return\n }\n\n // Known session ID but not in map → expired or terminated\n if (sessionId && !existingSession) {\n res.writeHead(404).end('Session not found')\n return\n }\n\n res.writeHead(400).end('Bad request')\n}\n\nconst MAX_BODY_SIZE = 4 * 1024 * 1024\n\nfunction parseJsonBody(req: http.IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let destroyed = false\n req.on('data', (chunk: Buffer) => {\n if (destroyed) return\n size += chunk.length\n if (size > MAX_BODY_SIZE) {\n destroyed = true\n req.destroy()\n reject(new Error('Request body too large'))\n return\n }\n chunks.push(chunk)\n })\n req.on('end', () => {\n if (destroyed) return\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf-8')))\n } catch (error) {\n reject(new Error(`Invalid JSON: ${(error as Error).message}`))\n }\n })\n req.on('error', (err) => {\n if (!destroyed) reject(err)\n })\n })\n}\n\nfunction createSocketServer(socketPath: string): NetServer {\n cleanupSocket(socketPath)\n\n const server = createServer((socket) => {\n // FIX #6: Clean up old connection before accepting new one\n if (extensionSocket && !extensionSocket.destroyed) {\n process.stderr.write('[viyv-browser:mcp] Replacing existing extension connection\\n')\n extensionSocket.destroy()\n }\n\n process.stderr.write('[viyv-browser:mcp] Extension connected via Unix socket\\n')\n extensionSocket = socket\n setExtensionConnected(true)\n\n // NM3: Send session_init with protocol version on connection\n const agentId = getDefaultAgentId()\n createSession(agentId)\n const initMsg = {\n id: randomUUID(),\n type: 'session_init',\n agentId,\n protocolVersion: PROTOCOL_VERSION,\n timestamp: Date.now(),\n }\n socket.write(`${JSON.stringify(initMsg)}\\n`)\n\n // TCP stream fragmentation fix: line-based buffer\n let lineBuffer = ''\n\n socket.on('data', (data) => {\n lineBuffer += data.toString('utf-8')\n const lines = lineBuffer.split('\\n')\n lineBuffer = lines.pop() ?? '' // Keep incomplete last line\n for (const line of lines) {\n if (!line) continue\n try {\n let parsed = JSON.parse(line)\n // NM5: Handle compressed messages from Native Host\n if (parsed.type === 'compressed' && typeof parsed.data === 'string') {\n const decompressed = decompressPayload(parsed.data, true)\n parsed = JSON.parse(decompressed)\n }\n handleExtensionMessage(parsed)\n } catch (error) {\n process.stderr.write(`[viyv-browser:mcp] Parse error: ${(error as Error).message}\\n`)\n }\n }\n })\n\n socket.on('close', () => {\n process.stderr.write('[viyv-browser:mcp] Extension disconnected\\n')\n // Only clear if this is still the active socket\n if (extensionSocket === socket) {\n extensionSocket = null\n setExtensionConnected(false)\n }\n\n // Reject all pending requests on disconnect\n for (const [id, pending] of pendingRequests) {\n clearTimeout(pending.timer)\n pendingRequests.delete(id)\n pending.resolve({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message: 'Extension disconnected while request was pending',\n },\n })\n }\n })\n\n socket.on('error', (error) => {\n process.stderr.write(`[viyv-browser:mcp] Socket error: ${error.message}\\n`)\n })\n })\n\n server.on('error', (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE') {\n process.stderr.write(\n `[viyv-browser:mcp] Socket ${socketPath} already in use, forcing cleanup...\\n`,\n )\n cleanupSocket(socketPath)\n server.listen(socketPath, () => {\n chmodSync(socketPath, 0o666)\n process.stderr.write(`[viyv-browser:mcp] Unix socket listening on ${socketPath} (retry)\\n`)\n })\n } else {\n process.stderr.write(`[viyv-browser:mcp] Server error: ${error.message} (${error.code})\\n`)\n }\n })\n\n server.listen(socketPath, () => {\n chmodSync(socketPath, 0o666)\n process.stderr.write(`[viyv-browser:mcp] Unix socket listening on ${socketPath}\\n`)\n })\n\n return server\n}\n\n// FIX #8: Validate message structure before processing\nfunction handleExtensionMessage(message: unknown) {\n if (!message || typeof message !== 'object') return\n const msg = message as Record<string, unknown>\n\n const type = typeof msg.type === 'string' ? msg.type : null\n const id = typeof msg.id === 'string' ? msg.id : null\n if (!type) return\n\n if (type === 'tool_result' && id) {\n const pending = pendingRequests.get(id)\n if (pending) {\n clearTimeout(pending.timer)\n pendingRequests.delete(id)\n\n if (msg.success) {\n pending.resolve((msg.result as Record<string, unknown>) ?? {})\n } else {\n const err = msg.error as Record<string, unknown> | undefined\n const code = typeof err?.code === 'string' ? err.code : 'UNKNOWN'\n const errMsg = typeof err?.message === 'string' ? err.message : 'Unknown error'\n pending.reject(new Error(`[${code}] ${errMsg}`))\n }\n }\n } else if (type === 'session_heartbeat') {\n recordHeartbeat()\n // NM6: Touch session on heartbeat\n const hbAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (hbAgentId) touchSession(hbAgentId)\n } else if (type === 'session_close') {\n // NH2: Clean up session resources on close\n const closeAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (closeAgentId) {\n closeSession(closeAgentId)\n // L2 FIX: Clean up stale event subscriptions for this agent\n removeSubscriptionsByAgent(closeAgentId)\n process.stderr.write(`[viyv-browser:mcp] Session closed and cleaned up: ${closeAgentId}\\n`)\n }\n } else if (type === 'session_recovery') {\n // NH2: Handle session recovery after SW restart\n const recoveryAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (recoveryAgentId) {\n createSession(recoveryAgentId)\n process.stderr.write(`[viyv-browser:mcp] Session recovered: ${recoveryAgentId}\\n`)\n }\n } else if (type === 'session_init') {\n // L3 FIX: Verify Extension's protocol version (bidirectional check)\n const remoteVersion = typeof msg.protocolVersion === 'string' ? msg.protocolVersion : null\n if (remoteVersion && remoteVersion !== PROTOCOL_VERSION) {\n process.stderr.write(\n `[viyv-browser:mcp] Protocol version mismatch: local=${PROTOCOL_VERSION}, remote=${remoteVersion}\\n`,\n )\n }\n } else if (type === 'browser_event') {\n process.stderr.write(`[viyv-browser:mcp] Browser event: ${String(msg.eventType)}\\n`)\n processEvent({\n eventType: msg.eventType as import('@viyv-browser/shared').BrowserEventType,\n agentId: String(msg.agentId ?? ''),\n tabId: Number(msg.tabId ?? 0),\n url: String(msg.url ?? ''),\n payload: (msg.payload as Record<string, unknown>) ?? {},\n sequenceNumber: Number(msg.sequenceNumber ?? 0),\n })\n }\n}\n\nasync function callExtensionTool(\n tool: string,\n input: Record<string, unknown>,\n): Promise<{ content: ToolContentItem[] }> {\n // browser_health is handled server-side: report connection status without requiring socket\n if (tool === 'browser_health') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(getHealthStatus()),\n },\n ],\n }\n }\n\n // switch_browser is handled server-side: disconnect and wait for reconnection\n if (tool === 'switch_browser') {\n return handleSwitchBrowser()\n }\n\n // file_upload: validate file paths exist before forwarding to extension\n if (tool === 'file_upload') {\n const paths = input.paths as string[] | undefined\n if (paths) {\n for (const p of paths) {\n try {\n if (!existsSync(p) || !statSync(p).isFile()) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'FILE_NOT_FOUND', message: `File not found: ${p}` },\n }),\n },\n ],\n }\n }\n } catch {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'FILE_NOT_FOUND', message: `Cannot access file: ${p}` },\n }),\n },\n ],\n }\n }\n }\n }\n }\n\n if (!extensionSocket || extensionSocket.destroyed) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message:\n 'Chrome Extension is not connected. Please open Chrome and click the Viyv Browser extension icon.',\n },\n }),\n },\n ],\n }\n }\n\n const requestId = randomUUID()\n const agentId = getDefaultAgentId()\n\n // NM6: Touch session to record activity\n touchSession(agentId)\n\n // Capture socket reference before entering Promise to avoid null race\n const sock = extensionSocket\n\n // Per-tool timeout: wait_for gets the tool's timeout + 5s buffer\n let toolTimeout = TIMEOUTS.MCP_TOOL\n if (tool === 'wait_for' && typeof input.timeout === 'number') {\n toolTimeout = input.timeout + 5000\n }\n\n return new Promise((resolve) => {\n // M3 FIX: Define error listener before timer so removeErrorListener is callable from timeout\n const onError = () => {\n const pending = pendingRequests.get(requestId)\n if (pending) {\n clearTimeout(pending.timer)\n pendingRequests.delete(requestId)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message: 'Socket write failed',\n },\n }),\n },\n ],\n })\n }\n }\n\n const removeErrorListener = () => {\n sock.removeListener('error', onError)\n }\n\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId)\n removeErrorListener()\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'TIMEOUT',\n message: `Tool '${tool}' timed out after ${toolTimeout}ms`,\n },\n }),\n },\n ],\n })\n }, toolTimeout)\n\n pendingRequests.set(requestId, {\n resolve: (result) => {\n removeErrorListener()\n if (tool === 'screenshot' && typeof result.data === 'string') {\n const { data, ...metadata } = result\n const mimeType = metadata.format === 'png' ? 'image/png' : 'image/jpeg'\n resolve({\n content: [\n { type: 'image' as const, data: data as string, mimeType },\n { type: 'text' as const, text: JSON.stringify(metadata) },\n ],\n })\n } else {\n resolve({\n content: [{ type: 'text' as const, text: JSON.stringify(result) }],\n })\n }\n },\n reject: (error) => {\n removeErrorListener()\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'CDP_ERROR', message: error.message },\n }),\n },\n ],\n })\n },\n timer,\n })\n\n // FIX #7: Handle socket write errors\n const request = {\n id: requestId,\n type: 'tool_call',\n agentId,\n tool,\n input,\n timestamp: Date.now(),\n }\n\n const written = sock.write(`${JSON.stringify(request)}\\n`)\n if (!written) {\n // Backpressure -- wait for drain but don't block\n sock.once('drain', () => {\n // Buffer flushed, nothing to do\n })\n }\n\n sock.once('error', onError)\n })\n}\n\nasync function handleSwitchBrowser(): Promise<{ content: ToolContentItem[] }> {\n const SWITCH_TIMEOUT = 60_000\n\n // Close existing connection gracefully\n if (extensionSocket && !extensionSocket.destroyed) {\n process.stderr.write('[viyv-browser:mcp] switch_browser: closing current connection\\n')\n extensionSocket.destroy()\n extensionSocket = null\n setExtensionConnected(false)\n }\n\n // Wait for a new connection\n process.stderr.write('[viyv-browser:mcp] switch_browser: waiting for new browser connection...\\n')\n return new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (extensionSocket && !extensionSocket.destroyed && isExtensionConnected()) {\n clearInterval(checkInterval)\n clearTimeout(timer)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n switched: true,\n message: 'Successfully connected to new browser instance.',\n }),\n },\n ],\n })\n }\n }, 500)\n\n const timer = setTimeout(() => {\n clearInterval(checkInterval)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'TIMEOUT',\n message: `No new browser connected within ${SWITCH_TIMEOUT / 1000}s. Please open Chrome and click the Viyv Browser extension icon.`,\n },\n }),\n },\n ],\n })\n }, SWITCH_TIMEOUT)\n })\n}\n\nfunction cleanupSocket(socketPath: string) {\n if (!existsSync(socketPath)) return\n\n try {\n unlinkSync(socketPath)\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'EPERM' || err.code === 'EACCES') {\n process.stderr.write(\n `[viyv-browser:mcp] Cannot remove stale socket (${err.code}), retrying with chmod...\\n`,\n )\n try {\n chmodSync(socketPath, 0o666)\n unlinkSync(socketPath)\n } catch (retryError) {\n process.stderr.write(\n `[viyv-browser:mcp] Failed to remove socket after chmod: ${(retryError as Error).message}\\n`,\n )\n }\n } else if (err.code !== 'ENOENT') {\n process.stderr.write(`[viyv-browser:mcp] Socket cleanup error: ${err.message}\\n`)\n }\n }\n}\n","/**\n * Multi-agent session management.\n * Tracks which agents are connected and their session tokens.\n */\n\nimport { randomUUID } from 'node:crypto'\n\ninterface AgentSessionInfo {\n agentId: string\n sessionToken: string\n agentName: string\n status: 'active' | 'idle' | 'disconnected'\n lastActivity: number\n createdAt: number\n}\n\nconst sessions = new Map<string, AgentSessionInfo>()\nlet configuredDefaultAgentId = 'default'\n\nexport function setDefaultAgentId(id: string): void {\n configuredDefaultAgentId = id\n}\n\nexport function createSession(agentId: string, agentName?: string): AgentSessionInfo {\n const existing = sessions.get(agentId)\n if (existing) {\n existing.lastActivity = Date.now()\n existing.status = 'active'\n return existing\n }\n\n const session: AgentSessionInfo = {\n agentId,\n sessionToken: randomUUID(),\n agentName: agentName ?? agentId,\n status: 'active',\n lastActivity: Date.now(),\n createdAt: Date.now(),\n }\n\n sessions.set(agentId, session)\n return session\n}\n\nexport function getSession(agentId: string): AgentSessionInfo | undefined {\n return sessions.get(agentId)\n}\n\nexport function validateSession(agentId: string, sessionToken: string): boolean {\n const session = sessions.get(agentId)\n return session?.sessionToken === sessionToken\n}\n\nexport function touchSession(agentId: string): void {\n const session = sessions.get(agentId)\n if (session) {\n session.lastActivity = Date.now()\n }\n}\n\nexport function closeSession(agentId: string): void {\n sessions.delete(agentId)\n}\n\nexport function listSessions(): AgentSessionInfo[] {\n return Array.from(sessions.values())\n}\n\nexport function getDefaultAgentId(): string {\n // Return the first active session, or create a default\n const active = Array.from(sessions.values()).find((s) => s.status === 'active')\n if (active) return active.agentId\n\n const defaultSession = createSession(configuredDefaultAgentId)\n return defaultSession.agentId\n}\n\nconst STALE_SESSION_TTL = 5 * 60 * 1000 // 5 minutes\nconst CLEANUP_INTERVAL = 60 * 1000 // Check every minute\n\nexport function cleanupStaleSessions(): number {\n const now = Date.now()\n let cleaned = 0\n for (const [agentId, session] of sessions) {\n if (now - session.lastActivity > STALE_SESSION_TTL) {\n sessions.delete(agentId)\n cleaned++\n }\n }\n if (cleaned > 0) {\n process.stderr.write(`[viyv-browser:mcp] Cleaned up ${cleaned} stale session(s)\\n`)\n }\n return cleaned\n}\n\n// Periodic stale session cleanup\nconst cleanupTimer = setInterval(cleanupStaleSessions, CLEANUP_INTERVAL)\ncleanupTimer.unref() // Don't prevent process from exiting\n","/**\n * Event bridge: forwards browser events from Extension to stdout\n * for consumption by viyv Daemon EventTriggerManager.\n */\n\nimport type { BrowserEventType, EventSubscription } from '@viyv-browser/shared'\n\nconst subscriptions = new Map<string, EventSubscription>()\nconst eventListeners = new Set<(event: Record<string, unknown>) => void>()\n\nexport function addEventListener(cb: (event: Record<string, unknown>) => void) {\n eventListeners.add(cb)\n}\n\nexport function removeEventListener(cb: (event: Record<string, unknown>) => void) {\n eventListeners.delete(cb)\n}\n\nexport function addSubscription(sub: EventSubscription): void {\n subscriptions.set(sub.id, sub)\n}\n\nexport function removeSubscription(subId: string): boolean {\n return subscriptions.delete(subId)\n}\n\n// L2 FIX: Remove all subscriptions for an agent on session close\nexport function removeSubscriptionsByAgent(agentId: string): number {\n let removed = 0\n for (const [id, sub] of subscriptions) {\n if (sub.agentId === agentId) {\n subscriptions.delete(id)\n removed++\n }\n }\n return removed\n}\n\nexport function getSubscriptions(agentId?: string): EventSubscription[] {\n const subs = Array.from(subscriptions.values())\n if (agentId) return subs.filter((s) => s.agentId === agentId)\n return subs\n}\n\nexport function processEvent(event: {\n eventType: BrowserEventType\n agentId: string\n tabId: number\n url: string\n payload: Record<string, unknown>\n sequenceNumber: number\n}): void {\n // Check subscriptions\n for (const sub of subscriptions.values()) {\n if (sub.agentId !== event.agentId) continue\n if (!sub.eventTypes.includes(event.eventType)) continue\n if (sub.urlPattern && !event.url.includes(sub.urlPattern)) continue\n\n // Forward to all listeners\n const payload = {\n type: 'browser_event',\n subscriptionId: sub.id,\n ...event,\n timestamp: Date.now(),\n }\n for (const listener of eventListeners) {\n listener(payload)\n }\n }\n}\n","/**\n * Health check for MCP Server ↔ Extension connection.\n */\n\nlet extensionConnected = false\nlet lastHeartbeat: number | null = null\n\nexport function setExtensionConnected(connected: boolean) {\n extensionConnected = connected\n if (connected) lastHeartbeat = Date.now()\n}\n\nexport function recordHeartbeat() {\n lastHeartbeat = Date.now()\n}\n\nconst HEARTBEAT_STALENESS_MS = 60_000\n\nexport function isExtensionConnected(): boolean {\n if (!extensionConnected) return false\n // Also verify heartbeat is within staleness threshold\n if (lastHeartbeat !== null && Date.now() - lastHeartbeat > HEARTBEAT_STALENESS_MS) {\n return false\n }\n return true\n}\n\nexport function getHealthStatus() {\n return {\n extensionConnected,\n lastHeartbeat,\n uptime: process.uptime(),\n memoryUsage: process.memoryUsage().heapUsed,\n }\n}\n","/**\n * Tool registry: defines all MCP tools and their schemas.\n */\n\nimport { z } from 'zod'\n\nimport { FILE_UPLOAD_DESCRIPTION } from './advanced/file-upload.js'\nimport { GIF_CREATOR_DESCRIPTION } from './advanced/gif-creator.js'\nimport { RESIZE_WINDOW_DESCRIPTION } from './advanced/resize-window.js'\nimport { SHORTCUTS_EXECUTE_DESCRIPTION } from './advanced/shortcuts-execute.js'\nimport { SHORTCUTS_LIST_DESCRIPTION } from './advanced/shortcuts-list.js'\nimport { SWITCH_BROWSER_DESCRIPTION } from './advanced/switch-browser.js'\nimport { UPDATE_PLAN_DESCRIPTION } from './advanced/update-plan.js'\nimport { UPLOAD_IMAGE_DESCRIPTION } from './advanced/upload-image.js'\nimport { CLICK_DESCRIPTION } from './core/click.js'\nimport { DRAG_DESCRIPTION } from './core/drag.js'\nimport { FIND_DESCRIPTION } from './core/find.js'\nimport { FORM_INPUT_DESCRIPTION } from './core/form-input.js'\nimport { GET_PAGE_TEXT_DESCRIPTION } from './core/get-page-text.js'\nimport { HANDLE_DIALOG_DESCRIPTION } from './core/handle-dialog.js'\nimport { HOVER_DESCRIPTION } from './core/hover.js'\nimport { JAVASCRIPT_EXEC_DESCRIPTION } from './core/javascript-exec.js'\nimport { KEY_DESCRIPTION } from './core/key.js'\nimport { NAVIGATE_DESCRIPTION } from './core/navigate.js'\nimport { READ_PAGE_DESCRIPTION } from './core/read-page.js'\nimport { SCREENSHOT_DESCRIPTION } from './core/screenshot.js'\nimport { SCROLL_DESCRIPTION } from './core/scroll.js'\nimport { TYPE_DESCRIPTION } from './core/type.js'\nimport { WAIT_FOR_DESCRIPTION } from './core/wait-for.js'\nimport { READ_CONSOLE_MESSAGES_DESCRIPTION } from './debug/read-console-messages.js'\nimport { READ_NETWORK_REQUESTS_DESCRIPTION } from './debug/read-network-requests.js'\nimport { SM_ADD_ACTION_DESCRIPTION } from './semantic/sm-add-action.js'\nimport { SM_ADD_FETCH_DESCRIPTION } from './semantic/sm-add-fetch.js'\nimport { SM_ADD_TARGET_DESCRIPTION } from './semantic/sm-add-target.js'\nimport { SM_CAPABILITIES_DESCRIPTION } from './semantic/sm-capabilities.js'\nimport {\n SM_CUSTOM_VIEW_CREATE_DESCRIPTION,\n SM_CUSTOM_VIEW_DELETE_DESCRIPTION,\n SM_CUSTOM_VIEW_GET_DESCRIPTION,\n SM_CUSTOM_VIEW_LIST_DESCRIPTION,\n SM_CUSTOM_VIEW_UPDATE_DESCRIPTION,\n} from './semantic/sm-custom-view.js'\nimport { SM_DELETE_DESCRIPTION } from './semantic/sm-delete.js'\nimport { SM_EXPORT_DESCRIPTION } from './semantic/sm-export.js'\nimport { SM_FETCH_DESCRIPTION } from './semantic/sm-fetch.js'\nimport { SM_IMPORT_DESCRIPTION } from './semantic/sm-import.js'\nimport { SM_INVOKE_DESCRIPTION } from './semantic/sm-invoke.js'\nimport { SM_JOB_CANCEL_DESCRIPTION } from './semantic/sm-job-cancel.js'\nimport { SM_JOB_CREATE_DESCRIPTION } from './semantic/sm-job-create.js'\nimport { SM_JOB_DELETE_DESCRIPTION } from './semantic/sm-job-delete.js'\nimport {\n SM_JOB_COMPARE_DESCRIPTION,\n SM_JOB_HISTORY_DESCRIPTION,\n SM_JOB_SNAPSHOT_GET_DESCRIPTION,\n} from './semantic/sm-job-history.js'\nimport { SM_JOB_LIST_DESCRIPTION } from './semantic/sm-job-list.js'\nimport { SM_JOB_REPORT_EXPORT_DESCRIPTION } from './semantic/sm-job-report-export.js'\nimport { SM_JOB_REPORT_GET_DESCRIPTION } from './semantic/sm-job-report-get.js'\nimport { SM_JOB_RUN_DESCRIPTION } from './semantic/sm-job-run.js'\nimport { SM_JOB_UPDATE_DESCRIPTION } from './semantic/sm-job-update.js'\nimport { SM_REGISTER_PAGE_DESCRIPTION } from './semantic/sm-register-page.js'\nimport { SM_REPORT_DELETE_DESCRIPTION } from './semantic/sm-report-delete.js'\nimport { SM_REPORT_EXPORT_DESCRIPTION } from './semantic/sm-report-export.js'\nimport { SM_REPORT_GET_DESCRIPTION } from './semantic/sm-report-get.js'\nimport { SM_REPORT_LIST_DESCRIPTION } from './semantic/sm-report-list.js'\nimport { SM_SCENARIO_CREATE_DESCRIPTION } from './semantic/sm-scenario-create.js'\nimport { SM_SCENARIO_DELETE_DESCRIPTION } from './semantic/sm-scenario-delete.js'\nimport { SM_SCENARIO_LIST_DESCRIPTION } from './semantic/sm-scenario-list.js'\nimport { SM_SCENARIO_RUN_DESCRIPTION } from './semantic/sm-scenario-run.js'\nimport { SM_SCENARIO_UPDATE_DESCRIPTION } from './semantic/sm-scenario-update.js'\nimport { SM_STATUS_DESCRIPTION } from './semantic/sm-status.js'\nimport { SM_TEST_TARGET_DESCRIPTION } from './semantic/sm-test-target.js'\nimport { SELECT_TAB_DESCRIPTION } from './tabs/select-tab.js'\nimport { TAB_CLOSE_DESCRIPTION } from './tabs/tab-close.js'\nimport { TABS_CONTEXT_DESCRIPTION } from './tabs/tabs-context.js'\nimport { TABS_CREATE_DESCRIPTION } from './tabs/tabs-create.js'\nimport { AGENT_TAB_ASSIGN_DESCRIPTION } from './viyv/agent-tab-assign.js'\nimport { AGENT_TAB_LIST_DESCRIPTION } from './viyv/agent-tab-list.js'\nimport { ARTIFACT_FROM_PAGE_DESCRIPTION } from './viyv/artifact-from-page.js'\nimport { BROWSER_EVENT_SUBSCRIBE_DESCRIPTION } from './viyv/browser-event-subscribe.js'\nimport { BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION } from './viyv/browser-event-unsubscribe.js'\nimport { BROWSER_HEALTH_DESCRIPTION } from './viyv/browser-health.js'\nimport { PAGE_DATA_EXTRACT_DESCRIPTION } from './viyv/page-data-extract.js'\n\nexport interface ToolDefinition {\n name: string\n description: string\n inputSchema: z.ZodType\n}\n\n// ── Core Browser Tools ──\n\nexport const navigateTool: ToolDefinition = {\n name: 'navigate',\n description: NAVIGATE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to navigate'),\n url: z.string().describe('URL to navigate to, or \"back\"/\"forward\" for history'),\n }),\n}\n\nexport const screenshotTool: ToolDefinition = {\n name: 'screenshot',\n description: SCREENSHOT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to capture'),\n format: z.enum(['jpeg', 'png']).optional().describe('Image format (default: jpeg)'),\n quality: z.coerce.number().min(1).max(100).optional().describe('JPEG quality (default: 80)'),\n region: z\n .tuple([z.coerce.number(), z.coerce.number(), z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Capture region [x0, y0, x1, y1]'),\n ref: z\n .string()\n .optional()\n .describe(\n 'Element reference ID from read_page or find. Captures only that element with padding. Ignored if region is also provided.',\n ),\n }),\n}\n\nexport const clickTool: ToolDefinition = {\n name: 'click',\n description: CLICK_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Click position [x, y]'),\n ref: z.string().optional().describe('Element reference ID'),\n action: z\n .enum(['left_click', 'right_click', 'double_click', 'triple_click'])\n .optional()\n .describe('Click type (default: left_click)'),\n modifiers: z.string().optional().describe('Modifier keys (e.g., \"ctrl+shift\")'),\n }),\n}\n\nexport const typeTool: ToolDefinition = {\n name: 'type',\n description: TYPE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n text: z.string().describe('Text to type'),\n }),\n}\n\nexport const keyTool: ToolDefinition = {\n name: 'key',\n description: KEY_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n keys: z.string().describe('Space-separated keys (e.g., \"Enter\", \"ctrl+a\")'),\n repeat: z.coerce.number().min(1).max(100).optional().describe('Repeat count'),\n }),\n}\n\nexport const scrollTool: ToolDefinition = {\n name: 'scroll',\n description: SCROLL_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Scroll position [x, y] (required for directional scroll)'),\n direction: z\n .enum(['up', 'down', 'left', 'right'])\n .optional()\n .describe('Scroll direction (required for directional scroll)'),\n amount: z.coerce.number().min(1).max(10).optional().describe('Scroll amount (default: 3)'),\n ref: z.string().optional().describe('Element reference ID to scroll into view'),\n }),\n}\n\nexport const hoverTool: ToolDefinition = {\n name: 'hover',\n description: HOVER_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Hover position [x, y]'),\n ref: z.string().optional().describe('Element reference ID'),\n }),\n}\n\nexport const dragTool: ToolDefinition = {\n name: 'drag',\n description: DRAG_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n startCoordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .describe('Start position [x, y]'),\n endCoordinate: z.tuple([z.coerce.number(), z.coerce.number()]).describe('End position [x, y]'),\n }),\n}\n\nexport const readPageTool: ToolDefinition = {\n name: 'read_page',\n description: READ_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n filter: z\n .enum(['interactive', 'all'])\n .optional()\n .describe('Filter: \"interactive\" for buttons/links/inputs, \"all\" for everything'),\n depth: z.coerce.number().min(1).max(20).optional().describe('Max tree depth (default: 15)'),\n refId: z.string().optional().describe('Focus on a specific element by ref'),\n maxChars: z.coerce.number().optional().describe('Max output characters (default: 50000)'),\n }),\n}\n\nexport const findTool: ToolDefinition = {\n name: 'find',\n description: FIND_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n query: z.string().describe('Natural language description of what to find'),\n }),\n}\n\nexport const formInputTool: ToolDefinition = {\n name: 'form_input',\n description: FORM_INPUT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n ref: z.string().describe('Element reference ID'),\n value: z.union([z.string(), z.boolean(), z.coerce.number()]).describe('Value to set'),\n }),\n}\n\nexport const javascriptExecTool: ToolDefinition = {\n name: 'javascript_exec',\n description: JAVASCRIPT_EXEC_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n code: z.string().describe('JavaScript code to execute'),\n }),\n}\n\nexport const waitForTool: ToolDefinition = {\n name: 'wait_for',\n description: WAIT_FOR_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n selector: z.string().optional().describe('CSS selector to wait for'),\n navigation: z.boolean().optional().describe('Wait for navigation to complete'),\n timeout: z.coerce.number().optional().describe('Timeout in ms (default: 30000)'),\n }),\n}\n\nexport const getPageTextTool: ToolDefinition = {\n name: 'get_page_text',\n description: GET_PAGE_TEXT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n }),\n}\n\nexport const handleDialogTool: ToolDefinition = {\n name: 'handle_dialog',\n description: HANDLE_DIALOG_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action: z.enum(['accept', 'dismiss']).describe('Dialog action'),\n text: z.string().optional().describe('Text for prompt dialog'),\n }),\n}\n\n// ── Tab Management Tools ──\n\nexport const tabsContextTool: ToolDefinition = {\n name: 'tabs_context',\n description: TABS_CONTEXT_DESCRIPTION,\n inputSchema: z.object({\n createIfEmpty: z.boolean().optional().describe('Create a new tab group if none exists'),\n }),\n}\n\nexport const tabsCreateTool: ToolDefinition = {\n name: 'tabs_create',\n description: TABS_CREATE_DESCRIPTION,\n inputSchema: z.object({\n url: z.string().optional().describe('URL to open in the new tab'),\n }),\n}\n\nexport const tabCloseTool: ToolDefinition = {\n name: 'tab_close',\n description: TAB_CLOSE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to close'),\n }),\n}\n\nexport const selectTabTool: ToolDefinition = {\n name: 'select_tab',\n description: SELECT_TAB_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to focus'),\n }),\n}\n\n// ── Debug Tools ──\n\nexport const readConsoleMessagesTool: ToolDefinition = {\n name: 'read_console_messages',\n description: READ_CONSOLE_MESSAGES_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n pattern: z.string().optional().describe('Regex pattern to filter messages'),\n onlyErrors: z.boolean().optional().describe('Only return errors'),\n limit: z.coerce.number().optional().describe('Max messages to return (default: 100)'),\n clear: z.boolean().optional().describe('Clear messages after reading'),\n }),\n}\n\nexport const readNetworkRequestsTool: ToolDefinition = {\n name: 'read_network_requests',\n description: READ_NETWORK_REQUESTS_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n urlPattern: z.string().optional().describe('URL pattern to filter requests'),\n limit: z.coerce.number().optional().describe('Max requests to return (default: 100)'),\n clear: z.boolean().optional().describe('Clear requests after reading'),\n }),\n}\n\n// ── Advanced Tools ──\n\nexport const gifCreatorTool: ToolDefinition = {\n name: 'gif_creator',\n description: GIF_CREATOR_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action: z.enum(['start_recording', 'stop_recording', 'export', 'clear']).describe('GIF action'),\n filename: z.string().optional().describe('Filename for export'),\n options: z\n .object({\n showClickIndicators: z.boolean().optional(),\n showDragPaths: z.boolean().optional(),\n showActionLabels: z.boolean().optional(),\n showProgressBar: z.boolean().optional(),\n showWatermark: z.boolean().optional(),\n quality: z.coerce.number().min(1).max(30).optional(),\n })\n .optional()\n .describe('GIF rendering options'),\n download: z.boolean().optional().describe('Download the GIF'),\n }),\n}\n\nexport const uploadImageTool: ToolDefinition = {\n name: 'upload_image',\n description: UPLOAD_IMAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n imageId: z.string().describe('Image ID from a previous screenshot'),\n ref: z.string().optional().describe('Element reference for file input'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Coordinates for drag & drop'),\n filename: z\n .string()\n .optional()\n .describe('Filename for the uploaded file (default: \"image.png\")'),\n }),\n}\n\nexport const updatePlanTool: ToolDefinition = {\n name: 'update_plan',\n description: UPDATE_PLAN_DESCRIPTION,\n inputSchema: z.object({\n domains: z.array(z.string()).describe('Domains to visit'),\n approach: z.array(z.string()).describe('Steps in the plan'),\n }),\n}\n\nexport const resizeWindowTool: ToolDefinition = {\n name: 'resize_window',\n description: RESIZE_WINDOW_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n width: z.coerce.number().describe('Window width in pixels'),\n height: z.coerce.number().describe('Window height in pixels'),\n }),\n}\n\nexport const shortcutsListTool: ToolDefinition = {\n name: 'shortcuts_list',\n description: SHORTCUTS_LIST_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().optional().describe('Tab ID (used to identify the tab group context)'),\n }),\n}\n\nexport const shortcutsExecuteTool: ToolDefinition = {\n name: 'shortcuts_execute',\n description: SHORTCUTS_EXECUTE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to execute the shortcut on'),\n command: z.string().optional().describe('Command name of the shortcut'),\n shortcutId: z.string().optional().describe('ID of the shortcut'),\n }),\n}\n\nexport const switchBrowserTool: ToolDefinition = {\n name: 'switch_browser',\n description: SWITCH_BROWSER_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const fileUploadTool: ToolDefinition = {\n name: 'file_upload',\n description: FILE_UPLOAD_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n ref: z.string().describe('Element reference ID of the file input'),\n paths: z.array(z.string()).min(1).describe('Absolute file paths to upload'),\n }),\n}\n\n// ── viyv Integration Tools ──\n\nexport const agentTabAssignTool: ToolDefinition = {\n name: 'agent_tab_assign',\n description: AGENT_TAB_ASSIGN_DESCRIPTION,\n inputSchema: z.object({\n agentId: z.string().describe('Agent ID'),\n agentName: z.string().describe('Display name'),\n color: z.string().optional().describe('Tab group color'),\n }),\n}\n\nexport const agentTabListTool: ToolDefinition = {\n name: 'agent_tab_list',\n description: AGENT_TAB_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const browserEventSubscribeTool: ToolDefinition = {\n name: 'browser_event_subscribe',\n description: BROWSER_EVENT_SUBSCRIBE_DESCRIPTION,\n inputSchema: z.object({\n eventTypes: z.array(z.string()).describe('Event types to subscribe to'),\n urlPattern: z.string().optional().describe('URL pattern filter'),\n conditions: z.record(z.unknown()).optional().describe('Additional conditions'),\n }),\n}\n\nexport const browserEventUnsubscribeTool: ToolDefinition = {\n name: 'browser_event_unsubscribe',\n description: BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION,\n inputSchema: z.object({\n subscriptionId: z.string().describe('Subscription ID'),\n }),\n}\n\nexport const artifactFromPageTool: ToolDefinition = {\n name: 'artifact_from_page',\n description: ARTIFACT_FROM_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n type: z.string().describe('Artifact type (text, html, screenshot)'),\n title: z.string().optional().describe('Artifact title'),\n }),\n}\n\nexport const pageDataExtractTool: ToolDefinition = {\n name: 'page_data_extract',\n description: PAGE_DATA_EXTRACT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n schema: z.record(z.unknown()).describe('Data extraction schema'),\n selector: z.string().optional().describe('CSS selector to scope extraction'),\n }),\n}\n\nexport const browserHealthTool: ToolDefinition = {\n name: 'browser_health',\n description: BROWSER_HEALTH_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\n// ── Semantic Tools ──\n\nexport const smCapabilitiesTool: ToolDefinition = {\n name: 'sm_capabilities',\n description: SM_CAPABILITIES_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n }),\n}\n\nexport const smInvokeTool: ToolDefinition = {\n name: 'sm_invoke',\n description: SM_INVOKE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action_id: z.string().describe('Action ID to execute'),\n params: z.record(z.unknown()).optional().describe('Parameters for template substitution'),\n }),\n}\n\nexport const smFetchTool: ToolDefinition = {\n name: 'sm_fetch',\n description: SM_FETCH_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n fetch_id: z.string().describe('Fetch definition ID to execute'),\n params: z.record(z.unknown()).optional().describe('Optional parameters'),\n }),\n}\n\nexport const smRegisterPageTool: ToolDefinition = {\n name: 'sm_register_page',\n description: SM_REGISTER_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Target tab'),\n label: z.string().describe('Page name (e.g., \"GitHub Login\")'),\n page_type: z\n .string()\n .optional()\n .describe(\n 'Page type within the domain (e.g., \"profile\", \"compose\", \"search\"). Used for grouping pages.',\n ),\n url_pattern: z.string().optional().describe('URL regex (auto-derived from tab URL if omitted)'),\n domains: z.array(z.string()).optional().describe('Domain scope (auto-derived if omitted)'),\n auth_state: z\n .enum(['logged_in', 'logged_out', 'any'])\n .optional()\n .describe('Auth state (default: any)'),\n must_exist: z.array(z.string()).optional().describe('Required CSS selectors'),\n must_not_exist: z.array(z.string()).optional().describe('Forbidden CSS selectors'),\n title_regex: z.string().optional().describe('Title regex'),\n }),\n}\n\nexport const smAddTargetTool: ToolDefinition = {\n name: 'sm_add_target',\n description: SM_ADD_TARGET_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Target tab where elements are present'),\n page_id: z.string().describe('Page ID these targets belong to'),\n targets: z\n .array(\n z.object({\n target_id: z.string().optional().describe('Existing target ID for re-bind'),\n label: z.string().describe('Target name'),\n role: z.string().describe('Semantic role (e.g., \"textbox\", \"button\")'),\n ref: z.string().optional().describe('Element ref from read_page/find'),\n locators: z\n .array(\n z.object({\n type: z.string().describe('Locator type'),\n value: z.string().describe('Locator value'),\n stability: z.enum(['high', 'medium', 'low']).describe('Stability level'),\n }),\n )\n .optional()\n .describe('Explicit locators'),\n }),\n )\n .min(1)\n .describe('Target definitions'),\n }),\n}\n\nexport const smAddActionTool: ToolDefinition = {\n name: 'sm_add_action',\n description: SM_ADD_ACTION_DESCRIPTION,\n inputSchema: z.object({\n page_id: z.string().describe('Page ID'),\n label: z.string().describe('Action name'),\n verb: z.string().describe('Action verb (e.g., \"login\", \"submit\")'),\n description: z.string().optional().describe('LLM-facing description'),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional()\n .describe('Parameter definitions'),\n steps: z\n .array(\n z.object({\n type: z\n .enum(['click', 'type', 'select', 'wait', 'scroll', 'key', 'navigate', 'file_upload'])\n .describe('Step type'),\n target_id: z.string().optional().describe('Target to act on'),\n params: z\n .object({\n text: z.string().optional(),\n value: z.string().optional(),\n keys: z.string().optional(),\n direction: z.enum(['up', 'down', 'left', 'right']).optional(),\n amount: z.coerce.number().optional(),\n url: z.string().optional(),\n param_ref: z.string().optional(),\n file_paths: z\n .array(z.string())\n .optional()\n .describe('File paths for file_upload step'),\n })\n .optional()\n .describe('Step parameters'),\n pre_wait: z\n .object({\n strategy: z.enum(['selector', 'navigation', 'time']),\n selector: z.string().optional(),\n timeout_ms: z.coerce.number().default(5000),\n })\n .optional()\n .describe('Pre-step wait rule'),\n description: z.string().optional(),\n }),\n )\n .min(1)\n .describe('Step sequence'),\n retry_policy: z\n .object({\n max_retries: z.coerce.number().min(0).max(5).optional(),\n backoff: z.enum(['fixed', 'exponential']).optional(),\n base_delay_ms: z.coerce.number().min(100).max(10000).optional(),\n jitter: z.boolean().optional(),\n })\n .optional()\n .describe('Retry policy'),\n }),\n}\n\nexport const smAddFetchTool: ToolDefinition = {\n name: 'sm_add_fetch',\n description: SM_ADD_FETCH_DESCRIPTION,\n inputSchema: z.object({\n page_id: z.string().describe('Page ID'),\n label: z.string().describe('Fetch name'),\n type_name: z.string().describe('Output type name (e.g., \"posts\")'),\n description: z\n .string()\n .optional()\n .describe('LLM-facing description for discovery via sm_capabilities'),\n fields: z\n .array(\n z.object({\n name: z.string().describe('Output field name'),\n target_id: z.string().describe('Target element'),\n extraction_type: z\n .enum(['text', 'attribute', 'list', 'count', 'exists'])\n .describe('Extraction type'),\n attribute: z.string().optional().describe('Attribute name (for attribute type)'),\n item_selector: z.string().optional().describe('List item CSS selector'),\n item_fields: z\n .array(\n z.object({\n name: z.string(),\n selector: z\n .string()\n .describe(\n 'CSS selector relative to each list item (use \":scope\" for item itself)',\n ),\n extraction_type: z.enum(['text', 'attribute', 'exists']),\n attribute: z.string().optional(),\n }),\n )\n .optional()\n .describe('Nested fields for structured list item extraction'),\n }),\n )\n .min(1)\n .describe('Extraction fields'),\n limits: z\n .object({\n max_chars: z.coerce.number().min(1000).max(200000).optional(),\n max_items: z.coerce.number().min(1).max(1000).optional(),\n })\n .optional()\n .describe('Output limits'),\n }),\n}\n\nexport const smStatusTool: ToolDefinition = {\n name: 'sm_status',\n description: SM_STATUS_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().optional().describe('Tab ID (required for test_resolve)'),\n page_id: z.string().optional().describe('Filter by page ID'),\n domain: z.string().optional().describe('Filter results to pages matching this domain'),\n test_resolve: z.boolean().optional().describe('Test-resolve all targets'),\n }),\n}\n\nexport const smTestTargetTool: ToolDefinition = {\n name: 'sm_test_target',\n description: SM_TEST_TARGET_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n target_id: z.string().describe('Target ID to test'),\n }),\n}\n\nexport const smDeleteTool: ToolDefinition = {\n name: 'sm_delete',\n description: SM_DELETE_DESCRIPTION,\n inputSchema: z.object({\n entity_type: z.enum(['page', 'target', 'action', 'fetch']).describe('Entity type'),\n entity_id: z.string().describe('Entity ID to delete'),\n dry_run: z.boolean().optional().describe('Preview impact without deleting'),\n }),\n}\n\nexport const smExportTool: ToolDefinition = {\n name: 'sm_export',\n description: SM_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n domain: z\n .string()\n .optional()\n .describe('Export only pages matching this domain (subdomain-aware). Omit for all.'),\n }),\n}\n\nexport const smImportTool: ToolDefinition = {\n name: 'sm_import',\n description: SM_IMPORT_DESCRIPTION,\n inputSchema: z.object({\n data: z\n .object({\n schema_version: z.string(),\n checksum: z.string(),\n exported_at: z.coerce.number().optional(),\n source: z.record(z.unknown()).optional(),\n pages: z.array(z.record(z.unknown())),\n targets: z.array(z.record(z.unknown())).optional(),\n actions: z.array(z.record(z.unknown())).optional(),\n fetches: z.array(z.record(z.unknown())).optional(),\n })\n .passthrough()\n .describe('SemanticExport JSON object from sm_export'),\n strategy: z\n .enum(['merge', 'replace-domain'])\n .optional()\n .describe('\"merge\" (default) or \"replace-domain\"'),\n }),\n}\n\n// ── Scenario & Report Tools ──\n\nconst scenarioStepSchema: z.ZodType = z.lazy(() =>\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('navigate'),\n label: z.string().optional(),\n url: z.string(),\n wait_for_load: z.boolean().optional(),\n }),\n z.object({\n type: z.literal('action'),\n label: z.string().optional(),\n action_id: z.string(),\n params: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal('fetch'),\n label: z.string().optional(),\n fetch_id: z.string(),\n result_key: z.string(),\n params: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal('loop'),\n label: z.string().optional(),\n variables: z.array(\n z.object({\n name: z.string(),\n source: z.enum(['static', 'target_options', 'previous_fetch']),\n values: z.array(z.string()).optional(),\n target_id: z.string().optional(),\n fetch_result_key: z.string().optional(),\n field_name: z.string().optional(),\n }),\n ),\n steps: z.array(scenarioStepSchema),\n delay_between_ms: z.coerce.number().optional(),\n max_iterations: z.coerce.number().min(1).max(500).optional(),\n }),\n z.object({\n type: z.literal('wait'),\n label: z.string().optional(),\n strategy: z.enum(['time', 'selector', 'navigation']),\n selector: z.string().optional(),\n timeout_ms: z.coerce.number(),\n }),\n ]),\n)\n\nexport const smScenarioCreateTool: ToolDefinition = {\n name: 'sm_scenario_create',\n description: SM_SCENARIO_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().describe('Scenario name'),\n description: z.string().optional().describe('LLM-facing description'),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional()\n .describe('Global parameter definitions'),\n steps: z.array(scenarioStepSchema).min(1).describe('Step sequence'),\n max_duration_ms: z.coerce.number().optional().describe('Timeout in ms (default: 300000)'),\n on_error: z\n .enum(['stop', 'skip_and_continue'])\n .optional()\n .describe('Error handling (default: stop)'),\n }),\n}\n\nexport const smScenarioUpdateTool: ToolDefinition = {\n name: 'sm_scenario_update',\n description: SM_SCENARIO_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().describe('Scenario ID to update'),\n label: z.string().optional(),\n description: z.string().optional(),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional(),\n steps: z.array(scenarioStepSchema).optional(),\n max_duration_ms: z.coerce.number().optional(),\n on_error: z.enum(['stop', 'skip_and_continue']).optional(),\n }),\n}\n\nexport const smScenarioDeleteTool: ToolDefinition = {\n name: 'sm_scenario_delete',\n description: SM_SCENARIO_DELETE_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().describe('Scenario ID to delete'),\n }),\n}\n\nexport const smScenarioListTool: ToolDefinition = {\n name: 'sm_scenario_list',\n description: SM_SCENARIO_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smScenarioRunTool: ToolDefinition = {\n name: 'sm_scenario_run',\n description: SM_SCENARIO_RUN_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID for execution'),\n scenario_id: z.string().describe('Scenario to execute'),\n params: z.record(z.unknown()).optional().describe('Parameter values'),\n wait_for_completion: z\n .boolean()\n .optional()\n .describe('Wait for completion (default: false, async)'),\n }),\n}\n\nexport const smReportListTool: ToolDefinition = {\n name: 'sm_report_list',\n description: SM_REPORT_LIST_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().optional().describe('Filter by scenario ID'),\n }),\n}\n\nexport const smReportGetTool: ToolDefinition = {\n name: 'sm_report_get',\n description: SM_REPORT_GET_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to retrieve'),\n }),\n}\n\nexport const smReportDeleteTool: ToolDefinition = {\n name: 'sm_report_delete',\n description: SM_REPORT_DELETE_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to delete'),\n }),\n}\n\nexport const smReportExportTool: ToolDefinition = {\n name: 'sm_report_export',\n description: SM_REPORT_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to export'),\n format: z.enum(['json', 'csv']).optional().describe('Export format (default: json)'),\n }),\n}\n\n// ── Job Tools ──\n\nconst jobEntrySchema = z.object({\n scenario_id: z.string().describe('Scenario ID to execute'),\n label: z.string().optional().describe('Display label override'),\n params: z.record(z.unknown()).optional().default({}).describe('Scenario parameter overrides'),\n})\n\nexport const smJobCreateTool: ToolDefinition = {\n name: 'sm_job_create',\n description: SM_JOB_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().min(1).describe('Job name'),\n description: z.string().optional().describe('Job description'),\n entries: z.array(jobEntrySchema).min(1).describe('Ordered list of scenarios to execute'),\n on_error: z\n .enum(['stop', 'skip_and_continue'])\n .optional()\n .describe('How to handle scenario failures (default: stop)'),\n }),\n}\n\nexport const smJobUpdateTool: ToolDefinition = {\n name: 'sm_job_update',\n description: SM_JOB_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to update'),\n label: z.string().optional(),\n description: z.string().optional(),\n entries: z.array(jobEntrySchema).min(1).optional(),\n on_error: z.enum(['stop', 'skip_and_continue']).optional(),\n }),\n}\n\nexport const smJobDeleteTool: ToolDefinition = {\n name: 'sm_job_delete',\n description: SM_JOB_DELETE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to delete'),\n }),\n}\n\nexport const smJobListTool: ToolDefinition = {\n name: 'sm_job_list',\n description: SM_JOB_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smJobRunTool: ToolDefinition = {\n name: 'sm_job_run',\n description: SM_JOB_RUN_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to execute scenarios on'),\n job_id: z.string().describe('Job ID to execute'),\n params: z\n .record(z.record(z.unknown()))\n .optional()\n .describe('Per-scenario param overrides keyed by scenario_id'),\n wait_for_completion: z\n .boolean()\n .optional()\n .describe('Wait for all scenarios to complete (default: false)'),\n }),\n}\n\nexport const smJobCancelTool: ToolDefinition = {\n name: 'sm_job_cancel',\n description: SM_JOB_CANCEL_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID where the job is running'),\n }),\n}\n\nexport const smJobReportGetTool: ToolDefinition = {\n name: 'sm_job_report_get',\n description: SM_JOB_REPORT_GET_DESCRIPTION,\n inputSchema: z.object({\n job_report_id: z.string().describe('Job report ID to retrieve'),\n }),\n}\n\nexport const smJobReportExportTool: ToolDefinition = {\n name: 'sm_job_report_export',\n description: SM_JOB_REPORT_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n job_report_id: z.string().describe('Job report ID to export'),\n format: z.enum(['json', 'csv']).optional().describe('Export format (default: json)'),\n }),\n}\n\n// ── Job History Tools ──\n\nexport const smJobHistoryTool: ToolDefinition = {\n name: 'sm_job_history',\n description: SM_JOB_HISTORY_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to get history for'),\n limit: z.coerce.number().min(1).max(100).optional().describe('Max snapshots (default: 20)'),\n }),\n}\n\nexport const smJobCompareTool: ToolDefinition = {\n name: 'sm_job_compare',\n description: SM_JOB_COMPARE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to compare'),\n base_snapshot_id: z\n .string()\n .optional()\n .describe('Older snapshot ID (default: second-most-recent)'),\n compare_snapshot_id: z.string().optional().describe('Newer snapshot ID (default: most-recent)'),\n changed_only: z.boolean().optional().describe('Omit unchanged rows (default: false)'),\n }),\n}\n\nexport const smJobSnapshotGetTool: ToolDefinition = {\n name: 'sm_job_snapshot_get',\n description: SM_JOB_SNAPSHOT_GET_DESCRIPTION,\n inputSchema: z.object({\n snapshot_id: z.string().describe('Snapshot ID to retrieve (SNP_xxxx)'),\n }),\n}\n\n// ── Custom View Tools ──\n\nconst dataBindingSchema = z.object({\n binding_id: z.string().min(1).max(20).describe('Unique binding ID within this view (e.g., \"b1\")'),\n source_type: z.enum(['job_report', 'report', 'job', 'scenario']).describe('Data source type'),\n source_id: z.string().describe('Source entity ID (e.g., \"JRP_xxxx\")'),\n projection: z\n .object({\n fields: z.array(z.string()).optional().describe('Field whitelist'),\n max_entries: z.number().min(1).max(1000).optional().describe('Max array entries'),\n })\n .optional()\n .describe('Data projection to limit injected data'),\n})\n\nexport const smCustomViewCreateTool: ToolDefinition = {\n name: 'sm_custom_view_create',\n description: SM_CUSTOM_VIEW_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().min(1).max(100).describe('View name'),\n description: z.string().max(500).optional().describe('View description'),\n html: z.string().max(200_000).describe('HTML content (max 200KB)'),\n data_bindings: z.array(dataBindingSchema).max(10).optional().describe('Data source bindings'),\n }),\n}\n\nexport const smCustomViewUpdateTool: ToolDefinition = {\n name: 'sm_custom_view_update',\n description: SM_CUSTOM_VIEW_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to update'),\n label: z.string().min(1).max(100).optional().describe('New label'),\n description: z.string().max(500).optional().describe('New description'),\n html: z.string().max(200_000).optional().describe('New HTML content'),\n data_bindings: z\n .array(dataBindingSchema)\n .max(10)\n .optional()\n .describe('New data bindings (replaces all)'),\n }),\n}\n\nexport const smCustomViewDeleteTool: ToolDefinition = {\n name: 'sm_custom_view_delete',\n description: SM_CUSTOM_VIEW_DELETE_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to delete'),\n }),\n}\n\nexport const smCustomViewListTool: ToolDefinition = {\n name: 'sm_custom_view_list',\n description: SM_CUSTOM_VIEW_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smCustomViewGetTool: ToolDefinition = {\n name: 'sm_custom_view_get',\n description: SM_CUSTOM_VIEW_GET_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to retrieve'),\n include_data: z\n .boolean()\n .optional()\n .describe('Include resolved data in response (default: false)'),\n }),\n}\n\n// ── All Tools ──\n\nexport const allTools: ToolDefinition[] = [\n // Core (15)\n navigateTool,\n screenshotTool,\n clickTool,\n typeTool,\n keyTool,\n scrollTool,\n hoverTool,\n dragTool,\n readPageTool,\n findTool,\n formInputTool,\n javascriptExecTool,\n waitForTool,\n getPageTextTool,\n handleDialogTool,\n // Tabs (4)\n tabsContextTool,\n tabsCreateTool,\n tabCloseTool,\n selectTabTool,\n // Debug (2)\n readConsoleMessagesTool,\n readNetworkRequestsTool,\n // Advanced (8)\n gifCreatorTool,\n uploadImageTool,\n fileUploadTool,\n updatePlanTool,\n resizeWindowTool,\n shortcutsListTool,\n shortcutsExecuteTool,\n switchBrowserTool,\n // viyv Integration (7)\n agentTabAssignTool,\n agentTabListTool,\n browserEventSubscribeTool,\n browserEventUnsubscribeTool,\n artifactFromPageTool,\n pageDataExtractTool,\n browserHealthTool,\n // Semantic (12)\n smCapabilitiesTool,\n smInvokeTool,\n smFetchTool,\n smRegisterPageTool,\n smAddTargetTool,\n smAddActionTool,\n smAddFetchTool,\n smStatusTool,\n smTestTargetTool,\n smDeleteTool,\n smExportTool,\n smImportTool,\n // Scenario & Report (9)\n smScenarioCreateTool,\n smScenarioUpdateTool,\n smScenarioDeleteTool,\n smScenarioListTool,\n smScenarioRunTool,\n smReportListTool,\n smReportGetTool,\n smReportDeleteTool,\n smReportExportTool,\n // Job (8)\n smJobCreateTool,\n smJobUpdateTool,\n smJobDeleteTool,\n smJobListTool,\n smJobRunTool,\n smJobCancelTool,\n smJobReportGetTool,\n smJobReportExportTool,\n // Job History (3)\n smJobHistoryTool,\n smJobCompareTool,\n smJobSnapshotGetTool,\n // Custom View (5)\n smCustomViewCreateTool,\n smCustomViewUpdateTool,\n smCustomViewDeleteTool,\n smCustomViewListTool,\n smCustomViewGetTool,\n]\n","export const FILE_UPLOAD_DESCRIPTION = `Upload local files to a file input element on the page using absolute file paths.\nDo not click on file input elements — clicking opens a native file picker dialog.\nInstead, use read_page or find to locate the file input, then use this tool with its ref.\nThe paths must be absolute paths accessible from the machine running Chrome.`\n","export const GIF_CREATOR_DESCRIPTION = `Record a GIF of browser activity.\nCaptures a sequence of screenshots over a specified duration\nand assembles them into an animated GIF. Useful for documenting\nvisual interactions or creating shareable recordings of workflows.`\n","export const RESIZE_WINDOW_DESCRIPTION = `Resize the browser window to specified dimensions.\nSets the width and height of the browser viewport, useful for\ntesting responsive layouts or ensuring consistent screenshot\ndimensions across different operations.`\n","export const SHORTCUTS_EXECUTE_DESCRIPTION = `Execute a shortcut or workflow by command name or ID.\n\nRuns the specified shortcut in the side panel using the current tab.\nLook up by command name or shortcutId. Use shortcuts_list first\nto see available shortcuts.`\n","export const SHORTCUTS_LIST_DESCRIPTION = `List all available shortcuts and workflows.\n\nReturns registered shortcuts with their commands, descriptions,\nand whether they are workflows. Shortcuts can be executed using\nthe shortcuts_execute tool.`\n","export const SWITCH_BROWSER_DESCRIPTION = `Switch to a different Chrome browser instance.\n\nDisconnects the current Extension connection and waits for a new\nChrome browser to connect (up to 60s). The user should click\n\"Connect\" in the desired browser's extension.`\n","export const UPDATE_PLAN_DESCRIPTION = `Present a step-by-step plan to the user for review.\nDisplays the proposed sequence of actions the agent intends to take,\nallowing the user to approve, modify, or reject the plan before\nexecution begins.`\n","export const UPLOAD_IMAGE_DESCRIPTION = `Upload a previously captured screenshot or user-uploaded image to a file input or drag & drop target.\nProvide imageId from a prior screenshot action. Supports targeting by\nelement ref (for file inputs) or coordinate (for drag & drop).\nSupports common image formats including PNG, JPEG, GIF, and WebP.`\n","export const CLICK_DESCRIPTION = `Click at coordinates or on a referenced element.\n\nProvide either coordinate [x, y] or ref (element reference from read_page/find).\nActions: left_click (default), right_click, double_click, triple_click.\nSupports modifier keys: ctrl, shift, alt, cmd (e.g., \"ctrl+shift\").`\n","export const DRAG_DESCRIPTION = `Drag from one coordinate to another.\n\nPerforms mousedown at start, mousemove to end, then mouseup.`\n","export const FIND_DESCRIPTION = `Find elements on the page using a natural language query.\nSearches the DOM for elements matching the given description,\nreturning references that can be used for subsequent interactions\nsuch as clicking, typing, or extracting content.`\n","export const FORM_INPUT_DESCRIPTION = `Set a value in a form element identified by its ref.\nSupports text inputs, textareas, selects, checkboxes, and radio buttons.\nThe ref must be obtained from a prior find or snapshot operation\nto ensure the correct element is targeted.`\n","export const GET_PAGE_TEXT_DESCRIPTION = `Extract readable text content from the current page.\nStrips away HTML tags, scripts, and styles to return a clean\ntext representation of the visible page content, suitable for\nanalysis, summarization, or further processing.`\n","export const HANDLE_DIALOG_DESCRIPTION = `Handle JavaScript dialogs such as alert, confirm, and prompt.\nAllows accepting or dismissing the dialog, and optionally providing\ninput text for prompt dialogs. Must be called while a dialog\nis actively displayed on the page.`\n","export const HOVER_DESCRIPTION = `Move mouse to coordinates or element without clicking.\n\nProvide either coordinate [x, y] or ref (element reference from read_page/find).\nUseful for revealing tooltips, dropdown menus, or triggering hover states.`\n","export const JAVASCRIPT_EXEC_DESCRIPTION = `Execute arbitrary JavaScript code in the page context.\nThe script runs in the main world of the active page and can access\nthe DOM, window object, and any page-level APIs. Returns the\nserialized result of the last evaluated expression.\nSupports top-level await (e.g., \"await fetch('/api').then(r => r.json())\").`\n","export const KEY_DESCRIPTION = `Press keyboard key(s).\n\nSpace-separated key names. Supports keyboard shortcuts.\nExamples: \"Enter\", \"Tab\", \"Backspace\", \"ctrl+a\", \"cmd+c\".\nUse repeat parameter for repeated presses (e.g., arrow keys).`\n","export const NAVIGATE_DESCRIPTION = `Navigate to a URL, or go forward/back in browser history.\n\nUse \"back\" to go back in history, \"forward\" to go forward.\nProvide a full URL (with protocol) to navigate to a new page.\nWaits for page load to complete before returning.`\n","export const READ_PAGE_DESCRIPTION = `Get accessibility tree representation of page elements.\n\nSupports:\n- filter: \"interactive\" for buttons/links/inputs only, \"all\" for everything\n- depth: max tree depth (1-20, default 8)\n- refId: focus on a specific element subtree\n- maxChars: limit output size (default 50000)\n\nReturns elements with ref IDs that can be used with click, form_input, etc.`\n","export const SCREENSHOT_DESCRIPTION = `Take a screenshot of a tab.\n\nReturns image as an MCP ImageContent block, plus metadata (imageId) as text.\nDefault format is JPEG with quality 80.\n\nIMPORTANT - Token-efficient alternatives (prefer these when possible):\n- read_page: Get accessibility tree with element text, values, and states\n- get_page_text: Extract all readable text from the page\n- find: Locate elements by natural language description\nUse screenshot only when visual verification is needed (layout, styling, images, charts).\n\nFor example: to verify text was typed into an input, use read_page to check the\ninput's value — don't take a screenshot. To confirm a page loaded, check the\naccessibility tree for expected headings or elements.\n\nUse ref to capture just a specific element (with padding) instead of the full page.\nThis dramatically reduces image size. If both ref and region are provided, region\ntakes precedence. The response includes an imageId for use with upload_image.`\n","export const SCROLL_DESCRIPTION = `Scroll in a direction at given coordinates, or scroll an element into view by ref.\n\nTwo modes:\n1. Directional scroll: provide coordinate + direction (+ optional amount 1-10, default 3).\n2. Scroll to element: provide ref (element reference ID from read_page/find). Scrolls the element into view using smooth scrolling.`\n","export const TYPE_DESCRIPTION = `Type text into the currently focused element.\n\nEach character is typed individually with keyDown/keyUp events.\nFor special keys (Enter, Tab, etc.), use the 'key' tool instead.`\n","export const WAIT_FOR_DESCRIPTION = `Wait for a specified condition before proceeding.\nSupports waiting for a CSS selector to appear in the DOM,\nfor a navigation event to complete, or for a fixed timeout duration.\nUseful for synchronizing with asynchronous page updates.\nAt least one of selector, navigation, or timeout must be specified.`\n","export const READ_CONSOLE_MESSAGES_DESCRIPTION = `Read console messages captured from the page.\nReturns log, warning, error, and info messages that have been\nemitted by page scripts. Supports filtering by log level\nand limiting the number of returned entries.\nUse the pattern parameter to filter messages by regex, and\nthe clear parameter to remove messages after reading.`\n","export const READ_NETWORK_REQUESTS_DESCRIPTION = `Read network requests captured from the page.\nReturns details of HTTP requests and responses including URL, method,\nstatus code, headers, and timing information. Supports filtering\nby URL pattern or resource type.`\n","export const SM_ADD_ACTION_DESCRIPTION = `Define a semantic action (step sequence) for a registered page.\n\nCreates an executable action with typed parameters and ordered steps.\nSteps reference targets by target_id and support param_ref for dynamic values.\n\nParameters:\n- page_id: the page this action belongs to\n- label: action name (e.g., \"Login\")\n- verb: action verb (e.g., \"login\", \"submit\", \"search\")\n- description (optional): LLM-facing description for discovery via sm_capabilities\n- params[]: parameter definitions [{name, type, required, secret, description, default_value}]\n- steps[]: ordered step sequence (minimum 1):\n - type: 'click' | 'type' | 'select' | 'wait' | 'scroll' | 'key' | 'navigate'\n - target_id: target to act on\n - params: {text, value, keys, direction, amount, url, param_ref}\n - pre_wait: {strategy, selector, timeout_ms}\n - description: step description\n- retry_policy (optional): {max_retries:0-5, backoff, base_delay_ms, jitter}\n\nReturns:\n- action_id, step_count\n- validation: {valid, warnings[]} with target/param reference checks`\n","export const SM_ADD_FETCH_DESCRIPTION = `Define a data extraction rule (fetch) for a registered page.\n\nCreates a structured data extraction definition that maps DOM elements to typed output fields.\nSupports text, attribute, list, count, and existence extraction types.\n\nParameters:\n- page_id: the page this fetch belongs to\n- label: fetch name (e.g., \"Get Posts\")\n- type_name: output type name (e.g., \"posts\", \"profile\")\n- description (optional): LLM-facing description for discovery via sm_capabilities\n- fields[]: extraction field definitions (minimum 1):\n - name: output field name\n - target_id: target element to extract from\n - extraction_type: 'text' | 'attribute' | 'list' | 'count' | 'exists'\n - attribute: attribute name (for 'attribute' type)\n - item_selector: CSS selector for list items (for 'list' type)\n - item_fields[]: structured extraction for each list item (for 'list' type):\n - name: output field name\n - selector: CSS selector relative to each list item (use \":scope\" for item element itself)\n - extraction_type: 'text' | 'attribute' | 'exists'\n - attribute: attribute name (for 'attribute' type)\n- limits (optional): {max_chars:1000-200000, max_items:1-1000}\n\nReturns:\n- fetch_id, field_count\n- validation: {valid, warnings[]} with target reference checks`\n","export const SM_ADD_TARGET_DESCRIPTION = `Create or update semantic targets (element locators) for a registered page.\n\nSupports batch creation and re-binding of existing targets.\nUse ref from read_page/find to auto-generate locators, or provide locators explicitly.\n\nParameters:\n- tabId: target tab where elements are present\n- page_id: the page these targets belong to\n- targets[]: array of target definitions:\n - target_id (optional): specify to re-bind an existing target's locators\n - label: target name (e.g., \"Username Input\")\n - role: semantic role (e.g., \"textbox\", \"button\")\n - ref (optional): element ref from read_page/find for auto-locator generation\n - locators (optional): explicit locator array [{type, value, stability}]\n\nEach target must have either ref or locators.\nWhen target_id is provided, only locators are updated (label/role preserved).\n\nReturns per target:\n- target_id, label, locators, resolve_test (live element check), updated (true = re-bind)`\n","export const SM_CAPABILITIES_DESCRIPTION = `Query semantic capabilities available for the current page.\n\nReturns the matched page definition, available actions, and fetches for the active tab.\nUses page signature matching (URL pattern + DOM markers) to identify the current page state.\n\nReturns:\n- ok: whether a page match was found\n- domain: hostname of the current tab\n- page_id / page_type / variant_id: matched page and variant\n- match_score: confidence score of the match\n- actions[]: available actions with their parameters\n- fetches[]: available data extractions with their parameters\n- other_pages[]: other registered pages on the same domain (for cross-page navigation)\n- hint: guidance message when no page matches\n\nUse this before sm_invoke or sm_fetch to discover what operations are available.\nIf no page matches (ok: false), use sm_register_page to register the current page,\nthen sm_add_target and sm_add_action/sm_add_fetch to configure automation.\nUse sm_status to review all existing configurations.`\n","export const SM_CUSTOM_VIEW_CREATE_DESCRIPTION = `Create a custom HTML view that can be opened in a new tab.\n\nUse this to build dashboards, charts, or reports using HTML/CSS/JS. The HTML can reference external CDN libraries (e.g., Chart.js, D3) and access bound data via window.__VIYV_DATA__.\n\nParameters:\n- label: view name (max 100 chars)\n- description: optional description (max 500 chars)\n- html: full HTML document (max 200KB)\n- data_bindings: optional array of data source references (max 10)\n - binding_id: unique ID within this view (e.g., \"b1\")\n - source_type: \"job_report\" | \"report\" | \"job\" | \"scenario\"\n - source_id: entity ID (e.g., \"JRP_xxxx\")\n - projection: optional {fields, max_entries} to limit injected data\n\nThe HTML should reference data as window.__VIYV_DATA__[binding_id]. Data is injected when the user opens the view.\n\nReturns: {ok, view_id, html_size, binding_count}`\n\nexport const SM_CUSTOM_VIEW_UPDATE_DESCRIPTION = `Update an existing custom view.\n\nUse this to refresh HTML after data structure changes (stale bindings) or to modify the view content.\n\nParameters:\n- view_id: view to update\n- label: new label (optional)\n- description: new description (optional)\n- html: new HTML content (optional, max 200KB)\n- data_bindings: new bindings array (optional, replaces all bindings)\n\nReturns: {ok, view_id, html_size, binding_count}`\n\nexport const SM_CUSTOM_VIEW_DELETE_DESCRIPTION = `Delete a custom view.\n\nParameters:\n- view_id: view to delete\n\nReturns: {ok, view_id}`\n\nexport const SM_CUSTOM_VIEW_LIST_DESCRIPTION = `List all custom views with binding health status.\n\nUse this to check which views exist and whether their data bindings are still valid. Each view includes binding_status for every binding:\n- \"ok\": source exists and structure matches\n- \"stale\": source exists but structure changed (stale_reason: \"schema_changed\", includes current vs saved fingerprint)\n- \"missing\": source has been deleted\n\nWhen bindings are stale, use sm_custom_view_get with include_data=true to fetch current data, then sm_custom_view_update to refresh the HTML.\n\nReturns: {ok, views[]: {view_id, label, description, html_size, binding_count, binding_status[], created_at, updated_at}}`\n\nexport const SM_CUSTOM_VIEW_GET_DESCRIPTION = `Get a custom view with optional data injection.\n\nParameters:\n- view_id: view to retrieve\n- include_data: if true, resolve all bindings and return actual data in injected_data (default: false)\n\nWhen include_data=true:\n- injected_data maps binding_id to resolved data from the source\n- Data is filtered by projection (fields, max_entries) if specified\n- Secret parameter values are masked\n\nbinding_status shows current health of each binding (ok/stale/missing).\n\nReturns: {ok, view, binding_status[], injected_data?}`\n","export const SM_DELETE_DESCRIPTION = `Delete a semantic entity (page, target, action, or fetch).\n\nSupports dry_run mode to preview deletion impact before committing.\nPage deletion cascades to all dependent targets, actions, and fetches.\nTarget deletion warns about referencing actions and fetches.\n\nParameters:\n- entity_type: 'page' | 'target' | 'action' | 'fetch'\n- entity_id: the entity ID to delete\n- dry_run (optional): if true, return impact preview without deleting\n\nReturns:\n- entity_type, entity_id, label\n- dry_run: whether this was a preview\n- cascaded: (page deletion) lists of deleted targets, actions, fetches\n- warnings: (target deletion) referencing actions/fetches that may break`\n","export const SM_EXPORT_DESCRIPTION = `Export semantic configuration as JSON.\n\nExports pages, targets, actions, and fetches. Optionally filter by domain.\nSecret parameter default values are stripped from the export.\nIncludes a SHA-256 checksum for integrity verification on import.\n\nParameters:\n- domain (optional): export only pages matching this domain (subdomain-aware). If omitted, exports all.\n\nReturns:\n- SemanticExport JSON with schema_version, checksum, pages[], targets[], actions[], fetches[]`\n","export const SM_FETCH_DESCRIPTION = `Extract structured data from the current page using predefined extraction rules.\n\nResolves target elements and extracts text, attributes, lists, counts, or existence checks.\nApplies output limits (max_chars, max_items) to prevent oversized responses.\n\nParameters:\n- tabId: target tab\n- fetch_id: the fetch definition to execute (from sm_capabilities)\n- params: optional parameters for the fetch\n\nReturns:\n- ok: whether extraction succeeded\n- data: extracted key-value data matching the fetch's return_schema\n- page_id_before / page_id_after: page state tracking\n- needs_rebind: true if any targets could not be resolved\n- missing_targets[]: list of target IDs that failed to resolve\n- hint: recovery guidance when errors occur\n\nWhen needs_rebind is true, use sm_test_target to diagnose each failing target,\nthen sm_add_target with target_id to re-bind locators.\nWhen fetch_id is not found, use sm_capabilities to discover available fetches.`\n","export const SM_IMPORT_DESCRIPTION = `Import semantic configuration from JSON.\n\nImports pages, targets, actions, and fetches from a SemanticExport JSON object.\nVerifies checksum integrity before importing.\n\nParameters:\n- data (required): SemanticExport JSON object (from sm_export)\n- strategy (optional): \"merge\" (default) adds new entities, skips existing IDs.\n \"replace-domain\" deletes all existing pages matching the import's domains\n (with cascade to targets/actions/fetches), then inserts all import entities.\n\nReturns:\n- ok: whether import succeeded\n- imported: number of entities imported\n- skipped: number of entities skipped (existing IDs in merge mode)\n- errors[]: any error messages`\n","export const SM_INVOKE_DESCRIPTION = `Execute a semantic action on the current page.\n\nRuns a predefined sequence of steps (click, type, select, wait, etc.) using\nstable element locators with automatic fallback. Handles navigation detection,\nretry with jitter, and template parameter substitution.\n\nParameters:\n- tabId: target tab\n- action_id: the action to execute (from sm_capabilities)\n- params: key-value parameters for template substitution (e.g., { username: \"...\" })\n\nReturns:\n- ok: whether all steps completed successfully\n- completed_steps / total_steps: execution progress\n- page_id_before / page_id_after: page state tracking (navigation detection)\n- observations[]: human-readable log of what happened (secrets redacted)\n- needs_rebind: true if any targets could not be resolved\n- missing_targets[]: list of target IDs that failed to resolve\n- hint: recovery guidance when errors occur\n\nWhen needs_rebind is true, use sm_test_target to diagnose each failing target,\nthen sm_add_target with target_id to re-bind locators.\nWhen action_id is not found, use sm_capabilities to discover available actions.`\n","export const SM_JOB_CANCEL_DESCRIPTION = `Cancel a running job and its currently executing scenario.\n\nRemaining unexecuted entries are marked as skipped.\n\nParameters:\n- tabId: tab where the job is running\n\nReturns:\n- ok: success status\n- cancelled: true if a job was found and cancelled`\n","export const SM_JOB_CREATE_DESCRIPTION = `Create a reusable job that groups multiple scenarios for sequential batch execution.\n\nEach entry specifies a scenario_id and optional parameter overrides. When executed, scenarios\nrun one after another on the same tab, each producing its own Report.\n\nParameters:\n- label: job name (e.g., \"Print Price Collection\")\n- description: optional description\n- entries: ordered list of scenarios to execute\n - scenario_id: existing scenario ID\n - label: display label override (uses scenario label if omitted)\n - params: parameter overrides for this scenario execution\n- on_error: 'stop' (default) halts on first failure, 'skip_and_continue' skips failed and continues\n\nReturns:\n- job_id: the created job ID (JOB_xxxx)\n- entry_count: number of entries`\n","export const SM_JOB_DELETE_DESCRIPTION = `Delete a job definition.\n\nRunning executions are not affected — only the job definition is removed.\n\nParameters:\n- job_id: job to delete\n\nReturns:\n- ok: success status\n- job_id: deleted job ID`\n","export const SM_JOB_HISTORY_DESCRIPTION = `Get execution history for a job. Returns condensed snapshots that persist beyond report pruning.\n\nUse this to review past executions, track trends over time (e.g. price changes), or select snapshots for comparison.\n\nParameters:\n- job_id: job to get history for\n- limit: max snapshots to return (default: 20, most recent first)\n\nReturns:\n- job_id, job_label\n- snapshots[]: list of {snapshot_id, status, started_at, completed_at, duration_ms, scenario_count}`\n\nexport const SM_JOB_COMPARE_DESCRIPTION = `Compare two job executions to see data changes between them.\n\nMatches scenarios by scenario_id, data groups by result_key, and rows by loop_params. Computes per-cell diffs with numeric deltas.\n\nParameters:\n- job_id: the job to compare\n- base_snapshot_id: older snapshot (optional, defaults to second-most-recent)\n- compare_snapshot_id: newer snapshot (optional, defaults to most-recent)\n- changed_only: if true, omit unchanged rows (default: false)\n\nReturns:\n- diffs[]: per-scenario, per-result_key diff with rows showing added/removed/modified/unchanged\n- summary: total counts of changes`\n\nexport const SM_JOB_SNAPSHOT_GET_DESCRIPTION = `Get detailed data from a specific job snapshot.\n\nUse this to inspect the full captured data for a single execution, including all scenario results and data groups.\n\nParameters:\n- snapshot_id: the snapshot to retrieve (SNP_xxxx)\n\nReturns:\n- snapshot: full JobSnapshot with scenario_snapshots and data_groups`\n","export const SM_JOB_LIST_DESCRIPTION = `List all defined jobs with entry counts and configuration.\n\nReturns:\n- jobs: array of job summaries\n - job_id, label, description, entry_count, on_error, created_at`\n","export const SM_JOB_REPORT_EXPORT_DESCRIPTION = `Export all scenario results from a job execution as aggregated JSON or CSV.\n\nCombines data from all linked scenario reports into a single file.\nCSV includes a job_entry column to distinguish scenarios.\n\nParameters:\n- job_report_id: job report ID (JRP_xxxx)\n- format: 'json' (default) or 'csv'\n\nReturns:\n- data: export content string\n- filename: suggested filename`\n","export const SM_JOB_REPORT_GET_DESCRIPTION = `Get job execution status and results.\n\nShows overall progress and per-scenario report summaries.\nUse sm_report_get with individual report_ids for detailed scenario data.\n\nParameters:\n- job_report_id: job report ID (JRP_xxxx)\n\nReturns:\n- job_report: full JobReport with entry statuses\n- scenario_summaries: per-scenario report summaries (entry_count, error_count)`\n","export const SM_JOB_RUN_DESCRIPTION = `Execute a job on a browser tab. Scenarios run sequentially.\n\nReturns job_report_id immediately by default. Poll with sm_job_report_get to check progress.\nSet wait_for_completion=true to block until all scenarios finish.\n\nOnly one job or scenario can run per tab at a time.\n\nParameters:\n- tabId: target tab for execution\n- job_id: the job to execute\n- params: optional per-scenario param overrides keyed by scenario_id\n- wait_for_completion: if true, wait for all scenarios to complete (default: false)\n\nReturns:\n- job_report_id: ID of the created job report (JRP_xxxx)\n- job_id: the executed job\n- status: 'running' (async) or 'completed'/'failed' (when wait_for_completion=true)`\n","export const SM_JOB_UPDATE_DESCRIPTION = `Update an existing job definition.\n\nSupports partial updates — only specified fields are changed.\n\nParameters:\n- job_id: job to update\n- label: new name (optional)\n- description: new description (optional)\n- entries: new entry list (optional, replaces all entries)\n- on_error: new error handling strategy (optional)\n\nReturns:\n- job_id: updated job ID\n- entry_count: number of entries after update`\n","export const SM_REGISTER_PAGE_DESCRIPTION = `Register a page for semantic automation.\n\nCreates a page definition with URL pattern matching and DOM markers.\nIdempotent: if a registered page already matches the current tab, returns the existing page_id.\nWhen page_type is specified on an already-registered page, it updates the page_type.\n\nPages are grouped by domain. Use page_type to distinguish different page types\nwithin the same domain (e.g., \"profile\", \"compose\", \"search\").\n\nParameters:\n- tabId: target tab (used to auto-derive url_pattern and domains if omitted)\n- label: human-readable page name (e.g., \"GitHub Login\")\n- page_type: page type within the domain (e.g., \"profile\", \"compose\", \"search\")\n- url_pattern: URL regex (auto-derived from tab URL if omitted)\n- domains: domain scope array (auto-derived from tab hostname if omitted)\n- auth_state: 'logged_in' | 'logged_out' | 'any' (default: 'any')\n- must_exist: CSS selectors that must be present on the page\n- must_not_exist: CSS selectors that must not be present\n- title_regex: regex to match page title\n\nReturns:\n- page_id, page_type, variant_id, label\n- already_registered: true if an existing page matched\n- match_test: result of matching the current tab against the page definition`\n","export const SM_REPORT_DELETE_DESCRIPTION = `Delete an execution report.\n\nPermanently removes a report and its data.\n\nParameters:\n- report_id: the report to delete\n\nReturns:\n- ok: whether deletion succeeded\n- report_id: the deleted report ID`\n","export const SM_REPORT_EXPORT_DESCRIPTION = `Export a report as JSON or CSV.\n\nJSON format includes the complete report structure.\nCSV format flattens entries into rows with columns for loop parameters and data fields.\nCSV uses UTF-8 BOM for Excel compatibility with non-ASCII characters.\n\nParameters:\n- report_id: the report to export\n- format: 'json' (default) or 'csv'\n\nReturns:\n- format: the export format used\n- data: the exported content as a string\n- filename: suggested filename for download`\n","export const SM_REPORT_GET_DESCRIPTION = `Get detailed execution report.\n\nReturns the full report including all data entries, observations, errors,\nand grouped data (entries organized by result_key).\n\nUse this to poll running scenarios for progress updates.\n\nParameters:\n- report_id: the report to retrieve\n\nReturns:\n- report: full Report object with entries[], grouped_data, observations[], errors[]\n- report.status: 'running' | 'completed' | 'failed' | 'cancelled'\n- report.entries[]: collected data with loop_params and extracted data\n- report.grouped_data: entries grouped by result_key for easy access`\n","export const SM_REPORT_LIST_DESCRIPTION = `List execution reports.\n\nReturns summaries of scenario execution reports, sorted by most recent first.\nOptionally filter by scenario_id.\n\nParameters:\n- scenario_id (optional): filter reports for a specific scenario\n\nReturns:\n- reports[]: array of report summaries with status, timing, and entry/error counts`\n","export const SM_SCENARIO_CREATE_DESCRIPTION = `Create a scenario for multi-page workflow automation.\n\nScenarios define sequences of steps (navigate, action, fetch, loop, wait) that execute\nacross multiple pages. Loop steps support cartesian product iteration over variables\n(static values, select options, or previous fetch results).\n\nParameters:\n- label: scenario name (e.g., \"Price Table Collection\")\n- description: optional LLM-facing description\n- params: global parameter definitions (available as {{param_name}} templates)\n- steps: ordered step sequence\n- max_duration_ms: timeout (default: 300000ms = 5min)\n- on_error: 'stop' (default) or 'skip_and_continue'\n\nStep types:\n- navigate: { url, wait_for_load } - navigate to URL (supports {{templates}})\n- action: { action_id, params } - execute an existing semantic action\n- fetch: { fetch_id, result_key, params } - extract data, stored in report under result_key\n- loop: { variables, steps, delay_between_ms, max_iterations } - iterate combinations\n- wait: { strategy, selector, timeout_ms } - wait for condition\n\nLoop variables:\n- static: explicit value list\n- target_options: auto-extract all <option> values from a <select> target\n- previous_fetch: extract values from prior fetch results\n\nInside loops, use {{loop.variable_name}} to reference loop variables.\n\nReturns:\n- scenario_id: the created scenario ID (SCN_xxxx)\n- step_count: total step count\n- validation: { valid, warnings[] } referential integrity check`\n","export const SM_SCENARIO_DELETE_DESCRIPTION = `Delete a scenario by ID.\n\nAssociated reports become orphaned but are not deleted.\n\nParameters:\n- scenario_id: the scenario to delete\n\nReturns:\n- ok: whether deletion succeeded\n- scenario_id: the deleted scenario ID`\n","export const SM_SCENARIO_LIST_DESCRIPTION = `List all registered scenarios.\n\nReturns a summary of each scenario including ID, label, step count,\nparameter names, and creation timestamp.\n\nNo parameters required.\n\nReturns:\n- scenarios[]: array of scenario summaries`\n","export const SM_SCENARIO_RUN_DESCRIPTION = `Execute a scenario on a tab.\n\nStarts scenario execution and returns immediately with a report_id.\nUse sm_report_get to poll for progress and final results.\n\nOnly one scenario can run per tab at a time.\n\nParameters:\n- tabId: target tab for execution\n- scenario_id: the scenario to execute\n- params: parameter values for template substitution\n- wait_for_completion: if true, wait for scenario to finish (up to max_duration_ms)\n\nReturns:\n- report_id: ID of the created report (RPT_xxxx)\n- scenario_id: the executed scenario\n- status: 'running' (async) or 'completed'/'failed' (when wait_for_completion=true)\n- error: error message if startup failed`\n","export const SM_SCENARIO_UPDATE_DESCRIPTION = `Update an existing scenario.\n\nSupports partial updates - only provide fields you want to change.\n\nParameters:\n- scenario_id: the scenario to update\n- label: new name\n- description: new description\n- params: new parameter definitions\n- steps: new step sequence\n- max_duration_ms: new timeout\n- on_error: new error handling strategy\n\nReturns:\n- scenario_id, step_count, validation`\n","export const SM_STATUS_DESCRIPTION = `View all semantic configuration (pages, targets, actions, fetches).\n\nReturns a summary and detailed listing of all registered entities.\nOptionally test-resolve all targets against the current tab.\n\nParameters:\n- tabId (optional): required when test_resolve is true\n- page_id (optional): filter results to a specific page\n- domain (optional): filter results to pages matching this domain\n- test_resolve (optional): if true, resolve all targets on the current tab\n\nReturns:\n- summary: {total_pages, total_targets, total_actions, total_fetches}\n- pages[]: page definitions with page_type, domains, url_patterns, and counts\n- targets[]: targets with locator info and optional resolve_result\n- actions[]: actions with step count and param names\n- fetches[]: fetches with field count\n- integrity[]: referential integrity warnings`\n","export const SM_TEST_TARGET_DESCRIPTION = `Test a specific target's locators against the current page.\n\nResolves each locator individually and reports which ones matched.\nUseful for diagnosing broken targets and deciding which locators to update.\n\nParameters:\n- tabId: target tab to test against\n- target_id: the target to test\n\nReturns:\n- found: whether any locator resolved successfully\n- locator_results[]: per-locator results {type, value, stability, matched}\n- element: resolved element info {tag, text, rect} if found\n- test_status: updated test status saved to storage`\n","export const SELECT_TAB_DESCRIPTION = `Switch focus to a specific tab by its identifier.\nMakes the target tab the active tab in the agent's group,\nbringing it to the foreground for subsequent operations\nsuch as navigation, clicking, or content extraction.`\n","export const TAB_CLOSE_DESCRIPTION = `Close a tab by its identifier.\nRemoves the specified tab from the browser and the agent's tab group.\nIf the closed tab was active, focus shifts to the nearest remaining\ntab in the group.`\n","export const TABS_CONTEXT_DESCRIPTION = `Get information about the current agent tab group.\nReturns the list of tabs belonging to the agent's assigned group,\nincluding each tab's ID, URL, title, and active status.\nUseful for understanding the current browsing context.`\n","export const TABS_CREATE_DESCRIPTION = `Create a new tab within the agent's tab group.\nOpens a new tab with an optional URL and automatically assigns it\nto the current agent's group. The new tab becomes the active tab\nunless otherwise specified.`\n","export const AGENT_TAB_ASSIGN_DESCRIPTION = `Assign a tab group to a specific agent.\nBinds an existing Chrome tab group to the calling agent, granting\nexclusive control over all tabs within the group. Prevents other\nagents from interfering with the assigned tabs.`\n","export const AGENT_TAB_LIST_DESCRIPTION = `List all agent-to-tab-group mappings.\nReturns a summary of which agents are assigned to which tab groups,\nincluding the group ID, agent identifier, and the number of tabs\nin each group.`\n","export const ARTIFACT_FROM_PAGE_DESCRIPTION = `Save the current page as a persistent artifact.\nCaptures the page content as HTML, text, or screenshot and stores it\nas a named artifact for later reference. Artifacts can be retrieved\nby other tools or returned to the user as output.`\n","export const BROWSER_EVENT_SUBSCRIBE_DESCRIPTION = `Subscribe to browser events for real-time monitoring.\nRegisters a listener for specified event types such as navigation,\ntab updates, DOM changes, or network activity. Events are queued\nand delivered on subsequent polling or callback.`\n","export const BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION = `Unsubscribe from previously registered browser events.\nRemoves the event listener for the specified subscription ID,\nstopping further event delivery. Cleans up associated resources\nand flushes any remaining queued events.`\n","export const BROWSER_HEALTH_DESCRIPTION = `Check the health status of the browser connection.\nVerifies that the browser process is running, the CDP connection\nis active, and the agent's tab group is accessible. Returns\ndiagnostic information useful for troubleshooting connectivity issues.`\n","export const PAGE_DATA_EXTRACT_DESCRIPTION = `Extract structured data from the current page.\nParses the page content according to a provided schema object,\nreturning well-formed JSON. Supports extracting tables, lists,\nkey-value pairs, and other structured patterns.\nThe schema defines CSS selectors for each field to extract.`\n","/**\n * Setup command: registers Native Messaging Host manifest.\n * `npx @viyv/browser-mcp setup`\n */\n\nimport { execSync } from 'node:child_process'\nimport { chmodSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir, platform } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { NATIVE_HOST_NAME } from '@viyv-browser/shared'\n\ninterface SetupOptions {\n extensionId?: string\n}\n\nexport function runSetup(options: SetupOptions = {}): void {\n const os = platform()\n const binaryPath = getBinaryPath()\n\n console.log('Viyv Browser MCP - Native Messaging Host Setup')\n console.log('================================================')\n console.log(`Platform: ${os}`)\n console.log(`Binary: ${binaryPath}`)\n\n // Verify binary path exists\n if (!existsSync(binaryPath)) {\n console.error(`WARNING: Binary not found at ${binaryPath}`)\n console.error('The Native Messaging Host may not work until the binary is available.')\n }\n\n const allowedOrigins = options.extensionId\n ? [`chrome-extension://${options.extensionId}/`]\n : ['chrome-extension://*/'] // Allow all during development\n\n // Security warning for wildcard origins\n if (!options.extensionId) {\n process.stderr.write(\n 'WARNING: Using wildcard allowed_origins (chrome-extension://*/). ' +\n 'This allows any Chrome extension to connect. ' +\n 'For production, specify --extension-id to restrict access.\\n',\n )\n }\n\n // Chrome Native Messaging Host manifest doesn't support args.\n // Create a wrapper script that launches the binary with --native-host flag.\n const wrapperPath = createNativeHostWrapper(os, binaryPath)\n\n const manifest = {\n name: NATIVE_HOST_NAME,\n description: 'Viyv Browser MCP Native Messaging Host',\n path: wrapperPath,\n type: 'stdio',\n allowed_origins: allowedOrigins,\n }\n\n const manifestPath = getManifestPath(os)\n const manifestDir = dirname(manifestPath)\n\n console.log(`Wrapper: ${wrapperPath}`)\n console.log(`Manifest path: ${manifestPath}`)\n\n mkdirSync(manifestDir, { recursive: true })\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))\n chmodSync(manifestPath, 0o644)\n\n console.log('\\nNative Messaging Host registered successfully!')\n console.log('\\nNext steps:')\n console.log('1. Start the MCP Server: node <path>/dist/index.js')\n console.log('2. Install the Viyv Browser Chrome Extension')\n console.log('3. Click the extension icon to connect')\n}\n\nfunction getBinaryPath(): string {\n // Find the actual binary path\n const whichCmd = process.platform === 'win32' ? 'where' : 'which'\n try {\n const found = execSync(`${whichCmd} viyv-browser-mcp`, { encoding: 'utf-8' }).trim()\n if (found) return found\n } catch {\n // Not globally installed, use npx path\n }\n\n // Fallback: resolve from current module\n const currentScript = process.argv[1]\n return resolve(currentScript)\n}\n\nfunction createNativeHostWrapper(os: string, binaryPath: string): string {\n const manifestDir = dirname(getManifestPath(os))\n mkdirSync(manifestDir, { recursive: true })\n\n // Chrome launches native hosts in a clean environment without user's PATH.\n // We must use the absolute path to node, not rely on #!/usr/bin/env node.\n const nodePath = getNodePath()\n\n if (os === 'win32') {\n // Windows: .bat wrapper\n const wrapperPath = resolve(manifestDir, `${NATIVE_HOST_NAME}.bat`)\n writeFileSync(wrapperPath, `@echo off\\r\\n\"${nodePath}\" \"${binaryPath}\" --native-host\\r\\n`)\n return wrapperPath\n }\n\n // macOS/Linux: shell wrapper\n const wrapperPath = resolve(manifestDir, `${NATIVE_HOST_NAME}.sh`)\n writeFileSync(wrapperPath, `#!/bin/bash\\nexec \"${nodePath}\" \"${binaryPath}\" --native-host\\n`)\n chmodSync(wrapperPath, 0o755)\n return wrapperPath\n}\n\nfunction getNodePath(): string {\n try {\n return execSync('which node', { encoding: 'utf-8' }).trim()\n } catch {\n // Fallback: use the current process's node binary\n return process.execPath\n }\n}\n\nfunction getManifestPath(os: string): string {\n const home = homedir()\n\n switch (os) {\n case 'darwin':\n return resolve(\n home,\n 'Library/Application Support/Google/Chrome/NativeMessagingHosts',\n `${NATIVE_HOST_NAME}.json`,\n )\n case 'linux':\n return resolve(home, '.config/google-chrome/NativeMessagingHosts', `${NATIVE_HOST_NAME}.json`)\n case 'win32':\n // On Windows, we'd also need to create a registry entry\n return resolve(\n home,\n 'AppData/Local/Google/Chrome/User Data/NativeMessagingHosts',\n `${NATIVE_HOST_NAME}.json`,\n )\n default:\n throw new Error(`Unsupported platform: ${os}`)\n }\n}\n"],"mappings":"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","names":["existsSync","randomUUID","existsSync","z","z","sessions","randomUUID","resolve","existsSync","chmodSync","existsSync","existsSync","chmodSync","wrapperPath","waitForSocket","existsSync"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/native-host/bridge.ts","../../shared/src/constants.ts","../src/native-host/compression.ts","../src/native-host/transport.ts","../src/server.ts","../src/agent-session.ts","../src/event-bridge.ts","../src/health.ts","../src/tools/index.ts","../src/tools/advanced/file-upload.ts","../src/tools/advanced/gif-creator.ts","../src/tools/advanced/resize-window.ts","../src/tools/advanced/shortcuts-execute.ts","../src/tools/advanced/shortcuts-list.ts","../src/tools/advanced/switch-browser.ts","../src/tools/advanced/update-plan.ts","../src/tools/advanced/upload-image.ts","../src/tools/core/click.ts","../src/tools/core/drag.ts","../src/tools/core/find.ts","../src/tools/core/form-input.ts","../src/tools/core/get-page-text.ts","../src/tools/core/handle-dialog.ts","../src/tools/core/hover.ts","../src/tools/core/javascript-exec.ts","../src/tools/core/key.ts","../src/tools/core/navigate.ts","../src/tools/core/read-page.ts","../src/tools/core/screenshot.ts","../src/tools/core/scroll.ts","../src/tools/core/type.ts","../src/tools/core/wait-for.ts","../src/tools/debug/read-console-messages.ts","../src/tools/debug/read-network-requests.ts","../src/tools/semantic/sm-add-action.ts","../src/tools/semantic/sm-add-fetch.ts","../src/tools/semantic/sm-add-target.ts","../src/tools/semantic/sm-capabilities.ts","../src/tools/semantic/sm-custom-view.ts","../src/tools/semantic/sm-delete.ts","../src/tools/semantic/sm-export.ts","../src/tools/semantic/sm-fetch.ts","../src/tools/semantic/sm-import.ts","../src/tools/semantic/sm-invoke.ts","../src/tools/semantic/sm-job-cancel.ts","../src/tools/semantic/sm-job-create.ts","../src/tools/semantic/sm-job-delete.ts","../src/tools/semantic/sm-job-history.ts","../src/tools/semantic/sm-job-list.ts","../src/tools/semantic/sm-job-report-export.ts","../src/tools/semantic/sm-job-report-get.ts","../src/tools/semantic/sm-job-run.ts","../src/tools/semantic/sm-job-update.ts","../src/tools/semantic/sm-register-page.ts","../src/tools/semantic/sm-report-delete.ts","../src/tools/semantic/sm-report-export.ts","../src/tools/semantic/sm-report-get.ts","../src/tools/semantic/sm-report-list.ts","../src/tools/semantic/sm-scenario-create.ts","../src/tools/semantic/sm-scenario-delete.ts","../src/tools/semantic/sm-scenario-list.ts","../src/tools/semantic/sm-scenario-run.ts","../src/tools/semantic/sm-scenario-update.ts","../src/tools/semantic/sm-status.ts","../src/tools/semantic/sm-test-target.ts","../src/tools/tabs/select-tab.ts","../src/tools/tabs/tab-close.ts","../src/tools/tabs/tabs-context.ts","../src/tools/tabs/tabs-create.ts","../src/tools/viyv/agent-tab-assign.ts","../src/tools/viyv/agent-tab-list.ts","../src/tools/viyv/artifact-from-page.ts","../src/tools/viyv/browser-event-subscribe.ts","../src/tools/viyv/browser-event-unsubscribe.ts","../src/tools/viyv/browser-health.ts","../src/tools/viyv/page-data-extract.ts","../src/setup.ts"],"sourcesContent":["/**\n * @viyv/browser-mcp CLI entry point.\n *\n * Modes:\n * viyv-browser-mcp → MCP Server (stdio | sse | streamable-http transport)\n * viyv-browser-mcp --native-host → Native Messaging Host mode (Chrome bridge)\n * viyv-browser-mcp setup → Register Native Messaging Host manifest\n */\n\nimport { existsSync, readdirSync } from 'node:fs'\nimport { startBridge } from './native-host/bridge.js'\nimport { startMcpServer } from './server.js'\nimport { runSetup } from './setup.js'\n\nconst args = process.argv.slice(2)\n\nif (args.includes('setup')) {\n // Setup mode: register Native Messaging Host\n const extensionIdIdx = args.indexOf('--extension-id')\n const extensionId = extensionIdIdx >= 0 ? args[extensionIdIdx + 1] : undefined\n runSetup({ extensionId })\n} else if (args.includes('--native-host')) {\n // Native Messaging Host mode: bridge Chrome ↔ MCP Server\n // Socket may not exist yet (MCP Server starts when AI client connects).\n // Wait and retry until the socket appears.\n const SOCKET_PATH = '/tmp/viyv-browser.sock'\n const POLL_INTERVAL = 2000\n const MAX_WAIT = 120_000\n\n function waitForSocket() {\n const start = Date.now()\n\n function poll() {\n const socketPath = findSocketPath()\n if (socketPath) {\n process.stderr.write(`[viyv-browser:native-host] Found socket at ${socketPath}\\n`)\n startBridge({\n socketPath,\n onError: (error) => {\n process.stderr.write(`[viyv-browser:native-host] Error: ${error.message}\\n`)\n },\n })\n return\n }\n\n if (Date.now() - start > MAX_WAIT) {\n process.stderr.write(\n `[viyv-browser:native-host] MCP server socket not found after ${MAX_WAIT / 1000}s. Exiting.\\n`,\n )\n process.exit(1)\n }\n\n process.stderr.write(\n `[viyv-browser:native-host] Waiting for MCP server socket (${SOCKET_PATH})...\\n`,\n )\n setTimeout(poll, POLL_INTERVAL)\n }\n\n poll()\n }\n\n waitForSocket()\n} else {\n // MCP Server mode (default) — fixed path so bridge can always find it on reconnect\n const socketPath = '/tmp/viyv-browser.sock'\n const agentNameIdx = args.indexOf('--agent-name')\n const agentName = agentNameIdx >= 0 ? args[agentNameIdx + 1] : undefined\n\n const transportIdx = args.indexOf('--transport')\n const transportMode = transportIdx >= 0 ? args[transportIdx + 1] : 'stdio'\n if (transportMode !== 'stdio' && transportMode !== 'sse' && transportMode !== 'streamable-http') {\n process.stderr.write(\n `[viyv-browser:mcp] Invalid transport: \"${transportMode}\". Must be \"stdio\", \"sse\", or \"streamable-http\".\\n`,\n )\n process.exit(1)\n }\n const portIdx = args.indexOf('--port')\n const port = portIdx >= 0 ? Number(args[portIdx + 1]) : undefined\n\n startMcpServer(socketPath, agentName, { transport: transportMode, port })\n}\n\nfunction findSocketPath(): string | null {\n const envSocket = process.env.VIYV_BROWSER_SOCKET\n if (envSocket) return envSocket\n\n // Check fixed socket path first\n const fixedPath = '/tmp/viyv-browser.sock'\n if (existsSync(fixedPath)) return fixedPath\n\n // Fallback: scan for legacy PID-based sockets\n try {\n const tmpFiles = readdirSync('/tmp')\n const socketFile = tmpFiles.find((f) => f.startsWith('viyv-browser-') && f.endsWith('.sock'))\n if (socketFile) return `/tmp/${socketFile}`\n } catch {\n // Ignore\n }\n\n return null\n}\n","/**\n * Bridge between Native Messaging Host and MCP Server via Unix socket.\n *\n * When running as --native-host:\n * Chrome <-> stdin/stdout (Native Messaging) <-> this bridge <-> Unix socket <-> MCP Server\n */\n\nimport { existsSync } from 'node:fs'\nimport { type Socket, createConnection } from 'node:net'\nimport { LIMITS, RECONNECT } from '@viyv-browser/shared'\nimport { compressPayload, decompressPayload } from './compression.js'\nimport { createMessageReader, writeMessage } from './transport.js'\n\nconst MAX_BUFFER_SIZE = 1000\n\nexport interface BridgeOptions {\n socketPath: string\n onError?: (error: Error) => void\n}\n\nexport function startBridge(options: BridgeOptions): void {\n const { socketPath, onError } = options\n let socket: Socket | null = null\n let reconnecting = false\n let retryCount = 0\n\n // FIX #2: Actual message buffer for messages received while socket is disconnected\n const pendingMessages: unknown[] = []\n\n function flushBuffer() {\n if (!socket || socket.destroyed) return\n while (pendingMessages.length > 0) {\n const msg = pendingMessages[0] // FIX NL3: Peek first, don't shift until write succeeds\n try {\n const written = socket.write(`${JSON.stringify(msg)}\\n`)\n pendingMessages.shift() // Safe to remove after successful write call\n if (!written) {\n // Backpressure: wait for drain before continuing flush\n socket.once('drain', () => flushBuffer())\n return\n }\n } catch (error) {\n // Message stays in buffer for retry on reconnection\n onError?.(error as Error)\n return\n }\n }\n }\n\n function scheduleReconnect() {\n if (reconnecting) return\n reconnecting = true\n\n // Poll for socket file with short fixed interval so we pick up\n // a new MCP server quickly when switching between clients\n const POLL_INTERVAL = 2000\n\n function attemptReconnect() {\n if (existsSync(socketPath)) {\n process.stderr.write(\n `[viyv-browser:native-host] Socket found, reconnecting (attempt ${retryCount + 1})\\n`,\n )\n reconnecting = false\n connectSocket()\n } else {\n retryCount++\n if (retryCount > 60) {\n process.stderr.write(\n '[viyv-browser:native-host] Socket not found after 120s, slowing down polling\\n',\n )\n setTimeout(attemptReconnect, RECONNECT.MAX_DELAY)\n } else {\n setTimeout(attemptReconnect, POLL_INTERVAL)\n }\n }\n }\n\n const delay = retryCount === 0 ? RECONNECT.INITIAL_DELAY : POLL_INTERVAL\n setTimeout(attemptReconnect, delay)\n }\n\n function connectSocket() {\n socket = createConnection(socketPath)\n\n socket.on('connect', () => {\n process.stderr.write(`[viyv-browser:native-host] Connected to MCP server at ${socketPath}\\n`)\n retryCount = 0 // Reset backoff on successful connection\n flushBuffer()\n })\n\n // Messages from MCP Server -> Chrome (via stdout)\n // TCP stream fragmentation fix: line-based buffer\n let lineBuffer = ''\n\n socket.on('data', (data) => {\n lineBuffer += data.toString('utf-8')\n const lines = lineBuffer.split('\\n')\n lineBuffer = lines.pop() ?? '' // Keep incomplete last line\n for (const line of lines) {\n if (!line) continue\n try {\n let message = JSON.parse(line)\n // NM5: Decompress incoming compressed messages from MCP Server\n if (message.type === 'compressed' && typeof message.data === 'string') {\n const decompressed = decompressPayload(message.data, true)\n message = JSON.parse(decompressed)\n }\n writeMessage(process.stdout, message)\n } catch (error) {\n onError?.(error as Error)\n }\n }\n })\n\n socket.on('error', (error) => {\n process.stderr.write(`[viyv-browser:native-host] Socket error: ${error.message}\\n`)\n onError?.(error)\n })\n\n socket.on('close', () => {\n process.stderr.write('[viyv-browser:native-host] Socket closed\\n')\n socket = null\n scheduleReconnect()\n })\n }\n\n // Messages from Chrome (via stdin) -> MCP Server\n createMessageReader(\n process.stdin,\n (message) => {\n if (socket && !socket.destroyed) {\n // NM5: Compress large payloads (e.g., screenshots) before Unix socket transfer\n const json = JSON.stringify(message)\n if (json.length > LIMITS.CHUNK_SIZE) {\n const { compressed, wasCompressed } = compressPayload(json)\n if (wasCompressed) {\n socket.write(`${JSON.stringify({ type: 'compressed', data: compressed })}\\n`)\n } else {\n socket.write(`${json}\\n`)\n }\n } else {\n socket.write(`${json}\\n`)\n }\n } else {\n // Buffer messages while disconnected\n if (pendingMessages.length < MAX_BUFFER_SIZE) {\n pendingMessages.push(message)\n } else {\n process.stderr.write('[viyv-browser:native-host] Message buffer full, dropping message\\n')\n }\n }\n },\n onError,\n )\n\n connectSocket()\n\n // Clean shutdown handlers\n process.on('SIGINT', () => {\n socket?.destroy()\n process.exit(0)\n })\n\n process.on('SIGTERM', () => {\n socket?.destroy()\n process.exit(0)\n })\n\n process.stdin.on('end', () => {\n process.stderr.write('[viyv-browser:native-host] stdin closed, shutting down\\n')\n socket?.destroy()\n process.exit(0)\n })\n}\n","/** Protocol version for compatibility checks */\nexport const PROTOCOL_VERSION = '1.0.0'\n\n/** Native Messaging host name (must match manifest) */\nexport const NATIVE_HOST_NAME = 'com.viyv.browser'\n\n/** Extension ID (will be assigned by CWS) */\nexport const EXTENSION_ID = '' // Set after CWS registration\n\n// ── Timeouts (ms) ──\n\nexport const TIMEOUTS = {\n /** Overall MCP tool timeout */\n MCP_TOOL: 30_000,\n /** Native Messaging request timeout */\n NATIVE_MESSAGE: 15_000,\n /** CDP command timeout */\n CDP_COMMAND: 10_000,\n /** Screenshot capture timeout */\n SCREENSHOT: 5_000,\n /** Navigation timeout */\n NAVIGATION: 30_000,\n /** Chunk reassembly timeout */\n CHUNK_REASSEMBLY: 10_000,\n /** Default wait_for timeout */\n WAIT_FOR: 30_000,\n /** Heartbeat interval */\n HEARTBEAT: 30_000,\n /** CDP idle detach delay */\n CDP_IDLE_DETACH: 5_000,\n /** Tab lock TTL (deadlock prevention) */\n TAB_LOCK_TTL: 60_000,\n} as const\n\n// ── Limits ──\n\nexport const LIMITS = {\n /** Native Messaging max message size (Chrome limit) */\n NATIVE_MESSAGE_MAX_BYTES: 1024 * 1024,\n /** Chunk size for large payloads */\n CHUNK_SIZE: 768 * 1024,\n /** A11y tree max elements */\n A11Y_MAX_ELEMENTS: 5000,\n /** A11y tree default depth */\n A11Y_DEFAULT_DEPTH: 15,\n /** A11y tree default max chars */\n A11Y_DEFAULT_MAX_CHARS: 50_000,\n /** Event buffer max entries */\n EVENT_BUFFER_MAX: 1000,\n /** Event buffer max bytes */\n EVENT_BUFFER_MAX_BYTES: 10 * 1024 * 1024,\n /** Message buffer during disconnection */\n MESSAGE_BUFFER_MAX: 1000,\n /** Default screenshot JPEG quality */\n SCREENSHOT_JPEG_QUALITY: 80,\n /** Console buffer per tab */\n CONSOLE_BUFFER_MAX: 1000,\n /** Network buffer per tab */\n NETWORK_BUFFER_MAX: 1000,\n} as const\n\n// ── Reconnection ──\n\nexport const RECONNECT = {\n /** Initial delay (ms) */\n INITIAL_DELAY: 1000,\n /** Max delay (ms) */\n MAX_DELAY: 30_000,\n /** Backoff multiplier */\n MULTIPLIER: 2,\n} as const\n\n// ── Keep-alive ──\n\nexport const KEEP_ALIVE = {\n /** Alarm name for backup keep-alive */\n ALARM_NAME: 'viyv-browser-keepalive',\n /** Alarm period (minutes) - minimum for Chrome alarms */\n ALARM_PERIOD_MIN: 0.5,\n} as const\n\n// ── MCP Server ──\n\nexport const MCP_SERVER = {\n /** Server name for MCP protocol */\n NAME: 'viyv-browser',\n /** Server version */\n VERSION: '0.1.0',\n /** Unix socket path template */\n SOCKET_PATH_TEMPLATE: '/tmp/viyv-browser-{pid}.sock',\n} as const\n","/**\n * Compression utilities for large payloads.\n * Used when messages approach the 1MB Native Messaging limit.\n */\n\nimport { gunzipSync, gzipSync } from 'node:zlib'\nimport type { ChunkedMessage } from '@viyv-browser/shared'\n\nconst CHUNK_SIZE = 768 * 1024 // 768KB per chunk\n\n// Use shared ChunkedMessage as the canonical type\nexport type ChunkedPayload = ChunkedMessage\n\nexport function compressPayload(data: string): { compressed: string; wasCompressed: boolean } {\n const original = Buffer.from(data, 'utf-8')\n const gzipped = gzipSync(original)\n\n if (gzipped.length < original.length) {\n return { compressed: gzipped.toString('base64'), wasCompressed: true }\n }\n return { compressed: data, wasCompressed: false }\n}\n\nexport function decompressPayload(data: string, isCompressed: boolean): string {\n if (!isCompressed) return data\n const buf = Buffer.from(data, 'base64')\n return gunzipSync(buf).toString('utf-8')\n}\n\nexport function chunkPayload(\n requestId: string,\n agentId: string,\n data: string,\n compressed: boolean,\n): ChunkedPayload[] {\n const totalSize = data.length\n const totalChunks = Math.ceil(totalSize / CHUNK_SIZE)\n const chunks: ChunkedPayload[] = []\n\n for (let i = 0; i < totalChunks; i++) {\n chunks.push({\n type: 'chunk',\n requestId,\n agentId,\n chunkIndex: i,\n totalChunks,\n totalSize,\n compressed,\n data: data.slice(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE),\n })\n }\n\n return chunks\n}\n\n// FIX #20: Guard against empty chunks array\nexport function reassembleChunks(chunks: ChunkedPayload[]): string {\n if (chunks.length === 0) {\n throw new Error('Cannot reassemble: no chunks provided')\n }\n\n const sorted = [...chunks].sort((a, b) => a.chunkIndex - b.chunkIndex)\n\n if (sorted.length !== sorted[0].totalChunks) {\n throw new Error(`Incomplete chunks: got ${sorted.length}, expected ${sorted[0].totalChunks}`)\n }\n\n const data = sorted.map((c) => c.data).join('')\n return decompressPayload(data, sorted[0].compressed)\n}\n","/**\n * Native Messaging transport: length-prefixed JSON over stdin/stdout.\n * Chrome Native Messaging uses 4-byte little-endian length prefix + UTF-8 JSON.\n */\n\nconst MAX_MESSAGE_SIZE = 1024 * 1024 // 1MB Chrome limit\n\nexport function encodeMessage(message: unknown): Buffer {\n const json = JSON.stringify(message)\n const body = Buffer.from(json, 'utf-8')\n\n if (body.length > MAX_MESSAGE_SIZE) {\n throw new Error(`Message too large: ${body.length} bytes (max ${MAX_MESSAGE_SIZE})`)\n }\n\n const header = Buffer.alloc(4)\n header.writeUInt32LE(body.length, 0)\n return Buffer.concat([header, body])\n}\n\nexport function createMessageReader(\n stream: NodeJS.ReadableStream,\n onMessage: (message: unknown) => void,\n onError?: (error: Error) => void,\n onClose?: () => void,\n) {\n let buffer = Buffer.alloc(0)\n let expectedLength: number | null = null\n\n stream.on('data', (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk])\n\n while (true) {\n // Read length header\n if (expectedLength === null) {\n if (buffer.length < 4) break\n expectedLength = buffer.readUInt32LE(0)\n buffer = buffer.subarray(4)\n\n if (expectedLength > MAX_MESSAGE_SIZE) {\n onError?.(new Error(`Message too large: ${expectedLength} bytes`))\n expectedLength = null\n buffer = Buffer.alloc(0)\n break\n }\n }\n\n // Read message body\n if (buffer.length < expectedLength) break\n\n const jsonBuffer = buffer.subarray(0, expectedLength)\n buffer = buffer.subarray(expectedLength)\n expectedLength = null\n\n try {\n const message = JSON.parse(jsonBuffer.toString('utf-8'))\n onMessage(message)\n } catch (error) {\n onError?.(new Error(`Invalid JSON: ${(error as Error).message}`))\n }\n }\n })\n\n // FIX #19: Handle stream close/error events\n stream.on('error', (error: Error) => {\n onError?.(new Error(`Stream error: ${error.message}`))\n })\n\n stream.on('end', () => {\n onClose?.()\n })\n\n stream.on('close', () => {\n onClose?.()\n })\n}\n\nexport function writeMessage(stream: NodeJS.WritableStream, message: unknown): void {\n const encoded = encodeMessage(message)\n stream.write(encoded)\n}\n","/**\n * MCP Server for viyv-browser.\n * Communicates with viyv Daemon via stdio (JSON-RPC), SSE (HTTP), or Streamable HTTP,\n * and with Chrome Extension via Unix socket <-> Native Messaging bridge.\n */\n\nimport { randomUUID } from 'node:crypto'\nimport { chmodSync, existsSync, statSync, unlinkSync } from 'node:fs'\nimport http from 'node:http'\nimport { type Server as NetServer, type Socket, createConnection, createServer } from 'node:net'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport { type BrowserEventType, MCP_SERVER, PROTOCOL_VERSION, TIMEOUTS } from '@viyv-browser/shared'\nimport { z } from 'zod'\nimport {\n closeSession,\n createSession,\n getDefaultAgentId,\n setDefaultAgentId,\n touchSession,\n} from './agent-session.js'\nimport {\n addEventListener,\n addSubscription,\n processEvent,\n removeEventListener,\n removeSubscription,\n removeSubscriptionsByAgent,\n} from './event-bridge.js'\nimport {\n getHealthStatus,\n isExtensionConnected,\n recordHeartbeat,\n setExtensionConnected,\n} from './health.js'\nimport { decompressPayload } from './native-host/compression.js'\nimport { allTools } from './tools/index.js'\n\ntype ToolContentItem =\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n\ninterface PendingRequest {\n resolve: (result: Record<string, unknown>) => void\n reject: (error: Error) => void\n timer: ReturnType<typeof setTimeout>\n}\n\nconst pendingRequests = new Map<string, PendingRequest>()\nlet extensionSocket: Socket | null = null\n\nexport interface McpServerOptions {\n transport?: 'stdio' | 'sse' | 'streamable-http'\n port?: number\n}\n\ninterface StreamableHttpSession {\n transport: StreamableHTTPServerTransport\n server: McpServer\n lastActivity: number\n}\n\n/**\n * Coerce a single string value to its intended type (before Zod validation).\n * Some MCP clients (e.g. Claude Code deferred tools) send all params as strings.\n */\nfunction coerceValue(v: unknown): unknown {\n if (typeof v !== 'string') return v\n // JSON arrays and objects\n if ((v.startsWith('[') && v.endsWith(']')) || (v.startsWith('{') && v.endsWith('}'))) {\n try {\n return JSON.parse(v)\n } catch {\n /* keep as string */\n }\n }\n // Booleans (can't use z.coerce.boolean: Boolean(\"false\") === true)\n if (v === 'true') return true\n if (v === 'false') return false\n return v\n}\n\n/**\n * Wrap each field in a Zod shape with z.preprocess() so string-encoded\n * values are coerced BEFORE Zod validation runs.\n */\nfunction coerceShape(shape: Record<string, z.ZodType>): Record<string, z.ZodType> {\n const result: Record<string, z.ZodType> = {}\n for (const [key, schema] of Object.entries(shape)) {\n result[key] = z.preprocess(coerceValue, schema)\n }\n return result\n}\n\n/**\n * Creates a fully configured McpServer with all tools registered and event forwarding.\n * Each session (SSE / Streamable HTTP) needs its own instance (McpServer.connect() can only be called once).\n */\nfunction createConfiguredMcpServer(): McpServer {\n const server = new McpServer({\n name: MCP_SERVER.NAME,\n version: MCP_SERVER.VERSION,\n })\n\n // Register all tools -- pass Zod shape directly (FIX #1: MCP SDK expects Zod, not JSON Schema)\n for (const tool of allTools) {\n const def = tool.inputSchema._def as { shape?: () => Record<string, unknown> }\n const shape = def.shape?.() ?? {}\n server.tool(\n tool.name,\n tool.description,\n coerceShape(shape as Record<string, z.ZodType>),\n async (params: Record<string, unknown>) => {\n const result = await callExtensionTool(tool.name, params as Record<string, unknown>)\n\n // BUG-4 FIX: Sync event subscriptions with MCP server's event-bridge\n const first = result.content[0]\n if (tool.name === 'browser_event_subscribe' && first?.type === 'text') {\n try {\n const parsed = JSON.parse(first.text)\n if (parsed.subscriptionId) {\n const p = params as Record<string, unknown>\n addSubscription({\n id: parsed.subscriptionId,\n agentId: getDefaultAgentId(),\n eventTypes: (p.eventTypes as BrowserEventType[]) ?? [],\n urlPattern: p.urlPattern as string | undefined,\n createdAt: Date.now(),\n })\n }\n } catch {\n /* ignore parse errors */\n }\n } else if (tool.name === 'browser_event_unsubscribe' && first?.type === 'text') {\n try {\n const parsed = JSON.parse(first.text)\n if (parsed.subscriptionId) {\n removeSubscription(parsed.subscriptionId)\n }\n } catch {\n /* ignore parse errors */\n }\n }\n\n return result\n },\n )\n }\n\n // Forward browser events through MCP logging notification\n const listener = (event: Record<string, unknown>) => {\n server\n .sendLoggingMessage({\n level: 'info',\n data: event,\n })\n .catch(() => {\n // Ignore send errors for events (client may not be listening)\n })\n }\n addEventListener(listener)\n\n // Clean up listener when transport closes\n server.server.onclose = () => {\n removeEventListener(listener)\n }\n\n return server\n}\n\nexport async function startMcpServer(\n socketPath: string,\n agentName?: string,\n options?: McpServerOptions,\n): Promise<void> {\n if (agentName) {\n setDefaultAgentId(agentName)\n }\n\n // -- Unix Socket Server (for Native Host connections) -- shared by all transports\n // Evict bridge from any previous MCP server so it reconnects to us\n await evictExistingBridge(socketPath)\n const socketServer = createSocketServer(socketPath)\n\n if (options?.transport === 'sse') {\n // -- SSE mode: HTTP server, one McpServer per SSE session --\n const sessions = new Map<string, { transport: SSEServerTransport; server: McpServer }>()\n\n const httpServer = http.createServer()\n\n httpServer.on('request', (req, res) => {\n handleSseRequest(req, res, sessions).catch((error) => {\n process.stderr.write(`[viyv-browser:mcp] SSE request error: ${(error as Error).message}\\n`)\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n })\n })\n\n const listenPort = options.port ?? 0\n httpServer.listen(listenPort, '127.0.0.1', () => {\n const addr = httpServer.address()\n const port = typeof addr === 'object' ? addr?.port : listenPort\n process.stdout.write(`${JSON.stringify({ port })}\\n`)\n process.stderr.write(`[viyv-browser:mcp] SSE server listening on 127.0.0.1:${port}\\n`)\n })\n\n process.stderr.write(`[viyv-browser:mcp] MCP Server started (SSE), socket: ${socketPath}\\n`)\n\n // Graceful shutdown: close SSE sessions async, then sync cleanup\n let shuttingDown = false\n const shutdown = async () => {\n if (shuttingDown) return\n shuttingDown = true\n for (const { server: s } of sessions.values()) {\n await s.close().catch(() => {})\n }\n httpServer.close(() => {})\n socketServer.close(() => {})\n cleanupSocket(socketPath)\n process.exit(0)\n }\n process.on('SIGINT', () => {\n shutdown()\n })\n process.on('SIGTERM', () => {\n shutdown()\n })\n\n // Sync fallback for unexpected exit (e.g. uncaughtException)\n // shutdown() already handled close — only clean up socket file here\n process.on('exit', () => {\n cleanupSocket(socketPath)\n })\n } else if (options?.transport === 'streamable-http') {\n // -- Streamable HTTP mode: per-session McpServer with TTL --\n const sessions = new Map<string, StreamableHttpSession>()\n\n const SESSION_TTL = 30 * 60 * 1000 // 30 minutes\n const SWEEP_INTERVAL = 5 * 60 * 1000 // 5 minutes\n\n const sweepTimer = setInterval(() => {\n const now = Date.now()\n for (const [id, session] of sessions) {\n if (now - session.lastActivity > SESSION_TTL) {\n process.stderr.write(`[viyv-browser:mcp] Streamable HTTP session TTL expired: ${id}\\n`)\n // Delete from Map first to prevent concurrent requests hitting a closing transport\n sessions.delete(id)\n session.server.close().catch(() => {})\n }\n }\n }, SWEEP_INTERVAL)\n sweepTimer.unref()\n\n const httpServer = http.createServer()\n\n httpServer.on('request', (req, res) => {\n handleStreamableHttpRequest(req, res, sessions).catch((error) => {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP request error: ${(error as Error).message}\\n`,\n )\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n })\n })\n\n const listenPort = options.port ?? 0\n httpServer.listen(listenPort, '127.0.0.1', () => {\n const addr = httpServer.address()\n const port = typeof addr === 'object' ? addr?.port : listenPort\n process.stdout.write(`${JSON.stringify({ port })}\\n`)\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP server listening on 127.0.0.1:${port}\\n`,\n )\n })\n\n process.stderr.write(\n `[viyv-browser:mcp] MCP Server started (streamable-http), socket: ${socketPath}\\n`,\n )\n\n // Graceful shutdown\n let shuttingDown = false\n const shutdown = async () => {\n if (shuttingDown) return\n shuttingDown = true\n clearInterval(sweepTimer)\n for (const { server: s } of sessions.values()) {\n await s.close().catch(() => {})\n }\n httpServer.close(() => {})\n socketServer.close(() => {})\n cleanupSocket(socketPath)\n process.exit(0)\n }\n process.on('SIGINT', () => {\n shutdown()\n })\n process.on('SIGTERM', () => {\n shutdown()\n })\n\n process.on('exit', () => {\n cleanupSocket(socketPath)\n })\n } else {\n // -- stdio mode (default) --\n const server = createConfiguredMcpServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n process.stderr.write(`[viyv-browser:mcp] MCP Server started (stdio), socket: ${socketPath}\\n`)\n\n process.on('SIGINT', () => process.exit(0))\n process.on('SIGTERM', () => process.exit(0))\n\n process.on('exit', () => {\n socketServer.close()\n cleanupSocket(socketPath)\n })\n }\n}\n\nasync function handleSseRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n sessions: Map<string, { transport: SSEServerTransport; server: McpServer }>,\n): Promise<void> {\n if (req.method === 'GET' && req.url === '/sse') {\n // New SSE session\n const transport = new SSEServerTransport('/message', res)\n const mcpServer = createConfiguredMcpServer()\n\n transport.onclose = () => {\n sessions.delete(transport.sessionId)\n }\n\n // Fallback: clean up session if HTTP connection closes without transport.onclose\n res.on('close', () => {\n if (sessions.has(transport.sessionId)) {\n sessions.delete(transport.sessionId)\n transport.close()\n }\n })\n\n await mcpServer.connect(transport)\n\n // Register session only after connect succeeds\n sessions.set(transport.sessionId, { transport, server: mcpServer })\n } else if (req.method === 'POST' && req.url?.startsWith('/message')) {\n // Route POST to the correct session\n const url = new URL(req.url, `http://${req.headers.host ?? 'localhost'}`)\n const sessionId = url.searchParams.get('sessionId')\n const session = sessionId ? sessions.get(sessionId) : null\n\n if (session) {\n await session.transport.handlePostMessage(req, res)\n } else {\n res.writeHead(404).end('Session not found')\n }\n } else {\n res.writeHead(404).end()\n }\n}\n\nasync function handleStreamableHttpRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n sessions: Map<string, StreamableHttpSession>,\n): Promise<void> {\n let url: URL\n try {\n url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)\n } catch {\n res.writeHead(400).end('Bad request')\n return\n }\n\n if (url.pathname !== '/mcp') {\n res.writeHead(404).end('Not found')\n return\n }\n\n const rawSessionId = req.headers['mcp-session-id']\n const sessionId = typeof rawSessionId === 'string' ? rawSessionId : undefined\n const existingSession = sessionId ? sessions.get(sessionId) : undefined\n\n // Existing session: route request to its transport\n if (existingSession) {\n existingSession.lastActivity = Date.now()\n\n if (req.method === 'POST') {\n let body: unknown\n try {\n body = await parseJsonBody(req)\n } catch (parseError) {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP body parse failed: ${(parseError as Error).message}\\n`,\n )\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32700, message: 'Parse error' },\n id: null,\n }),\n )\n return\n }\n await existingSession.transport.handleRequest(req, res, body)\n } else {\n // GET (SSE stream) or DELETE (session termination) — SDK handles method routing\n await existingSession.transport.handleRequest(req, res)\n }\n return\n }\n\n // New session: only accept POST with initialize request\n if (!sessionId && req.method === 'POST') {\n let body: unknown\n try {\n body = await parseJsonBody(req)\n } catch (parseError) {\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP body parse failed: ${(parseError as Error).message}\\n`,\n )\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32700, message: 'Parse error' },\n id: null,\n }),\n )\n return\n }\n\n if (!isInitializeRequest(body)) {\n const requestId =\n body && typeof body === 'object' && 'id' in body ? (body as { id: unknown }).id : null\n res.writeHead(400, { 'Content-Type': 'application/json' }).end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32600, message: 'First request must be an initialize request' },\n id: requestId ?? null,\n }),\n )\n return\n }\n\n const mcpServer = createConfiguredMcpServer()\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { transport, server: mcpServer, lastActivity: Date.now() })\n },\n })\n\n // Set onclose before server.connect() — Protocol wraps existing onclose\n transport.onclose = () => {\n const id = transport.sessionId\n if (id) sessions.delete(id)\n }\n\n let connected = false\n try {\n await mcpServer.connect(transport)\n connected = true\n await transport.handleRequest(req, res, body)\n } catch (error) {\n const stage = connected ? 'handleRequest' : 'connect'\n process.stderr.write(\n `[viyv-browser:mcp] Streamable HTTP session ${stage} failed: ${(error as Error).message}\\n`,\n )\n // Ensure event listener cleanup even if connect() didn't complete wrapping\n try {\n mcpServer.server.onclose?.()\n } catch {\n /* ignore */\n }\n await mcpServer.close().catch(() => {})\n if (!res.headersSent) {\n res.writeHead(500).end('Internal server error')\n }\n }\n return\n }\n\n // Known session ID but not in map → expired or terminated\n if (sessionId && !existingSession) {\n res.writeHead(404).end('Session not found')\n return\n }\n\n res.writeHead(400).end('Bad request')\n}\n\nconst MAX_BODY_SIZE = 4 * 1024 * 1024\n\nfunction parseJsonBody(req: http.IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = []\n let size = 0\n let destroyed = false\n req.on('data', (chunk: Buffer) => {\n if (destroyed) return\n size += chunk.length\n if (size > MAX_BODY_SIZE) {\n destroyed = true\n req.destroy()\n reject(new Error('Request body too large'))\n return\n }\n chunks.push(chunk)\n })\n req.on('end', () => {\n if (destroyed) return\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString('utf-8')))\n } catch (error) {\n reject(new Error(`Invalid JSON: ${(error as Error).message}`))\n }\n })\n req.on('error', (err) => {\n if (!destroyed) reject(err)\n })\n })\n}\n\n/**\n * Connect briefly to an existing socket to trigger FIX #6 (bridge disconnect).\n * The old MCP server's connection handler destroys the current bridge connection\n * when a new connection arrives, causing the bridge to reconnect.\n */\nfunction evictExistingBridge(socketPath: string): Promise<void> {\n if (!existsSync(socketPath)) return Promise.resolve()\n\n return new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n tempSocket.destroy()\n resolve()\n }, 2000)\n\n const tempSocket = createConnection(socketPath)\n\n tempSocket.on('connect', () => {\n process.stderr.write('[viyv-browser:mcp] Evicted bridge from previous MCP server\\n')\n // Give the old server a moment to process the disconnect\n setTimeout(() => {\n tempSocket.destroy()\n clearTimeout(timeout)\n resolve()\n }, 300)\n })\n\n tempSocket.on('error', () => {\n clearTimeout(timeout)\n resolve()\n })\n })\n}\n\nfunction createSocketServer(socketPath: string): NetServer {\n cleanupSocket(socketPath)\n\n const server = createServer((socket) => {\n // FIX #6: Clean up old connection before accepting new one\n if (extensionSocket && !extensionSocket.destroyed) {\n process.stderr.write('[viyv-browser:mcp] Replacing existing extension connection\\n')\n extensionSocket.destroy()\n }\n\n process.stderr.write('[viyv-browser:mcp] Extension connected via Unix socket\\n')\n extensionSocket = socket\n setExtensionConnected(true)\n\n // NM3: Send session_init with protocol version on connection\n const agentId = getDefaultAgentId()\n createSession(agentId)\n const initMsg = {\n id: randomUUID(),\n type: 'session_init',\n agentId,\n protocolVersion: PROTOCOL_VERSION,\n timestamp: Date.now(),\n }\n socket.write(`${JSON.stringify(initMsg)}\\n`)\n\n // TCP stream fragmentation fix: line-based buffer\n let lineBuffer = ''\n\n socket.on('data', (data) => {\n lineBuffer += data.toString('utf-8')\n const lines = lineBuffer.split('\\n')\n lineBuffer = lines.pop() ?? '' // Keep incomplete last line\n for (const line of lines) {\n if (!line) continue\n try {\n let parsed = JSON.parse(line)\n // NM5: Handle compressed messages from Native Host\n if (parsed.type === 'compressed' && typeof parsed.data === 'string') {\n const decompressed = decompressPayload(parsed.data, true)\n parsed = JSON.parse(decompressed)\n }\n handleExtensionMessage(parsed)\n } catch (error) {\n process.stderr.write(`[viyv-browser:mcp] Parse error: ${(error as Error).message}\\n`)\n }\n }\n })\n\n socket.on('close', () => {\n process.stderr.write('[viyv-browser:mcp] Extension disconnected\\n')\n // Only clear if this is still the active socket\n if (extensionSocket === socket) {\n extensionSocket = null\n setExtensionConnected(false)\n }\n\n // Reject all pending requests on disconnect\n for (const [id, pending] of pendingRequests) {\n clearTimeout(pending.timer)\n pendingRequests.delete(id)\n pending.resolve({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message: 'Extension disconnected while request was pending',\n },\n })\n }\n })\n\n socket.on('error', (error) => {\n process.stderr.write(`[viyv-browser:mcp] Socket error: ${error.message}\\n`)\n })\n })\n\n server.on('error', (error: NodeJS.ErrnoException) => {\n if (error.code === 'EADDRINUSE') {\n process.stderr.write(\n `[viyv-browser:mcp] Socket ${socketPath} already in use, forcing cleanup...\\n`,\n )\n cleanupSocket(socketPath)\n server.listen(socketPath, () => {\n chmodSync(socketPath, 0o666)\n process.stderr.write(`[viyv-browser:mcp] Unix socket listening on ${socketPath} (retry)\\n`)\n })\n } else {\n process.stderr.write(`[viyv-browser:mcp] Server error: ${error.message} (${error.code})\\n`)\n }\n })\n\n server.listen(socketPath, () => {\n chmodSync(socketPath, 0o666)\n process.stderr.write(`[viyv-browser:mcp] Unix socket listening on ${socketPath}\\n`)\n })\n\n return server\n}\n\n// FIX #8: Validate message structure before processing\nfunction handleExtensionMessage(message: unknown) {\n if (!message || typeof message !== 'object') return\n const msg = message as Record<string, unknown>\n\n const type = typeof msg.type === 'string' ? msg.type : null\n const id = typeof msg.id === 'string' ? msg.id : null\n if (!type) return\n\n if (type === 'tool_result' && id) {\n const pending = pendingRequests.get(id)\n if (pending) {\n clearTimeout(pending.timer)\n pendingRequests.delete(id)\n\n if (msg.success) {\n pending.resolve((msg.result as Record<string, unknown>) ?? {})\n } else {\n const err = msg.error as Record<string, unknown> | undefined\n const code = typeof err?.code === 'string' ? err.code : 'UNKNOWN'\n const errMsg = typeof err?.message === 'string' ? err.message : 'Unknown error'\n pending.reject(new Error(`[${code}] ${errMsg}`))\n }\n }\n } else if (type === 'session_heartbeat') {\n recordHeartbeat()\n // NM6: Touch session on heartbeat\n const hbAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (hbAgentId) touchSession(hbAgentId)\n } else if (type === 'session_close') {\n // NH2: Clean up session resources on close\n const closeAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (closeAgentId) {\n closeSession(closeAgentId)\n // L2 FIX: Clean up stale event subscriptions for this agent\n removeSubscriptionsByAgent(closeAgentId)\n process.stderr.write(`[viyv-browser:mcp] Session closed and cleaned up: ${closeAgentId}\\n`)\n }\n } else if (type === 'session_recovery') {\n // NH2: Handle session recovery after SW restart\n const recoveryAgentId = typeof msg.agentId === 'string' ? msg.agentId : null\n if (recoveryAgentId) {\n createSession(recoveryAgentId)\n process.stderr.write(`[viyv-browser:mcp] Session recovered: ${recoveryAgentId}\\n`)\n }\n } else if (type === 'session_init') {\n // L3 FIX: Verify Extension's protocol version (bidirectional check)\n const remoteVersion = typeof msg.protocolVersion === 'string' ? msg.protocolVersion : null\n if (remoteVersion && remoteVersion !== PROTOCOL_VERSION) {\n process.stderr.write(\n `[viyv-browser:mcp] Protocol version mismatch: local=${PROTOCOL_VERSION}, remote=${remoteVersion}\\n`,\n )\n }\n } else if (type === 'browser_event') {\n process.stderr.write(`[viyv-browser:mcp] Browser event: ${String(msg.eventType)}\\n`)\n processEvent({\n eventType: msg.eventType as import('@viyv-browser/shared').BrowserEventType,\n agentId: String(msg.agentId ?? ''),\n tabId: Number(msg.tabId ?? 0),\n url: String(msg.url ?? ''),\n payload: (msg.payload as Record<string, unknown>) ?? {},\n sequenceNumber: Number(msg.sequenceNumber ?? 0),\n })\n }\n}\n\nasync function callExtensionTool(\n tool: string,\n input: Record<string, unknown>,\n): Promise<{ content: ToolContentItem[] }> {\n // browser_health is handled server-side: report connection status without requiring socket\n if (tool === 'browser_health') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(getHealthStatus()),\n },\n ],\n }\n }\n\n // switch_browser is handled server-side: disconnect and wait for reconnection\n if (tool === 'switch_browser') {\n return handleSwitchBrowser()\n }\n\n // file_upload: validate file paths exist before forwarding to extension\n if (tool === 'file_upload') {\n const paths = input.paths as string[] | undefined\n if (paths) {\n for (const p of paths) {\n try {\n if (!existsSync(p) || !statSync(p).isFile()) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'FILE_NOT_FOUND', message: `File not found: ${p}` },\n }),\n },\n ],\n }\n }\n } catch {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'FILE_NOT_FOUND', message: `Cannot access file: ${p}` },\n }),\n },\n ],\n }\n }\n }\n }\n }\n\n if (!extensionSocket || extensionSocket.destroyed) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message:\n 'Chrome Extension is not connected. Please open Chrome and click the Viyv Browser extension icon.',\n },\n }),\n },\n ],\n }\n }\n\n const requestId = randomUUID()\n const agentId = getDefaultAgentId()\n\n // NM6: Touch session to record activity\n touchSession(agentId)\n\n // Capture socket reference before entering Promise to avoid null race\n const sock = extensionSocket\n\n // Per-tool timeout: wait_for gets the tool's timeout + 5s buffer\n let toolTimeout = TIMEOUTS.MCP_TOOL\n if (tool === 'wait_for' && typeof input.timeout === 'number') {\n toolTimeout = input.timeout + 5000\n }\n\n return new Promise((resolve) => {\n // M3 FIX: Define error listener before timer so removeErrorListener is callable from timeout\n const onError = () => {\n const pending = pendingRequests.get(requestId)\n if (pending) {\n clearTimeout(pending.timer)\n pendingRequests.delete(requestId)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'EXTENSION_NOT_CONNECTED',\n message: 'Socket write failed',\n },\n }),\n },\n ],\n })\n }\n }\n\n const removeErrorListener = () => {\n sock.removeListener('error', onError)\n }\n\n const timer = setTimeout(() => {\n pendingRequests.delete(requestId)\n removeErrorListener()\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'TIMEOUT',\n message: `Tool '${tool}' timed out after ${toolTimeout}ms`,\n },\n }),\n },\n ],\n })\n }, toolTimeout)\n\n pendingRequests.set(requestId, {\n resolve: (result) => {\n removeErrorListener()\n if (tool === 'screenshot' && typeof result.data === 'string') {\n const { data, ...metadata } = result\n const mimeType = metadata.format === 'png' ? 'image/png' : 'image/jpeg'\n resolve({\n content: [\n { type: 'image' as const, data: data as string, mimeType },\n { type: 'text' as const, text: JSON.stringify(metadata) },\n ],\n })\n } else {\n resolve({\n content: [{ type: 'text' as const, text: JSON.stringify(result) }],\n })\n }\n },\n reject: (error) => {\n removeErrorListener()\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: { code: 'CDP_ERROR', message: error.message },\n }),\n },\n ],\n })\n },\n timer,\n })\n\n // FIX #7: Handle socket write errors\n const request = {\n id: requestId,\n type: 'tool_call',\n agentId,\n tool,\n input,\n timestamp: Date.now(),\n }\n\n const written = sock.write(`${JSON.stringify(request)}\\n`)\n if (!written) {\n // Backpressure -- wait for drain but don't block\n sock.once('drain', () => {\n // Buffer flushed, nothing to do\n })\n }\n\n sock.once('error', onError)\n })\n}\n\nasync function handleSwitchBrowser(): Promise<{ content: ToolContentItem[] }> {\n const SWITCH_TIMEOUT = 60_000\n\n // Close existing connection gracefully\n if (extensionSocket && !extensionSocket.destroyed) {\n process.stderr.write('[viyv-browser:mcp] switch_browser: closing current connection\\n')\n extensionSocket.destroy()\n extensionSocket = null\n setExtensionConnected(false)\n }\n\n // Wait for a new connection\n process.stderr.write('[viyv-browser:mcp] switch_browser: waiting for new browser connection...\\n')\n return new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (extensionSocket && !extensionSocket.destroyed && isExtensionConnected()) {\n clearInterval(checkInterval)\n clearTimeout(timer)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n switched: true,\n message: 'Successfully connected to new browser instance.',\n }),\n },\n ],\n })\n }\n }, 500)\n\n const timer = setTimeout(() => {\n clearInterval(checkInterval)\n resolve({\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n error: {\n code: 'TIMEOUT',\n message: `No new browser connected within ${SWITCH_TIMEOUT / 1000}s. Please open Chrome and click the Viyv Browser extension icon.`,\n },\n }),\n },\n ],\n })\n }, SWITCH_TIMEOUT)\n })\n}\n\nfunction cleanupSocket(socketPath: string) {\n if (!existsSync(socketPath)) return\n\n try {\n unlinkSync(socketPath)\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'EPERM' || err.code === 'EACCES') {\n process.stderr.write(\n `[viyv-browser:mcp] Cannot remove stale socket (${err.code}), retrying with chmod...\\n`,\n )\n try {\n chmodSync(socketPath, 0o666)\n unlinkSync(socketPath)\n } catch (retryError) {\n process.stderr.write(\n `[viyv-browser:mcp] Failed to remove socket after chmod: ${(retryError as Error).message}\\n`,\n )\n }\n } else if (err.code !== 'ENOENT') {\n process.stderr.write(`[viyv-browser:mcp] Socket cleanup error: ${err.message}\\n`)\n }\n }\n}\n","/**\n * Multi-agent session management.\n * Tracks which agents are connected and their session tokens.\n */\n\nimport { randomUUID } from 'node:crypto'\n\ninterface AgentSessionInfo {\n agentId: string\n sessionToken: string\n agentName: string\n status: 'active' | 'idle' | 'disconnected'\n lastActivity: number\n createdAt: number\n}\n\nconst sessions = new Map<string, AgentSessionInfo>()\nlet configuredDefaultAgentId = 'default'\n\nexport function setDefaultAgentId(id: string): void {\n configuredDefaultAgentId = id\n}\n\nexport function createSession(agentId: string, agentName?: string): AgentSessionInfo {\n const existing = sessions.get(agentId)\n if (existing) {\n existing.lastActivity = Date.now()\n existing.status = 'active'\n return existing\n }\n\n const session: AgentSessionInfo = {\n agentId,\n sessionToken: randomUUID(),\n agentName: agentName ?? agentId,\n status: 'active',\n lastActivity: Date.now(),\n createdAt: Date.now(),\n }\n\n sessions.set(agentId, session)\n return session\n}\n\nexport function getSession(agentId: string): AgentSessionInfo | undefined {\n return sessions.get(agentId)\n}\n\nexport function validateSession(agentId: string, sessionToken: string): boolean {\n const session = sessions.get(agentId)\n return session?.sessionToken === sessionToken\n}\n\nexport function touchSession(agentId: string): void {\n const session = sessions.get(agentId)\n if (session) {\n session.lastActivity = Date.now()\n }\n}\n\nexport function closeSession(agentId: string): void {\n sessions.delete(agentId)\n}\n\nexport function listSessions(): AgentSessionInfo[] {\n return Array.from(sessions.values())\n}\n\nexport function getDefaultAgentId(): string {\n // Return the first active session, or create a default\n const active = Array.from(sessions.values()).find((s) => s.status === 'active')\n if (active) return active.agentId\n\n const defaultSession = createSession(configuredDefaultAgentId)\n return defaultSession.agentId\n}\n\nconst STALE_SESSION_TTL = 5 * 60 * 1000 // 5 minutes\nconst CLEANUP_INTERVAL = 60 * 1000 // Check every minute\n\nexport function cleanupStaleSessions(): number {\n const now = Date.now()\n let cleaned = 0\n for (const [agentId, session] of sessions) {\n if (now - session.lastActivity > STALE_SESSION_TTL) {\n sessions.delete(agentId)\n cleaned++\n }\n }\n if (cleaned > 0) {\n process.stderr.write(`[viyv-browser:mcp] Cleaned up ${cleaned} stale session(s)\\n`)\n }\n return cleaned\n}\n\n// Periodic stale session cleanup\nconst cleanupTimer = setInterval(cleanupStaleSessions, CLEANUP_INTERVAL)\ncleanupTimer.unref() // Don't prevent process from exiting\n","/**\n * Event bridge: forwards browser events from Extension to stdout\n * for consumption by viyv Daemon EventTriggerManager.\n */\n\nimport type { BrowserEventType, EventSubscription } from '@viyv-browser/shared'\n\nconst subscriptions = new Map<string, EventSubscription>()\nconst eventListeners = new Set<(event: Record<string, unknown>) => void>()\n\nexport function addEventListener(cb: (event: Record<string, unknown>) => void) {\n eventListeners.add(cb)\n}\n\nexport function removeEventListener(cb: (event: Record<string, unknown>) => void) {\n eventListeners.delete(cb)\n}\n\nexport function addSubscription(sub: EventSubscription): void {\n subscriptions.set(sub.id, sub)\n}\n\nexport function removeSubscription(subId: string): boolean {\n return subscriptions.delete(subId)\n}\n\n// L2 FIX: Remove all subscriptions for an agent on session close\nexport function removeSubscriptionsByAgent(agentId: string): number {\n let removed = 0\n for (const [id, sub] of subscriptions) {\n if (sub.agentId === agentId) {\n subscriptions.delete(id)\n removed++\n }\n }\n return removed\n}\n\nexport function getSubscriptions(agentId?: string): EventSubscription[] {\n const subs = Array.from(subscriptions.values())\n if (agentId) return subs.filter((s) => s.agentId === agentId)\n return subs\n}\n\nexport function processEvent(event: {\n eventType: BrowserEventType\n agentId: string\n tabId: number\n url: string\n payload: Record<string, unknown>\n sequenceNumber: number\n}): void {\n // Check subscriptions\n for (const sub of subscriptions.values()) {\n if (sub.agentId !== event.agentId) continue\n if (!sub.eventTypes.includes(event.eventType)) continue\n if (sub.urlPattern && !event.url.includes(sub.urlPattern)) continue\n\n // Forward to all listeners\n const payload = {\n type: 'browser_event',\n subscriptionId: sub.id,\n ...event,\n timestamp: Date.now(),\n }\n for (const listener of eventListeners) {\n listener(payload)\n }\n }\n}\n","/**\n * Health check for MCP Server ↔ Extension connection.\n */\n\nlet extensionConnected = false\nlet lastHeartbeat: number | null = null\n\nexport function setExtensionConnected(connected: boolean) {\n extensionConnected = connected\n if (connected) lastHeartbeat = Date.now()\n}\n\nexport function recordHeartbeat() {\n lastHeartbeat = Date.now()\n}\n\nconst HEARTBEAT_STALENESS_MS = 60_000\n\nexport function isExtensionConnected(): boolean {\n if (!extensionConnected) return false\n // Also verify heartbeat is within staleness threshold\n if (lastHeartbeat !== null && Date.now() - lastHeartbeat > HEARTBEAT_STALENESS_MS) {\n return false\n }\n return true\n}\n\nexport function getHealthStatus() {\n return {\n extensionConnected,\n lastHeartbeat,\n uptime: process.uptime(),\n memoryUsage: process.memoryUsage().heapUsed,\n }\n}\n","/**\n * Tool registry: defines all MCP tools and their schemas.\n */\n\nimport { z } from 'zod'\n\nimport { FILE_UPLOAD_DESCRIPTION } from './advanced/file-upload.js'\nimport { GIF_CREATOR_DESCRIPTION } from './advanced/gif-creator.js'\nimport { RESIZE_WINDOW_DESCRIPTION } from './advanced/resize-window.js'\nimport { SHORTCUTS_EXECUTE_DESCRIPTION } from './advanced/shortcuts-execute.js'\nimport { SHORTCUTS_LIST_DESCRIPTION } from './advanced/shortcuts-list.js'\nimport { SWITCH_BROWSER_DESCRIPTION } from './advanced/switch-browser.js'\nimport { UPDATE_PLAN_DESCRIPTION } from './advanced/update-plan.js'\nimport { UPLOAD_IMAGE_DESCRIPTION } from './advanced/upload-image.js'\nimport { CLICK_DESCRIPTION } from './core/click.js'\nimport { DRAG_DESCRIPTION } from './core/drag.js'\nimport { FIND_DESCRIPTION } from './core/find.js'\nimport { FORM_INPUT_DESCRIPTION } from './core/form-input.js'\nimport { GET_PAGE_TEXT_DESCRIPTION } from './core/get-page-text.js'\nimport { HANDLE_DIALOG_DESCRIPTION } from './core/handle-dialog.js'\nimport { HOVER_DESCRIPTION } from './core/hover.js'\nimport { JAVASCRIPT_EXEC_DESCRIPTION } from './core/javascript-exec.js'\nimport { KEY_DESCRIPTION } from './core/key.js'\nimport { NAVIGATE_DESCRIPTION } from './core/navigate.js'\nimport { READ_PAGE_DESCRIPTION } from './core/read-page.js'\nimport { SCREENSHOT_DESCRIPTION } from './core/screenshot.js'\nimport { SCROLL_DESCRIPTION } from './core/scroll.js'\nimport { TYPE_DESCRIPTION } from './core/type.js'\nimport { WAIT_FOR_DESCRIPTION } from './core/wait-for.js'\nimport { READ_CONSOLE_MESSAGES_DESCRIPTION } from './debug/read-console-messages.js'\nimport { READ_NETWORK_REQUESTS_DESCRIPTION } from './debug/read-network-requests.js'\nimport { SM_ADD_ACTION_DESCRIPTION } from './semantic/sm-add-action.js'\nimport { SM_ADD_FETCH_DESCRIPTION } from './semantic/sm-add-fetch.js'\nimport { SM_ADD_TARGET_DESCRIPTION } from './semantic/sm-add-target.js'\nimport { SM_CAPABILITIES_DESCRIPTION } from './semantic/sm-capabilities.js'\nimport {\n SM_CUSTOM_VIEW_CREATE_DESCRIPTION,\n SM_CUSTOM_VIEW_DELETE_DESCRIPTION,\n SM_CUSTOM_VIEW_GET_DESCRIPTION,\n SM_CUSTOM_VIEW_LIST_DESCRIPTION,\n SM_CUSTOM_VIEW_UPDATE_DESCRIPTION,\n} from './semantic/sm-custom-view.js'\nimport { SM_DELETE_DESCRIPTION } from './semantic/sm-delete.js'\nimport { SM_EXPORT_DESCRIPTION } from './semantic/sm-export.js'\nimport { SM_FETCH_DESCRIPTION } from './semantic/sm-fetch.js'\nimport { SM_IMPORT_DESCRIPTION } from './semantic/sm-import.js'\nimport { SM_INVOKE_DESCRIPTION } from './semantic/sm-invoke.js'\nimport { SM_JOB_CANCEL_DESCRIPTION } from './semantic/sm-job-cancel.js'\nimport { SM_JOB_CREATE_DESCRIPTION } from './semantic/sm-job-create.js'\nimport { SM_JOB_DELETE_DESCRIPTION } from './semantic/sm-job-delete.js'\nimport {\n SM_JOB_COMPARE_DESCRIPTION,\n SM_JOB_HISTORY_DESCRIPTION,\n SM_JOB_SNAPSHOT_GET_DESCRIPTION,\n} from './semantic/sm-job-history.js'\nimport { SM_JOB_LIST_DESCRIPTION } from './semantic/sm-job-list.js'\nimport { SM_JOB_REPORT_EXPORT_DESCRIPTION } from './semantic/sm-job-report-export.js'\nimport { SM_JOB_REPORT_GET_DESCRIPTION } from './semantic/sm-job-report-get.js'\nimport { SM_JOB_RUN_DESCRIPTION } from './semantic/sm-job-run.js'\nimport { SM_JOB_UPDATE_DESCRIPTION } from './semantic/sm-job-update.js'\nimport { SM_REGISTER_PAGE_DESCRIPTION } from './semantic/sm-register-page.js'\nimport { SM_REPORT_DELETE_DESCRIPTION } from './semantic/sm-report-delete.js'\nimport { SM_REPORT_EXPORT_DESCRIPTION } from './semantic/sm-report-export.js'\nimport { SM_REPORT_GET_DESCRIPTION } from './semantic/sm-report-get.js'\nimport { SM_REPORT_LIST_DESCRIPTION } from './semantic/sm-report-list.js'\nimport { SM_SCENARIO_CREATE_DESCRIPTION } from './semantic/sm-scenario-create.js'\nimport { SM_SCENARIO_DELETE_DESCRIPTION } from './semantic/sm-scenario-delete.js'\nimport { SM_SCENARIO_LIST_DESCRIPTION } from './semantic/sm-scenario-list.js'\nimport { SM_SCENARIO_RUN_DESCRIPTION } from './semantic/sm-scenario-run.js'\nimport { SM_SCENARIO_UPDATE_DESCRIPTION } from './semantic/sm-scenario-update.js'\nimport { SM_STATUS_DESCRIPTION } from './semantic/sm-status.js'\nimport { SM_TEST_TARGET_DESCRIPTION } from './semantic/sm-test-target.js'\nimport { SELECT_TAB_DESCRIPTION } from './tabs/select-tab.js'\nimport { TAB_CLOSE_DESCRIPTION } from './tabs/tab-close.js'\nimport { TABS_CONTEXT_DESCRIPTION } from './tabs/tabs-context.js'\nimport { TABS_CREATE_DESCRIPTION } from './tabs/tabs-create.js'\nimport { AGENT_TAB_ASSIGN_DESCRIPTION } from './viyv/agent-tab-assign.js'\nimport { AGENT_TAB_LIST_DESCRIPTION } from './viyv/agent-tab-list.js'\nimport { ARTIFACT_FROM_PAGE_DESCRIPTION } from './viyv/artifact-from-page.js'\nimport { BROWSER_EVENT_SUBSCRIBE_DESCRIPTION } from './viyv/browser-event-subscribe.js'\nimport { BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION } from './viyv/browser-event-unsubscribe.js'\nimport { BROWSER_HEALTH_DESCRIPTION } from './viyv/browser-health.js'\nimport { PAGE_DATA_EXTRACT_DESCRIPTION } from './viyv/page-data-extract.js'\n\nexport interface ToolDefinition {\n name: string\n description: string\n inputSchema: z.ZodType\n}\n\n// ── Core Browser Tools ──\n\nexport const navigateTool: ToolDefinition = {\n name: 'navigate',\n description: NAVIGATE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to navigate'),\n url: z.string().describe('URL to navigate to, or \"back\"/\"forward\" for history'),\n }),\n}\n\nexport const screenshotTool: ToolDefinition = {\n name: 'screenshot',\n description: SCREENSHOT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to capture'),\n format: z.enum(['jpeg', 'png']).optional().describe('Image format (default: jpeg)'),\n quality: z.coerce.number().min(1).max(100).optional().describe('JPEG quality (default: 80)'),\n region: z\n .tuple([z.coerce.number(), z.coerce.number(), z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Capture region [x0, y0, x1, y1]'),\n ref: z\n .string()\n .optional()\n .describe(\n 'Element reference ID from read_page or find. Captures only that element with padding. Ignored if region is also provided.',\n ),\n }),\n}\n\nexport const clickTool: ToolDefinition = {\n name: 'click',\n description: CLICK_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Click position [x, y]'),\n ref: z.string().optional().describe('Element reference ID'),\n action: z\n .enum(['left_click', 'right_click', 'double_click', 'triple_click'])\n .optional()\n .describe('Click type (default: left_click)'),\n modifiers: z.string().optional().describe('Modifier keys (e.g., \"ctrl+shift\")'),\n }),\n}\n\nexport const typeTool: ToolDefinition = {\n name: 'type',\n description: TYPE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n text: z.string().describe('Text to type'),\n }),\n}\n\nexport const keyTool: ToolDefinition = {\n name: 'key',\n description: KEY_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n keys: z.string().describe('Space-separated keys (e.g., \"Enter\", \"ctrl+a\")'),\n repeat: z.coerce.number().min(1).max(100).optional().describe('Repeat count'),\n }),\n}\n\nexport const scrollTool: ToolDefinition = {\n name: 'scroll',\n description: SCROLL_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Scroll position [x, y] (required for directional scroll)'),\n direction: z\n .enum(['up', 'down', 'left', 'right'])\n .optional()\n .describe('Scroll direction (required for directional scroll)'),\n amount: z.coerce.number().min(1).max(10).optional().describe('Scroll amount (default: 3)'),\n ref: z.string().optional().describe('Element reference ID to scroll into view'),\n }),\n}\n\nexport const hoverTool: ToolDefinition = {\n name: 'hover',\n description: HOVER_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Hover position [x, y]'),\n ref: z.string().optional().describe('Element reference ID'),\n }),\n}\n\nexport const dragTool: ToolDefinition = {\n name: 'drag',\n description: DRAG_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n startCoordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .describe('Start position [x, y]'),\n endCoordinate: z.tuple([z.coerce.number(), z.coerce.number()]).describe('End position [x, y]'),\n }),\n}\n\nexport const readPageTool: ToolDefinition = {\n name: 'read_page',\n description: READ_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n filter: z\n .enum(['interactive', 'all'])\n .optional()\n .describe('Filter: \"interactive\" for buttons/links/inputs, \"all\" for everything'),\n depth: z.coerce.number().min(1).max(20).optional().describe('Max tree depth (default: 15)'),\n refId: z.string().optional().describe('Focus on a specific element by ref'),\n maxChars: z.coerce.number().optional().describe('Max output characters (default: 50000)'),\n }),\n}\n\nexport const findTool: ToolDefinition = {\n name: 'find',\n description: FIND_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n query: z.string().describe('Natural language description of what to find'),\n }),\n}\n\nexport const formInputTool: ToolDefinition = {\n name: 'form_input',\n description: FORM_INPUT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n ref: z.string().describe('Element reference ID'),\n value: z.union([z.string(), z.boolean(), z.coerce.number()]).describe('Value to set'),\n }),\n}\n\nexport const javascriptExecTool: ToolDefinition = {\n name: 'javascript_exec',\n description: JAVASCRIPT_EXEC_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n code: z.string().describe('JavaScript code to execute'),\n }),\n}\n\nexport const waitForTool: ToolDefinition = {\n name: 'wait_for',\n description: WAIT_FOR_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n selector: z.string().optional().describe('CSS selector to wait for'),\n navigation: z.boolean().optional().describe('Wait for navigation to complete'),\n timeout: z.coerce.number().optional().describe('Timeout in ms (default: 30000)'),\n }),\n}\n\nexport const getPageTextTool: ToolDefinition = {\n name: 'get_page_text',\n description: GET_PAGE_TEXT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n }),\n}\n\nexport const handleDialogTool: ToolDefinition = {\n name: 'handle_dialog',\n description: HANDLE_DIALOG_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action: z.enum(['accept', 'dismiss']).describe('Dialog action'),\n text: z.string().optional().describe('Text for prompt dialog'),\n }),\n}\n\n// ── Tab Management Tools ──\n\nexport const tabsContextTool: ToolDefinition = {\n name: 'tabs_context',\n description: TABS_CONTEXT_DESCRIPTION,\n inputSchema: z.object({\n createIfEmpty: z.boolean().optional().describe('Create a new tab group if none exists'),\n }),\n}\n\nexport const tabsCreateTool: ToolDefinition = {\n name: 'tabs_create',\n description: TABS_CREATE_DESCRIPTION,\n inputSchema: z.object({\n url: z.string().optional().describe('URL to open in the new tab'),\n }),\n}\n\nexport const tabCloseTool: ToolDefinition = {\n name: 'tab_close',\n description: TAB_CLOSE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to close'),\n }),\n}\n\nexport const selectTabTool: ToolDefinition = {\n name: 'select_tab',\n description: SELECT_TAB_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to focus'),\n }),\n}\n\n// ── Debug Tools ──\n\nexport const readConsoleMessagesTool: ToolDefinition = {\n name: 'read_console_messages',\n description: READ_CONSOLE_MESSAGES_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n pattern: z.string().optional().describe('Regex pattern to filter messages'),\n onlyErrors: z.boolean().optional().describe('Only return errors'),\n limit: z.coerce.number().optional().describe('Max messages to return (default: 100)'),\n clear: z.boolean().optional().describe('Clear messages after reading'),\n }),\n}\n\nexport const readNetworkRequestsTool: ToolDefinition = {\n name: 'read_network_requests',\n description: READ_NETWORK_REQUESTS_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n urlPattern: z.string().optional().describe('URL pattern to filter requests'),\n limit: z.coerce.number().optional().describe('Max requests to return (default: 100)'),\n clear: z.boolean().optional().describe('Clear requests after reading'),\n }),\n}\n\n// ── Advanced Tools ──\n\nexport const gifCreatorTool: ToolDefinition = {\n name: 'gif_creator',\n description: GIF_CREATOR_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action: z.enum(['start_recording', 'stop_recording', 'export', 'clear']).describe('GIF action'),\n filename: z.string().optional().describe('Filename for export'),\n options: z\n .object({\n showClickIndicators: z.boolean().optional(),\n showDragPaths: z.boolean().optional(),\n showActionLabels: z.boolean().optional(),\n showProgressBar: z.boolean().optional(),\n showWatermark: z.boolean().optional(),\n quality: z.coerce.number().min(1).max(30).optional(),\n })\n .optional()\n .describe('GIF rendering options'),\n download: z.boolean().optional().describe('Download the GIF'),\n }),\n}\n\nexport const uploadImageTool: ToolDefinition = {\n name: 'upload_image',\n description: UPLOAD_IMAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n imageId: z.string().describe('Image ID from a previous screenshot'),\n ref: z.string().optional().describe('Element reference for file input'),\n coordinate: z\n .tuple([z.coerce.number(), z.coerce.number()])\n .optional()\n .describe('Coordinates for drag & drop'),\n filename: z\n .string()\n .optional()\n .describe('Filename for the uploaded file (default: \"image.png\")'),\n }),\n}\n\nexport const updatePlanTool: ToolDefinition = {\n name: 'update_plan',\n description: UPDATE_PLAN_DESCRIPTION,\n inputSchema: z.object({\n domains: z.array(z.string()).describe('Domains to visit'),\n approach: z.array(z.string()).describe('Steps in the plan'),\n }),\n}\n\nexport const resizeWindowTool: ToolDefinition = {\n name: 'resize_window',\n description: RESIZE_WINDOW_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n width: z.coerce.number().describe('Window width in pixels'),\n height: z.coerce.number().describe('Window height in pixels'),\n }),\n}\n\nexport const shortcutsListTool: ToolDefinition = {\n name: 'shortcuts_list',\n description: SHORTCUTS_LIST_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().optional().describe('Tab ID (used to identify the tab group context)'),\n }),\n}\n\nexport const shortcutsExecuteTool: ToolDefinition = {\n name: 'shortcuts_execute',\n description: SHORTCUTS_EXECUTE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to execute the shortcut on'),\n command: z.string().optional().describe('Command name of the shortcut'),\n shortcutId: z.string().optional().describe('ID of the shortcut'),\n }),\n}\n\nexport const switchBrowserTool: ToolDefinition = {\n name: 'switch_browser',\n description: SWITCH_BROWSER_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const fileUploadTool: ToolDefinition = {\n name: 'file_upload',\n description: FILE_UPLOAD_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n ref: z.string().describe('Element reference ID of the file input'),\n paths: z.array(z.string()).min(1).describe('Absolute file paths to upload'),\n }),\n}\n\n// ── viyv Integration Tools ──\n\nexport const agentTabAssignTool: ToolDefinition = {\n name: 'agent_tab_assign',\n description: AGENT_TAB_ASSIGN_DESCRIPTION,\n inputSchema: z.object({\n agentId: z.string().describe('Agent ID'),\n agentName: z.string().describe('Display name'),\n color: z.string().optional().describe('Tab group color'),\n }),\n}\n\nexport const agentTabListTool: ToolDefinition = {\n name: 'agent_tab_list',\n description: AGENT_TAB_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const browserEventSubscribeTool: ToolDefinition = {\n name: 'browser_event_subscribe',\n description: BROWSER_EVENT_SUBSCRIBE_DESCRIPTION,\n inputSchema: z.object({\n eventTypes: z.array(z.string()).describe('Event types to subscribe to'),\n urlPattern: z.string().optional().describe('URL pattern filter'),\n conditions: z.record(z.unknown()).optional().describe('Additional conditions'),\n }),\n}\n\nexport const browserEventUnsubscribeTool: ToolDefinition = {\n name: 'browser_event_unsubscribe',\n description: BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION,\n inputSchema: z.object({\n subscriptionId: z.string().describe('Subscription ID'),\n }),\n}\n\nexport const artifactFromPageTool: ToolDefinition = {\n name: 'artifact_from_page',\n description: ARTIFACT_FROM_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n type: z.string().describe('Artifact type (text, html, screenshot)'),\n title: z.string().optional().describe('Artifact title'),\n }),\n}\n\nexport const pageDataExtractTool: ToolDefinition = {\n name: 'page_data_extract',\n description: PAGE_DATA_EXTRACT_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n schema: z.record(z.unknown()).describe('Data extraction schema'),\n selector: z.string().optional().describe('CSS selector to scope extraction'),\n }),\n}\n\nexport const browserHealthTool: ToolDefinition = {\n name: 'browser_health',\n description: BROWSER_HEALTH_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\n// ── Semantic Tools ──\n\nexport const smCapabilitiesTool: ToolDefinition = {\n name: 'sm_capabilities',\n description: SM_CAPABILITIES_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n }),\n}\n\nexport const smInvokeTool: ToolDefinition = {\n name: 'sm_invoke',\n description: SM_INVOKE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n action_id: z.string().describe('Action ID to execute'),\n params: z.record(z.unknown()).optional().describe('Parameters for template substitution'),\n }),\n}\n\nexport const smFetchTool: ToolDefinition = {\n name: 'sm_fetch',\n description: SM_FETCH_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n fetch_id: z.string().describe('Fetch definition ID to execute'),\n params: z.record(z.unknown()).optional().describe('Optional parameters'),\n }),\n}\n\nexport const smRegisterPageTool: ToolDefinition = {\n name: 'sm_register_page',\n description: SM_REGISTER_PAGE_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Target tab'),\n label: z.string().describe('Page name (e.g., \"GitHub Login\")'),\n page_type: z\n .string()\n .optional()\n .describe(\n 'Page type within the domain (e.g., \"profile\", \"compose\", \"search\"). Used for grouping pages.',\n ),\n url_pattern: z.string().optional().describe('URL regex (auto-derived from tab URL if omitted)'),\n domains: z.array(z.string()).optional().describe('Domain scope (auto-derived if omitted)'),\n auth_state: z\n .enum(['logged_in', 'logged_out', 'any'])\n .optional()\n .describe('Auth state (default: any)'),\n must_exist: z.array(z.string()).optional().describe('Required CSS selectors'),\n must_not_exist: z.array(z.string()).optional().describe('Forbidden CSS selectors'),\n title_regex: z.string().optional().describe('Title regex'),\n }),\n}\n\nexport const smAddTargetTool: ToolDefinition = {\n name: 'sm_add_target',\n description: SM_ADD_TARGET_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Target tab where elements are present'),\n page_id: z.string().describe('Page ID these targets belong to'),\n targets: z\n .array(\n z.object({\n target_id: z.string().optional().describe('Existing target ID for re-bind'),\n label: z.string().describe('Target name'),\n role: z.string().describe('Semantic role (e.g., \"textbox\", \"button\")'),\n ref: z.string().optional().describe('Element ref from read_page/find'),\n locators: z\n .array(\n z.object({\n type: z.string().describe('Locator type'),\n value: z.string().describe('Locator value'),\n stability: z.enum(['high', 'medium', 'low']).describe('Stability level'),\n }),\n )\n .optional()\n .describe('Explicit locators'),\n }),\n )\n .min(1)\n .describe('Target definitions'),\n }),\n}\n\nexport const smAddActionTool: ToolDefinition = {\n name: 'sm_add_action',\n description: SM_ADD_ACTION_DESCRIPTION,\n inputSchema: z.object({\n page_id: z.string().describe('Page ID'),\n label: z.string().describe('Action name'),\n verb: z.string().describe('Action verb (e.g., \"login\", \"submit\")'),\n description: z.string().optional().describe('LLM-facing description'),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional()\n .describe('Parameter definitions'),\n steps: z\n .array(\n z.object({\n type: z\n .enum(['click', 'type', 'select', 'wait', 'scroll', 'key', 'navigate', 'file_upload'])\n .describe('Step type'),\n target_id: z.string().optional().describe('Target to act on'),\n params: z\n .object({\n text: z.string().optional(),\n value: z.string().optional(),\n keys: z.string().optional(),\n direction: z.enum(['up', 'down', 'left', 'right']).optional(),\n amount: z.coerce.number().optional(),\n url: z.string().optional(),\n param_ref: z.string().optional(),\n file_paths: z\n .array(z.string())\n .optional()\n .describe('File paths for file_upload step'),\n })\n .optional()\n .describe('Step parameters'),\n pre_wait: z\n .object({\n strategy: z.enum(['selector', 'navigation', 'time']),\n selector: z.string().optional(),\n timeout_ms: z.coerce.number().default(5000),\n })\n .optional()\n .describe('Pre-step wait rule'),\n description: z.string().optional(),\n }),\n )\n .min(1)\n .describe('Step sequence'),\n retry_policy: z\n .object({\n max_retries: z.coerce.number().min(0).max(5).optional(),\n backoff: z.enum(['fixed', 'exponential']).optional(),\n base_delay_ms: z.coerce.number().min(100).max(10000).optional(),\n jitter: z.boolean().optional(),\n })\n .optional()\n .describe('Retry policy'),\n }),\n}\n\nexport const smAddFetchTool: ToolDefinition = {\n name: 'sm_add_fetch',\n description: SM_ADD_FETCH_DESCRIPTION,\n inputSchema: z.object({\n page_id: z.string().describe('Page ID'),\n label: z.string().describe('Fetch name'),\n type_name: z.string().describe('Output type name (e.g., \"posts\")'),\n description: z\n .string()\n .optional()\n .describe('LLM-facing description for discovery via sm_capabilities'),\n fields: z\n .array(\n z.object({\n name: z.string().describe('Output field name'),\n target_id: z.string().describe('Target element'),\n extraction_type: z\n .enum(['text', 'attribute', 'list', 'count', 'exists'])\n .describe('Extraction type'),\n attribute: z.string().optional().describe('Attribute name (for attribute type)'),\n item_selector: z.string().optional().describe('List item CSS selector'),\n item_fields: z\n .array(\n z.object({\n name: z.string(),\n selector: z\n .string()\n .describe(\n 'CSS selector relative to each list item (use \":scope\" for item itself)',\n ),\n extraction_type: z.enum(['text', 'attribute', 'exists']),\n attribute: z.string().optional(),\n }),\n )\n .optional()\n .describe('Nested fields for structured list item extraction'),\n }),\n )\n .min(1)\n .describe('Extraction fields'),\n limits: z\n .object({\n max_chars: z.coerce.number().min(1000).max(200000).optional(),\n max_items: z.coerce.number().min(1).max(1000).optional(),\n })\n .optional()\n .describe('Output limits'),\n }),\n}\n\nexport const smStatusTool: ToolDefinition = {\n name: 'sm_status',\n description: SM_STATUS_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().optional().describe('Tab ID (required for test_resolve)'),\n page_id: z.string().optional().describe('Filter by page ID'),\n domain: z.string().optional().describe('Filter results to pages matching this domain'),\n test_resolve: z.boolean().optional().describe('Test-resolve all targets'),\n }),\n}\n\nexport const smTestTargetTool: ToolDefinition = {\n name: 'sm_test_target',\n description: SM_TEST_TARGET_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID'),\n target_id: z.string().describe('Target ID to test'),\n }),\n}\n\nexport const smDeleteTool: ToolDefinition = {\n name: 'sm_delete',\n description: SM_DELETE_DESCRIPTION,\n inputSchema: z.object({\n entity_type: z.enum(['page', 'target', 'action', 'fetch']).describe('Entity type'),\n entity_id: z.string().describe('Entity ID to delete'),\n dry_run: z.boolean().optional().describe('Preview impact without deleting'),\n }),\n}\n\nexport const smExportTool: ToolDefinition = {\n name: 'sm_export',\n description: SM_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n domain: z\n .string()\n .optional()\n .describe('Export only pages matching this domain (subdomain-aware). Omit for all.'),\n }),\n}\n\nexport const smImportTool: ToolDefinition = {\n name: 'sm_import',\n description: SM_IMPORT_DESCRIPTION,\n inputSchema: z.object({\n data: z\n .object({\n schema_version: z.string(),\n checksum: z.string(),\n exported_at: z.coerce.number().optional(),\n source: z.record(z.unknown()).optional(),\n pages: z.array(z.record(z.unknown())),\n targets: z.array(z.record(z.unknown())).optional(),\n actions: z.array(z.record(z.unknown())).optional(),\n fetches: z.array(z.record(z.unknown())).optional(),\n })\n .passthrough()\n .describe('SemanticExport JSON object from sm_export'),\n strategy: z\n .enum(['merge', 'replace-domain'])\n .optional()\n .describe('\"merge\" (default) or \"replace-domain\"'),\n }),\n}\n\n// ── Scenario & Report Tools ──\n\nconst scenarioStepSchema: z.ZodType = z.lazy(() =>\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('navigate'),\n label: z.string().optional(),\n url: z.string(),\n wait_for_load: z.boolean().optional(),\n }),\n z.object({\n type: z.literal('action'),\n label: z.string().optional(),\n action_id: z.string(),\n params: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal('fetch'),\n label: z.string().optional(),\n fetch_id: z.string(),\n result_key: z.string(),\n params: z.record(z.string()).optional(),\n }),\n z.object({\n type: z.literal('loop'),\n label: z.string().optional(),\n variables: z.array(\n z.object({\n name: z.string(),\n source: z.enum(['static', 'target_options', 'previous_fetch']),\n values: z.array(z.string()).optional(),\n target_id: z.string().optional(),\n fetch_result_key: z.string().optional(),\n field_name: z.string().optional(),\n }),\n ),\n steps: z.array(scenarioStepSchema),\n delay_between_ms: z.coerce.number().optional(),\n max_iterations: z.coerce.number().min(1).max(500).optional(),\n }),\n z.object({\n type: z.literal('wait'),\n label: z.string().optional(),\n strategy: z.enum(['time', 'selector', 'navigation']),\n selector: z.string().optional(),\n timeout_ms: z.coerce.number(),\n }),\n ]),\n)\n\nexport const smScenarioCreateTool: ToolDefinition = {\n name: 'sm_scenario_create',\n description: SM_SCENARIO_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().describe('Scenario name'),\n description: z.string().optional().describe('LLM-facing description'),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional()\n .describe('Global parameter definitions'),\n steps: z.array(scenarioStepSchema).min(1).describe('Step sequence'),\n max_duration_ms: z.coerce.number().optional().describe('Timeout in ms (default: 300000)'),\n on_error: z\n .enum(['stop', 'skip_and_continue'])\n .optional()\n .describe('Error handling (default: stop)'),\n }),\n}\n\nexport const smScenarioUpdateTool: ToolDefinition = {\n name: 'sm_scenario_update',\n description: SM_SCENARIO_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().describe('Scenario ID to update'),\n label: z.string().optional(),\n description: z.string().optional(),\n params: z\n .array(\n z.object({\n name: z.string(),\n type: z.enum(['string', 'number', 'boolean']).default('string'),\n required: z.boolean().default(true),\n secret: z.boolean().default(false),\n description: z.string().optional(),\n default_value: z.union([z.string(), z.coerce.number(), z.boolean()]).optional(),\n }),\n )\n .optional(),\n steps: z.array(scenarioStepSchema).optional(),\n max_duration_ms: z.coerce.number().optional(),\n on_error: z.enum(['stop', 'skip_and_continue']).optional(),\n }),\n}\n\nexport const smScenarioDeleteTool: ToolDefinition = {\n name: 'sm_scenario_delete',\n description: SM_SCENARIO_DELETE_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().describe('Scenario ID to delete'),\n }),\n}\n\nexport const smScenarioListTool: ToolDefinition = {\n name: 'sm_scenario_list',\n description: SM_SCENARIO_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smScenarioRunTool: ToolDefinition = {\n name: 'sm_scenario_run',\n description: SM_SCENARIO_RUN_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID for execution'),\n scenario_id: z.string().describe('Scenario to execute'),\n params: z.record(z.unknown()).optional().describe('Parameter values'),\n wait_for_completion: z\n .boolean()\n .optional()\n .describe('Wait for completion (default: false, async)'),\n }),\n}\n\nexport const smReportListTool: ToolDefinition = {\n name: 'sm_report_list',\n description: SM_REPORT_LIST_DESCRIPTION,\n inputSchema: z.object({\n scenario_id: z.string().optional().describe('Filter by scenario ID'),\n }),\n}\n\nexport const smReportGetTool: ToolDefinition = {\n name: 'sm_report_get',\n description: SM_REPORT_GET_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to retrieve'),\n }),\n}\n\nexport const smReportDeleteTool: ToolDefinition = {\n name: 'sm_report_delete',\n description: SM_REPORT_DELETE_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to delete'),\n }),\n}\n\nexport const smReportExportTool: ToolDefinition = {\n name: 'sm_report_export',\n description: SM_REPORT_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n report_id: z.string().describe('Report ID to export'),\n format: z.enum(['json', 'csv']).optional().describe('Export format (default: json)'),\n }),\n}\n\n// ── Job Tools ──\n\nconst jobEntrySchema = z.object({\n scenario_id: z.string().describe('Scenario ID to execute'),\n label: z.string().optional().describe('Display label override'),\n params: z.record(z.unknown()).optional().default({}).describe('Scenario parameter overrides'),\n})\n\nexport const smJobCreateTool: ToolDefinition = {\n name: 'sm_job_create',\n description: SM_JOB_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().min(1).describe('Job name'),\n description: z.string().optional().describe('Job description'),\n entries: z.array(jobEntrySchema).min(1).describe('Ordered list of scenarios to execute'),\n on_error: z\n .enum(['stop', 'skip_and_continue'])\n .optional()\n .describe('How to handle scenario failures (default: stop)'),\n }),\n}\n\nexport const smJobUpdateTool: ToolDefinition = {\n name: 'sm_job_update',\n description: SM_JOB_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to update'),\n label: z.string().optional(),\n description: z.string().optional(),\n entries: z.array(jobEntrySchema).min(1).optional(),\n on_error: z.enum(['stop', 'skip_and_continue']).optional(),\n }),\n}\n\nexport const smJobDeleteTool: ToolDefinition = {\n name: 'sm_job_delete',\n description: SM_JOB_DELETE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to delete'),\n }),\n}\n\nexport const smJobListTool: ToolDefinition = {\n name: 'sm_job_list',\n description: SM_JOB_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smJobRunTool: ToolDefinition = {\n name: 'sm_job_run',\n description: SM_JOB_RUN_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID to execute scenarios on'),\n job_id: z.string().describe('Job ID to execute'),\n params: z\n .record(z.record(z.unknown()))\n .optional()\n .describe('Per-scenario param overrides keyed by scenario_id'),\n wait_for_completion: z\n .boolean()\n .optional()\n .describe('Wait for all scenarios to complete (default: false)'),\n }),\n}\n\nexport const smJobCancelTool: ToolDefinition = {\n name: 'sm_job_cancel',\n description: SM_JOB_CANCEL_DESCRIPTION,\n inputSchema: z.object({\n tabId: z.coerce.number().describe('Tab ID where the job is running'),\n }),\n}\n\nexport const smJobReportGetTool: ToolDefinition = {\n name: 'sm_job_report_get',\n description: SM_JOB_REPORT_GET_DESCRIPTION,\n inputSchema: z.object({\n job_report_id: z.string().describe('Job report ID to retrieve'),\n }),\n}\n\nexport const smJobReportExportTool: ToolDefinition = {\n name: 'sm_job_report_export',\n description: SM_JOB_REPORT_EXPORT_DESCRIPTION,\n inputSchema: z.object({\n job_report_id: z.string().describe('Job report ID to export'),\n format: z.enum(['json', 'csv']).optional().describe('Export format (default: json)'),\n }),\n}\n\n// ── Job History Tools ──\n\nexport const smJobHistoryTool: ToolDefinition = {\n name: 'sm_job_history',\n description: SM_JOB_HISTORY_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to get history for'),\n limit: z.coerce.number().min(1).max(100).optional().describe('Max snapshots (default: 20)'),\n }),\n}\n\nexport const smJobCompareTool: ToolDefinition = {\n name: 'sm_job_compare',\n description: SM_JOB_COMPARE_DESCRIPTION,\n inputSchema: z.object({\n job_id: z.string().describe('Job ID to compare'),\n base_snapshot_id: z\n .string()\n .optional()\n .describe('Older snapshot ID (default: second-most-recent)'),\n compare_snapshot_id: z.string().optional().describe('Newer snapshot ID (default: most-recent)'),\n changed_only: z.boolean().optional().describe('Omit unchanged rows (default: false)'),\n }),\n}\n\nexport const smJobSnapshotGetTool: ToolDefinition = {\n name: 'sm_job_snapshot_get',\n description: SM_JOB_SNAPSHOT_GET_DESCRIPTION,\n inputSchema: z.object({\n snapshot_id: z.string().describe('Snapshot ID to retrieve (SNP_xxxx)'),\n }),\n}\n\n// ── Custom View Tools ──\n\nconst dataBindingSchema = z.object({\n binding_id: z.string().min(1).max(20).describe('Unique binding ID within this view (e.g., \"b1\")'),\n source_type: z.enum(['job_report', 'report', 'job', 'scenario']).describe('Data source type'),\n source_id: z.string().describe('Source entity ID (e.g., \"JRP_xxxx\")'),\n projection: z\n .object({\n fields: z.array(z.string()).optional().describe('Field whitelist'),\n max_entries: z.number().min(1).max(1000).optional().describe('Max array entries'),\n })\n .optional()\n .describe('Data projection to limit injected data'),\n})\n\nexport const smCustomViewCreateTool: ToolDefinition = {\n name: 'sm_custom_view_create',\n description: SM_CUSTOM_VIEW_CREATE_DESCRIPTION,\n inputSchema: z.object({\n label: z.string().min(1).max(100).describe('View name'),\n description: z.string().max(500).optional().describe('View description'),\n html: z.string().max(200_000).describe('HTML content (max 200KB)'),\n data_bindings: z.array(dataBindingSchema).max(10).optional().describe('Data source bindings'),\n }),\n}\n\nexport const smCustomViewUpdateTool: ToolDefinition = {\n name: 'sm_custom_view_update',\n description: SM_CUSTOM_VIEW_UPDATE_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to update'),\n label: z.string().min(1).max(100).optional().describe('New label'),\n description: z.string().max(500).optional().describe('New description'),\n html: z.string().max(200_000).optional().describe('New HTML content'),\n data_bindings: z\n .array(dataBindingSchema)\n .max(10)\n .optional()\n .describe('New data bindings (replaces all)'),\n }),\n}\n\nexport const smCustomViewDeleteTool: ToolDefinition = {\n name: 'sm_custom_view_delete',\n description: SM_CUSTOM_VIEW_DELETE_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to delete'),\n }),\n}\n\nexport const smCustomViewListTool: ToolDefinition = {\n name: 'sm_custom_view_list',\n description: SM_CUSTOM_VIEW_LIST_DESCRIPTION,\n inputSchema: z.object({}),\n}\n\nexport const smCustomViewGetTool: ToolDefinition = {\n name: 'sm_custom_view_get',\n description: SM_CUSTOM_VIEW_GET_DESCRIPTION,\n inputSchema: z.object({\n view_id: z.string().describe('View ID to retrieve'),\n include_data: z\n .boolean()\n .optional()\n .describe('Include resolved data in response (default: false)'),\n }),\n}\n\n// ── All Tools ──\n\nexport const allTools: ToolDefinition[] = [\n // Core (15)\n navigateTool,\n screenshotTool,\n clickTool,\n typeTool,\n keyTool,\n scrollTool,\n hoverTool,\n dragTool,\n readPageTool,\n findTool,\n formInputTool,\n javascriptExecTool,\n waitForTool,\n getPageTextTool,\n handleDialogTool,\n // Tabs (4)\n tabsContextTool,\n tabsCreateTool,\n tabCloseTool,\n selectTabTool,\n // Debug (2)\n readConsoleMessagesTool,\n readNetworkRequestsTool,\n // Advanced (8)\n gifCreatorTool,\n uploadImageTool,\n fileUploadTool,\n updatePlanTool,\n resizeWindowTool,\n shortcutsListTool,\n shortcutsExecuteTool,\n switchBrowserTool,\n // viyv Integration (7)\n agentTabAssignTool,\n agentTabListTool,\n browserEventSubscribeTool,\n browserEventUnsubscribeTool,\n artifactFromPageTool,\n pageDataExtractTool,\n browserHealthTool,\n // Semantic (12)\n smCapabilitiesTool,\n smInvokeTool,\n smFetchTool,\n smRegisterPageTool,\n smAddTargetTool,\n smAddActionTool,\n smAddFetchTool,\n smStatusTool,\n smTestTargetTool,\n smDeleteTool,\n smExportTool,\n smImportTool,\n // Scenario & Report (9)\n smScenarioCreateTool,\n smScenarioUpdateTool,\n smScenarioDeleteTool,\n smScenarioListTool,\n smScenarioRunTool,\n smReportListTool,\n smReportGetTool,\n smReportDeleteTool,\n smReportExportTool,\n // Job (8)\n smJobCreateTool,\n smJobUpdateTool,\n smJobDeleteTool,\n smJobListTool,\n smJobRunTool,\n smJobCancelTool,\n smJobReportGetTool,\n smJobReportExportTool,\n // Job History (3)\n smJobHistoryTool,\n smJobCompareTool,\n smJobSnapshotGetTool,\n // Custom View (5)\n smCustomViewCreateTool,\n smCustomViewUpdateTool,\n smCustomViewDeleteTool,\n smCustomViewListTool,\n smCustomViewGetTool,\n]\n","export const FILE_UPLOAD_DESCRIPTION = `Upload local files to a file input element on the page using absolute file paths.\nDo not click on file input elements — clicking opens a native file picker dialog.\nInstead, use read_page or find to locate the file input, then use this tool with its ref.\nThe paths must be absolute paths accessible from the machine running Chrome.`\n","export const GIF_CREATOR_DESCRIPTION = `Record a GIF of browser activity.\nCaptures a sequence of screenshots over a specified duration\nand assembles them into an animated GIF. Useful for documenting\nvisual interactions or creating shareable recordings of workflows.`\n","export const RESIZE_WINDOW_DESCRIPTION = `Resize the browser window to specified dimensions.\nSets the width and height of the browser viewport, useful for\ntesting responsive layouts or ensuring consistent screenshot\ndimensions across different operations.`\n","export const SHORTCUTS_EXECUTE_DESCRIPTION = `Execute a shortcut or workflow by command name or ID.\n\nRuns the specified shortcut in the side panel using the current tab.\nLook up by command name or shortcutId. Use shortcuts_list first\nto see available shortcuts.`\n","export const SHORTCUTS_LIST_DESCRIPTION = `List all available shortcuts and workflows.\n\nReturns registered shortcuts with their commands, descriptions,\nand whether they are workflows. Shortcuts can be executed using\nthe shortcuts_execute tool.`\n","export const SWITCH_BROWSER_DESCRIPTION = `Switch to a different Chrome browser instance.\n\nDisconnects the current Extension connection and waits for a new\nChrome browser to connect (up to 60s). The user should click\n\"Connect\" in the desired browser's extension.`\n","export const UPDATE_PLAN_DESCRIPTION = `Present a step-by-step plan to the user for review.\nDisplays the proposed sequence of actions the agent intends to take,\nallowing the user to approve, modify, or reject the plan before\nexecution begins.`\n","export const UPLOAD_IMAGE_DESCRIPTION = `Upload a previously captured screenshot or user-uploaded image to a file input or drag & drop target.\nProvide imageId from a prior screenshot action. Supports targeting by\nelement ref (for file inputs) or coordinate (for drag & drop).\nSupports common image formats including PNG, JPEG, GIF, and WebP.`\n","export const CLICK_DESCRIPTION = `Click at coordinates or on a referenced element.\n\nProvide either coordinate [x, y] or ref (element reference from read_page/find).\nActions: left_click (default), right_click, double_click, triple_click.\nSupports modifier keys: ctrl, shift, alt, cmd (e.g., \"ctrl+shift\").`\n","export const DRAG_DESCRIPTION = `Drag from one coordinate to another.\n\nPerforms mousedown at start, mousemove to end, then mouseup.`\n","export const FIND_DESCRIPTION = `Find elements on the page using a natural language query.\nSearches the DOM for elements matching the given description,\nreturning references that can be used for subsequent interactions\nsuch as clicking, typing, or extracting content.`\n","export const FORM_INPUT_DESCRIPTION = `Set a value in a form element identified by its ref.\nSupports text inputs, textareas, selects, checkboxes, and radio buttons.\nThe ref must be obtained from a prior find or snapshot operation\nto ensure the correct element is targeted.`\n","export const GET_PAGE_TEXT_DESCRIPTION = `Extract readable text content from the current page.\nStrips away HTML tags, scripts, and styles to return a clean\ntext representation of the visible page content, suitable for\nanalysis, summarization, or further processing.`\n","export const HANDLE_DIALOG_DESCRIPTION = `Handle JavaScript dialogs such as alert, confirm, and prompt.\nAllows accepting or dismissing the dialog, and optionally providing\ninput text for prompt dialogs. Must be called while a dialog\nis actively displayed on the page.`\n","export const HOVER_DESCRIPTION = `Move mouse to coordinates or element without clicking.\n\nProvide either coordinate [x, y] or ref (element reference from read_page/find).\nUseful for revealing tooltips, dropdown menus, or triggering hover states.`\n","export const JAVASCRIPT_EXEC_DESCRIPTION = `Execute arbitrary JavaScript code in the page context.\nThe script runs in the main world of the active page and can access\nthe DOM, window object, and any page-level APIs. Returns the\nserialized result of the last evaluated expression.\nSupports top-level await (e.g., \"await fetch('/api').then(r => r.json())\").`\n","export const KEY_DESCRIPTION = `Press keyboard key(s).\n\nSpace-separated key names. Supports keyboard shortcuts.\nExamples: \"Enter\", \"Tab\", \"Backspace\", \"ctrl+a\", \"cmd+c\".\nUse repeat parameter for repeated presses (e.g., arrow keys).`\n","export const NAVIGATE_DESCRIPTION = `Navigate to a URL, or go forward/back in browser history.\n\nUse \"back\" to go back in history, \"forward\" to go forward.\nProvide a full URL (with protocol) to navigate to a new page.\nWaits for page load to complete before returning.`\n","export const READ_PAGE_DESCRIPTION = `Get accessibility tree representation of page elements.\n\nSupports:\n- filter: \"interactive\" for buttons/links/inputs only, \"all\" for everything\n- depth: max tree depth (1-20, default 8)\n- refId: focus on a specific element subtree\n- maxChars: limit output size (default 50000)\n\nReturns elements with ref IDs that can be used with click, form_input, etc.`\n","export const SCREENSHOT_DESCRIPTION = `Take a screenshot of a tab.\n\nReturns image as an MCP ImageContent block, plus metadata (imageId) as text.\nDefault format is JPEG with quality 80.\n\nIMPORTANT - Token-efficient alternatives (prefer these when possible):\n- read_page: Get accessibility tree with element text, values, and states\n- get_page_text: Extract all readable text from the page\n- find: Locate elements by natural language description\nUse screenshot only when visual verification is needed (layout, styling, images, charts).\n\nFor example: to verify text was typed into an input, use read_page to check the\ninput's value — don't take a screenshot. To confirm a page loaded, check the\naccessibility tree for expected headings or elements.\n\nUse ref to capture just a specific element (with padding) instead of the full page.\nThis dramatically reduces image size. If both ref and region are provided, region\ntakes precedence. The response includes an imageId for use with upload_image.`\n","export const SCROLL_DESCRIPTION = `Scroll in a direction at given coordinates, or scroll an element into view by ref.\n\nTwo modes:\n1. Directional scroll: provide coordinate + direction (+ optional amount 1-10, default 3).\n2. Scroll to element: provide ref (element reference ID from read_page/find). Scrolls the element into view using smooth scrolling.`\n","export const TYPE_DESCRIPTION = `Type text into the currently focused element.\n\nEach character is typed individually with keyDown/keyUp events.\nFor special keys (Enter, Tab, etc.), use the 'key' tool instead.`\n","export const WAIT_FOR_DESCRIPTION = `Wait for a specified condition before proceeding.\nSupports waiting for a CSS selector to appear in the DOM,\nfor a navigation event to complete, or for a fixed timeout duration.\nUseful for synchronizing with asynchronous page updates.\nAt least one of selector, navigation, or timeout must be specified.`\n","export const READ_CONSOLE_MESSAGES_DESCRIPTION = `Read console messages captured from the page.\nReturns log, warning, error, and info messages that have been\nemitted by page scripts. Supports filtering by log level\nand limiting the number of returned entries.\nUse the pattern parameter to filter messages by regex, and\nthe clear parameter to remove messages after reading.`\n","export const READ_NETWORK_REQUESTS_DESCRIPTION = `Read network requests captured from the page.\nReturns details of HTTP requests and responses including URL, method,\nstatus code, headers, and timing information. Supports filtering\nby URL pattern or resource type.`\n","export const SM_ADD_ACTION_DESCRIPTION = `Define a semantic action (step sequence) for a registered page.\n\nCreates an executable action with typed parameters and ordered steps.\nSteps reference targets by target_id and support param_ref for dynamic values.\n\nParameters:\n- page_id: the page this action belongs to\n- label: action name (e.g., \"Login\")\n- verb: action verb (e.g., \"login\", \"submit\", \"search\")\n- description (optional): LLM-facing description for discovery via sm_capabilities\n- params[]: parameter definitions [{name, type, required, secret, description, default_value}]\n- steps[]: ordered step sequence (minimum 1):\n - type: 'click' | 'type' | 'select' | 'wait' | 'scroll' | 'key' | 'navigate'\n - target_id: target to act on\n - params: {text, value, keys, direction, amount, url, param_ref}\n - pre_wait: {strategy, selector, timeout_ms}\n - description: step description\n- retry_policy (optional): {max_retries:0-5, backoff, base_delay_ms, jitter}\n\nReturns:\n- action_id, step_count\n- validation: {valid, warnings[]} with target/param reference checks`\n","export const SM_ADD_FETCH_DESCRIPTION = `Define a data extraction rule (fetch) for a registered page.\n\nCreates a structured data extraction definition that maps DOM elements to typed output fields.\nSupports text, attribute, list, count, and existence extraction types.\n\nParameters:\n- page_id: the page this fetch belongs to\n- label: fetch name (e.g., \"Get Posts\")\n- type_name: output type name (e.g., \"posts\", \"profile\")\n- description (optional): LLM-facing description for discovery via sm_capabilities\n- fields[]: extraction field definitions (minimum 1):\n - name: output field name\n - target_id: target element to extract from\n - extraction_type: 'text' | 'attribute' | 'list' | 'count' | 'exists'\n - attribute: attribute name (for 'attribute' type)\n - item_selector: CSS selector for list items (for 'list' type)\n - item_fields[]: structured extraction for each list item (for 'list' type):\n - name: output field name\n - selector: CSS selector relative to each list item (use \":scope\" for item element itself)\n - extraction_type: 'text' | 'attribute' | 'exists'\n - attribute: attribute name (for 'attribute' type)\n- limits (optional): {max_chars:1000-200000, max_items:1-1000}\n\nReturns:\n- fetch_id, field_count\n- validation: {valid, warnings[]} with target reference checks`\n","export const SM_ADD_TARGET_DESCRIPTION = `Create or update semantic targets (element locators) for a registered page.\n\nSupports batch creation and re-binding of existing targets.\nUse ref from read_page/find to auto-generate locators, or provide locators explicitly.\n\nParameters:\n- tabId: target tab where elements are present\n- page_id: the page these targets belong to\n- targets[]: array of target definitions:\n - target_id (optional): specify to re-bind an existing target's locators\n - label: target name (e.g., \"Username Input\")\n - role: semantic role (e.g., \"textbox\", \"button\")\n - ref (optional): element ref from read_page/find for auto-locator generation\n - locators (optional): explicit locator array [{type, value, stability}]\n\nEach target must have either ref or locators.\nWhen target_id is provided, only locators are updated (label/role preserved).\n\nReturns per target:\n- target_id, label, locators, resolve_test (live element check), updated (true = re-bind)`\n","export const SM_CAPABILITIES_DESCRIPTION = `Query semantic capabilities available for the current page.\n\nReturns the matched page definition, available actions, and fetches for the active tab.\nUses page signature matching (URL pattern + DOM markers) to identify the current page state.\n\nReturns:\n- ok: whether a page match was found\n- domain: hostname of the current tab\n- page_id / page_type / variant_id: matched page and variant\n- match_score: confidence score of the match\n- actions[]: available actions with their parameters\n- fetches[]: available data extractions with their parameters\n- other_pages[]: other registered pages on the same domain (for cross-page navigation)\n- hint: guidance message when no page matches\n\nUse this before sm_invoke or sm_fetch to discover what operations are available.\nIf no page matches (ok: false), use sm_register_page to register the current page,\nthen sm_add_target and sm_add_action/sm_add_fetch to configure automation.\nUse sm_status to review all existing configurations.`\n","export const SM_CUSTOM_VIEW_CREATE_DESCRIPTION = `Create a custom HTML view that can be opened in a new tab.\n\nUse this to build dashboards, charts, or reports using HTML/CSS/JS. The HTML can reference external CDN libraries (e.g., Chart.js, D3) and access bound data via window.__VIYV_DATA__.\n\nParameters:\n- label: view name (max 100 chars)\n- description: optional description (max 500 chars)\n- html: full HTML document (max 200KB)\n- data_bindings: optional array of data source references (max 10)\n - binding_id: unique ID within this view (e.g., \"b1\")\n - source_type: \"job_report\" | \"report\" | \"job\" | \"scenario\"\n - source_id: entity ID (e.g., \"JRP_xxxx\")\n - projection: optional {fields, max_entries} to limit injected data\n\nThe HTML should reference data as window.__VIYV_DATA__[binding_id]. Data is injected when the user opens the view.\n\nReturns: {ok, view_id, html_size, binding_count}`\n\nexport const SM_CUSTOM_VIEW_UPDATE_DESCRIPTION = `Update an existing custom view.\n\nUse this to refresh HTML after data structure changes (stale bindings) or to modify the view content.\n\nParameters:\n- view_id: view to update\n- label: new label (optional)\n- description: new description (optional)\n- html: new HTML content (optional, max 200KB)\n- data_bindings: new bindings array (optional, replaces all bindings)\n\nReturns: {ok, view_id, html_size, binding_count}`\n\nexport const SM_CUSTOM_VIEW_DELETE_DESCRIPTION = `Delete a custom view.\n\nParameters:\n- view_id: view to delete\n\nReturns: {ok, view_id}`\n\nexport const SM_CUSTOM_VIEW_LIST_DESCRIPTION = `List all custom views with binding health status.\n\nUse this to check which views exist and whether their data bindings are still valid. Each view includes binding_status for every binding:\n- \"ok\": source exists and structure matches\n- \"stale\": source exists but structure changed (stale_reason: \"schema_changed\", includes current vs saved fingerprint)\n- \"missing\": source has been deleted\n\nWhen bindings are stale, use sm_custom_view_get with include_data=true to fetch current data, then sm_custom_view_update to refresh the HTML.\n\nReturns: {ok, views[]: {view_id, label, description, html_size, binding_count, binding_status[], created_at, updated_at}}`\n\nexport const SM_CUSTOM_VIEW_GET_DESCRIPTION = `Get a custom view with optional data injection.\n\nParameters:\n- view_id: view to retrieve\n- include_data: if true, resolve all bindings and return actual data in injected_data (default: false)\n\nWhen include_data=true:\n- injected_data maps binding_id to resolved data from the source\n- Data is filtered by projection (fields, max_entries) if specified\n- Secret parameter values are masked\n\nbinding_status shows current health of each binding (ok/stale/missing).\n\nReturns: {ok, view, binding_status[], injected_data?}`\n","export const SM_DELETE_DESCRIPTION = `Delete a semantic entity (page, target, action, or fetch).\n\nSupports dry_run mode to preview deletion impact before committing.\nPage deletion cascades to all dependent targets, actions, and fetches.\nTarget deletion warns about referencing actions and fetches.\n\nParameters:\n- entity_type: 'page' | 'target' | 'action' | 'fetch'\n- entity_id: the entity ID to delete\n- dry_run (optional): if true, return impact preview without deleting\n\nReturns:\n- entity_type, entity_id, label\n- dry_run: whether this was a preview\n- cascaded: (page deletion) lists of deleted targets, actions, fetches\n- warnings: (target deletion) referencing actions/fetches that may break`\n","export const SM_EXPORT_DESCRIPTION = `Export semantic configuration as JSON.\n\nExports pages, targets, actions, and fetches. Optionally filter by domain.\nSecret parameter default values are stripped from the export.\nIncludes a SHA-256 checksum for integrity verification on import.\n\nParameters:\n- domain (optional): export only pages matching this domain (subdomain-aware). If omitted, exports all.\n\nReturns:\n- SemanticExport JSON with schema_version, checksum, pages[], targets[], actions[], fetches[]`\n","export const SM_FETCH_DESCRIPTION = `Extract structured data from the current page using predefined extraction rules.\n\nResolves target elements and extracts text, attributes, lists, counts, or existence checks.\nApplies output limits (max_chars, max_items) to prevent oversized responses.\n\nParameters:\n- tabId: target tab\n- fetch_id: the fetch definition to execute (from sm_capabilities)\n- params: optional parameters for the fetch\n\nReturns:\n- ok: whether extraction succeeded\n- data: extracted key-value data matching the fetch's return_schema\n- page_id_before / page_id_after: page state tracking\n- needs_rebind: true if any targets could not be resolved\n- missing_targets[]: list of target IDs that failed to resolve\n- hint: recovery guidance when errors occur\n\nWhen needs_rebind is true, use sm_test_target to diagnose each failing target,\nthen sm_add_target with target_id to re-bind locators.\nWhen fetch_id is not found, use sm_capabilities to discover available fetches.`\n","export const SM_IMPORT_DESCRIPTION = `Import semantic configuration from JSON.\n\nImports pages, targets, actions, and fetches from a SemanticExport JSON object.\nVerifies checksum integrity before importing.\n\nParameters:\n- data (required): SemanticExport JSON object (from sm_export)\n- strategy (optional): \"merge\" (default) adds new entities, skips existing IDs.\n \"replace-domain\" deletes all existing pages matching the import's domains\n (with cascade to targets/actions/fetches), then inserts all import entities.\n\nReturns:\n- ok: whether import succeeded\n- imported: number of entities imported\n- skipped: number of entities skipped (existing IDs in merge mode)\n- errors[]: any error messages`\n","export const SM_INVOKE_DESCRIPTION = `Execute a semantic action on the current page.\n\nRuns a predefined sequence of steps (click, type, select, wait, etc.) using\nstable element locators with automatic fallback. Handles navigation detection,\nretry with jitter, and template parameter substitution.\n\nParameters:\n- tabId: target tab\n- action_id: the action to execute (from sm_capabilities)\n- params: key-value parameters for template substitution (e.g., { username: \"...\" })\n\nReturns:\n- ok: whether all steps completed successfully\n- completed_steps / total_steps: execution progress\n- page_id_before / page_id_after: page state tracking (navigation detection)\n- observations[]: human-readable log of what happened (secrets redacted)\n- needs_rebind: true if any targets could not be resolved\n- missing_targets[]: list of target IDs that failed to resolve\n- hint: recovery guidance when errors occur\n\nWhen needs_rebind is true, use sm_test_target to diagnose each failing target,\nthen sm_add_target with target_id to re-bind locators.\nWhen action_id is not found, use sm_capabilities to discover available actions.`\n","export const SM_JOB_CANCEL_DESCRIPTION = `Cancel a running job and its currently executing scenario.\n\nRemaining unexecuted entries are marked as skipped.\n\nParameters:\n- tabId: tab where the job is running\n\nReturns:\n- ok: success status\n- cancelled: true if a job was found and cancelled`\n","export const SM_JOB_CREATE_DESCRIPTION = `Create a reusable job that groups multiple scenarios for sequential batch execution.\n\nEach entry specifies a scenario_id and optional parameter overrides. When executed, scenarios\nrun one after another on the same tab, each producing its own Report.\n\nParameters:\n- label: job name (e.g., \"Print Price Collection\")\n- description: optional description\n- entries: ordered list of scenarios to execute\n - scenario_id: existing scenario ID\n - label: display label override (uses scenario label if omitted)\n - params: parameter overrides for this scenario execution\n- on_error: 'stop' (default) halts on first failure, 'skip_and_continue' skips failed and continues\n\nReturns:\n- job_id: the created job ID (JOB_xxxx)\n- entry_count: number of entries`\n","export const SM_JOB_DELETE_DESCRIPTION = `Delete a job definition.\n\nRunning executions are not affected — only the job definition is removed.\n\nParameters:\n- job_id: job to delete\n\nReturns:\n- ok: success status\n- job_id: deleted job ID`\n","export const SM_JOB_HISTORY_DESCRIPTION = `Get execution history for a job. Returns condensed snapshots that persist beyond report pruning.\n\nUse this to review past executions, track trends over time (e.g. price changes), or select snapshots for comparison.\n\nParameters:\n- job_id: job to get history for\n- limit: max snapshots to return (default: 20, most recent first)\n\nReturns:\n- job_id, job_label\n- snapshots[]: list of {snapshot_id, status, started_at, completed_at, duration_ms, scenario_count}`\n\nexport const SM_JOB_COMPARE_DESCRIPTION = `Compare two job executions to see data changes between them.\n\nMatches scenarios by scenario_id, data groups by result_key, and rows by loop_params. Computes per-cell diffs with numeric deltas.\n\nParameters:\n- job_id: the job to compare\n- base_snapshot_id: older snapshot (optional, defaults to second-most-recent)\n- compare_snapshot_id: newer snapshot (optional, defaults to most-recent)\n- changed_only: if true, omit unchanged rows (default: false)\n\nReturns:\n- diffs[]: per-scenario, per-result_key diff with rows showing added/removed/modified/unchanged\n- summary: total counts of changes`\n\nexport const SM_JOB_SNAPSHOT_GET_DESCRIPTION = `Get detailed data from a specific job snapshot.\n\nUse this to inspect the full captured data for a single execution, including all scenario results and data groups.\n\nParameters:\n- snapshot_id: the snapshot to retrieve (SNP_xxxx)\n\nReturns:\n- snapshot: full JobSnapshot with scenario_snapshots and data_groups`\n","export const SM_JOB_LIST_DESCRIPTION = `List all defined jobs with entry counts and configuration.\n\nReturns:\n- jobs: array of job summaries\n - job_id, label, description, entry_count, on_error, created_at`\n","export const SM_JOB_REPORT_EXPORT_DESCRIPTION = `Export all scenario results from a job execution as aggregated JSON or CSV.\n\nCombines data from all linked scenario reports into a single file.\nCSV includes a job_entry column to distinguish scenarios.\n\nParameters:\n- job_report_id: job report ID (JRP_xxxx)\n- format: 'json' (default) or 'csv'\n\nReturns:\n- data: export content string\n- filename: suggested filename`\n","export const SM_JOB_REPORT_GET_DESCRIPTION = `Get job execution status and results.\n\nShows overall progress and per-scenario report summaries.\nUse sm_report_get with individual report_ids for detailed scenario data.\n\nParameters:\n- job_report_id: job report ID (JRP_xxxx)\n\nReturns:\n- job_report: full JobReport with entry statuses\n- scenario_summaries: per-scenario report summaries (entry_count, error_count)`\n","export const SM_JOB_RUN_DESCRIPTION = `Execute a job on a browser tab. Scenarios run sequentially.\n\nReturns job_report_id immediately by default. Poll with sm_job_report_get to check progress.\nSet wait_for_completion=true to block until all scenarios finish.\n\nOnly one job or scenario can run per tab at a time.\n\nParameters:\n- tabId: target tab for execution\n- job_id: the job to execute\n- params: optional per-scenario param overrides keyed by scenario_id\n- wait_for_completion: if true, wait for all scenarios to complete (default: false)\n\nReturns:\n- job_report_id: ID of the created job report (JRP_xxxx)\n- job_id: the executed job\n- status: 'running' (async) or 'completed'/'failed' (when wait_for_completion=true)`\n","export const SM_JOB_UPDATE_DESCRIPTION = `Update an existing job definition.\n\nSupports partial updates — only specified fields are changed.\n\nParameters:\n- job_id: job to update\n- label: new name (optional)\n- description: new description (optional)\n- entries: new entry list (optional, replaces all entries)\n- on_error: new error handling strategy (optional)\n\nReturns:\n- job_id: updated job ID\n- entry_count: number of entries after update`\n","export const SM_REGISTER_PAGE_DESCRIPTION = `Register a page for semantic automation.\n\nCreates a page definition with URL pattern matching and DOM markers.\nIdempotent: if a registered page already matches the current tab, returns the existing page_id.\nWhen page_type is specified on an already-registered page, it updates the page_type.\n\nPages are grouped by domain. Use page_type to distinguish different page types\nwithin the same domain (e.g., \"profile\", \"compose\", \"search\").\n\nParameters:\n- tabId: target tab (used to auto-derive url_pattern and domains if omitted)\n- label: human-readable page name (e.g., \"GitHub Login\")\n- page_type: page type within the domain (e.g., \"profile\", \"compose\", \"search\")\n- url_pattern: URL regex (auto-derived from tab URL if omitted)\n- domains: domain scope array (auto-derived from tab hostname if omitted)\n- auth_state: 'logged_in' | 'logged_out' | 'any' (default: 'any')\n- must_exist: CSS selectors that must be present on the page\n- must_not_exist: CSS selectors that must not be present\n- title_regex: regex to match page title\n\nReturns:\n- page_id, page_type, variant_id, label\n- already_registered: true if an existing page matched\n- match_test: result of matching the current tab against the page definition`\n","export const SM_REPORT_DELETE_DESCRIPTION = `Delete an execution report.\n\nPermanently removes a report and its data.\n\nParameters:\n- report_id: the report to delete\n\nReturns:\n- ok: whether deletion succeeded\n- report_id: the deleted report ID`\n","export const SM_REPORT_EXPORT_DESCRIPTION = `Export a report as JSON or CSV.\n\nJSON format includes the complete report structure.\nCSV format flattens entries into rows with columns for loop parameters and data fields.\nCSV uses UTF-8 BOM for Excel compatibility with non-ASCII characters.\n\nParameters:\n- report_id: the report to export\n- format: 'json' (default) or 'csv'\n\nReturns:\n- format: the export format used\n- data: the exported content as a string\n- filename: suggested filename for download`\n","export const SM_REPORT_GET_DESCRIPTION = `Get detailed execution report.\n\nReturns the full report including all data entries, observations, errors,\nand grouped data (entries organized by result_key).\n\nUse this to poll running scenarios for progress updates.\n\nParameters:\n- report_id: the report to retrieve\n\nReturns:\n- report: full Report object with entries[], grouped_data, observations[], errors[]\n- report.status: 'running' | 'completed' | 'failed' | 'cancelled'\n- report.entries[]: collected data with loop_params and extracted data\n- report.grouped_data: entries grouped by result_key for easy access`\n","export const SM_REPORT_LIST_DESCRIPTION = `List execution reports.\n\nReturns summaries of scenario execution reports, sorted by most recent first.\nOptionally filter by scenario_id.\n\nParameters:\n- scenario_id (optional): filter reports for a specific scenario\n\nReturns:\n- reports[]: array of report summaries with status, timing, and entry/error counts`\n","export const SM_SCENARIO_CREATE_DESCRIPTION = `Create a scenario for multi-page workflow automation.\n\nScenarios define sequences of steps (navigate, action, fetch, loop, wait) that execute\nacross multiple pages. Loop steps support cartesian product iteration over variables\n(static values, select options, or previous fetch results).\n\nParameters:\n- label: scenario name (e.g., \"Price Table Collection\")\n- description: optional LLM-facing description\n- params: global parameter definitions (available as {{param_name}} templates)\n- steps: ordered step sequence\n- max_duration_ms: timeout (default: 300000ms = 5min)\n- on_error: 'stop' (default) or 'skip_and_continue'\n\nStep types:\n- navigate: { url, wait_for_load } - navigate to URL (supports {{templates}})\n- action: { action_id, params } - execute an existing semantic action\n- fetch: { fetch_id, result_key, params } - extract data, stored in report under result_key\n- loop: { variables, steps, delay_between_ms, max_iterations } - iterate combinations\n- wait: { strategy, selector, timeout_ms } - wait for condition\n\nLoop variables:\n- static: explicit value list\n- target_options: auto-extract all <option> values from a <select> target\n- previous_fetch: extract values from prior fetch results\n\nInside loops, use {{loop.variable_name}} to reference loop variables.\n\nReturns:\n- scenario_id: the created scenario ID (SCN_xxxx)\n- step_count: total step count\n- validation: { valid, warnings[] } referential integrity check`\n","export const SM_SCENARIO_DELETE_DESCRIPTION = `Delete a scenario by ID.\n\nAssociated reports become orphaned but are not deleted.\n\nParameters:\n- scenario_id: the scenario to delete\n\nReturns:\n- ok: whether deletion succeeded\n- scenario_id: the deleted scenario ID`\n","export const SM_SCENARIO_LIST_DESCRIPTION = `List all registered scenarios.\n\nReturns a summary of each scenario including ID, label, step count,\nparameter names, and creation timestamp.\n\nNo parameters required.\n\nReturns:\n- scenarios[]: array of scenario summaries`\n","export const SM_SCENARIO_RUN_DESCRIPTION = `Execute a scenario on a tab.\n\nStarts scenario execution and returns immediately with a report_id.\nUse sm_report_get to poll for progress and final results.\n\nOnly one scenario can run per tab at a time.\n\nParameters:\n- tabId: target tab for execution\n- scenario_id: the scenario to execute\n- params: parameter values for template substitution\n- wait_for_completion: if true, wait for scenario to finish (up to max_duration_ms)\n\nReturns:\n- report_id: ID of the created report (RPT_xxxx)\n- scenario_id: the executed scenario\n- status: 'running' (async) or 'completed'/'failed' (when wait_for_completion=true)\n- error: error message if startup failed`\n","export const SM_SCENARIO_UPDATE_DESCRIPTION = `Update an existing scenario.\n\nSupports partial updates - only provide fields you want to change.\n\nParameters:\n- scenario_id: the scenario to update\n- label: new name\n- description: new description\n- params: new parameter definitions\n- steps: new step sequence\n- max_duration_ms: new timeout\n- on_error: new error handling strategy\n\nReturns:\n- scenario_id, step_count, validation`\n","export const SM_STATUS_DESCRIPTION = `View all semantic configuration (pages, targets, actions, fetches).\n\nReturns a summary and detailed listing of all registered entities.\nOptionally test-resolve all targets against the current tab.\n\nParameters:\n- tabId (optional): required when test_resolve is true\n- page_id (optional): filter results to a specific page\n- domain (optional): filter results to pages matching this domain\n- test_resolve (optional): if true, resolve all targets on the current tab\n\nReturns:\n- summary: {total_pages, total_targets, total_actions, total_fetches}\n- pages[]: page definitions with page_type, domains, url_patterns, and counts\n- targets[]: targets with locator info and optional resolve_result\n- actions[]: actions with step count and param names\n- fetches[]: fetches with field count\n- integrity[]: referential integrity warnings`\n","export const SM_TEST_TARGET_DESCRIPTION = `Test a specific target's locators against the current page.\n\nResolves each locator individually and reports which ones matched.\nUseful for diagnosing broken targets and deciding which locators to update.\n\nParameters:\n- tabId: target tab to test against\n- target_id: the target to test\n\nReturns:\n- found: whether any locator resolved successfully\n- locator_results[]: per-locator results {type, value, stability, matched}\n- element: resolved element info {tag, text, rect} if found\n- test_status: updated test status saved to storage`\n","export const SELECT_TAB_DESCRIPTION = `Switch focus to a specific tab by its identifier.\nMakes the target tab the active tab in the agent's group,\nbringing it to the foreground for subsequent operations\nsuch as navigation, clicking, or content extraction.`\n","export const TAB_CLOSE_DESCRIPTION = `Close a tab by its identifier.\nRemoves the specified tab from the browser and the agent's tab group.\nIf the closed tab was active, focus shifts to the nearest remaining\ntab in the group.`\n","export const TABS_CONTEXT_DESCRIPTION = `Get information about the current agent tab group.\nReturns the list of tabs belonging to the agent's assigned group,\nincluding each tab's ID, URL, title, and active status.\nUseful for understanding the current browsing context.`\n","export const TABS_CREATE_DESCRIPTION = `Create a new tab within the agent's tab group.\nOpens a new tab with an optional URL and automatically assigns it\nto the current agent's group. The new tab becomes the active tab\nunless otherwise specified.`\n","export const AGENT_TAB_ASSIGN_DESCRIPTION = `Assign a tab group to a specific agent.\nBinds an existing Chrome tab group to the calling agent, granting\nexclusive control over all tabs within the group. Prevents other\nagents from interfering with the assigned tabs.`\n","export const AGENT_TAB_LIST_DESCRIPTION = `List all agent-to-tab-group mappings.\nReturns a summary of which agents are assigned to which tab groups,\nincluding the group ID, agent identifier, and the number of tabs\nin each group.`\n","export const ARTIFACT_FROM_PAGE_DESCRIPTION = `Save the current page as a persistent artifact.\nCaptures the page content as HTML, text, or screenshot and stores it\nas a named artifact for later reference. Artifacts can be retrieved\nby other tools or returned to the user as output.`\n","export const BROWSER_EVENT_SUBSCRIBE_DESCRIPTION = `Subscribe to browser events for real-time monitoring.\nRegisters a listener for specified event types such as navigation,\ntab updates, DOM changes, or network activity. Events are queued\nand delivered on subsequent polling or callback.`\n","export const BROWSER_EVENT_UNSUBSCRIBE_DESCRIPTION = `Unsubscribe from previously registered browser events.\nRemoves the event listener for the specified subscription ID,\nstopping further event delivery. Cleans up associated resources\nand flushes any remaining queued events.`\n","export const BROWSER_HEALTH_DESCRIPTION = `Check the health status of the browser connection.\nVerifies that the browser process is running, the CDP connection\nis active, and the agent's tab group is accessible. Returns\ndiagnostic information useful for troubleshooting connectivity issues.`\n","export const PAGE_DATA_EXTRACT_DESCRIPTION = `Extract structured data from the current page.\nParses the page content according to a provided schema object,\nreturning well-formed JSON. Supports extracting tables, lists,\nkey-value pairs, and other structured patterns.\nThe schema defines CSS selectors for each field to extract.`\n","/**\n * Setup command: registers Native Messaging Host manifest.\n * `npx @viyv/browser-mcp setup`\n */\n\nimport { execSync } from 'node:child_process'\nimport { chmodSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir, platform } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { NATIVE_HOST_NAME } from '@viyv-browser/shared'\n\ninterface SetupOptions {\n extensionId?: string\n}\n\nexport function runSetup(options: SetupOptions = {}): void {\n const os = platform()\n const binaryPath = getBinaryPath()\n\n console.log('Viyv Browser MCP - Native Messaging Host Setup')\n console.log('================================================')\n console.log(`Platform: ${os}`)\n console.log(`Binary: ${binaryPath}`)\n\n // Verify binary path exists\n if (!existsSync(binaryPath)) {\n console.error(`WARNING: Binary not found at ${binaryPath}`)\n console.error('The Native Messaging Host may not work until the binary is available.')\n }\n\n const allowedOrigins = options.extensionId\n ? [`chrome-extension://${options.extensionId}/`]\n : ['chrome-extension://*/'] // Allow all during development\n\n // Security warning for wildcard origins\n if (!options.extensionId) {\n process.stderr.write(\n 'WARNING: Using wildcard allowed_origins (chrome-extension://*/). ' +\n 'This allows any Chrome extension to connect. ' +\n 'For production, specify --extension-id to restrict access.\\n',\n )\n }\n\n // Chrome Native Messaging Host manifest doesn't support args.\n // Create a wrapper script that launches the binary with --native-host flag.\n const wrapperPath = createNativeHostWrapper(os, binaryPath)\n\n const manifest = {\n name: NATIVE_HOST_NAME,\n description: 'Viyv Browser MCP Native Messaging Host',\n path: wrapperPath,\n type: 'stdio',\n allowed_origins: allowedOrigins,\n }\n\n const manifestPath = getManifestPath(os)\n const manifestDir = dirname(manifestPath)\n\n console.log(`Wrapper: ${wrapperPath}`)\n console.log(`Manifest path: ${manifestPath}`)\n\n mkdirSync(manifestDir, { recursive: true })\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))\n chmodSync(manifestPath, 0o644)\n\n console.log('\\nNative Messaging Host registered successfully!')\n console.log('\\nNext steps:')\n console.log('1. Start the MCP Server: node <path>/dist/index.js')\n console.log('2. Install the Viyv Browser Chrome Extension')\n console.log('3. Click the extension icon to connect')\n}\n\nfunction getBinaryPath(): string {\n // Find the actual binary path\n const whichCmd = process.platform === 'win32' ? 'where' : 'which'\n try {\n const found = execSync(`${whichCmd} viyv-browser-mcp`, { encoding: 'utf-8' }).trim()\n if (found) return found\n } catch {\n // Not globally installed, use npx path\n }\n\n // Fallback: resolve from current module\n const currentScript = process.argv[1]\n return resolve(currentScript)\n}\n\nfunction createNativeHostWrapper(os: string, binaryPath: string): string {\n const manifestDir = dirname(getManifestPath(os))\n mkdirSync(manifestDir, { recursive: true })\n\n // Chrome launches native hosts in a clean environment without user's PATH.\n // We must use the absolute path to node, not rely on #!/usr/bin/env node.\n const nodePath = getNodePath()\n\n if (os === 'win32') {\n // Windows: .bat wrapper\n const wrapperPath = resolve(manifestDir, `${NATIVE_HOST_NAME}.bat`)\n writeFileSync(wrapperPath, `@echo off\\r\\n\"${nodePath}\" \"${binaryPath}\" --native-host\\r\\n`)\n return wrapperPath\n }\n\n // macOS/Linux: shell wrapper\n const wrapperPath = resolve(manifestDir, `${NATIVE_HOST_NAME}.sh`)\n writeFileSync(wrapperPath, `#!/bin/bash\\nexec \"${nodePath}\" \"${binaryPath}\" --native-host\\n`)\n chmodSync(wrapperPath, 0o755)\n return wrapperPath\n}\n\nfunction getNodePath(): string {\n try {\n return execSync('which node', { encoding: 'utf-8' }).trim()\n } catch {\n // Fallback: use the current process's node binary\n return process.execPath\n }\n}\n\nfunction getManifestPath(os: string): string {\n const home = homedir()\n\n switch (os) {\n case 'darwin':\n return resolve(\n home,\n 'Library/Application Support/Google/Chrome/NativeMessagingHosts',\n `${NATIVE_HOST_NAME}.json`,\n )\n case 'linux':\n return resolve(home, '.config/google-chrome/NativeMessagingHosts', `${NATIVE_HOST_NAME}.json`)\n case 'win32':\n // On Windows, we'd also need to create a registry entry\n return resolve(\n home,\n 'AppData/Local/Google/Chrome/User Data/NativeMessagingHosts',\n `${NATIVE_HOST_NAME}.json`,\n )\n default:\n throw new Error(`Unsupported platform: ${os}`)\n }\n}\n"],"mappings":"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","names":["existsSync","randomUUID","existsSync","createConnection","z","z","sessions","randomUUID","resolve","existsSync","createConnection","chmodSync","existsSync","existsSync","chmodSync","wrapperPath","waitForSocket","existsSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "viyv-browser-mcp",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "MCP Server for AI agent browser automation via Chrome Extension",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",