Shopping Workflow
OpenDevBrowser CLI Command-line interface for installing and managing the OpenDevBrowser plugin, plus automation commands for agents. Status: active Last updated: 2026-04-13 OpenDevBrowser exposes 70 opendevbrowser_ tool
OpenDevBrowser CLI
Command-line interface for installing and managing the OpenDevBrowser plugin, plus automation commands for agents.
Status: active
Last updated: 2026-04-13
OpenDevBrowser exposes 70 opendevbrowser_* tools; see README.md and docs/SURFACE_REFERENCE.md for the full inventories.
Generated help is the primary first-contact inventory and onboarding surface. Agent runs should start with opendevbrowser_prompting_guide or opendevbrowser_skill_load opendevbrowser-best-practices "quick start" before low-level browser commands, then load opendevbrowser_skill_load opendevbrowser-best-practices "validated capability lanes" when they need the currently proven transcript, research, and shopping workflows. Load opendevbrowser_skill_load opendevbrowser-design-agent "canvas-contract" immediately after that baseline for frontend, screenshot-to-code, or /canvas design work. Use continuity guidance only for long-running handoff or compaction.
That generated help surface now leads with a Find It Fast block that uses the exact lookup terms screencast / browser replay, desktop observation, and computer use / browser-scoped computer use. It maps replay to screencast-start / screencast-stop, desktop observation to the public read-only desktop-* family, and browser-scoped computer use to --challenge-automation-mode on research run, shopping run, product-video run, inspiredesign run, and macro-resolve --execute, with research run --topic ... --challenge-automation-mode browser as the first entry command.
Tool-only commands opendevbrowser_prompting_guide, opendevbrowser_skill_list, and opendevbrowser_skill_load run locally via the skill loader. They are onboarding helpers, not browser-runtime commands, and they do not require relay or daemon bootstrap.
CLI-only power command rpc intentionally has no tool equivalent; it is an internal daemon escape hatch behind an explicit safety flag and should be used with extreme caution.
Public-surface metadata now flows from src/public-surface/source.ts through scripts/generate-public-surface-manifest.mjs into src/public-surface/generated-manifest.ts and src/public-surface/generated-manifest.json, which are consumed by src/cli/help.ts, src/cli/args.ts, inventory scripts, mirrored website inputs, and re-export paths in src/tools/index.ts. Onboarding literals still live in src/cli/onboarding-metadata.json, and runtime execution authority remains src/cli/args.ts plus src/tools/index.ts.
The generated first-contact inventory mirrored into downstream website and release flows is tracked in docs/ASSET_INVENTORY.md.
Dependency inventory: docs/DEPENDENCIES.md
First-run local-artifact onboarding: docs/FIRST_RUN_ONBOARDING.md
Parity and skill-pack gates:
npm run test -- tests/cli-help-parity.test.ts
npm run test -- tests/parity-matrix.test.ts
./skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh
./skills/opendevbrowser-design-agent/scripts/validate-skill-assets.sh
./skills/opendevbrowser-design-agent/scripts/design-workflow.sh research-harvest
./skills/opendevbrowser-design-agent/scripts/design-workflow.sh release-gate
Treat those checks as contract and documentation guards. Live release proof comes from the direct-run harnesses documented later in this guide and in docs/RELEASE_RUNBOOK.md.
Installation
Requires Node.js >=18.
# Interactive installation (prompts for location)
npx opendevbrowser
# Non-interactive with flags
npx opendevbrowser --global # Install to ~/.config/opencode/opencode.json
npx opendevbrowser --local # Install to ./opencode.json
# Optional: persistent global CLI
npm install -g opendevbrowser
opendevbrowser --version
Local package onboarding from a source tarball
cd <public-repo-root>
npm pack
WORKDIR=$(mktemp -d /tmp/opendevbrowser-first-run-XXXXXX)
ISOLATED_ROOT=$(mktemp -d /tmp/opendevbrowser-first-run-isolated-XXXXXX)
export HOME="$ISOLATED_ROOT/home"
export OPENCODE_CONFIG_DIR="$ISOLATED_ROOT/opencode-config"
export OPENCODE_CACHE_DIR="$ISOLATED_ROOT/opencode-cache"
export CODEX_HOME="$ISOLATED_ROOT/codex-home"
export CLAUDECODE_HOME="$ISOLATED_ROOT/claudecode-home"
export AMP_CLI_HOME="$ISOLATED_ROOT/ampcli-home"
cd "$WORKDIR"
npm init -y
npm install <public-repo-root>/opendevbrowser-0.0.22.tgz
npx --no-install opendevbrowser --help
npx --no-install opendevbrowser help
Load extension unpacked from:
$WORKDIR/node_modules/opendevbrowser/extension
Set OPDEVBROWSER_SKIP_POSTINSTALL_SKILL_SYNC=1 before npm install only if you need a packaging smoke test that avoids the install-time managed-skill refresh entirely.
By default (--skills-global), the CLI installs bundled skills to global OpenCode/Codex/ClaudeCode/AmpCLI locations. Use --skills-local for project-local locations or --no-skills to skip CLI-managed skill installation. Package installation (npm install -g, local tarball install, or equivalent) also best-effort syncs the canonical bundled packs into the managed global skill targets during package postinstall. Use --full to always create opendevbrowser.jsonc and pre-extract extension assets.
Installer inventory:
--skills-globaland--skills-localsync the 9 canonicalopendevbrowser-*packs underskills/into managed global or project-local agent directories.- Managed installs write a target-level ownership marker, so default updates and uninstall only act on CLI-managed targets or older config installs that already contain canonical packs.
- Reinstall and update refresh drifted managed copies and leave matching packs unchanged.
- Uninstall removes managed canonical packs, retires repo-owned legacy alias directories that match shipped content, and leaves unrelated directories untouched.
OPENCODE_CONFIG_DIR changes config lookup, but the extracted unpacked-extension copy created by --full still lives at ~/.config/opencode/opendevbrowser/extension.
Published npm consumer proof is a separate release gate:
node scripts/registry-consumer-smoke.mjs --version X.Y.Z --output artifacts/release/vX.Y.Z/registry-consumer-smoke.json
Skill discovery order
The skill loader discovers skills in this order (first match wins):
- Project-local:
./.opencode/skill - Global:
~/.config/opencode/skill(or$OPENCODE_CONFIG_DIR/skill) - Compatibility (project):
./.codex/skills - Compatibility (global):
$CODEX_HOME/skills(fallback~/.codex/skills) - Compatibility (project):
./.claude/skills - Compatibility (global):
$CLAUDECODE_HOME/skills(fallback~/.claude/skills) - Compatibility (project):
./.amp/skills - Compatibility (global):
$AMP_CLI_HOME/skills(fallback~/.amp/skills) - Extra paths from
skillPaths(advanced) - Bundled package fallback: packaged
skills/directory afterskillPathswhen no installed copy matches
Output formats
Use --output-format to switch output formats for automation.
text(default): human-friendly outputjson: single JSON objectstream-json: emit one JSON object per line for arrays; otherwise emits a single JSON object
Use --quiet to suppress output. Use --no-interactive (alias of --no-prompt) to disable prompts.
Exit codes
0: success1: usage error (invalid args, missing flags)2: execution error (runtime/daemon failures)10: disconnected (daemon not running or unreachable)
Fatal errors are emitted even when --quiet is set. For JSON output, fatal errors are emitted as:
{ "success": false, "error": "message", "exitCode": 2 }
Argument validation
The CLI validates common flags early and returns a usage error (exitCode: 1) when inputs are invalid.
- Conflicting flags are rejected (examples:
--global+--local,--skills-global+--skills-local). - Numeric flags must be positive integers:
--port,--cdp-port--wait-timeout-ms,--timeout-ms
Surface inventory (source-accurate)
Canonical inventory document: docs/SURFACE_REFERENCE.md.
CLI command surface
- Total commands:
77. - Categories: install/runtime management, session/connection plus capability discovery, navigation plus desktop-assisted browser review, interaction plus low-level pointer control, targets/pages, DOM inspection, browser capture and replay, desktop observation, design canvas, export plus session-centric diagnostics and browser-scoped inspection, macro/annotation, and internal power (
rpc).
Tool surface
- Total tools:
70(opendevbrowser_*). - CLI-tool pairs:
67. - Tool-only surface (no CLI equivalent):
opendevbrowser_prompting_guide,opendevbrowser_skill_list,opendevbrowser_skill_load. - CLI-only surface (no tool equivalent):
install,update,uninstall,help,version,serve,daemon,native,artifacts,rpc.
Relay channel surface
/ops(default extension channel): high-level command protocol; seedocs/SURFACE_REFERENCE.mdfor all59command names./canvas(design-canvas channel): typed design-canvas protocol; seedocs/SURFACE_REFERENCE.mdfor all35command names and envelope contracts./cdp(legacy): low-levelforwardCDPCommandrelay path with explicit opt-in (--extension-legacy).
Challenge orchestration contract
- Managed and
/ops-backed manager responses preserve the shipped blocker fieldsmeta.blocker,meta.blockerState, andmeta.blockerResolution, and may append additivemeta.challengeplusmeta.challengeOrchestration. - Browser-assisted provider fallback reports explicit transport
disposition:completed,challenge_preserved,deferred, orfailed. When bounded challenge orchestration runs during fallback, decision evidence is recorded indetails.challengeOrchestration. - Workflow and daemon callers can set
challengeAutomationModetooff,browser, orbrowser_with_helper. Effective precedence isrun > session > config. - Shipped config defaults now resolve to
providers.challengeOrchestration.mode = browser_with_helperandproviders.challengeOrchestration.optionalComputerUseBridge.enabled = true. meta.challengeOrchestrationand fallbackdetails.challengeOrchestrationcan exposemode,source,standDownReason, andhelperEligibilityso stand-down decisions stay explicit.ProviderRegistryis the only durable anti-bot pressure authority used by policy, runtime routing, and workflow summaries. Provider modules only contribute extraction logic and optionalrecoveryHints().- Direct browser,
/ops, and provider fallback flows share one bounded challenge plane. It can try auth navigation, legitimate session or cookie reuse, non-secret field fill, and bounded browser-native interaction experimentation before yielding. - The optional helper bridge is browser-scoped, not a desktop agent.
browserkeeps it disabled andbrowser_with_helperonly evaluates it after the existing hard gates pass. - Separate
desktop.*config controls the shipped public read-only desktop observation plane. It is enabled by default, is never enabled bychallengeAutomationMode, and does not widen the browser challenge helper into a desktop agent or desktop/opsfamily. - Provider and workflow auto-resume still happen only after manager-owned verification clears the blocker.
- In scope: preserved sessions, visual observation loops, low-level pointer controls, bounded interaction experimentation, reclaimable human yield packets, and owned-environment fixtures that use vendor test keys only.
- Out of scope: hidden bypass paths, CAPTCHA-solving services, challenge token harvesting, or autonomous unsandboxed solving of third-party anti-bot systems.
Commands
Install (default)
# Interactive - prompts for global or local
npx opendevbrowser
# Global installation (user-wide)
npx opendevbrowser --global
npx opendevbrowser -g
# Local installation (current project)
npx opendevbrowser --local
npx opendevbrowser -l
# Skip prompts, use default (global)
npx opendevbrowser --no-prompt
npx opendevbrowser --no-interactive
# Full install (config + extension assets)
npx opendevbrowser --full
# Also create opendevbrowser.jsonc config file
npx opendevbrowser --global --with-config
# Full install (plugin + config + bundled skills)
npx opendevbrowser --global --with-config --skills-global
# Install skills locally (project scope)
npx opendevbrowser --skills-local
# Skip installing skills
npx opendevbrowser --no-skills
On successful installs, the CLI reconciles daemon auto-start on supported platforms (macOS/Windows) so the relay is available on
login. Existing installs are rechecked and repaired when the per-user auto-start entry is missing or stale on macOS and Windows,
and when the macOS LaunchAgent is malformed. If the current CLI entrypoint lives under a transient temp-root path (for example a
first-run /tmp or /private/tmp npx workspace), OpenDevBrowser refuses to persist that path as auto-start. Plugin install
still succeeds, but auto-start repair warns and you must rerun opendevbrowser daemon install from a stable install location, or
npx --no-install opendevbrowser daemon install from a persistent local package install. You can remove auto-start later with
opendevbrowser daemon uninstall.
Update
Clear the OpenCode cache to trigger reinstallation of the latest version.
npx opendevbrowser --update
npx opendevbrowser -u
This removes cached files from ~/.cache/opencode/node_modules/opendevbrowser/. OpenCode will download the latest version on next run.
Uninstall
Remove the plugin from configuration and clean managed skill packs for the selected install target.
# Remove from global config
npx opendevbrowser --uninstall --global
# Remove from local config
npx opendevbrowser --uninstall --local
# Interactive - prompts which to remove if both exist
npx opendevbrowser --uninstall
Help / Version
npx opendevbrowser --help
npx opendevbrowser -h
npx opendevbrowser help
npx opendevbrowser --version
npx opendevbrowser -v
--help and help print the same generated first-contact inventory:
- A
Find It Fastblock that uses the exact lookup termsscreencast / browser replay,desktop observation, andcomputer use / browser-scoped computer use. - That block maps replay to
screencast-start/screencast-stop, desktop observation to the publicdesktop-*family, and browser-scoped computer use to--challenge-automation-modeonresearch run,shopping run,product-video run,inspiredesign run, andmacro-resolve --execute, with a concreteresearch run --topic ... --challenge-automation-mode browserentry command. - An
Agent Quick Startblock that tells agents to start withopendevbrowser_prompting_guideoropendevbrowser_skill_load opendevbrowser-best-practices "quick start"before low-level browser commands. - A follow-up
validated_lanesentry that points agents toopendevbrowser_skill_load opendevbrowser-best-practices "validated capability lanes"for the current reliable transcript, research, and shopping runbook. - A direct pointer to
opendevbrowser_skill_listwhen an agent needs a different local skill lane. - A browser-scoped computer-use description that makes the optional helper boundary explicit and does not imply a desktop agent.
- The complete generated CLI command, flag, and
opendevbrowser_*tool inventories. - Canonical pointers to
docs/FIRST_RUN_ONBOARDING.md,skills/opendevbrowser-best-practices/SKILL.md, anddocs/SURFACE_REFERENCE.md.
Quick lookup terms from generated help:
screencast / browser replay:screencast-start,screencast-stopdesktop observation:desktop-status,desktop-windows,desktop-active-window,desktop-capture-desktop,desktop-capture-window,desktop-accessibility-snapshotcomputer use / browser-scoped computer use:--challenge-automation-mode off|browser|browser_with_helperonresearch run,shopping run,product-video run,inspiredesign run, andmacro-resolve --execute; entry commandnpx opendevbrowser research run --topic "account recovery flow" --source-selection auto --challenge-automation-mode browser --mode json --output-format json
These first-contact assets are also mirrored as release and website inputs through src/cli/onboarding-metadata.json, src/public-surface/generated-manifest.ts, and src/public-surface/generated-manifest.json.
Operational help parity check:
npx opendevbrowser --help
npx opendevbrowser help
First-run proof lane:
node scripts/cli-onboarding-smoke.mjs
Automation commands (daemon)
Serve (daemon)
Start a local daemon to keep sessions alive between commands.
npx opendevbrowser serve
npx opendevbrowser serve --port 8788 --token my-token
# Stop the daemon
npx opendevbrowser serve --stop
The daemon listens on 127.0.0.1 and starts the relay the extension connects to. Metadata lives in
~/.cache/opendevbrowser/daemon.json (cache only);
/status is the source of truth. The daemon port/token are persisted in opendevbrowser.jsonc as daemonPort/daemonToken.
serve now performs a stale-daemon preflight and terminates orphan opendevbrowser serve processes before starting (or before
returning "already running"), while preserving the active daemon on the requested port.
If you run onboarding tests alongside an existing daemon, isolate config/cache via OPENCODE_CONFIG_DIR and OPENCODE_CACHE_DIR
to avoid token/port collisions between sessions.
If nativeExtensionId is set in opendevbrowser.jsonc, serve will auto-install the native messaging host when it is missing.
If it is not set, serve attempts to auto-detect the extension ID from Chrome, Brave, or Chromium profiles; if detection fails it continues startup.
Relay HTTP endpoints (/config, /status, /pair) accept extension origins and loopback requests with no Origin (including
Origin: null) to support MV3 + PNA. Non-extension origins are rejected; preflights include
Access-Control-Allow-Private-Network: true when requested.
#### Manual recovery (if the daemon is down or stuck)
# Start the daemon manually
npx opendevbrowser serve
# Stop/kill an existing daemon before restarting
npx opendevbrowser serve --stop
Daemon auto-start
Install or remove OS-level auto-start for the daemon. This persists an absolute node + cli + serve entrypoint (no PATH
reliance) only when the current CLI path is stable. Temporary npx caches and temp onboarding workdirs are rejected instead of
being written to LaunchAgent or Task Scheduler state, and all commands return machine-readable output with --output-format json.
opendevbrowser daemon install
opendevbrowser daemon uninstall
opendevbrowser daemon status
# Persistent local package install alternative
npx --no-install opendevbrowser daemon install
Behavior:
- macOS: LaunchAgent at
~/Library/LaunchAgents/com.opendevbrowser.daemon.plisttargeting an absolutenode + cli + serveentrypoint. - Windows: per-user Task Scheduler logon task targeting an absolute
node + cli + serveentrypoint; status inspects the persisted scheduled-task action from Task Scheduler XML instead of task presence alone. daemon status --output-format jsonkeeps top-levelinstalledandrunning, adds nestedautostarton supported platforms, and includesstatusonly when the daemon is running.autostartis the canonical detail object and includeshealth,needsRepair,reason,command, andexpectedCommand.autostart.reasoncan betransient_cli_pathwhen an existing LaunchAgent or Task Scheduler action points at a temp-root CLI path that should be repaired.- when the current invocation is transient, a stable persisted auto-start entry can still report
health="healthy";expectedCommandis omitted instead of advertising the transient current path as the repair target. daemon statusreturns exit code0when the daemon is reachable even if auto-start is missing, stale, or malformed, and10when the daemon is not running.- Successful plugin installs surface auto-start reconciliation through
autostartAction;autostartErroris included only when repair fails. - If install-time reconciliation is running from a transient temp-root CLI path, it refuses to write auto-start and reports
autostartAction="repair_failed"with guidance to rerunopendevbrowser daemon installfrom a stable install location.
Exit codes align with the CLI:
0: success1: usage error2: execution error (permissions, missing binary, OS service failure, unsupporteddaemon install|uninstall, or unexpected status evaluation failure)10: disconnected/not running (status only)
#### Auto-start install + manual fallback
# Install auto-start (recommended)
opendevbrowser daemon install
# Or, from a persistent local package install
npx --no-install opendevbrowser daemon install
# If auto-start fails, start manually
npx opendevbrowser serve
# Stop/kill before restarting
npx opendevbrowser serve --stop
If you are running from a first-run temp workspace or transient npx cache, rerun opendevbrowser daemon install from a stable
install location before expecting login auto-start to persist.
Native messaging host
Install the native messaging host for the extension to use as a fallback transport when the relay WebSocket is unavailable.
# Install native host (requires extension ID)
npx opendevbrowser native install <extension-id>
# Check native host status
npx opendevbrowser native status
# Remove native host
npx opendevbrowser native uninstall
Notes:
- Supported on macOS, Linux, and Windows.
- Windows install writes a registry entry under
HKCU\Software\Google\Chrome\NativeMessagingHosts\com.opendevbrowser.native. native installrequires the extension ID (chrome://extensions → copy ID).- Set
nativeExtensionIdinopendevbrowser.jsoncto allowserveto auto-install the native host when missing (preferred). servealso attempts auto-detection from Chrome, Brave, or Chromium profiles, but explicit config is more reliable.native statusreports installed state + extension ID from the manifest.- Use
--transport nativewithstatusto check native host status without requiring the daemon.
Workflow wrappers
The workflow wrappers expose the finalized research, shopping, product-video, and inspiredesign surfaces from
docs/RESEARCH_SHOPPING_PRODUCT_VIDEO_FINAL_SPEC.md plus the shared inspiredesign handoff source at src/inspiredesign/handoff.ts.
#### Research (research run)
npx opendevbrowser research run --topic "browser automation" --days 30 --mode compact
npx opendevbrowser research run --topic "Chrome extension debugging workflows" --days 30 --source-selection auto --mode json
npx opendevbrowser research run --topic "creator tools" --sources web,shopping --include-engagement --limit-per-source 5 --mode context
Flags:
--topic(required)--days--from--to--source-selection(auto|web|community|social|shopping|all)--sources(comma-separated concrete sources)--mode(compact|json|md|context|path)--include-engagement--limit-per-source--timeout-ms--output-dir--ttl-hours--use-cookies(true|false; bare flag meanstrue)--challenge-automation-mode(off|browser|browser_with_helper)--cookie-policy-override(off|auto|required)--cookie-policy(alias of--cookie-policy-override)
Notes:
- Use
--source-selection autofor generic topical research. - In the current contract,
autoandallboth stay inside the public topical families (web,community,social). - Add shopping only with
--source-selection shoppingor explicit--sources ...shopping...when the task is deliberately commercial.
#### Shopping (shopping run)
npx opendevbrowser shopping run --query "usb microphone" --mode compact
npx opendevbrowser shopping run --query "wireless ergonomic mouse" --providers shopping/bestbuy,shopping/ebay --budget 150 --browser-mode managed --mode json --output-format json
npx opendevbrowser shopping run --query "27 inch 4k monitor" --providers shopping/bestbuy,shopping/ebay --budget 350 --sort lowest_price --browser-mode managed --mode json --output-format json
npx opendevbrowser shopping run --query "wireless earbuds" --providers shopping/amazon --region us --browser-mode managed --mode json --output-format json
Flags:
--query(required)--providers(comma-separated; defaults to all v1 adapters)--budget--region--browser-mode(auto|extension|managed)--sort(best_deal|lowest_price|highest_rating|fastest_shipping)--mode(compact|json|md|context|path)--timeout-ms--output-dir--ttl-hours--use-cookies(true|false; bare flag meanstrue)--challenge-automation-mode(off|browser|browser_with_helper)--cookie-policy-override(off|auto|required)--cookie-policy(alias of--cookie-policy-override)
Notes:
- Use explicit providers plus
--browser-mode managedfor the most reproducible live reruns. - Treat
--regionas advisory unlessmeta.selection.region_authoritative=true. - When a run returns no final offers, inspect
meta.primaryConstraintSummaryfirst. - If
meta.primaryConstraint.guidanceis present, followmeta.primaryConstraint.guidance.reasonandmeta.primaryConstraint.guidance.recommendedNextCommands[]before classifying the provider path as broken. - If
meta.primaryConstraint.guidanceis absent, inspectmeta.offerFilterDiagnostics; summary-only outcomes are usually offer-filter constraints such as budget or region heuristics, not provider outage proof.
#### Product presentation asset (product-video run)
npx opendevbrowser product-video run --product-url "https://example.com/p/1" --include-screenshots
npx opendevbrowser product-video run --product-name "Sample Product" --provider-hint shopping/amazon --output-dir /tmp/product-assets
Flags:
--product-url(required unless--product-nameis provided)--product-name(required unless--product-urlis provided)--provider-hint--include-screenshots(true|false; bare flag meanstrue)--include-all-images(true|false; bare flag meanstrue)--include-copy(true|false; bare flag meanstrue)--timeout-ms--output-dir--ttl-hours--use-cookies(true|false; bare flag meanstrue)--challenge-automation-mode(off|browser|browser_with_helper)--cookie-policy-override(off|auto|required)--cookie-policy(alias of--cookie-policy-override)
#### Inspiredesign (inspiredesign run)
npx opendevbrowser inspiredesign run --brief "Synthesize a premium docs landing page from calm editorial references" --url https://stripe.com --url https://vercel.com
npx opendevbrowser inspiredesign run --brief "Extract a reusable dashboard design contract from live references" --url https://linear.app --capture-mode deep --include-prototype-guidance --output-dir /tmp/inspiredesign
Flags:
--brief(required)--url(repeatable inspiration URL input)--capture-mode(off|deep)--include-prototype-guidance(true|false; bare flag meanstrue)--mode(compact|json|md|context|path)--timeout-ms--output-dir--ttl-hours--use-cookies(true|false; bare flag meanstrue)--challenge-automation-mode(off|browser|browser_with_helper)--cookie-policy-override(off|auto|required)--cookie-policy(alias of--cookie-policy-override)
Notes:
--capture-modedefaults tooff; opt intodeeponly when live DOM/layout capture is required.- Repeat
--urlfor multiple inspiration sources. There is no--urlsalias. --include-prototype-guidanceappends prototype structure guidance to the generated design contract output.- Successful runs now emit
canvas-plan.request.jsonanddesign-agent-handoff.jsonalongside the existing design contract and implementation artifacts. - The follow-through path is explicit: load
opendevbrowser_skill_load opendevbrowser-best-practices "quick start"plusopendevbrowser_skill_load opendevbrowser-design-agent "canvas-contract", fill the session ids incanvas-plan.request.json, runopendevbrowser canvas --command canvas.plan.set --params-file ./canvas-plan.request.json, confirmplanStatus=accepted, then patch only the governance blocks called out bydesign-agent-handoff.json.
Wrapper behavior:
- Timebox semantics are strict (
--daysis mutually exclusive with--from/--to). - Render modes for
research,shopping, andinspiredesignare shared:compact|json|md|context|path. product-video runalways returns a path-based local asset pack.inspiredesign runreturns a reusable design contract plus a Canvas-first handoff bundle;--include-prototype-guidanceadds prototype structure guidance to the same workflow output.- Path-bearing modes persist artifacts under the configured output directory (or default tmp namespace) and include TTL metadata in manifest files.
- Workflow cookie policy defaults to
providers.cookiePolicy=autoand source defaults toproviders.cookieSource(file,env, orinline). - Effective policy precedence is
--cookie-policy-override/--cookie-policy>--use-cookies> config defaults. autoattempts injection when cookies are available and continues when cookies are missing/unusable.requiredfails fast withreasonCode=auth_requiredwhen cookie loading/injection/verification cannot establish a session.- Workflow challenge automation defaults to
providers.challengeOrchestration.mode. - Effective challenge precedence is
challengeAutomationModewithrun > session > config. offkeeps detection and reporting active but stands down challenge actions.browserenables only browser-native lanes and forces the helper bridge to stand down.browser_with_helperpreserves browser-first lane ordering and only evaluates the browser-scoped helper bridge when hard gates pass.- The helper bridge is browser-scoped and is not a desktop agent.
- Cookie diagnostics are exposed in workflow metrics under
meta.metrics.cookie_diagnosticsandmeta.metrics.cookieDiagnostics. - Shopping providers that return zero usable offer records now emit
meta.failures[*].error.reasonCode=env_limitedinstead of silently counting as success.
Artifact lifecycle cleanup
Use the artifact cleanup command to remove expired bundles generated by workflow runs:
npx opendevbrowser artifacts cleanup --expired-only
npx opendevbrowser artifacts cleanup --expired-only --output-dir /tmp/opendevbrowser
Script helper:
./scripts/artifacts-cleanup.sh
./scripts/artifacts-cleanup.sh /tmp/opendevbrowser
Notes:
--expired-onlyis required.- Default cleanup root is
${TMPDIR:-/tmp}/opendevbrowser. - Output includes
removedandskippedrun paths.
Run (single-shot script)
Run a JSON script without the daemon.
npx opendevbrowser run --script ./script.json --output-format json
# Or pipe JSON
cat ./script.json | npx opendevbrowser run --output-format stream-json
# Optional launch flags for run
npx opendevbrowser run --script ./script.json --headless --profile default --start-url https://example.com
npx opendevbrowser run --script ./script.json --chrome-path "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --flag "--disable-gpu"
Supported run launch flags:
--headless--profile--persist-profile--chrome-path--start-url--flag(repeatable)
--chrome-path accepts Google Chrome, Chromium, or a Playwright-installed Chrome for Testing binary when you need a deterministic automation browser.
Script format:
[
{ "action": "goto", "args": { "url": "https://example.com" } },
{ "action": "snapshot" },
{ "action": "click", "args": { "ref": "r1" } }
]
Session commands (daemon required)
Launch
npx opendevbrowser launch --profile default --start-url https://example.com
# Extension relay controls
npx opendevbrowser launch --extension-only
npx opendevbrowser launch --no-extension
npx opendevbrowser launch --extension-legacy
npx opendevbrowser launch --wait-for-extension --wait-timeout-ms 30000
Flags:
--headless--profile--start-url--chrome-path--persist-profile--flag(repeatable)--no-extension--extension-only--extension-legacy--wait-for-extension--wait-timeout-ms
Default behavior:
- Extension relay (
extensionmode) is the default when available, using the/opsWebSocket. - If the extension is not connected, launch fails with guidance and exact commands for the explicit alternatives.
- Headless is never the default.
- Extension headless is unsupported.
launch --headlessmust be paired with--no-extension; extension-intent headless requests fail withunsupported_mode. - When hub mode is enabled, there is no local relay fallback. If the hub is unavailable, commands fail with guidance.
- Extension relay requires Chrome 125+ (flat CDP sessions).
- Managed and
cdpConnectsessions automatically try to bootstrap readable cookies from the discovered system Chrome-family profile before first navigation. Extension mode reuses the already logged-in tab or profile instead of importing cookies. - For isolated automation harnesses that rely on browser startup flags such as
--disable-extensions-except, prefer Chromium or Chrome for Testing. Google Chrome stable may ignore those flags.
Interactive vs non-interactive:
- Interactive CLI (TTY): you will be prompted to connect the extension, then explicitly choose Managed or CDPConnect if you want to proceed.
- Non-interactive (agents/CI): the command fails fast and prints the exact commands to run for Managed or CDPConnect.
- If
status --daemonshowsext=onbuthandshake=off, reopen the extension popup and click Connect again to re-establish a clean daemon-extension handshake before retrying extension-mode work.
Connection flags & status semantics
| Flag / Status | Meaning | Notes |
|---|---|---|
--no-extension |
Force managed mode | Bypasses relay and extension entirely. |
--extension-only |
Require extension mode | Fails if extension is not connected/handshaken. |
--extension-legacy |
Use legacy extension relay | Routes through relay /cdp instead of /ops. |
--wait-for-extension |
Wait for extension handshake | Only applies to extension mode; waits up to --wait-timeout-ms. |
--wait-timeout-ms |
Max wait for extension | Defaults to 30s. |
extensionConnected |
Extension websocket connected | false means popup isn’t connected to relay. |
extensionHandshakeComplete |
Extension handshake done | false means reconnect/repair from popup. |
annotationConnected |
Active /annotation client attached |
Expected false unless annotate relay transport is active. |
opsConnected |
Active /ops client attached |
Presence-only signal; it does not prove the current extension target is owned by /ops. |
canvasConnected |
Active /canvas client attached |
Expected false unless a design-canvas session is using relay preview/overlay features. |
cdpConnected |
Active /cdp client attached |
Expected false until a legacy /cdp session connects. |
pairingRequired |
Relay token required | When true, /ops, /canvas, /annotation, and /cdp require a token (auto-fetched). |
Connect
npx opendevbrowser connect --ws-endpoint ws://127.0.0.1:9222/devtools/browser/...
npx opendevbrowser connect --host 127.0.0.1 --cdp-port 9222
This command starts a cdpConnect session (attach to an existing Chrome with remote debugging enabled).
If the --ws-endpoint points at the local relay (for example ws://127.0.0.1:8787 or ws://127.0.0.1:8787/ops),
the CLI will normalize to /ops and route through the extension relay (extension mode).
Use --extension-legacy if you need the legacy /cdp relay path.
When routing through the relay, the CLI automatically fetches relay config and the pairing token (if required) and authenticates
the /ops or /cdp connection. Direct relay websocket connections without a token are rejected when pairing is enabled.
Direct cdpConnect sessions use the same automatic Chrome-family cookie bootstrap path as managed launches.
Relay binding queue
Hub binding is exclusive only for binding/legacy paths (for example /cdp and commands that require a binding). Additional clients are queued FIFO and wait up to 30s by default.
If you see RELAY_WAIT_TIMEOUT, retry after the current binding expires or stop the other bound client.
Relay behavior note: extension uses a single extension websocket, while the relay can serve multiple /ops clients. Disconnecting the extension or restarting the relay drops active sessions, including annotation flows. Reconnect via the popup (or restart the daemon) before retrying.
Concurrency semantics
- Transport-level concurrency:
/opssupports multi-client access and multiple sessions. - Runtime scheduling uses
ExecutionKey = (sessionId, targetId)with target-scoped queues. - Same target stays FIFO; different targets in one session run in parallel up to
effectiveParallelCap. session-per-workerremains the safest baseline for simple operational isolation, but in-session multi-target parallelism is supported on/ops, managed, andcdpConnect.- Use explicit
--target-idrouting for concurrent flows; treattarget-useas ergonomic fallback only. - Use
/opsas the default concurrent relay channel. Use--extension-legacy(/cdp) only for compatibility-specific paths. - Legacy
/cdpdoes not coexist with an active/opslease. If launch fails withcdp_attach_blocked, disconnect the/opssession and retry--extension-legacy. - Legacy
/cdpstays sequential (effectiveParallelCap=1) by design. - For managed parallel launches with persisted profiles, use unique profile directories per session (or disable persistence) to avoid ProcessSingleton/SingletonLock collisions.
- Parity divergences are registry-bound in
docs/PARITY_DECLARED_DIVERGENCES.md.
Disconnect
npx opendevbrowser disconnect --session-id <session-id>
npx opendevbrowser disconnect --session-id <session-id> --close-browser
Status
npx opendevbrowser status # daemon status (default)
npx opendevbrowser status --daemon # daemon status (explicit)
npx opendevbrowser status --session-id <session-id>
npx opendevbrowser status --transport native
Status capabilities
npx opendevbrowser status-capabilities
npx opendevbrowser status-capabilities --session-id <session-id> --target-id <target-id> --challenge-automation-mode browser_with_helper --timeout-ms 30000
Notes:
status-capabilitiescan inspect host capability discovery without a session, or add--session-idto include session-scoped browser and policy state.--challenge-automation-modelets you preview the effective browser-scoped computer-use mode and source before running a workflow.
Cookie import
npx opendevbrowser cookie-import \
--session-id <session-id> \
--cookies '[{"name":"session","value":"abc123","url":"https://example.com"}]'
npx opendevbrowser cookie-import \
--session-id <session-id> \
--cookies-file ./cookies.json \
--strict=false \
--request-id req-cookie-001
Notes:
- Provide exactly one cookies source:
--cookiesor--cookies-file. --strictdefaults totrue.- Managed and
cdpConnectsessions already attempt Chrome-family cookie bootstrap on session creation; usecookie-importwhen you need to add or override cookies explicitly. - Supported across
managed, default extension/ops, extension legacy/cdp, and directcdpConnectsessions.
Cookie list
npx opendevbrowser cookie-list \
--session-id <session-id>
npx opendevbrowser cookie-list \
--session-id <session-id> \
--url https://example.com \
--url https://shop.example.com \
--request-id req-cookie-list-001
Notes:
--urlis optional and repeatable; each value is normalized and deduplicated.- Supports
managed, default extension/ops, extension legacy/cdp, and directcdpConnectsessions.
Macro resolve
npx opendevbrowser macro-resolve --expression '@web.search("openai")'
npx opendevbrowser macro-resolve --expression '@social.post("x", "ship it")' --default-provider social/x --include-catalog
npx opendevbrowser macro-resolve --expression '@web.search("opendevbrowser")' --execute --output-format json
npx opendevbrowser macro-resolve --expression '@media.search("youtube transcript parity", "youtube", 5)' --execute --timeout-ms 120000 --output-format json
npx opendevbrowser macro-resolve --expression '@community.search("browser automation failures", 4)' --execute --challenge-automation-mode browser_with_helper --output-format json
Notes:
- Default mode is resolve-only (returns the resolved action/provenance payload).
--executeruns the resolved provider action and returns additive execution metadata (meta.tier.selected,meta.tier.reasonCode,meta.provenance.provider,meta.provenance.retrievalPath,meta.provenance.retrievedAt).--timeout-mssets client-side daemon transport timeout for slow--executeruns.--challenge-automation-modeis accepted for--executeruns and maps tochallengeAutomationModewith the samerun > session > configprecedence as workflow commands.opendevbrowser --helpincludes this timeout flag in the global flag inventory.
Blocker contract (v2)
Compatibility rule (v2):
- Blocker fields are additive-only and live under
meta.blocker(orexecution.meta.blockerformacro-resolve --execute). - Existing success/error fields and codes remain unchanged.
- Consumers should treat missing blocker fields as backward-compatible
no blocker metadata.
Canonical placement:
goto:data.meta.blockerState+ optionaldata.meta.blocker.wait:data.meta.blockerState+ optionaldata.meta.blocker.debug-trace-snapshot:data.meta.blockerState+ optionaldata.meta.blocker+ optionaldata.meta.blockerArtifacts.macro-resolve --execute:data.execution.meta.ok+ optionaldata.execution.meta.blocker.status:data.meta.blockerState+ optionaldata.meta.blockerResolution(resolved | unresolved | deferred).
Canonical examples:
{
"command": "goto",
"success": true,
"data": {
"finalUrl": "https://example.com",
"status": 200,
"timingMs": 412,
"meta": {
"blockerState": "clear"
}
}
}
{
"command": "goto",
"success": true,
"data": {
"finalUrl": "https://x.com/i/flow/login",
"status": 200,
"timingMs": 588,
"meta": {
"blockerState": "active",
"blocker": {
"schemaVersion": "1.0",
"type": "auth_required",
"source": "navigation",
"confidence": 0.97,
"retryable": false
}
}
}
}
{
"command": "wait",
"success": true,
"data": {
"timingMs": 221,
"meta": {
"blockerState": "clear"
}
}
}
{
"command": "status",
"success": true,
"data": {
"mode": "managed",
"activeTargetId": "target-1",
"url": "https://x.com/i/flow/login",
"title": "Log in to X / X",
"meta": {
"blockerState": "active",
"blockerResolution": {
"status": "unresolved",
"reason": "verification_timeout",
"updatedAt": "2026-02-15T14:18:28.000Z"
}
}
}
}
{
"command": "wait",
"success": true,
"data": {
"timingMs": 1470,
"meta": {
"blockerState": "active",
"blocker": {
"schemaVersion": "1.0",
"type": "anti_bot_challenge",
"source": "navigation",
"confidence": 0.96,
"retryable": false
}
}
}
}
{
"command": "debug-trace-snapshot",
"success": true,
"data": {
"requestId": "req-debug-001",
"meta": {
"blockerState": "clear"
}
}
}
{
"command": "debug-trace-snapshot",
"success": true,
"data": {
"requestId": "req-debug-002",
"meta": {
"blockerState": "active",
"blocker": {
"schemaVersion": "1.0",
"type": "anti_bot_challenge",
"source": "network",
"confidence": 0.96,
"retryable": false
},
"blockerArtifacts": {
"schemaVersion": "1.0",
"hosts": ["www.recaptcha.net", "challenges.cloudflare.com"]
}
}
}
}
{
"command": "macro-resolve --execute",
"success": true,
"data": {
"runtime": "macros",
"execution": {
"meta": {
"ok": true,
"partial": false
}
}
}
}
{
"command": "macro-resolve --execute",
"success": true,
"data": {
"runtime": "macros",
"execution": {
"meta": {
"ok": false,
"partial": true,
"blocker": {
"schemaVersion": "1.0",
"type": "env_limited",
"source": "macro_execution",
"confidence": 0.9,
"retryable": true
}
}
}
}
}
Design Canvas
Use canvas to call the typed canvas.* surface through the daemon. The normal sequence is:
canvas.session.open -> inspect the handshake (planStatus, preflightState, generationPlanRequirements.allowedValues, generationPlanIssues, guidance.recommendedNextCommands) -> canvas.plan.set -> if accepted, follow returned guidance into canvas.document.patch (including governance.update blocks) -> canvas.preview.render -> canvas.feedback.poll -> canvas.document.save or canvas.document.export.
If canvas.plan.set fails with generation_plan_invalid, inspect the returned details.missingFields and details.issues, or re-read the current state with canvas.plan.get / canvas.capabilities.get, then resubmit canvas.plan.set. canvas.plan.get is diagnostic on that failure path, not a required success-path checkpoint.
Additional same-session clients use canvas.session.attach with attachMode=observer or attachMode=lease_reclaim.
Unless params.repoRoot is provided explicitly, the CLI injects the caller cwd as the canvas session repo root. Relative canvas.document.save, canvas.document.export, and canvas.code.* paths resolve against that session root even when the daemon is launchd-owned or started from another working directory.
# Open a canvas session bound to an existing browser session
npx opendevbrowser canvas --command canvas.session.open \
--params '{"browserSessionId":"<session-id>","documentId":"landing-page","mode":"dual-track"}' \
--output-format json
# Submit a generation plan (required before patching)
npx opendevbrowser canvas --command canvas.plan.set --params-file ./canvas-plan.json --output-format json
# Apply a patch batch against a specific revision, including governance blocks required before save
npx opendevbrowser canvas --command canvas.document.patch \
--params '{"canvasSessionId":"<canvas-session-id>","leaseId":"<lease-id>","baseRevision":1,"patches":[{"op":"governance.update","block":"intent","changes":{"summary":"Marketing landing page refresh"}},{"op":"governance.update","block":"designLanguage","changes":{"profile":"clean-room"}},{"op":"page.create","page":{"id":"page_home","rootNodeId":null,"name":"Home","path":"/","description":"Marketing landing page"}}]}' \
--output-format json
# Save the canonical design document back into the repo
npx opendevbrowser canvas --command canvas.document.save \
--params '{"canvasSessionId":"<canvas-session-id>","leaseId":"<lease-id>"}' \
--output-format json
canvas.session.open returns a handshake with canvasSessionId, leaseId, governance block states, required generation-plan fields, generationPlanRequirements.allowedValues, runtime budgets, warning classes, generationPlanIssues, mutationPolicy.allowedBeforePlan, and guidance.recommendedNextCommands. Treat planStatus="missing" with preflightState="handshake_read" as "submit a plan next." Treat planStatus="invalid" with preflightState="plan_invalid" as "fix the reported plan issues before mutation." A successful canvas.plan.set response is authoritative enough to proceed: it already returns accepted state plus next-step guidance, so canvas.plan.get is only needed when diagnosing invalid-plan responses or re-reading current state after attach. canvas.document.patch is blocked until canvas.plan.set succeeds. canvas.document.save and canvas.document.export return policy_violation until all requiredBeforeSave governance blocks are present. canvas.document.import now imports Figma file URLs, node URLs, or raw file-key inputs into the same lease-governed document surface; it resolves auth from FIGMA_ACCESS_TOKEN first and integrations.figma.accessToken second, caches image and SVG receipts under .opendevbrowser/canvas/assets/figma/<fileKey>/, records provenance in document.meta.imports[], and degrades variables/local failures with typed feedback (scope_denied, plan_limited, account_limited, or variables_unavailable) instead of opaque fatal errors. canvas.history.undo and canvas.history.redo are now public lease-governed mutations; they are unavailable before the first accepted-plan edit, require the active lease holder, and invalidate deterministically when document revision drift makes the recorded stack stale. In extension mode, canvas.tab.open opens an extension-hosted canvas.html infinite-canvas editor that persists full page state in IndexedDB, converges same-origin tabs through BroadcastChannel, forwards editor-originated patch requests through /canvas, exposes pages/layers/properties/history controls plus keyboard shortcuts, and keeps freeform region annotation scoped to the extension-hosted stage. canvas.feedback.poll remains the snapshot query for cursor-based audits, and when the plan is still missing or invalid it synthesizes the same preflight blocker agents see from mutation commands. canvas.feedback.subscribe, canvas.feedback.next, and canvas.feedback.unsubscribe now expose the public pull-stream contract. In stream-json mode, the CLI emits initialItems, then loops on canvas.feedback.next until feedback.complete or CLI timeout, and finally best-effort calls canvas.feedback.unsubscribe. canvas.inventory.list now returns the merged reusable inventory surface: document-backed promoted items plus the shipped built-in kit catalog entries. canvas.inventory.insert materializes either kind of inventory template back onto the stage as a governed mutation. canvas.starter.list exposes the eight shipped built-in starters, and canvas.starter.apply now seeds a generation plan when needed, merges built-in kit token collections, installs required kit inventory entries into the live document, and inserts a starter shell with semantic fallback when the requested framework or adapter is unavailable. For starter application, prefer libraryAdapterId when selecting or reading the resolved built-in kit adapter; the legacy adapterId field remains as a backward-compatible alias and is distinct from code-sync frameworkAdapterId. The public /canvas surface is now 35 commands. The tool wrapper stays thin and uses the same public opendevbrowser_canvas commands through repeated calls.
canvas.code.bind, canvas.code.unbind, canvas.code.pull, canvas.code.push, canvas.code.status, and canvas.code.resolve add framework-adapter-backed code sync on top of the same session. Built-in lanes currently ship for builtin:react-tsx-v2, builtin:html-static-v1, builtin:custom-elements-v1, builtin:vue-sfc-v1, and builtin:svelte-sfc-v1; legacy tsx-react-v1 bindings and manifests migrate on load to builtin:react-tsx-v2 instead of failing ambiguously. Bound source manifests are stored under .opendevbrowser/canvas/code-sync/<documentId>/<bindingId>.json; preview targets default to projected canvas_html and only attempt bound_app_runtime reconciliation when the binding opts in and runtime bridge preflight succeeds. canvas.code.status returns frameworkAdapterId, frameworkId, sourceFamily, declared/granted capabilities, explicit denial entries, and deterministic reasonCode values such as framework_migrated, manifest_migrated, plugin_not_found, and plugin_load_failed. Repo-local BYO adapter plugins are discovered from workspace package.json, .opendevbrowser/canvas/adapters.json, and explicit local config declarations only; declaration-level capabilityOverrides narrow plugin capabilities rather than widening them. See docs/CANVAS_ADAPTER_PLUGIN_CONTRACT.md for the plugin manifest and trust model, and node scripts/canvas-competitive-validation.mjs --out <report.json> for the grouped canvas validator.
RPC (power-user, internal)
Execute any daemon command directly. This bypasses the stable CLI command surface, is intentionally unsafe/internal, and requires --unsafe-internal.
# Minimal call (empty params object)
npx opendevbrowser rpc --unsafe-internal --name relay.status --output-format json
# With inline JSON params
npx opendevbrowser rpc --unsafe-internal --name nav.goto \
--params '{"sessionId":"<session-id>","url":"https://example.com","waitUntil":"load","timeoutMs":30000}' \
--timeout-ms 45000 --output-format json
# With params from file
npx opendevbrowser rpc --unsafe-internal --name session.status --params-file ./rpc-params.json --output-format json
Notes:
- Params must be a JSON object.
- Use
--output-format jsonfor machine-readable responses. rpcis CLI-only by design and is not part of the stable tool parity surface.rpccommand names/params are internal and may change without compatibility guarantees.- A bad
rpccall can close sessions, navigate logged-in tabs, or trigger unintended side effects. - Prefer stable commands (
goto,snapshot,click,type, and related tool equivalents) whenever possible. - Use
rpconly when necessary, validate params carefully, and test in a disposable session first.
Navigation commands (daemon required)
Goto
npx opendevbrowser goto --session-id <session-id> --url https://example.com
npx opendevbrowser goto --session-id <session-id> --url https://example.com --wait-until load --timeout-ms 30000
Wait
npx opendevbrowser wait --session-id <session-id> --until load
npx opendevbrowser wait --session-id <session-id> --ref r12 --state visible --timeout-ms 15000
Snapshot
npx opendevbrowser snapshot --session-id <session-id>
npx opendevbrowser snapshot --session-id <session-id> --max-chars 16000 --cursor <cursor>
Review
Use review as the explicit snapshot -> review -> action step when you want the active target summary plus a fresh actionables capture in one response.
npx opendevbrowser review --session-id <session-id>
npx opendevbrowser review --session-id <session-id> --target-id <target-id> --max-chars 16000 --cursor <cursor>
Review desktop
Use review-desktop when you want the browser-owned review payload plus read-only desktop observation evidence in one correlated response.
npx opendevbrowser review-desktop --session-id <session-id> --reason "compare browser review with visible desktop state"
npx opendevbrowser review-desktop --session-id <session-id> --target-id <target-id> --reason "audit active target" --max-chars 16000 --cursor <cursor>
Notes:
review-desktopkeeps authority in the review family and augments it with public desktop observation evidence.- Use
--reasonwhen you want explicit audit context recorded alongside the correlated desktop evidence.
Interaction commands (daemon required)
Click
npx opendevbrowser click --session-id <session-id> --ref r12 [--timeout-ms <ms>]
Notes:
--timeout-mssets the client-side daemon timeout for the click request.- Without
--timeout-ms,clickuses a 60s client-side daemon timeout so blocking browser dialogs can be inspected and handled without the opener expiring immediately.
Hover
npx opendevbrowser hover --session-id <session-id> --ref r12
Press
npx opendevbrowser press --session-id <session-id> --key Enter
npx opendevbrowser press --session-id <session-id> --key Enter --ref r12
Check / Uncheck
npx opendevbrowser check --session-id <session-id> --ref r12
npx opendevbrowser uncheck --session-id <session-id> --ref r12
Type
npx opendevbrowser type --session-id <session-id> --ref r12 --text "hello"
npx opendevbrowser type --session-id <session-id> --ref r12 --text "hello" --clear --submit
Select
npx opendevbrowser select --session-id <session-id> --ref r12 --values value1,value2
Scroll
npx opendevbrowser scroll --session-id <session-id> --dy 500
npx opendevbrowser scroll --session-id <session-id> --ref r12 --dy 300
Scroll into view
npx opendevbrowser scroll-into-view --session-id <session-id> --ref r12
Upload
npx opendevbrowser upload --session-id <session-id> --ref r12 --files ./avatar.png
npx opendevbrowser upload --session-id <session-id> --target-id <target-id> --ref r12 --files ./front.png,./back.png
Notes:
--filesaccepts a comma-separated list of host file paths.- Upload resolves the target from the existing ref model and reports
modeasdirect_inputorfile_chooser.
Annotation (direct + relay)
Annotations are available through both the CLI command and the opendevbrowser_annotate tool. The default transport (auto)
uses direct CDP when possible and falls back to relay in extension sessions. annotate --stored resolves the shared repo-local
agent inbox first, then the extension-local stored payload fallback. See docs/ANNOTATE.md for setup and details.
npx opendevbrowser annotate --session-id <session-id>
# Force direct annotate on a target
npx opendevbrowser annotate --session-id <session-id> --transport direct --target-id <target-id>
# Force relay annotate on a specific tab
npx opendevbrowser annotate --session-id <session-id> --transport relay --tab-id 123
# With URL + context + debug metadata
npx opendevbrowser annotate --session-id <session-id> --url https://example.com \
--screenshot-mode visible --context "Review the hero layout" --timeout-ms 90000 --debug
# Return the last stored annotation payload
npx opendevbrowser annotate --session-id <session-id> --stored
# Prefer the extension-local in-memory stored payload with screenshots when still available
npx opendevbrowser annotate --session-id <session-id> --stored --include-screenshots
Target commands (daemon required)
Targets list
npx opendevbrowser targets-list --session-id <session-id>
npx opendevbrowser targets-list --session-id <session-id> --include-urls
Target use
npx opendevbrowser target-use --session-id <session-id> --target-id <target-id>
Target new
npx opendevbrowser target-new --session-id <session-id> --url https://example.com
Target close
npx opendevbrowser target-close --session-id <session-id> --target-id <target-id>
Page commands (daemon required)
Page open
npx opendevbrowser page --session-id <session-id> --name main
npx opendevbrowser page --session-id <session-id> --name main --url https://example.com
Pages list
npx opendevbrowser pages --session-id <session-id>
Page close
npx opendevbrowser page-close --session-id <session-id> --name main
DOM commands (daemon required)
DOM HTML
npx opendevbrowser dom-html --session-id <session-id> --ref r12 --max-chars 8000
DOM Text
npx opendevbrowser dom-text --session-id <session-id> --ref r12 --max-chars 8000
DOM Attribute
npx opendevbrowser dom-attr --session-id <session-id> --ref r12 --attr aria-label
DOM Value
npx opendevbrowser dom-value --session-id <session-id> --ref r12
DOM State Checks
npx opendevbrowser dom-visible --session-id <session-id> --ref r12
npx opendevbrowser dom-enabled --session-id <session-id> --ref r12
npx opendevbrowser dom-checked --session-id <session-id> --ref r12
Export commands (daemon required)
Clone page
npx opendevbrowser clone-page --session-id <session-id>
Clone component
npx opendevbrowser clone-component --session-id <session-id> --ref r12
Devtools commands (daemon required)
Performance metrics
npx opendevbrowser perf --session-id <session-id>
Screenshot
npx opendevbrowser screenshot --session-id <session-id>
npx opendevbrowser screenshot --session-id <session-id> --path ./capture.png
npx opendevbrowser screenshot --session-id <session-id> --ref r12
npx opendevbrowser screenshot --session-id <session-id> --full-page
npx opendevbrowser screenshot --session-id <session-id> --path ./capture.png --timeout-ms 60000
Notes:
--refand--full-pageare mutually exclusive.--timeout-mssets client-side daemon timeout for screenshot capture.- Default visible capture may still report the existing viewport-only fallback warning when extension capture has to degrade, but ref and full-page requests do not silently reuse that fallback.
Screencast start
npx opendevbrowser screencast-start --session-id <session-id>
npx opendevbrowser screencast-start \
--session-id <session-id> \
--target-id <target-id> \
--output-dir ./artifacts/replay \
--interval-ms 1000 \
--max-frames 120
Notes:
screencast-startis a manager-owned browser replay lane layered on the existing screenshot primitive.- The recorder writes
replay.json,replay.html,frames/, andpreview.pnginto the chosen output directory. --interval-msdefaults to1000and must be at least250.--max-framesdefaults to300.
Screencast stop
npx opendevbrowser screencast-stop --session-id <session-id> --screencast-id <screencast-id>
Notes:
--session-idand--screencast-idare both required.--screencast-idmust match the id returned byscreencast-startfor that same session.- Stop returns the final artifact metadata, including replay paths and the terminal
endedReason.
Dialog
npx opendevbrowser dialog --session-id <session-id>
npx opendevbrowser dialog --session-id <session-id> --action dismiss
npx opendevbrowser dialog --session-id <session-id> --action accept --prompt-text "Ship it"
Notes:
--actionsupportsstatus,accept, anddismiss.--prompt-textis only valid when--action acceptis used for a prompt dialog.--timeout-mssets the client-side daemon timeout for the dialog request.- Without
--timeout-ms,dialoguses a 30s client-side daemon timeout.
Console poll
npx opendevbrowser console-poll --session-id <session-id> --since-seq 0 --max 50
Network poll
npx opendevbrowser network-poll --session-id <session-id> --since-seq 0 --max 50
Debug trace snapshot
npx opendevbrowser debug-trace-snapshot --session-id <session-id>
npx opendevbrowser debug-trace-snapshot \
--session-id <session-id> \
--since-console-seq 100 \
--since-network-seq 80 \
--since-exception-seq 10 \
--max 200 \
--request-id req-debug-001
Session inspector
npx opendevbrowser session-inspector --session-id <session-id>
npx opendevbrowser session-inspector \
--session-id <session-id> \
--include-urls \
--since-console-seq 100 \
--since-network-seq 80 \
--since-exception-seq 10 \
--max 50 \
--request-id req-session-inspector-001
Notes:
- Returns session status, relay health, target summary, proof artifact metadata,
healthState, and a suggested next action in one payload. --include-urlskeeps target URLs in the target summary. Omit it to use the default runtime behavior.--since-console-seq,--since-network-seq,--since-exception-seq, and--maxmirror the trace cursors used bydebug-trace-snapshot.
Session inspector plan
npx opendevbrowser session-inspector-plan --session-id <session-id>
npx opendevbrowser session-inspector-plan --session-id <session-id> --target-id <target-id> --challenge-automation-mode browser --timeout-ms 30000
Notes:
- Returns browser-scoped computer-use policy, eligibility, stand-down reasons, yield state, and safe suggested steps without running a provider workflow.
--challenge-automation-modelets you inspect the effective mode you want to compare against current session or config defaults.
Session inspector audit
npx opendevbrowser session-inspector-audit --session-id <session-id> --reason "capture correlated operator audit"
npx opendevbrowser session-inspector-audit --session-id <session-id> --target-id <target-id> --reason "trace challenge state" --include-urls --request-id req-session-audit-001 --challenge-automation-mode browser_with_helper
Notes:
- Returns a correlated audit bundle across desktop evidence, browser review, session status, and browser-scoped policy state.
--reason,--request-id, trace cursors, and--include-urlsmirror the session-inspector and review audit lanes in one surface.
Desktop observation commands (daemon required)
These commands expose the sibling DesktopRuntimeLike observation plane directly. They are read-only, return audit metadata on both success and failure, and are gated by separate desktop.* config plus local OS permissions.
Desktop status
npx opendevbrowser desktop-status
Desktop windows
npx opendevbrowser desktop-windows --reason "inspect visible windows before capture"
Desktop active window
npx opendevbrowser desktop-active-window --reason "inspect current foreground window"
Desktop capture desktop
npx opendevbrowser desktop-capture-desktop --reason "capture current desktop surface"
Desktop capture window
npx opendevbrowser desktop-capture-window --window-id <window-id> --reason "capture a specific window"
Desktop accessibility snapshot
npx opendevbrowser desktop-accessibility-snapshot --reason "capture accessibility tree"
npx opendevbrowser desktop-accessibility-snapshot --window-id <window-id> --reason "capture one window accessibility tree"
Notes:
- On supported macOS hosts, availability, window inventory, and accessibility probes require the local
swiftcommand. Ifdesktop-statusreturnsdesktop_unsupportedon macOS, install Xcode or a Swift toolchain and retry. - Desktop screenshots use macOS
screencapture. desktop-statusreports availability, permissions, capabilities, and the configured audit artifacts directory.desktop-windowsanddesktop-active-windowaccept optional--reasonvalues for audit context.desktop-capture-desktop,desktop-capture-window, anddesktop-accessibility-snapshotrequire--reason.desktop-capture-windowrequires--window-id.desktop-accessibility-snapshotaccepts an optional--window-id.- This plane is public and observe-only. It is not a desktop agent and does not create a desktop
/opsfamily.
Flags reference
Global flags
| Flag | Short | Description | |||
|---|---|---|---|---|---|
--global |
-g |
Install to ~/.config/opencode/opencode.json |
|||
--local |
-l |
Install to ./opencode.json |
|||
--update |
-u |
Clear cache to trigger reinstall | |||
--uninstall |
Remove plugin from config and clean managed skills | ||||
--with-config |
Also create opendevbrowser.jsonc |
||||
--full |
-f |
Create config and pre-extract extension assets | |||
--no-prompt |
Skip prompts, use defaults | ||||
--no-interactive |
Alias of --no-prompt |
||||
--quiet |
Suppress output | ||||
--output-format |
text, json, or stream-json |
||||
--transport |
Transport selector for transport-aware commands (status: `relay |
native; annotate: auto |
direct | relay`) | |
--daemon |
Daemon status selector for status |
||||
--skills-global |
Install skills to global OpenCode/Codex/ClaudeCode/AmpCLI directories | ||||
--skills-local |
Install skills to project-local OpenCode/Codex/ClaudeCode/AmpCLI directories | ||||
--no-skills |
Skip installing bundled skills | ||||
--help |
-h |
Show usage information | |||
--version |
-v |
Show version number |
Serve flags
| Flag | Description |
|---|---|
--port |
Override daemon port |
--token |
Override daemon token |
--stop |
Stop the daemon |
Command-specific flags
Session + connection
| Flag | Used by | Description | ||
|---|---|---|---|---|
--session-id |
most daemon commands | Active session id from launch/connect |
||
--close-browser |
disconnect |
Close managed browser on disconnect | ||
--ws-endpoint |
connect |
Remote debugging websocket URL | ||
--host |
connect |
Host for CDP connection (--cdp-port required) |
||
--cdp-port |
connect |
CDP port for host-based connect | ||
--daemon |
status |
Force daemon status mode (mutually exclusive with --session-id) |
||
--no-extension |
launch |
Force managed mode (ignore extension) | ||
--extension-only |
launch |
Fail if extension not connected | ||
--extension-legacy |
launch, connect |
Use legacy extension relay (/cdp) |
||
--wait-for-extension |
launch |
Wait for extension handshake | ||
--wait-timeout-ms |
launch |
Max wait for extension handshake | ||
--cookies |
cookie-import |
Inline JSON array of cookie objects | ||
--cookies-file |
cookie-import |
Path to JSON file containing cookie objects | ||
--strict |
cookie-import |
Reject on invalid cookie entries (true/false) |
||
--request-id |
cookie-import, cookie-list, debug-trace-snapshot, session-inspector, session-inspector-audit |
Optional request correlation id | ||
--expression |
macro-resolve |
Macro expression to resolve | ||
--default-provider |
macro-resolve |
Provider fallback for shorthand macros | ||
--include-catalog |
macro-resolve |
Include macro catalog in response | ||
--execute |
macro-resolve |
Execute the resolved provider action and include additive meta.* fields |
||
--timeout-ms |
macro-resolve |
Client-side daemon call timeout in ms | ||
--use-cookies |
research run, shopping run, product-video run, inspiredesign run |
Enable/disable provider cookie injection for the run (`true | false; bare flag means true`) |
|
--challenge-automation-mode |
research run, shopping run, product-video run, inspiredesign run, macro-resolve --execute, status-capabilities, session-inspector-plan, session-inspector-audit |
Per-run or inspection challenge automation override stored as challengeAutomationMode (`off |
browser | browser_with_helper) with run > session > config` precedence |
--cookie-policy-override |
research run, shopping run, product-video run, inspiredesign run |
Per-run provider cookie policy override (`off | auto | required`) |
--cookie-policy |
research run, shopping run, product-video run, inspiredesign run |
Alias of --cookie-policy-override |
Browser launch (launch/run)
| Flag | Used by | Description |
|---|---|---|
--headless |
launch, run |
Run managed Chrome headless |
--profile |
launch, run |
Profile directory name |
--persist-profile |
launch, run |
Keep profile directory after run |
--chrome-path |
launch, run |
Explicit Chrome executable path |
--start-url |
launch, run |
Initial URL for the session |
--flag |
launch, run |
Additional Chrome flag (repeatable) |
--script |
run |
JSON script path |
Navigation + waiting
| Flag | Used by | Description |
|---|---|---|
--url |
goto, page, target-new, cookie-list |
URL to navigate/open or filter cookie listing |
--wait-until |
goto |
Load state (load, domcontentloaded, etc.) |
--timeout-ms |
goto, wait, review, review-desktop, status-capabilities, session-inspector-plan, session-inspector-audit |
Timeout in ms |
--ref |
wait |
Element ref to wait for |
--state |
wait |
Element state (e.g. visible) |
--until |
wait |
Page load state |
--mode |
snapshot |
Snapshot mode (outline or actionables) |
--target-id |
review, review-desktop, status-capabilities, session-inspector-plan, session-inspector-audit |
Optional target override for review or inspection payloads |
--max-chars |
snapshot, review, review-desktop, session-inspector-audit, dom-* |
Max characters returned |
--cursor |
snapshot, review, review-desktop, session-inspector-audit |
Snapshot pagination cursor |
Annotation
| Flag | Used by | Description |
|---|---|---|
--transport |
annotate |
auto (default), direct, or relay |
--target-id |
annotate |
Target id for direct annotate |
--tab-id |
annotate |
Chrome tab id for relay annotate |
--screenshot-mode |
annotate |
visible (default), full, or none |
--include-screenshots |
annotate |
When used with --stored, prefer the in-memory payload that still includes screenshots if available |
--context |
annotate |
Optional context text pre-filled in the UI |
--debug |
annotate |
Include debug metadata in the payload |
--stored |
annotate |
Return the last stored annotation payload for the session |
--timeout-ms |
annotate |
Annotation timeout in ms |
Canvas
| Flag | Used by | Description |
|---|---|---|
--command |
canvas |
canvas.* command name (for example canvas.session.open) |
--params |
canvas |
Inline JSON object command params |
--params-file |
canvas |
Path to JSON object command params |
--timeout-ms |
canvas |
Client-side daemon call timeout in ms |
RPC (internal)
| Flag | Used by | Description |
|---|---|---|
--unsafe-internal |
rpc |
Required opt-in acknowledging unsafe/internal RPC execution (power-user only) |
--name |
rpc |
Daemon command name (for example relay.status) |
--params |
rpc |
Inline JSON object command params |
--params-file |
rpc |
Path to JSON object params file |
--timeout-ms |
rpc |
Client-side daemon call timeout in ms |
Interaction
| Flag | Used by | Description |
|---|---|---|
--ref |
element commands | Element ref from snapshot |
--timeout-ms |
click |
Client-side daemon call timeout in ms; defaults to 60s |
--text |
type |
Text to type |
--clear |
type |
Clear input before typing |
--submit |
type |
Submit after typing |
--values |
select |
Comma-separated values |
--files |
upload |
Comma-separated file paths for upload |
--dy |
scroll |
Scroll delta on Y axis |
--key |
press |
Keyboard key name (e.g. Enter) |
Targets + pages
| Flag | Used by | Description |
|---|---|---|
--target-id |
target-use, target-close |
Target id from targets-list |
--include-urls |
targets-list, session-inspector, session-inspector-audit |
Include URLs in target or session-inspector target-list output |
--name |
page, page-close |
Named page identifier |
Devtools
| Flag | Used by | Description |
|---|---|---|
--attr |
dom-attr |
Attribute name to read |
--path |
screenshot |
Output file path |
--ref |
screenshot |
Capture an element screenshot by ref |
--full-page |
screenshot |
Capture the full scrollable page |
--target-id |
screencast-start |
Optional target override for screencast capture |
--output-dir |
screencast-start |
Directory where screencast replay artifacts are written |
--interval-ms |
screencast-start |
Frame capture interval in ms (minimum 250) |
--max-frames |
screencast-start |
Maximum frame count before auto-stop |
--screencast-id |
screencast-stop |
Screencast id returned by screencast-start for the same session |
--action |
dialog |
Dialog action: status, accept, or dismiss |
--prompt-text |
dialog |
Prompt text to submit when accepting a prompt dialog |
--timeout-ms |
screenshot, screencast-start, screencast-stop |
Explicit client-side daemon call timeout in ms |
--timeout-ms |
dialog |
Client-side daemon call timeout in ms; defaults to 30s |
--since-seq |
console-poll, network-poll |
Start sequence number |
--since-console-seq |
debug-trace-snapshot, session-inspector, session-inspector-audit |
Resume cursor for console channel |
--since-network-seq |
debug-trace-snapshot, session-inspector, session-inspector-audit |
Resume cursor for network channel |
--since-exception-seq |
debug-trace-snapshot, session-inspector, session-inspector-audit |
Resume cursor for exception channel |
--max |
console-poll, network-poll, debug-trace-snapshot, session-inspector, session-inspector-audit |
Max events to return per channel |
Desktop observation
| Flag | Used by | Description |
|---|---|---|
--reason |
review-desktop, session-inspector-audit, desktop-windows, desktop-active-window, desktop-capture-desktop, desktop-capture-window, desktop-accessibility-snapshot |
Audit reason recorded with review, audit, or desktop observation results |
--window-id |
desktop-capture-window, desktop-accessibility-snapshot |
Window id for direct window capture or accessibility requests |
--timeout-ms |
all desktop-* commands |
Client-side daemon call timeout in ms |
CLI smoke test
Run the automated CLI coverage script (managed mode):
npm run build
node scripts/cli-smoke-test.mjs
The script uses temporary config/cache directories and exercises all CLI commands, including the new interaction and DOM state checks.
Validate extension mode separately with launch + disconnect while the extension is connected.
Direct live regression harness
Run the direct scenario pack instead of the old broad matrix:
npm run build
node scripts/live-regression-direct.mjs
What it runs:
scripts/cli-smoke-test.mjsscripts/canvas-live-workflow.mjs --surface managed-headlessscripts/canvas-live-workflow.mjs --surface managed-headedscripts/canvas-live-workflow.mjs --surface extensionscripts/canvas-live-workflow.mjs --surface cdpscripts/annotate-live-probe.mjs --transport relayscripts/annotate-live-probe.mjs --transport direct
Strict release gate mode:
node scripts/live-regression-direct.mjs --release-gate --out artifacts/release/vX.Y.Z/live-regression-direct.json
Behavior:
- Runs each scenario as an explicit child script with its own artifact instead of a nested matrix.
- Prints per-step progress so long runs do not idle silently.
- Fails on any direct scenario failure in
--release-gatemode. - Records
infra.daemon_statusas an initial preflight snapshot before child scenarios run. If a later child script repairs native messaging state, rerunopendevbrowser status --daemon --output-format jsonafter the pack for final daemon/native truth. - Uses temporary managed profiles for the managed canvas surfaces and the direct annotate probe so persisted-profile locks do not contaminate release runs.
- Waits for
/opsownership to drain before the legacy/cdpscenario so extension-backed CDP attach does not race a prior extension canvas run. - Treats manual annotation timeout boundaries as
skippedin--release-gatemode instead of misreporting them as runtime failures. - Requires a healthy daemon and a connected extension before running extension or CDP scenarios.
Direct provider runs
Run provider-by-provider live checks:
npm run build
node scripts/provider-direct-runs.mjs --out /tmp/odb-provider-direct-runs.json
Strict release gate mode:
npm run build
node scripts/provider-direct-runs.mjs --release-gate --out artifacts/release/vX.Y.Z/provider-direct-runs.json
Smoke mode:
npm run build
node scripts/provider-direct-runs.mjs --smoke --out /tmp/odb-provider-direct-runs-smoke.json
What it covers:
- Web/default direct search and fetch probes.
- Community/default direct search probes.
- Social/search and shopping/provider probes through the same direct CLI entrypoints used in real runs.
- Generic timeout outcomes stay visible as
fail;env_limitedis reserved for explicit environment/capability boundaries such as auth walls, browser-required shells, or challenge pages. - Social platform search probes for every registered platform in
src/providers/social/index.ts. - Shopping provider runs for every registered shopping provider in
src/providers/shopping/index.ts. - Optional social post probes for explicitly requested write-path validation.
Key report fields:
data.guidanceReasonanddata.recommendedNextCommandsummarize the first actionable provider follow-up emitted by the workflow or failure envelope.- Shopping and research workflow payloads keep the canonical structured source at
meta.primaryConstraint.guidance.reasonandmeta.primaryConstraint.guidance.recommendedNextCommands[]. - Product-video remains summary-first today: inspect
meta.primaryConstraintSummaryplus failure reason-code distributions when no structured guidance is present.
Key options:
--include-auth-gatedincludes auth-dependent provider scenarios.--include-high-frictionincludes high-friction shopping providers.--include-social-postsincludes social post scenarios.--use-global-envis kept as a compatibility flag; direct runs already use the current environment.--release-gateenables auth-gated + high-friction + social-post cases and fails on any non-passstatus.
Run contract parity and skill-asset gates as part of release checks:
npm run test -- tests/parity-matrix.test.ts
npm run test -- tests/providers-performance-gate.test.ts
./skills/opendevbrowser-best-practices/scripts/validate-skill-assets.sh
These commands are release guards, not the live release-proof lane. Use the direct-run harness commands above for release evidence.
Release gate source of truth: docs/RELEASE_RUNBOOK.md and docs/RELEASE_0.0.21_EVIDENCE.md.
Benchmark fixture manifest: docs/benchmarks/provider-fixtures.md.
Extension-only manual test (no OpenCode plugin)
Use this to validate the Chrome extension + relay without starting OpenCode.
- Ensure the daemon is running:
npx opendevbrowser serve(manual).opendevbrowser daemon installconfigures auto-start on supported platforms from a stable install location; for this manual test, usenpx opendevbrowser serveas the explicit start command for the current session. - Build and load the extension:
npm run extension:build, then Chrome →chrome://extensions→ Developer mode → Load unpacked →extension/. - Open a normal
http(s)tab (notchrome://or extension pages). - Open the extension popup, confirm Auto-connect + Auto-pair are ON, click Connect.
- Verify the popup shows Connected and
npx opendevbrowser status --daemonreportsextensionConnected: trueandextensionHandshakeComplete: true. - Optional session check:
npx opendevbrowser launch --extension-only --wait-for-extension, thennpx opendevbrowser disconnect --session-id <id>. - Optional annotation check (OpenCode): call
opendevbrowser_annotateand confirm screenshots are written to a temp folder.
If it fails, run npx opendevbrowser serve --stop then npx opendevbrowser serve, and confirm site access includes http://127.0.0.1/* and http://localhost/* in the extension settings.
Configuration files
OpenCode config
The CLI modifies opencode.json to register the plugin:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opendevbrowser"]
}
Locations:
- Global:
~/.config/opencode/opencode.json - Local:
./opencode.json
Plugin config (optional)
When using --with-config, a opendevbrowser.jsonc is created with documented defaults:
{
"headless": false,
"profile": "default",
"persistProfile": true,
"snapshot": { "maxChars": 16000, "maxNodes": 1000 },
"export": { "maxNodes": 1000, "inlineStyles": true },
"devtools": { "showFullUrls": false, "showFullConsole": false },
"security": {
"allowRawCDP": false,
"allowNonLocalCdp": false,
"allowUnsafeExport": false
},
"skillPaths": [],
"skills": {
"nudge": {
"enabled": true,
"keywords": ["quick start", "getting started", "launch", "connect", "setup"],
"maxAgeMs": 60000
}
},
"continuity": {
"enabled": true,
"filePath": "opendevbrowser_continuity.md",
"nudge": {
"enabled": true,
"keywords": ["plan", "multi-step", "long-running", "refactor", "migration", "rollout", "continue"],
"maxAgeMs": 60000
}
},
"providers": {
"antiBotPolicy": {
"enabled": true,
"cooldownMs": 30000,
"maxChallengeRetries": 1,
"allowBrowserEscalation": true
// "proxyHint": "residential_pool_a",
// "sessionHint": "warm_profile"
},
"transcript": {
"modeDefault": "auto",
"strategyOrder": ["youtubei", "native_caption_parse", "ytdlp_audio_asr", "apify"],
"enableYtdlp": false,
"enableAsr": false,
"enableYtdlpAudioAsr": true,
"enableApify": true,
"apifyActorId": "streamers/youtube-scraper",
"enableBrowserFallback": false,
"ytdlpTimeoutMs": 10000
}
},
"desktop": {
"permissionLevel": "observe",
"commandTimeoutMs": 10000,
"auditArtifactsDir": ".opendevbrowser/desktop-runtime",
"accessibilityMaxDepth": 2,
"accessibilityMaxChildren": 25
},
"daemonPort": 8788,
"daemonToken": "auto-generated-on-first-run",
"flags": [],
"checkForUpdates": false
}
The optional skills.nudge section controls the small one-time prompt hint that encourages early skill(...) usage on skill-relevant tasks. The optional continuity section controls the long-running task nudge and the ledger file path.
Fingerprint runtime defaults are Tier 1/2/3 enabled, with Tier 2 and Tier 3 driven by continuous signals (debug trace remains readout/reporting).
Provider runtime anti-bot/transcript controls default to a public-first YouTube resolver chain:
- Transcript mode semantics:
auto | web | no-auto | yt-dlp | apify. - Request filter precedence is
filters.youtube_mode > providers.transcript.modeDefault > auto. - No CLI mode flag is introduced in this phase; mode is configured in
providers.transcript.modeDefaultor per-requestyoutube_modefilter. - Auto mode fallback chain is
youtubei -> native_caption_parse -> ytdlp_audio_asr -> apify. yt-dlpaudio transcription requiresproviders.transcript.enableYtdlpAudioAsr=true.- Apify requires
providers.transcript.enableApify=true, a validAPIFY_TOKEN, and legal checklist approval forapify. - Browser-assisted fallback is opt-in only and requires
providers.transcript.enableBrowserFallback=trueplusproviders.antiBotPolicy.allowBrowserEscalation=true. - If browser fallback is enabled, run it in an isolated automation profile instead of a daily logged-in Google profile.
Provider workflow and execution outputs now include normalized transcript/anti-bot telemetry:
- Primary provider follow-up summary:
meta.primaryConstraintSummary. - Research and shopping workflow follow-up guidance:
meta.primaryConstraint.guidance.reasonandmeta.primaryConstraint.guidance.recommendedNextCommands[]when provider recovery steps are known. - Failure reason codes:
meta.metrics.reasonCodeDistributionfor research/shopping,meta.reasonCodeDistributionfor product-video, andreasonCodeon provider failures. - Transcript fallback diagnostics:
meta.metrics.transcript_strategy_failures(legacy) andmeta.metrics.transcriptStrategyFailures(camelCase alias). - Strategy-detail diagnostics:
meta.metrics.transcript_strategy_detail_failures/meta.metrics.transcriptStrategyDetailFailuresandmeta.metrics.transcript_strategy_detail_distribution/meta.metrics.transcriptStrategyDetailDistribution. - Durability/pressure dimensions:
meta.metrics.transcriptDurabilityandmeta.metrics.antiBotPressure(snake_case aliases are also emitted). - YouTube fetch metadata:
transcript_strategy(legacy bucket),transcript_strategy_detail(exact strategy),attempt_chain, and failurereasonCodewhen transcript retrieval is unavailable.
Provider reliability criteria (resolver/browser fallback):
npm run test -- tests/providers-performance-gate.test.tsmust pass.- Latest observation window must satisfy
meta.metrics.transcriptDurability.attempted >= 10andmeta.metrics.transcriptDurability.success_rate >= 0.85. - Latest observation window must satisfy
meta.metrics.antiBotPressure.anti_bot_failure_ratio <= 0.15. - Trigger remediation immediately if either condition fails in two consecutive windows.
npx opendevbrowser shopping run --help