/** * Kept free of execution imports so CLI command registration does not load * the Playwright-backed browser stack. */ import type { BrowserOperationMeta } from "./types.js"; /** * Metadata for every browser operation, describing fields, types, and * constraints. Used by the CLI command builder to generate subcommands. * * The `browser_mode` field is handled as a shared parent-level option * on the `assistant browser` command (--browser-mode), not as a * per-operation field. The `activity` field is omitted because it is * an internal execution concern, not a user-facing parameter. */ export const BROWSER_OPERATION_META: readonly BrowserOperationMeta[] = [ { operation: "navigate", description: "Navigate the browser to a URL and return the page title.", fields: [ { name: "url", type: "string", description: "The URL to navigate to.", required: true, }, { name: "allow_private_network", type: "boolean", description: "Allow navigation to localhost/private-network hosts.", required: false, }, { name: "new_tab", type: "boolean", description: "Force a brand-new browser tab even when this session already has a dedicated tab, and pin subsequent operations to it. Extension backend only; ignored on other backends.", required: false, }, { name: "use_active_tab", type: "boolean", description: "Navigate the currently-active browser tab instead of a dedicated tab. Extension backend only; ignored on other backends.", required: false, }, ], helpText: `Loads the given URL and waits for the page to reach a stable state. Returns the page title on success. On the Chrome extension backend, navigate opens a dedicated tab the first time it runs in a conversation and pins this session's subsequent operations to it, so browsing never disturbs the tab you're on (often the tab you're chatting with the assistant from). Later navigates reuse that pinned tab. Pass --new-tab to force a fresh tab even when one is already pinned, or --use-active-tab to navigate the currently-active tab instead. Examples: $ assistant browser navigate --url https://example.com $ assistant browser navigate --url http://localhost:3000 --allow-private-network $ assistant browser navigate --url https://github.com --new-tab $ assistant browser navigate --url https://github.com --use-active-tab $ assistant browser --session s1 navigate --url https://github.com`, }, { operation: "snapshot", description: "List interactive elements on the current page with unique IDs.", fields: [], helpText: `Returns a structured list of interactive elements (buttons, links, inputs, etc.) with stable element IDs that can be passed to click, type, and other element-targeting commands. Examples: $ assistant browser snapshot $ assistant browser --json snapshot`, }, { operation: "screenshot", description: "Take a visual screenshot of the current page.", fields: [ { name: "full_page", type: "boolean", description: "Capture the full scrollable page instead of just the viewport.", required: false, }, ], helpText: `Captures a JPEG screenshot. Use --output to save to a file, or --json to receive base64-encoded image data in the output. Examples: $ assistant browser screenshot --output page.jpg $ assistant browser screenshot --full-page --output full.jpg $ assistant browser --json screenshot`, }, { operation: "close", description: "Close the browser page for the current conversation.", fields: [ { name: "close_all_pages", type: "boolean", description: "Close all browser pages and the browser context.", required: false, }, ], helpText: `Closes the browser page for the current session. Use --close-all-pages to tear down the entire browser context including all pages. Examples: $ assistant browser close $ assistant browser close --close-all-pages $ assistant browser --session s1 close`, }, { operation: "attach", description: "Attach the Chrome debugger to the active browser tab.", fields: [], helpText: `Connects the assistant to a running Chrome instance via the Chrome DevTools Protocol. Required before interacting with Chrome-attached tabs. Examples: $ assistant browser attach $ assistant browser --session s1 attach`, }, { operation: "detach", description: "Detach the Chrome debugger from the active browser tab.", fields: [], helpText: `Disconnects the assistant from the Chrome DevTools Protocol session. The browser tab continues running but is no longer controlled. Examples: $ assistant browser detach $ assistant browser --session s1 detach`, }, { operation: "click", description: "Click an element on the page.", fields: [ { name: "element_id", type: "string", description: "Element ID from a previous browser snapshot.", required: false, }, { name: "selector", type: "string", description: "CSS selector to target.", required: false, }, ], helpText: `Clicks an element identified by element ID (from snapshot) or CSS selector. Provide at least one of --element-id or --selector. Examples: $ assistant browser click --element-id e14 $ assistant browser click --selector "#login-button" $ assistant browser click --selector "a.nav-link"`, }, { operation: "type", description: "Type text into an input element.", fields: [ { name: "text", type: "string", description: "The text to type into the element.", required: true, }, { name: "element_id", type: "string", description: "Element ID from a previous browser snapshot.", required: false, }, { name: "selector", type: "string", description: "CSS selector to target.", required: false, }, { name: "clear_first", type: "boolean", description: "Clear existing content before typing. Default: true.", required: false, }, { name: "press_enter", type: "boolean", description: "Press Enter after typing the text.", required: false, }, ], helpText: `Types text into the focused or targeted element. By default, existing content is cleared first (--clear-first). Use --no-clear-first to append to existing content. Use --press-enter to submit after typing. Examples: $ assistant browser type --text "hello world" --element-id e14 $ assistant browser type --text "search query" --selector "#search" --press-enter $ assistant browser type --text "append this" --no-clear-first`, }, { operation: "press_key", description: "Press a keyboard key, optionally targeting an element.", fields: [ { name: "key", type: "string", description: 'The key to press (e.g. "Enter", "Escape", "Tab", "ArrowDown").', required: true, }, { name: "element_id", type: "string", description: "Optional element ID from browser snapshot.", required: false, }, { name: "selector", type: "string", description: "Optional CSS selector to target.", required: false, }, ], helpText: `Sends a keyboard key press. If --element-id or --selector is given, the key is dispatched to that element; otherwise to the focused element. Examples: $ assistant browser press-key --key Enter $ assistant browser press-key --key Tab --element-id e5 $ assistant browser press-key --key Escape`, }, { operation: "scroll", description: "Scroll the page or a specific element.", fields: [ { name: "direction", type: "string", description: "The direction to scroll.", required: true, enum: ["up", "down", "left", "right"], }, { name: "amount", type: "number", description: "The number of pixels to scroll. Default: 500.", required: false, }, { name: "element_id", type: "string", description: "Optional element ID to scroll within.", required: false, }, { name: "selector", type: "string", description: "Optional CSS selector of element to scroll within.", required: false, }, ], helpText: `Scrolls the page or a specific scrollable element. Direction is required; amount defaults to 500 pixels. Examples: $ assistant browser scroll --direction down $ assistant browser scroll --direction up --amount 1000 $ assistant browser scroll --direction down --element-id e8`, }, { operation: "select_option", description: "Select an option from a native from browser snapshot.", required: false, }, { name: "selector", type: "string", description: "CSS selector for the element by value, label, or index. Provide at least one of --value, --label, or --index to identify the option, and --element-id or --selector to identify the