From 47238894bebf824d02049a562d17c02cabecaee8 Mon Sep 17 00:00:00 2001 From: NianJiuZst <3235467914@qq.com> Date: Fri, 2 Oct 2026 03:43:46 +0800 Subject: [PATCH 1/5] refactor(protocol): generate shared contracts and require complete policies Refs #388. Derive extension contracts and validators from the Rust catalog, enforce exhaustive handler and execution policies, and preserve evaluation settlement across caller deadlines. --- .github/workflows/ci.yml | 5 + Cargo.lock | 86 +- Cargo.toml | 2 +- apps/extension/src/debug/capabilities.ts | 28 +- apps/extension/src/debug/types.ts | 432 +-- .../src/tools/__tests__/dispatcher.test.ts | 12 +- .../src/tools/__tests__/human-loop.test.ts | 2 +- .../src/tools/background-execution.ts | 44 +- apps/extension/src/tools/dispatcher.ts | 1091 +++--- apps/extension/src/tools/policy.ts | 281 ++ apps/extension/src/tools/session.ts | 46 +- apps/extension/src/tools/tabs.ts | 126 +- apps/extension/src/tools/window.ts | 20 +- .../src/transport/generated/input.ts | 3242 +++++++++++++++++ .../src/transport/generated/manifest.json | 242 ++ .../src/transport/generated/methods.ts | 590 +++ .../src/transport/generated/normalizers.ts | 2703 ++++++++++++++ .../src/transport/generated/output.ts | 3242 +++++++++++++++++ .../src/transport/generated/types.ts | 194 + .../src/transport/generated/validators.d.ts | 160 + .../src/transport/generated/validators.js | 30 + apps/extension/src/transport/handshake.ts | 25 +- apps/extension/src/transport/protocol.ts | 101 + apps/extension/src/transport/types.ts | 1010 +---- apps/extension/src/transport/ws-transport.ts | 6 +- biome.json | 3 +- crates/bsk-cli/src/cli/debug.rs | 2 +- crates/bsk-cli/src/daemon/ipc.rs | 18 +- crates/bsk-cli/src/daemon/mod.rs | 1 + crates/bsk-cli/src/daemon/queue.rs | 176 +- crates/bsk-cli/src/daemon/state.rs | 4 +- crates/bsk-cli/src/daemon/tool_policy.rs | 107 + crates/bsk-cli/src/daemon/ws.rs | 22 +- crates/bsk-protocol/Cargo.toml | 4 + crates/bsk-protocol/README.md | 92 +- crates/bsk-protocol/src/bin/dump-schema.rs | 233 +- .../bsk-protocol/src/bin/export-protocol.rs | 8 + crates/bsk-protocol/src/catalog.rs | 119 + crates/bsk-protocol/src/error.rs | 2 +- crates/bsk-protocol/src/lib.rs | 1 + crates/bsk-protocol/src/method.rs | 347 +- crates/bsk-protocol/src/system.rs | 20 + crates/bsk-protocol/src/tools/console.rs | 2 +- crates/bsk-protocol/src/tools/debug.rs | 137 +- crates/bsk-protocol/src/tools/network.rs | 2 +- crates/bsk-protocol/src/tools/record.rs | 106 +- crates/bsk-protocol/src/tools/record_v2.rs | 79 +- crates/bsk-protocol/src/tools/record_v3.rs | 9 +- crates/bsk-protocol/src/tools/session.rs | 23 +- package.json | 7 +- pnpm-lock.yaml | 86 +- scripts/protocol.mjs | 343 ++ 52 files changed, 12857 insertions(+), 2816 deletions(-) create mode 100644 apps/extension/src/tools/policy.ts create mode 100644 apps/extension/src/transport/generated/input.ts create mode 100644 apps/extension/src/transport/generated/manifest.json create mode 100644 apps/extension/src/transport/generated/methods.ts create mode 100644 apps/extension/src/transport/generated/normalizers.ts create mode 100644 apps/extension/src/transport/generated/output.ts create mode 100644 apps/extension/src/transport/generated/types.ts create mode 100644 apps/extension/src/transport/generated/validators.d.ts create mode 100644 apps/extension/src/transport/generated/validators.js create mode 100644 apps/extension/src/transport/protocol.ts create mode 100644 crates/bsk-cli/src/daemon/tool_policy.rs create mode 100644 crates/bsk-protocol/src/bin/export-protocol.rs create mode 100644 crates/bsk-protocol/src/catalog.rs create mode 100644 scripts/protocol.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fba409890..45088155a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -134,6 +134,11 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - uses: dtolnay/rust-toolchain@stable + + - name: Verify generated protocol against current Rust sources + run: pnpm protocol:check + - name: Prepare extension types run: pnpm --filter @browser-skill/extension exec wxt prepare diff --git a/Cargo.lock b/Cargo.lock index 93ad30613..81a7615aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,7 +268,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -476,7 +476,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -607,7 +607,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -977,7 +977,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn", + "syn 2.0.117", ] [[package]] @@ -996,7 +996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1240,7 +1240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", ] [[package]] @@ -1400,6 +1400,26 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.6", +] + [[package]] name = "regex-automata" version = "0.4.14" @@ -1598,11 +1618,12 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.22" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", + "ref-cast", "schemars_derive", "serde", "serde_json", @@ -1610,14 +1631,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.22" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +checksum = "d98c67716b46af2f0b8cf752abc930f6f9aecfbf671ecfb531db8a31dbe4e2ba" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 3.0.6", ] [[package]] @@ -1686,18 +1707,18 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] name = "serde_derive_internals" -version = "0.29.1" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +checksum = "f852137cce035d6a4df67ccce505ff6b3e9fd3a10e3e52b24dc71e650bb1a9bd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -1845,6 +1866,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -1862,7 +1894,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1915,7 +1947,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1926,7 +1958,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2019,7 +2051,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2121,7 +2153,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2375,7 +2407,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -2681,7 +2713,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -2697,7 +2729,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -2774,7 +2806,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -2795,7 +2827,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2815,7 +2847,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -2855,7 +2887,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 925b13ae0..42bfea042 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ futures-util = "0.3" serde = { version = "1", features = ["derive"] } serde_json = "1" semver = { version = "1", features = ["serde"] } -schemars = { version = "0.8", features = ["derive"] } +schemars = { version = "1.2.2", features = ["derive"] } thiserror = "2" anyhow = "1" tracing = "0.1" diff --git a/apps/extension/src/debug/capabilities.ts b/apps/extension/src/debug/capabilities.ts index aa0f904fe..edfa4e4d5 100644 --- a/apps/extension/src/debug/capabilities.ts +++ b/apps/extension/src/debug/capabilities.ts @@ -1,32 +1,12 @@ +import { debugActions } from "@/transport/generated/methods"; import { HISTORY_AGE_MS, HISTORY_BYTES, HISTORY_LIMIT } from "./archive"; import { JOURNAL_BYTES, JOURNAL_PINS, JOURNAL_REQUESTS } from "./journal"; declare const __BSK_EXT_BUILD__: string; declare const __BSK_EXT_VERSION__: string; -export const DEBUG_ACTIONS = [ - "performance", - "aggregate", - "duplicates", - "start", - "stop", - "status", - "requests", - "request", - "operations", - "operation", - "console", - "pages", - "export", - "rules", - "rule_add", - "rule_enable", - "rule_disable", - "rule_remove", - "replay", - "capabilities", - "pin", - "unpin", -] as const; +export const DEBUG_ACTIONS = debugActions + .filter((action) => action.owner === "extension") + .map((action) => action.action); export const DEBUG_FIELDS = [ "resource_type", "frame_id", diff --git a/apps/extension/src/debug/types.ts b/apps/extension/src/debug/types.ts index a11b21882..27129ac44 100644 --- a/apps/extension/src/debug/types.ts +++ b/apps/extension/src/debug/types.ts @@ -1,328 +1,36 @@ -/** Opt-in, task-owned evidence. All timestamps are epoch milliseconds. */ -export type DebugAction = - | "performance" - | "aggregate" - | "duplicates" - | "capabilities" - | "activity" - | "wait" - | "pin" - | "unpin" - | "start" - | "stop" - | "status" - | "requests" - | "request" - | "operations" - | "operation" - | "console" - | "pages" - | "export" - | "rules" - | "rule_add" - | "rule_enable" - | "rule_disable" - | "rule_remove" - | "replay"; - -export interface DebugRequestEdit { - url?: string; - method?: string; - headers?: Record; - body?: string; - /** Top-level JSON object edits; applied to the live request, before redaction. */ - json?: { set?: Record; remove?: string[]; rename?: Record }; -} -export interface DebugRuleSpec { - name?: string; - match: { url: string; method?: string; resource_type?: "Fetch" | "XHR" | "Document" }; - effect: - | { type: "block" } - | ({ type: "modify" } & DebugRequestEdit) - | { - type: "mock"; - status: number; - headers?: Record; - body: string; - delay_ms?: number; - }; - /** Defaults to one match. Zero means until disabled or capture ends. */ - times?: number; -} -export interface DebugRule extends DebugRuleSpec { - id: string; - state: "enabled" | "disabled" | "exhausted" | "removed" | "stopped"; - hits: number; - failures: number; - created_at: number; - last_error?: string; -} -export interface DebugReplaySpec extends Omit { - /** Reusing a key in the same capture never sends another request. */ - key: string; -} -export interface DebugReplay { - id: string; - key: string; - source_request_id: string; - request_id?: string; - state: "running" | "complete" | "failed" | "interrupted"; - error?: string; -} -export interface DebugIntervention { - rule_id: string; - type: "block" | "modify" | "mock"; - state: "pending" | "applied" | "failed" | "cancelled"; - error?: string; - /** Small redacted change summary; retained request body is the effective body. */ - changes?: string[]; -} - -export interface DebugParams { - session_id: string; - action: DebugAction; - tab_id?: number; - run_id?: string; - id?: string; - name?: string; - since?: number; - limit?: number; - /** Detail projection. Metadata never includes body text. */ - part?: "metadata" | "request" | "response" | "headers" | "timing"; - offset?: number; - max_chars?: number; - /** RFC 6901 JSON pointer, applied to a complete redacted body. */ - pointer?: string; - rule?: DebugRuleSpec; - replay?: DebugReplaySpec; - /** UTF-8 bytes of JSON output (default 65536; export is exempt). */ - budget?: number; - slow_ms?: number; - window_ms?: number; - include_controlled?: boolean; - url?: string; - method?: string; - resource_type?: string; - status?: number; - state?: DebugRequest["state"]; - kind?: "business" | "resource" | "extension" | "all"; - fields?: string[]; - wait_ms?: number; - command_id?: string; -} - -export interface DebugBody { - state: "pending" | "available" | "empty" | "truncated" | "unavailable" | "omitted" | "evicted"; - reason?: string; - text?: string; - chars?: number; - offset?: number; - next_offset?: number; - redacted?: boolean; - /** True only when complete retained text is identical to the captured body. */ - replay_safe?: boolean; -} - -export interface DebugRequest { - id: string; - run_id: string; - sequence: number; - started_at: number; - finished_at?: number; - method: string; - url: string; - /** Absent on older evidence, whose URL/body fidelity cannot be established. */ - integrity?: { - url: "complete" | "redacted" | "truncated"; - /** Request metadata needed for replay; excludes response headers. */ - metadata: "complete" | "truncated"; - response_headers?: "complete" | "truncated"; - }; - resource_type?: string; - frame_id?: string; - loader_id?: string; - state: "pending" | "complete" | "failed" | "redirected" | "interrupted"; - status?: number; - error?: string; - mime_type?: string; - duration_ms?: number; - transfer_bytes?: number; - decoded_bytes?: number; - from_cache?: boolean; - from_service_worker?: boolean; - redirect_from?: string; - initiator?: string; - request_headers?: Record; - response_headers?: Record; - timing?: Record; - request_body: DebugBody; - response_body: DebugBody; - truncated?: boolean; - intervention?: DebugIntervention; - replay_from?: string; - replay_id?: string; - pinned?: boolean; -} - -export interface DebugConsole { - id: string; - at: number; - level: string; - text: string; - count: number; - last_at: number; - stack?: string; - source?: "website" | "extension" | "browser" | "unknown"; - source_url?: string; - relation?: "window" | "delayed"; -} - -export interface DebugField { - key: string; - name?: string; - label: string; - value?: string; - state: "available" | "redacted" | "truncated"; -} - -export interface DebugPage { - at: number; - url?: string; - title?: string; - text?: string; - state: "available" | "unavailable"; - truncated?: boolean; - fields?: DebugField[]; - fields_partial?: boolean; - navigation?: string; -} - -export interface DebugOperation { - id: string; - run_id: string; - sequence: number; - method: string; - target?: string; - source?: "human" | "agent"; - started_at: number; - finished_at?: number; - /** Time-window correlation, never a causal assertion. */ - window_end?: number; - state: "running" | "completed" | "error" | "interrupted"; - error?: string; - before?: DebugPage; - after?: DebugPage; - observations?: DebugPage[]; - observation_end?: number; - observation_limited?: boolean; - request_ids: string[]; - console_ids: string[]; - truncated: boolean; -} - -export interface DebugRun { - id: string; - session_id: string; - tab_id: number; - name: string; - url: string; - started_at: number; - stopped_at?: number; - state: "capturing" | "stopped"; - stop_reason?: string; - requests: number; - operations: number; - errors: number; - dropped_requests: number; - dropped_operations: number; - dropped_console: number; - coverage: string[]; - next_since: number; - active_rules?: number; - saved_at?: number; - storage_error?: string; - storage?: { requests: number; bytes: number; dropped: number; pins: number }; - environment?: { extension_version?: string; user_agent?: string }; -} - -export interface DebugValue { - state: string; - value?: string; - source?: string; - at?: number; -} -export interface DebugFieldTrace { - key: string; - label: string; - before: DebugValue; - input: DebugValue; - submitted: DebugValue[]; - response: DebugValue[]; - later: DebugValue; -} -export interface DebugEvidence { - fields: DebugFieldTrace[]; - payloads: { - request_id: string; - part: string; - path: string; - value: string; - truncated?: boolean; - }[]; - links: { request_id: string; relation: "window" | "delayed" }[]; - gaps: string[]; - changes: { added: string[]; removed: string[]; truncated: boolean }; - observations: DebugPage[]; -} - -/** Portable, already-redacted snapshot. Also used by browser-local history. */ -export interface DebugRecording { - version: 1; - saved_at: number; - run: DebugRun; - requests: DebugRequest[]; - operations: DebugOperation[]; - console: DebugConsole[]; - pages: DebugPage[]; - rules?: DebugRule[]; - replays?: DebugReplay[]; - performance?: DebugPerformance[]; -} - -export interface DebugResult { - session_id: string; - run?: DebugRun; - runs?: DebugRun[]; - requests?: DebugRequest[]; - request?: DebugRequest; - operations?: DebugOperation[]; - operation?: DebugOperation; - console?: DebugConsole[]; - pages?: DebugPage[]; - recording?: DebugRecording; - evidence?: DebugEvidence; - rules?: DebugRule[]; - replays?: DebugReplay[]; - performance?: DebugPerformance[]; - replay?: DebugReplay; - aggregates?: DebugEndpoint[]; - duplicates?: DebugDuplicate[]; - analysis?: DebugAnalysis; - next_offset?: number; - next_since?: number; - truncated?: boolean; - capabilities?: Record; - output?: { budget: number; truncated: boolean; omitted: string[] }; - activity?: { - state: string; - command_id?: string; - method?: string; - started_at?: number; - elapsed_ms?: number; - wait_complete?: boolean; - wait_timed_out?: boolean; - }; -} +import type { DebugRun } from "@/transport/types"; + +export type { + DebugAction, + DebugAnalysis, + DebugBody, + DebugConsole, + DebugDuplicate, + DebugEndpoint, + DebugEvidence, + DebugField, + DebugFieldTrace, + DebugIntervention, + DebugMetric, + DebugOperation, + DebugPage, + DebugParams, + DebugPerformance, + DebugRecording, + DebugReplay, + DebugReplaySpec, + DebugRequest, + DebugResult, + DebugRule, + DebugRuleSpec, + DebugRun, + DebugValue, +} from "@/transport/types"; + +export type DebugRequestEdit = Omit< + Extract, + "type" +>; export interface DebugTask { session_id: string; @@ -332,77 +40,3 @@ export interface DebugTask { url?: string; run?: DebugRun; } - -export interface DebugMetric { - value?: number; - state: "available" | "provisional" | "partial" | "unavailable" | "unsupported"; - reasons: string[]; -} -export interface DebugPerformance { - id: string; - document_key: string; - sequence: number; - time_origin: number; - started_at: number; - observed_at: number; - url: string; - navigation: string; - state: "capturing" | "completed" | "interrupted"; - early: boolean; - scope: "main_frame"; - visibility: { at: number; state: string }[]; - visibility_truncated: boolean; - metrics: Record; - long_tasks: { at: number; duration_ms: number }[]; - long_tasks_truncated: boolean; - coverage: string[]; -} -export interface DebugEndpoint { - id: string; - method: string; - endpoint: string; - count: number; - failed: number; - http_errors: number; - pending: number; - interrupted: number; - statuses: Record; - slow: number; - timing_samples: number; - duration_ms?: { min: number; mean: number; p50: number; p95: number; max: number; total: number }; - transfer_bytes: number; - transfer_samples: number; - cached: number; - service_worker: number; - controlled: number; - replayed: number; - request_ids: string[]; - refs_truncated: boolean; -} -export interface DebugDuplicate { - id: string; - method: string; - url: string; - count: number; - extra_requests: number; - started_at: number; - ended_at: number; - overlap_count: number; - possible_retry: boolean; - request_ids: string[]; - operation_ids: string[]; - refs_truncated: boolean; -} -export interface DebugAnalysis { - retained: number; - matched: number; - included: number; - excluded_controlled: number; - uncomparable: number; - groups: number; - suspected_extra_requests: number; - window_ms: number; - slow_ms: number; - coverage: string[]; - semantics: string; -} diff --git a/apps/extension/src/tools/__tests__/dispatcher.test.ts b/apps/extension/src/tools/__tests__/dispatcher.test.ts index b97588623..c91a6110d 100644 --- a/apps/extension/src/tools/__tests__/dispatcher.test.ts +++ b/apps/extension/src/tools/__tests__/dispatcher.test.ts @@ -480,7 +480,9 @@ describe("ToolDispatcher", () => { // ...and the window is released rather than closed, so the user's tab survives. expect(closeWindow).not.toHaveBeenCalled(); expect(sessions.has("aa11")).toBe(false); - expect(sent[0]).toEqual({ id: "r-1", result: { window_released: true } }); + await vi.waitFor(() => + expect(sent[0]).toEqual({ id: "r-1", result: { window_released: true } }), + ); }); it("routes tool.console through the CDP console buffer", async () => { @@ -1600,7 +1602,7 @@ it.each([ }); dispatcher.start(); try { - f.deliver({ id: "open", method, params: { session_id: "popup", tab_id: 10 } }); + f.deliver({ id: "open", method, params: { session_id: "popup", tab_id: 10, key: "Enter" } }); await vi.waitFor(() => expect(f.sent.some((r) => "id" in r && r.id === "open")).toBe(true)); expect(task.observedTabs?.has(20)).toBe(true); expect(task.agentCreatedTabs.has(20)).toBe(false); @@ -1660,7 +1662,11 @@ it("passes dispatcher cancellation to popup tracking before the tool settles", a }); dispatcher.start(); try { - f.deliver({ id: "open", method: "tool.press", params: { session_id: "popup", tab_id: 10 } }); + f.deliver({ + id: "open", + method: "tool.press", + params: { session_id: "popup", tab_id: 10, key: "Enter" }, + }); await vi.waitFor(() => expect(invoke).toHaveBeenCalled()); f.deliver({ id: "cancel", method: "cancel", params: { rpc_id: "open" } }); await vi.waitFor(() => diff --git a/apps/extension/src/tools/__tests__/human-loop.test.ts b/apps/extension/src/tools/__tests__/human-loop.test.ts index 6472c4642..4265ee55f 100644 --- a/apps/extension/src/tools/__tests__/human-loop.test.ts +++ b/apps/extension/src/tools/__tests__/human-loop.test.ts @@ -717,7 +717,7 @@ describe("handleRequestHelp", () => { fakeManager("abcd", 99, 5), baseParams({ completion_criteria: { - any: [{ url_matches: urlMatches, url_contains: "/done" }], + any: [{ url_matches: urlMatches as string | undefined, url_contains: "/done" }], stable_for_ms: 0, }, }), diff --git a/apps/extension/src/tools/background-execution.ts b/apps/extension/src/tools/background-execution.ts index 710c1640d..e925d74ad 100644 --- a/apps/extension/src/tools/background-execution.ts +++ b/apps/extension/src/tools/background-execution.ts @@ -1,5 +1,6 @@ import { isAgentControlledTab, type SessionManager } from "@/session-manager/manager"; import type { RequestFrame, RpcError } from "@/transport/types"; +import { toolPolicy } from "./policy"; import { type CdpRunner, type ChromeTabsApi, @@ -9,37 +10,6 @@ import { resolveTargetTab, } from "./shared"; -const reads = new Set([ - "tool.snapshot", - "tool.observe", - "tool.screenshot", - "tool.get_html", - "tool.evaluate", - "tool.console", - "tool.network", -]); -const pageTools = new Set([ - ...reads, - "tool.navigate", - "tool.navigate_back", - "tool.navigate_forward", - "tool.reload", - "tool.click", - "tool.hover", - "tool.wheel", - "tool.scroll_to", - "tool.focus", - "tool.blur", - "tool.fill", - "tool.press", - "tool.select", - "tool.upload", - "tool.download", - "tool.emulate", - "tool.wait_for_navigation", - "tool.screenshot_full_page", -]); - /** Prepare only explicitly controlled targets, before page reads or readiness waits. * Resolve once and pin the request to that tab; UI activation is never targeting. */ export async function prepareBackgroundExecution( @@ -49,24 +19,20 @@ export async function prepareBackgroundExecution( tabs: ChromeTabsApi, signal: AbortSignal, ): Promise { - if (!cdp?.acquireBackgroundExecution || !pageTools.has(request.method)) return; + const policy = toolPolicy(request.method); + if (!cdp?.acquireBackgroundExecution || !policy || policy.background === "none") return; const params = request.params as { session_id?: string; tab_id?: number } | undefined; if (!params?.session_id) return; const ctx = manager.get(params.session_id); if (!ctx) return; - const target = await (reads.has(request.method) + const target = await (policy.background === "accessible" ? resolveCdpAccessibleTargetTab(manager, ctx, params.tab_id, tabs, request.method) : resolveTargetTab(manager, ctx, params.tab_id, tabs)); if (isRpcError(target)) return target; request.params = { ...params, tab_id: target.tabId }; // Navigation owns preparation: an inaccessible source document must still // be able to leave through browser navigation before CDP becomes available. - if ( - ["tool.navigate", "tool.reload", "tool.navigate_back", "tool.navigate_forward"].includes( - request.method, - ) - ) - return; + if (policy.background === "navigation") return; if (!isAgentControlledTab(ctx, target.tabId) || target.windowId !== ctx.agentWindowId) return; // Other page tools cannot establish execution on browser-internal documents. if (cdpBlockedUrlReason(target.url)) return; diff --git a/apps/extension/src/tools/dispatcher.ts b/apps/extension/src/tools/dispatcher.ts index 0a658904a..a7cd0491a 100644 --- a/apps/extension/src/tools/dispatcher.ts +++ b/apps/extension/src/tools/dispatcher.ts @@ -1,49 +1,20 @@ import type { DebugManager, DebugTicket } from "@/debug/manager"; -import type { DebugParams } from "@/debug/types"; import type { InteractionPreferenceStore } from "@/lib/interaction-preferences"; import { OVERLAY_AUTOMATION_BYPASS } from "@/lib/overlay-bridge"; import { ScreenshotExports } from "@/long-screenshot/exports"; import type { SessionManager } from "@/session-manager/manager"; import { withTaskPopups } from "@/session-manager/task-popups"; +import type { ExtensionToolMethod, ResultOf } from "@/transport/generated/methods"; +import { + decodeToolRequest, + isExtensionToolMethod, + type ToolHandlerMap, + type ToolRequest, + validateCancelParams, + validateToolResult, +} from "@/transport/protocol"; import type { Transport } from "@/transport/transport"; -import type { - BlurParams, - ClickParams, - ConsoleParams, - DownloadParams, - EmulateParams, - EvaluateParams, - FillParams, - FocusParams, - GetHtmlParams, - HoverParams, - HoverResult, - NavigateBackParams, - NavigateForwardParams, - NavigateParams, - NetworkParams, - ObserveParams, - PressParams, - ProtocolFrame, - RecordAwaitParams, - RecordStartParams, - RecordStopParams, - ReloadParams, - RequestFrame, - RequestHelpParams, - ResponseFrame, - RpcError, - ScreenshotFullPageParams, - ScreenshotParams, - ScreenshotReadParams, - ScreenshotReleaseParams, - ScrollToParams, - SelectParams, - SnapshotParams, - UploadParams, - WaitForNavigationParams, - WheelParams, -} from "@/transport/types"; +import type { HoverResult, ProtocolFrame, ResponseFrame, RpcError } from "@/transport/types"; import { isRequestFrame } from "@/transport/types"; import { auditContext } from "./audit-context"; import { prepareBackgroundExecution } from "./background-execution"; @@ -78,6 +49,7 @@ import { handleScreenshot, handleSnapshot, } from "./observation"; +import { resumesBrowserControl, TOOL_POLICIES } from "./policy"; import { clearRecordingForSession, handleRecordAwait, @@ -87,12 +59,7 @@ import { } from "./record"; import { handleFullPageScreenshot } from "./screenshot-full-page"; import { handleScrollTo } from "./scroll"; -import { - handleSessionStart, - handleSessionStop, - type SessionStartParams, - type SessionStopParams, -} from "./session"; +import { handleSessionStart, handleSessionStop } from "./session"; import { chromeTabsApi, lookupSession, resolveTargetTab } from "./shared"; import { type BorrowConfirmationApprover, @@ -103,17 +70,11 @@ import { handleTabList, handleTabReturn, handleTabSelect, - type TabBorrowParams, - type TabCloseParams, - type TabCreateParams, - type TabListParams, - type TabReturnParams, - type TabSelectParams, } from "./tabs"; import { handleUpload } from "./upload"; import { handleWaitForNavigation } from "./waits"; import { handleWheel } from "./wheel"; -import { handleWindowResize, type WindowResizeParams } from "./window"; +import { handleWindowResize } from "./window"; type DispatcherCdpRunner = CdpRunner & NetworkCdpRunner & @@ -157,9 +118,6 @@ export interface DispatcherDeps { helpNotificationCopy?: () => { title: string; body: string }; } -/** Tools whose page input can make the page open another tab or window. */ -const OPENS_TABS = new Set(["tool.click", "tool.press"]); - /** * Routes RPC requests pushed by the daemon over the Transport to the * appropriate tool implementation. @@ -268,13 +226,20 @@ export class ToolDispatcher { private async dispatch(msg: ProtocolFrame): Promise { if (!isRequestFrame(msg)) return; - const req = msg as RequestFrame; + const raw = msg; // Cancel frames take a fast path: trip the matching controller // (if any), reply with `{cancelled}` so the daemon can answer // its own peer, and skip the regular tool dispatch. - if (req.method === "cancel") { - const params = (req.params as { rpc_id?: string } | undefined) ?? {}; + if (raw.method === "cancel") { + if (!validateCancelParams(raw.params)) { + this.sendResponse({ + id: raw.id, + error: { code: "invalid_params", message: "cancel requires a string rpc_id" }, + }); + return; + } + const params = raw.params; const target = typeof params.rpc_id === "string" ? params.rpc_id : ""; const ac = target ? this.inflightAbortControllers.get(target) : undefined; if (ac) { @@ -285,17 +250,38 @@ export class ToolDispatcher { } } const reply: ResponseFrame = { - id: req.id, + id: raw.id, result: { cancelled: ac !== undefined }, }; - try { - this.transport.send(reply); - } catch (sendErr) { - console.warn("[bsk dispatcher] failed to ack cancel", sendErr); - } + this.sendResponse(reply); return; } + // Capability rejection is independent of payload details. Preserve it for + // remote gateways before validating local file-operation parameters. + if (isExtensionToolMethod(raw.method) && !TOOL_POLICIES[raw.method].remoteAllowed) { + const params = raw.params; + const sessionId = + typeof params === "object" && params !== null && "session_id" in params + ? params.session_id + : undefined; + if (typeof sessionId === "string" && this.sessions.get(sessionId)?.remote) { + this.sendResponse({ + id: raw.id, + error: { + code: "unsupported", + message: "Remote connections do not support upload or download", + }, + }); + return; + } + } + const decoded = decodeToolRequest(raw); + if (!decoded.ok) { + this.sendResponse({ id: raw.id, error: decoded.error }); + return; + } + const req = decoded.request; const startsSession = req.method === "tool.session_start"; const mutatesSessions = startsSession || req.method === "tool.session_stop"; if (startsSession) this.pendingSessionStarts += 1; @@ -323,7 +309,7 @@ export class ToolDispatcher { /* Evidence must not block the operation. */ } throwIfDispatchAborted(ac.signal); - const result = OPENS_TABS.has(req.method) + let result = TOOL_POLICIES[req.method].opensTabs ? await withTaskPopups( this.sessions, (req.params ?? {}) as { session_id?: string; tab_id?: number }, @@ -332,6 +318,11 @@ export class ToolDispatcher { ac.signal, ) : await this.invoke(req, ac.signal); + if (!isRpcError(result)) { + const invalid = validateToolResult(req.method, result); + if (invalid && startsSession) await this.sessions.stop(req.params.session_id); + result = invalid ?? result; + } this.debug?.after(debugTicket, isRpcError(result) ? result.message : undefined); debugTicket = undefined; if (isRpcError(result)) { @@ -339,7 +330,7 @@ export class ToolDispatcher { } else { body = { id: req.id, result }; if (req.method === "tool.session_start") { - startedSession = (req.params as SessionStartParams | undefined)?.session_id ?? null; + startedSession = req.params.session_id; } } } catch (err) { @@ -362,20 +353,7 @@ export class ToolDispatcher { this.debug?.after(debugTicket, "operation failed"); this.inflightAbortControllers.delete(req.id); } - let sent = true; - try { - this.transport.send(body); - } catch (sendErr) { - sent = false; - // Transport is dead by the time we want to reply. Drop the link - // proactively so the alarm-driven keepalive reconnects sooner - // and the daemon's pending RPC times out cleanly instead of - // waiting for the full 15s budget (review M4/M5 I9). - console.warn("[bsk dispatcher] failed to send response; dropping transport", sendErr); - void this.transport.disconnect().catch((e) => { - console.debug("[bsk dispatcher] disconnect after send failure errored", e); - }); - } + const sent = this.sendResponse(body); if (!sent && startedSession) { // The daemon never observed the session id we just allocated, so // its `start_session` reservation will be cancelled. Roll back @@ -399,463 +377,483 @@ export class ToolDispatcher { this.onSessionsChanged?.(); } } - - private async invoke( - req: RequestFrame, - signal: AbortSignal, - onInputSent?: (tabId: number) => void, - ): Promise { - const sessionId = (req.params as { session_id?: string } | undefined)?.session_id; - // Also enforce this for gateways backed by a local-mode daemon, where the - // standalone server's early IPC rejection does not apply. - if ( - sessionId && - this.sessions.get(sessionId)?.remote && - (req.method === "tool.upload" || req.method === "tool.download") - ) { - return { - code: "unsupported", - message: "Remote connections do not support upload or download", - }; + private sendResponse(body: ResponseFrame): boolean { + try { + this.transport.send(body); + return true; + } catch (error) { + // Both normal replies and boundary rejections must retire a dead link. + console.warn("[bsk dispatcher] failed to send response; dropping transport", error); + void this.transport.disconnect().catch((disconnectError) => { + console.debug("[bsk dispatcher] disconnect after send failure errored", disconnectError); + }); + return false; } - const preparationError = await prepareBackgroundExecution( - this.sessions, - req, - this.cdp, - chromeTabsApi, - signal, - ); - if (preparationError) return preparationError; - switch (req.method) { - case "tool.debug": - if (!this.debug) - return { - code: "unsupported", - message: "Website debugging requires a compatible extension", - }; - return handleDebug( - this.sessions, - req.params as DebugParams, - this.debug, - chromeTabsApi, - signal, - ); - case "tool.session_start": - return handleSessionStart(this.sessions, req.params as SessionStartParams, { - signal, - preferences: this.interactionPreferences, - }); - case "tool.session_stop": { - this.debug?.releaseSession((req.params as SessionStopParams).session_id); - await this.screenshotExports.releaseSession((req.params as SessionStopParams).session_id); - await this.releaseHoverLatch((req.params as SessionStopParams).session_id); - return handleSessionStop(this.sessions, req.params as SessionStopParams, { - cdp: this.cdp, - // Must be wired in production: the agent-tab cleanup and the - // window-release decision (issue #57) read these deps directly - // and silently no-op when they are absent. - tabManagement: { tabs: chromeTabMutationApi }, - tabsQuery: chromeTabsApi, - signal, - }); - } - case "tool.tab_list": - return handleTabList(this.sessions, req.params as TabListParams, chromeTabsApi, signal); - case "tool.tab_create": { - const result = await handleTabCreate(this.sessions, req.params as TabCreateParams, { - signal, - cdp: this.cdp, - }); - if (!isRpcError(result)) { - this.onAgentTabClaimed?.(result.tab_id, result.window_id); - } - return result; + } + + private readonly handlers: ToolHandlerMap = { + "tool.debug": async (params, signal, onInputSent) => { + if (!this.debug) + return { + code: "unsupported", + message: "Website debugging requires a compatible extension", + }; + return handleDebug(this.sessions, params, this.debug, chromeTabsApi, signal); + }, + "tool.session_start": async (params, signal, onInputSent) => { + return handleSessionStart(this.sessions, params, { + signal, + preferences: this.interactionPreferences, + }); + }, + "tool.session_stop": async (params, signal, onInputSent) => { + this.debug?.releaseSession(params.session_id); + await this.screenshotExports.releaseSession(params.session_id); + await this.releaseHoverLatch(params.session_id); + return handleSessionStop(this.sessions, params, { + cdp: this.cdp, + // Must be wired in production: the agent-tab cleanup and the + // window-release decision (issue #57) read these deps directly + // and silently no-op when they are absent. + tabManagement: { tabs: chromeTabMutationApi }, + tabsQuery: chromeTabsApi, + signal, + }); + }, + "tool.tab_list": async (params, signal, onInputSent) => { + return handleTabList(this.sessions, params, chromeTabsApi, signal); + }, + "tool.tab_create": async (params, signal, onInputSent) => { + const result = await handleTabCreate(this.sessions, params, { + signal, + cdp: this.cdp, + }); + if (!isRpcError(result)) { + this.onAgentTabClaimed?.(result.tab_id, result.window_id); } - case "tool.tab_close": - return this.withHoverReleaseForRequest( - req.params as TabCloseParams, - () => handleTabClose(this.sessions, req.params as TabCloseParams, { signal }), - signal, - ); - case "tool.tab_select": - return handleTabSelect(this.sessions, req.params as TabSelectParams, { signal }); - case "tool.tab_borrow": { - const result = await handleTabBorrow(this.sessions, req.params as TabBorrowParams, { - signal, - approveBorrow: this.approveBorrow, - cdp: this.cdp, - }); - if (!isRpcError(result)) { - this.onAgentTabClaimed?.(result.tab_id, result.agent_window_id); - } - return result; + return result; + }, + "tool.tab_close": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => handleTabClose(this.sessions, params, { signal }), + signal, + ); + }, + "tool.tab_select": async (params, signal, onInputSent) => { + return handleTabSelect(this.sessions, params, { signal }); + }, + "tool.tab_borrow": async (params, signal, onInputSent) => { + const result = await handleTabBorrow(this.sessions, params, { + signal, + approveBorrow: this.approveBorrow, + cdp: this.cdp, + }); + if (!isRpcError(result)) { + this.onAgentTabClaimed?.(result.tab_id, result.agent_window_id); } - case "tool.tab_return": - return handleTabReturn(this.sessions, req.params as TabReturnParams, { - signal, + return result; + }, + "tool.tab_return": async (params, signal, onInputSent) => { + return handleTabReturn(this.sessions, params, { + signal, + cdp: this.cdp, + beforeReturn: async (sessionId, tabId) => { + this.debug?.stopTab(tabId); + if (this.sessions.get(sessionId)?.remote) clearRecordingForSession(sessionId); + await this.releaseHoverLatch(sessionId, tabId); + }, + }); + }, + "tool.window_resize": async (params, signal, onInputSent) => { + return handleWindowResize(this.sessions, params, undefined, signal); + }, + "tool.emulate": async (params, signal, onInputSent) => { + return handleEmulate( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ); + }, + "tool.screenshot_full_page": async (params, signal, onInputSent) => { + if (!this.cdp) return { code: "unsupported", message: "Full-page screenshot requires CDP" }; + return handleFullPageScreenshot( + this.sessions, + params, + { cdp: this.cdp, - beforeReturn: async (sessionId, tabId) => { - this.debug?.stopTab(tabId); - if (this.sessions.get(sessionId)?.remote) clearRecordingForSession(sessionId); - await this.releaseHoverLatch(sessionId, tabId); - }, - }); - case "tool.window_resize": - return handleWindowResize( - this.sessions, - req.params as WindowResizeParams, - undefined, - signal, - ); - case "tool.emulate": - return handleEmulate( - this.sessions, - req.params as EmulateParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ); - case "tool.screenshot_full_page": - if (!this.cdp) return { code: "unsupported", message: "Full-page screenshot requires CDP" }; - return handleFullPageScreenshot( - this.sessions, - req.params as ScreenshotFullPageParams, - { - cdp: this.cdp, - tabsApi: chromeTabsApi, - exports: this.screenshotExports, - }, - signal, - ); - case "tool.screenshot_read": - return this.screenshotExports.read(req.params as ScreenshotReadParams); - case "tool.screenshot_release": - return this.screenshotExports.release(req.params as ScreenshotReleaseParams); - case "tool.screenshot": - return handleScreenshot( - this.sessions, - req.params as ScreenshotParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi, captureApi: chromeTabsCaptureApi } - : undefined, - signal, - ); - case "tool.console": - return handleConsole( - this.sessions, - req.params as ConsoleParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi } : undefined, - signal, - ); - case "tool.network": - return handleNetwork( - this.sessions, - req.params as NetworkParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi } : undefined, - signal, - ); - case "tool.snapshot": - return this.withHoverReassert( - req.params as SnapshotParams, - () => - handleSnapshot( - this.sessions, - req.params as SnapshotParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi } : undefined, - signal, - ), - {}, - signal, - ); - case "tool.observe": { - const params = req.params as ObserveParams; - const hoverScope = await this.resolveHoverLatchScope(params); - throwIfDispatchAborted(signal); - return this.withHoverReassert( - params, - () => - handleObserve( - this.sessions, - params, - this.cdp - ? { - cdp: this.cdp, - tabsApi: chromeTabsCaptureApi, - // Active hover probing is opt-in. A held hover latch still - // suppresses it, because probing would move the cursor off - // the element the caller is deliberately holding. - conditionalSurfaceProbe: - params.probe_hover === true && !this.hasHoverLatchForScope(hoverScope), - hoverProbeBypassOverlay: bypassOverlay, - } - : undefined, - signal, - ), - {}, - signal, - ); - } - case "tool.get_html": - return handleGetHtml( - this.sessions, - req.params as GetHtmlParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi } : undefined, - signal, - ); - case "tool.navigate": - return this.withHoverReleaseForRequest( - req.params as NavigateParams, - () => - handleNavigate( - this.sessions, - req.params as NavigateParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } - : undefined, - ), - signal, - ); - case "tool.navigate_back": - return this.withHoverReleaseForRequest( - req.params as NavigateBackParams, - () => - handleNavigateBack( - this.sessions, - req.params as NavigateBackParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } - : undefined, - ), - signal, - ); - case "tool.navigate_forward": - return this.withHoverReleaseForRequest( - req.params as NavigateForwardParams, - () => - handleNavigateForward( - this.sessions, - req.params as NavigateForwardParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } - : undefined, - ), - signal, - ); - case "tool.reload": - return this.withHoverReleaseForRequest( - req.params as ReloadParams, - () => - handleReload( - this.sessions, - req.params as ReloadParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } - : undefined, - ), - signal, - ); - case "tool.click": - return this.withHoverReassert( - req.params as ClickParams, - () => - handleClick( - this.sessions, - req.params as ClickParams, - this.cdp - ? { - cdp: this.cdp, - tabsApi: chromeTabsApi, - signal, - bypassOverlay, - onInputSent, - } - : undefined, - ), - { releaseAfter: true }, - signal, - ); - case "tool.hover": { - const result = await handleHover( - this.sessions, - req.params as HoverParams, - this.cdp - ? { - cdp: this.cdp, - tabsApi: chromeTabsApi, - signal, - bypassOverlay: (tabId, enabled) => - this.setHoverBypass((req.params as HoverParams).session_id, tabId, enabled), - keepOverlayBypassAfterHover: true, - } - : undefined, - ); - return this.rememberHover((req.params as HoverParams).session_id, result); - } - case "tool.wheel": - return this.withHoverReassert( - req.params as WheelParams, - () => - handleWheel( - this.sessions, - req.params as WheelParams, - this.cdp - ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, bypassOverlay } - : undefined, - ), - { releaseAfter: true }, - signal, - ); - case "tool.scroll_to": - return this.withHoverReleaseForRequest( - req.params as ScrollToParams, - () => - handleScrollTo( - this.sessions, - req.params as ScrollToParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ), - signal, - ); - case "tool.focus": - return this.withHoverReleaseForRequest( - req.params as FocusParams, - () => - handleFocus( - this.sessions, - req.params as FocusParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ), - signal, - ); - case "tool.blur": - return this.withHoverReleaseForRequest( - req.params as BlurParams, - () => - handleBlur( - this.sessions, - req.params as BlurParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ), - signal, - ); - case "tool.fill": - return this.withHoverReleaseForRequest( - req.params as FillParams, - () => - handleFill( - this.sessions, - req.params as FillParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ), - signal, - ); - case "tool.press": - return this.withHoverReleaseForRequest( - req.params as PressParams, - () => - handlePress( - this.sessions, - req.params as PressParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, onInputSent } : undefined, - ), - signal, - ); - case "tool.select": - return this.withHoverReleaseForRequest( - req.params as SelectParams, - () => - handleSelect( - this.sessions, - req.params as SelectParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ), - signal, - ); - case "tool.upload": - return this.withHoverReleaseForRequest( - req.params as UploadParams, - () => + tabsApi: chromeTabsApi, + exports: this.screenshotExports, + }, + signal, + ); + }, + "tool.screenshot_read": async (params, signal, onInputSent) => { + return this.screenshotExports.read(params); + }, + "tool.screenshot_release": async (params, signal, onInputSent) => { + return this.screenshotExports.release(params); + }, + "tool.screenshot": async (params, signal, onInputSent) => { + return handleScreenshot( + this.sessions, + params, + this.cdp + ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi, captureApi: chromeTabsCaptureApi } + : undefined, + signal, + ); + }, + "tool.console": async (params, signal, onInputSent) => { + return handleConsole( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi } : undefined, + signal, + ); + }, + "tool.network": async (params, signal, onInputSent) => { + return handleNetwork( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi } : undefined, + signal, + ); + }, + "tool.snapshot": async (params, signal, onInputSent) => { + return this.withHoverReassert( + params, + () => + handleSnapshot( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi } : undefined, + signal, + ), + {}, + signal, + ); + }, + "tool.observe": async (params, signal, onInputSent) => { + const hoverScope = await this.resolveHoverLatchScope(params); + throwIfDispatchAborted(signal); + return this.withHoverReassert( + params, + () => + handleObserve( + this.sessions, + params, this.cdp - ? handleUpload(this.sessions, req.params as UploadParams, { + ? { cdp: this.cdp, - tabsApi: chromeTabsApi, - signal, - bypassOverlay, - }) - : Promise.resolve({ - code: "unsupported", - message: "upload requires CDP", - } satisfies RpcError), - signal, - ); - case "tool.download": - return this.withHoverReleaseForRequest( - req.params as DownloadParams, - () => + tabsApi: chromeTabsCaptureApi, + // Active hover probing is opt-in. A held hover latch still + // suppresses it, because probing would move the cursor off + // the element the caller is deliberately holding. + conditionalSurfaceProbe: + params.probe_hover === true && !this.hasHoverLatchForScope(hoverScope), + hoverProbeBypassOverlay: bypassOverlay, + } + : undefined, + signal, + ), + {}, + signal, + ); + }, + "tool.get_html": async (params, signal, onInputSent) => { + return handleGetHtml( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsCaptureApi } : undefined, + signal, + ); + }, + "tool.navigate": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleNavigate( + this.sessions, + params, this.cdp - ? handleDownload(this.sessions, req.params as DownloadParams, { + ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } + : undefined, + ), + signal, + ); + }, + "tool.navigate_back": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleNavigateBack( + this.sessions, + params, + this.cdp + ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } + : undefined, + ), + signal, + ); + }, + "tool.navigate_forward": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleNavigateForward( + this.sessions, + params, + this.cdp + ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } + : undefined, + ), + signal, + ); + }, + "tool.reload": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleReload( + this.sessions, + params, + this.cdp + ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, backgroundExecution: true } + : undefined, + ), + signal, + ); + }, + "tool.click": async (params, signal, onInputSent) => { + return this.withHoverReassert( + params, + () => + handleClick( + this.sessions, + params, + this.cdp + ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, bypassOverlay, - }) - : Promise.resolve({ - code: "unsupported", - message: "download requires CDP", - } satisfies RpcError), - signal, - ); - case "tool.evaluate": - return handleEvaluate( - this.sessions, - req.params as EvaluateParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ); - case "tool.wait_for_navigation": - return handleWaitForNavigation( - this.sessions, - req.params as WaitForNavigationParams, - this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, - ); - case "tool.request_help": - return handleRequestHelp(this.sessions, req.params as RequestHelpParams, { - preferences: this.interactionPreferences, - tabsApi: chromeTabsApi, - windows: { update: (id, info) => chrome.windows.update(id, info) }, - activateTab: async (tabId) => { - await chrome.tabs.update(tabId, { active: true }); - }, - sendToTab: (tabId, msg) => chrome.tabs.sendMessage(tabId, msg), - ...(this.cdp ? { cdp: this.cdp } : {}), - notifications: makeHelpNotifications(), - notificationCopy: this.helpNotificationCopy?.(), - signal, - }); - case "tool.record_start": - return this.recording - ? handleRecordStart(this.sessions, req.params as RecordStartParams, { - ...this.recording, - signal, - }) - : recordingRuntimeUnavailable(); - case "tool.record_stop": - return this.recording - ? handleRecordStop(this.sessions, req.params as RecordStopParams, { - ...this.recording, - signal, - }) - : recordingRuntimeUnavailable(); - case "tool.record_await": - return this.recording - ? handleRecordAwait(this.sessions, req.params as RecordAwaitParams, { - ...this.recording, + onInputSent, + } + : undefined, + ), + { releaseAfter: true }, + signal, + ); + }, + "tool.hover": async (params, signal, onInputSent) => { + const result = await handleHover( + this.sessions, + params, + this.cdp + ? { + cdp: this.cdp, + tabsApi: chromeTabsApi, signal, - }) - : recordingRuntimeUnavailable(); - default: - return { - code: "unknown_method", - message: `${req.method} not implemented in extension`, - } satisfies RpcError; - } + bypassOverlay: (tabId, enabled) => + this.setHoverBypass(params.session_id, tabId, enabled), + keepOverlayBypassAfterHover: true, + } + : undefined, + ); + return this.rememberHover(params.session_id, result); + }, + "tool.wheel": async (params, signal, onInputSent) => { + return this.withHoverReassert( + params, + () => + handleWheel( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, bypassOverlay } : undefined, + ), + { releaseAfter: true }, + signal, + ); + }, + "tool.scroll_to": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleScrollTo( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ), + signal, + ); + }, + "tool.focus": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleFocus( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ), + signal, + ); + }, + "tool.blur": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleBlur( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ), + signal, + ); + }, + "tool.fill": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleFill( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ), + signal, + ); + }, + "tool.press": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handlePress( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal, onInputSent } : undefined, + ), + signal, + ); + }, + "tool.select": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + handleSelect( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ), + signal, + ); + }, + "tool.upload": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + this.cdp + ? handleUpload(this.sessions, params, { + cdp: this.cdp, + tabsApi: chromeTabsApi, + signal, + bypassOverlay, + }) + : Promise.resolve({ + code: "unsupported", + message: "upload requires CDP", + } satisfies RpcError), + signal, + ); + }, + "tool.download": async (params, signal, onInputSent) => { + return this.withHoverReleaseForRequest( + params, + () => + this.cdp + ? handleDownload(this.sessions, params, { + cdp: this.cdp, + tabsApi: chromeTabsApi, + signal, + bypassOverlay, + }) + : Promise.resolve({ + code: "unsupported", + message: "download requires CDP", + } satisfies RpcError), + signal, + ); + }, + "tool.evaluate": async (params, signal, onInputSent) => { + return handleEvaluate( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ); + }, + "tool.wait_for_navigation": async (params, signal, onInputSent) => { + return handleWaitForNavigation( + this.sessions, + params, + this.cdp ? { cdp: this.cdp, tabsApi: chromeTabsApi, signal } : undefined, + ); + }, + "tool.request_help": async (params, signal, onInputSent) => { + return handleRequestHelp(this.sessions, params, { + preferences: this.interactionPreferences, + tabsApi: chromeTabsApi, + windows: { update: (id, info) => chrome.windows.update(id, info) }, + activateTab: async (tabId) => { + await chrome.tabs.update(tabId, { active: true }); + }, + sendToTab: (tabId, msg) => chrome.tabs.sendMessage(tabId, msg), + ...(this.cdp ? { cdp: this.cdp } : {}), + notifications: makeHelpNotifications(), + notificationCopy: this.helpNotificationCopy?.(), + signal, + }); + }, + "tool.record_start": async (params, signal, onInputSent) => { + return this.recording + ? handleRecordStart(this.sessions, params, { + ...this.recording, + signal, + }) + : recordingRuntimeUnavailable(); + }, + "tool.record_stop": async (params, signal, onInputSent) => { + return this.recording + ? handleRecordStop(this.sessions, params, { + ...this.recording, + signal, + }) + : recordingRuntimeUnavailable(); + }, + "tool.record_await": async (params, signal, onInputSent) => { + return this.recording + ? handleRecordAwait(this.sessions, params, { + ...this.recording, + signal, + }) + : recordingRuntimeUnavailable(); + }, + }; + + private async invoke( + req: ToolRequest, + signal: AbortSignal, + onInputSent?: (tabId: number) => void, + ): Promise | RpcError> { + const preparationError = await prepareBackgroundExecution( + this.sessions, + req, + this.cdp, + chromeTabsApi, + signal, + ); + if (preparationError) return preparationError; + + return this.handlers[req.method](req.params, signal, onInputSent); } private async setHoverBypass(sessionId: string, tabId: number, enabled: boolean): Promise { @@ -992,47 +990,8 @@ function recordingRuntimeUnavailable(): RpcError { }; } -function sessionIdForBrowserControlMethod(req: RequestFrame): string | null { - if (req.method === "tool.debug") { - const params = req.params as DebugParams | undefined; - return params && ["rule_add", "rule_enable", "replay"].includes(params.action) - ? params.session_id - : null; - } - switch (req.method) { - case "tool.tab_create": - case "tool.tab_close": - case "tool.tab_select": - case "tool.tab_borrow": - case "tool.tab_return": - case "tool.window_resize": - case "tool.emulate": - case "tool.navigate": - case "tool.navigate_back": - case "tool.navigate_forward": - case "tool.reload": - case "tool.click": - case "tool.hover": - case "tool.wheel": - case "tool.scroll_to": - case "tool.focus": - case "tool.blur": - case "tool.fill": - case "tool.press": - case "tool.select": - case "tool.upload": - case "tool.download": - case "tool.evaluate": - case "tool.observe": - case "tool.screenshot_full_page": - case "tool.request_help": - case "tool.record_start": { - const sessionId = (req.params as { session_id?: unknown } | undefined)?.session_id; - return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : null; - } - default: - return null; - } +function sessionIdForBrowserControlMethod(req: ToolRequest): string | null { + return resumesBrowserControl(req.method, req.params) ? req.params.session_id : null; } async function bypassOverlay(tabId: number, enabled: boolean): Promise { diff --git a/apps/extension/src/tools/policy.ts b/apps/extension/src/tools/policy.ts new file mode 100644 index 000000000..099f0794b --- /dev/null +++ b/apps/extension/src/tools/policy.ts @@ -0,0 +1,281 @@ +import { debugActions, type ExtensionToolMethod, methods } from "@/transport/generated/methods"; + +export interface ToolPolicy { + background: "none" | "accessible" | "controlled" | "navigation"; + resumeControl: "effect" | "always"; + opensTabs: boolean; + remoteAllowed: boolean; +} + +// Every extension method must deliberately select each local execution policy. +export const TOOL_POLICIES = { + "tool.session_start": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.session_stop": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.window_resize": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.emulate": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_list": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_create": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_close": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_borrow": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_return": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.tab_select": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.navigate": { + background: "navigation", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.navigate_back": { + background: "navigation", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.navigate_forward": { + background: "navigation", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.reload": { + background: "navigation", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.click": { + background: "controlled", + resumeControl: "effect", + opensTabs: true, + remoteAllowed: true, + }, + "tool.hover": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.wheel": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.scroll_to": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.focus": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.blur": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.fill": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.press": { + background: "controlled", + resumeControl: "effect", + opensTabs: true, + remoteAllowed: true, + }, + "tool.select": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.upload": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: false, + }, + "tool.download": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: false, + }, + "tool.snapshot": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.observe": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.get_html": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.screenshot": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.screenshot_full_page": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.screenshot_read": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.screenshot_release": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.console": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.debug": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.network": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.evaluate": { + background: "accessible", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.wait_for_navigation": { + background: "controlled", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.request_help": { + background: "none", + resumeControl: "always", + opensTabs: false, + remoteAllowed: true, + }, + "tool.record_start": { + background: "none", + resumeControl: "always", + opensTabs: false, + remoteAllowed: true, + }, + "tool.record_stop": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, + "tool.record_await": { + background: "none", + resumeControl: "effect", + opensTabs: false, + remoteAllowed: true, + }, +} satisfies Record; + +export function toolPolicy(method: string): ToolPolicy | undefined { + return Object.hasOwn(TOOL_POLICIES, method) + ? TOOL_POLICIES[method as ExtensionToolMethod] + : undefined; +} + +const effects = new Map(methods.map((method) => [method.method, method.effect])); + +export function resumesBrowserControl(method: ExtensionToolMethod, params: unknown): boolean { + if (method !== "tool.debug") { + const effect = effects.get(method); + return ( + TOOL_POLICIES[method].resumeControl === "always" || + effect === "browser_mutation" || + effect === "transient_input" + ); + } + const action = (params as { action?: unknown } | undefined)?.action; + return debugActions.some( + (definition) => definition.action === action && definition.effect === "browser_mutation", + ); +} diff --git a/apps/extension/src/tools/session.ts b/apps/extension/src/tools/session.ts index d398945c0..7ccb031f9 100644 --- a/apps/extension/src/tools/session.ts +++ b/apps/extension/src/tools/session.ts @@ -5,13 +5,21 @@ import { } from "@/lib/interaction-preferences"; import { withTaskPreviewStop } from "@/lib/task-preview"; import { type SessionManager, SessionStartCleanupError } from "@/session-manager/manager"; -import type { InteractionPolicy, RpcError } from "@/transport/types"; +import type { + SessionStartParams as ProtocolSessionStartParams, + RpcError, + SessionStartResult, + SessionStopParams, + SessionStopResult, +} from "@/transport/types"; import { rpcError } from "./errors"; import { clearRecordingForSession } from "./record"; import type { CdpRunner, ChromeTabsApi } from "./shared"; import { isRpcError } from "./shared"; import { chromeAgentOverlayResetApi, returnBorrowedTab, type TabManagementDeps } from "./tabs"; +export type { SessionStartResult, SessionStopParams, SessionStopResult } from "@/transport/types"; + /** Valid range for Agent Window dimensions in CSS pixels. */ export const WINDOW_SIZE_MIN = 100; export const WINDOW_SIZE_MAX = 7680; @@ -50,48 +58,16 @@ export function validateWindowSize( } return { width: width as number, height: height as number }; } - -export interface SessionStartParams { - session_id: string; - browser_instance_id?: string; - /** Optional Agent Window outer width in CSS pixels (100..=7680). */ - width?: number; - /** Optional Agent Window outer height in CSS pixels (100..=7680). */ - height?: number; - /** Defaults to true so existing clients preserve visible Agent Windows. */ - focused?: boolean; - /** Legacy input accepted for compatibility; browser settings always decide. */ +/** Legacy input remains accepted at the handler boundary. */ +export interface SessionStartParams extends ProtocolSessionStartParams { unattended?: boolean; } -export interface SessionStartResult { - interaction?: InteractionPolicy; - agent_window_id?: number; -} - export interface SessionStartDeps { preferences?: InteractionPreferenceStore; signal?: AbortSignal; } -export interface SessionStopParams { - session_id: string; -} - -export interface SessionStopResult { - /** Tab ids that were returned to their original (or fallback) window. */ - returned_tab_ids?: number[]; - /** Tab ids whose return path failed; those entries remain borrowed so - * shutdown can be retried without closing the Agent Window. */ - return_failures?: Array<{ tab_id: number; code: string; message: string }>; - /** - * True when the Agent Window was *released* to the user (instead of being - * closed) because it still contained user-created tabs after the agent's own - * tabs were closed. Single-session scope. - */ - window_released?: boolean; -} - export interface SessionStopDeps { signal?: AbortSignal; cdp?: Pick & { diff --git a/apps/extension/src/tools/tabs.ts b/apps/extension/src/tools/tabs.ts index 5d30fa2b4..63771bc9b 100644 --- a/apps/extension/src/tools/tabs.ts +++ b/apps/extension/src/tools/tabs.ts @@ -1,4 +1,38 @@ import { withUiTeardown } from "@/session-manager/ui-activity"; +import type { + TabBorrowParams, + TabBorrowResult, + TabCloseParams, + TabCloseResult, + TabCreateParams, + TabCreateResult, + TabInfo, + TabListParams, + TabListResult, + TabReturnParams, + TabReturnResult, + TabScope, + TabSelectParams, + TabSelectResult, +} from "@/transport/types"; + +export type { + TabBorrowParams, + TabBorrowResult, + TabCloseParams, + TabCloseResult, + TabCreateParams, + TabCreateResult, + TabInfo, + TabListParams, + TabListResult, + TabReturnParams, + TabReturnResult, + TabScope, + TabSelectParams, + TabSelectResult, +} from "@/transport/types"; + // Tab-tool handlers. M6 wired `tool.tab_list`; M8 adds the rest of // the tab namespace: `tab_create`, `tab_close`, `tab_select`, // `tab_borrow`, `tab_return`. The dispatcher routes each method to a @@ -18,98 +52,6 @@ import type { RpcError } from "@/transport/types"; import { rpcError } from "./errors"; import { type CdpRunner, cdpBlockedUrlReason, isRpcError, lookupSession } from "./shared"; -export type TabScope = "user" | "agent" | "all"; - -/** - * Mirror of bsk-protocol `TabInfo` (see - * crates/bsk-protocol/src/tools/tabs.rs). - */ -export interface TabInfo { - tab_id: number; - title?: string; - url?: string; - window_id?: number; - active?: boolean; - /** - * Where the tab sits relative to the requesting session: tabs in any - * window other than an Agent Window are `user`; tabs in this - * session's own Agent Window are `agent`. Tabs in *other* sessions' - * Agent Windows are filtered out entirely (cross-session isolation, - * design §6). - */ - scope?: "user" | "agent"; -} - -export interface TabListParams { - session_id: string; - scope?: TabScope; -} - -export interface TabListResult { - tabs: TabInfo[]; -} - -// --- M8 payload mirrors (bsk-protocol/src/tools/tabs.rs) --- - -export interface TabCreateParams { - session_id: string; - url?: string; - active?: boolean; - index?: number; -} - -export interface TabCreateResult { - tab_id: number; - window_id: number; - url: string; -} - -export interface TabCloseParams { - session_id: string; - tab_id: number; -} - -export interface TabCloseResult { - tab_id: number; -} - -export interface TabSelectParams { - session_id: string; - tab_id: number; -} - -export interface TabSelectResult { - tab_id: number; - window_id: number; -} - -export interface TabBorrowParams { - session_id: string; - tab_id: number; - /** Legacy input, ignored. The browser preference decides confirmation. */ - confirm?: boolean; - confirmation_timeout_ms?: number; -} - -export interface TabBorrowResult { - tab_id: number; - original_window_id: number; - original_index: number; - agent_window_id: number; -} - -export interface TabReturnParams { - session_id: string; - tab_id: number; -} - -export interface TabReturnResult { - tab_id: number; - returned_to_window_id: number; - returned_to_index: number; - fallback?: boolean; -} - const TAB_SCOPES = new Set(["user", "agent", "all"]); /** Default URL used when `tool.tab_create` is called with no `url`. */ diff --git a/apps/extension/src/tools/window.ts b/apps/extension/src/tools/window.ts index ccec54e6a..0bd7bdde3 100755 --- a/apps/extension/src/tools/window.ts +++ b/apps/extension/src/tools/window.ts @@ -1,3 +1,7 @@ +import type { WindowResizeParams, WindowResizeResult } from "@/transport/types"; + +export type { WindowResizeParams, WindowResizeResult } from "@/transport/types"; + // Window-tool handlers: `tool.window_resize` resizes the session's // Agent Window via `chrome.windows.update`. @@ -6,22 +10,6 @@ import type { RpcError } from "@/transport/types"; import { validateWindowSize } from "./session"; import { isRpcError, lookupSession } from "./shared"; -/** - * Mirror of bsk-protocol `WindowResizeParams` / - * `WindowResizeResult` (see crates/bsk-protocol/src/tools/window.rs). - */ -export interface WindowResizeParams { - session_id: string; - width: number; - height: number; -} - -export interface WindowResizeResult { - window_id: number; - width: number; - height: number; -} - /** * Subset of `chrome.windows` we depend on, injectable so unit tests * can fake the browser without monkey-patching the global `chrome`. diff --git a/apps/extension/src/transport/generated/input.ts b/apps/extension/src/transport/generated/input.ts new file mode 100644 index 000000000..f9a98494d --- /dev/null +++ b/apps/extension/src/transport/generated/input.ts @@ -0,0 +1,3242 @@ +// Generated by scripts/protocol.mjs from bsk-protocol. Do not edit. + +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "AnyValue". + */ +export type AnyValue = unknown; +/** + * How the extension resolved the dialog so CDP could continue. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "JavaScriptDialogHandledAction". + */ +export type JavaScriptDialogHandledAction = "accepted" | "dismissed"; +/** + * Native JS dialog kind reported by CDP. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "JavaScriptDialogType". + */ +export type JavaScriptDialogType = "alert" | "confirm" | "prompt" | "beforeunload"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BorrowConfirmationPolicy". + */ +export type BorrowConfirmationPolicy = "always" | "never"; +/** + * Mouse button selector for `tool.click`. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "MouseButton". + */ +export type MouseButton = "left" | "middle" | "right"; +/** + * Keyboard modifier flags. Multiple flags may be combined; the + * extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, + * shift=8`). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "KeyModifier". + */ +export type KeyModifier = "alt" | "ctrl" | "meta" | "shift"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ConsoleEntryKind". + */ +export type ConsoleEntryKind = "console" | "exception" | "log"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugAction". + */ +export type DebugAction = + | "performance" + | "aggregate" + | "duplicates" + | "capabilities" + | "activity" + | "wait" + | "pin" + | "unpin" + | "start" + | "stop" + | "status" + | "requests" + | "request" + | "operations" + | "operation" + | "console" + | "pages" + | "export" + | "rules" + | "rule_add" + | "rule_enable" + | "rule_disable" + | "rule_remove" + | "replay"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugInterventionKind". + */ +export type DebugInterventionKind = "block" | "modify" | "mock"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugOperationState". + */ +export type DebugOperationState = "running" | "completed" | "error" | "interrupted"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRuleEffect". + */ +export type DebugRuleEffect = + | { + type: "block"; + } + | { + body?: string; + headers?: { + [k: string]: string | null; + }; + json?: DebugJsonEdit; + method?: string; + type: "modify"; + url?: string; + } + | { + body: string; + delay_ms?: number; + headers?: { + [k: string]: string; + }; + status: number; + type: "mock"; + }; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRuleState". + */ +export type DebugRuleState = "enabled" | "disabled" | "exhausted" | "removed" | "stopped"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRunState". + */ +export type DebugRunState = "capturing" | "stopped"; +/** + * Stable daemon/extension error codes (§4.5). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ErrorCode". + */ +export type ErrorCode = + | "unknown_method" + | "unsupported" + | "invalid_params" + | "not_found" + | "permission_denied" + | "timeout" + | "cdp_failed" + | "protocol_error" + | "cancelled" + | "user_aborted" + | "version_too_old" + | "multiple_browsers_online" + | "no_browser_connected"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "FillCommit". + */ +export type FillCommit = "enter" | "suggestion" | "blur"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HelpCompletedBy". + */ +export type HelpCompletedBy = "system"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HelpOutcome". + */ +export type HelpOutcome = + "continued" | "cancelled" | "timed_out" | "completed" | "navigated" | "disabled"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RequestHelpPolicy". + */ +export type RequestHelpPolicy = "enabled" | "disabled"; +/** + * Page-lifecycle checkpoint a navigation should wait on. + * + * Mapping to CDP `Page.lifecycleEvent` names: + * * `Load` → `load` + * * `DomContentLoaded` → `DOMContentLoaded` + * * `NetworkIdle` → `networkIdle` + * * `Commit` → `commit` (earliest event after the navigation actually + * commits to a new document) + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitUntil". + */ +export type WaitUntil = "load" | "domcontentloaded" | "networkidle" | "commit"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigationCause". + */ +export type NavigationCause = + "user_typed" | "link" | "form_submit" | "reload" | "history" | "script" | "browser"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NetworkEntryKind". + */ +export type NetworkEntryKind = "response" | "failure"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordedTrace". + */ +export type RecordedTrace = TraceV3 | TraceV2; +/** + * One recorded user action — discriminated union by `op`. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StepV3". + */ +export type StepV3 = + | { + cause: NavigationCause; + id: number; + op: "navigate"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + to: string; + } + | { + id: number; + op: "switch_tab"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + } + | { + id: number; + op: "click"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + target: TargetDescriptorV3; + } + | { + id: number; + op: "hover"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + target: TargetDescriptorV3; + } + | { + commit: FillCommit; + id: number; + op: "fill"; + redacted?: boolean; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + target: TargetDescriptorV3; + value: string; + } + | { + id: number; + op: "select"; + result: StepResultV3; + selection?: SelectedOptionV3[]; + /** + * Observation id immediately before this action. + */ + state: string; + target: TargetDescriptorV3; + } + | { + id: number; + key: string; + modifiers?: KeyModifier[]; + op: "press"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + target?: TargetDescriptorV3; + } + | { + id: number; + op: "scroll"; + result: StepResultV3; + /** + * Observation id immediately before this action. + */ + state: string; + }; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StopReason". + */ +export type StopReason = "user_finish" | "cli_stop"; +/** + * One recorded user action — discriminated union by `op` (v2). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StepV2". + */ +export type StepV2 = + | { + effect?: StepEffectV2; + id: number; + op: "navigate"; + /** + * Reference into `pages[]`. + */ + page: string; + to: string; + } + | { + effect?: StepEffectV2; + id: number; + op: "click"; + /** + * Reference into `pages[]`. + */ + page: string; + target: TargetDescriptorV2; + } + | { + effect?: StepEffectV2; + id: number; + op: "hover"; + /** + * Reference into `pages[]`. + */ + page: string; + target: TargetDescriptorV2; + } + | { + effect?: StepEffectV2; + id: number; + op: "fill"; + /** + * Reference into `pages[]`. + */ + page: string; + redacted?: boolean; + target: TargetDescriptorV2; + value: string; + } + | { + effect?: StepEffectV2; + id: number; + op: "select"; + /** + * Reference into `pages[]`. + */ + page: string; + selection: SelectedOptionV2[]; + target: TargetDescriptorV2; + } + | { + effect?: StepEffectV2; + id: number; + key: string; + modifiers?: KeyModifier[]; + op: "press"; + /** + * Reference into `pages[]`. + */ + page: string; + target?: TargetDescriptorV2; + }; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordedStep". + */ +export type RecordedStep = StepV3 | StepV2; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotScope". + */ +export type ScreenshotScope = "follow" | "current"; +/** + * View scope for [`TabListParams`] (§6 sandbox table). + * + * * `User` — tabs that live in any window other than an Agent Window. + * * `Agent` — tabs in the requesting session's Agent Window only. + * * `All` — both of the above; never reveals other sessions' Agent + * Windows (cross-session isolation per §6). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabScope". + */ +export type TabScope = "user" | "agent" | "all"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UploadMode". + */ +export type UploadMode = "input" | "drop"; +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitForNavigationReached". + */ +export type WaitForNavigationReached = + "load" | "domcontentloaded" | "networkidle" | "commit" | "timeout"; + +export interface ProtocolTypes { + AnyValue: AnyValue; + BlurParams: BlurParams; + BlurResult: BlurResult; + BorrowConfirmationPolicy: BorrowConfirmationPolicy; + BrowserListParams: BrowserListParams; + BrowserPeerInfo: BrowserPeerInfo; + BrowserStatusEntry: BrowserStatusEntry; + CancelParams: CancelParams; + CancelResult: CancelResult; + ClickParams: ClickParams; + ClickResult: ClickResult; + ConsoleEntry: ConsoleEntry; + ConsoleEntryKind: ConsoleEntryKind; + ConsoleParams: ConsoleParams; + ConsoleResult: ConsoleResult; + ConsoleStackFrame: ConsoleStackFrame; + DebugAction: DebugAction; + DebugActivity: DebugActivity; + DebugAnalysis: DebugAnalysis; + DebugBody: DebugBody; + DebugConsole: DebugConsole; + DebugDuplicate: DebugDuplicate; + DebugDurationStats: DebugDurationStats; + DebugEndpoint: DebugEndpoint; + DebugEvidence: DebugEvidence; + DebugField: DebugField; + DebugFieldTrace: DebugFieldTrace; + DebugIntervention: DebugIntervention; + DebugInterventionKind: DebugInterventionKind; + DebugJsonEdit: DebugJsonEdit; + DebugLongTask: DebugLongTask; + DebugMetric: DebugMetric; + DebugOperation: DebugOperation; + DebugOperationState: DebugOperationState; + DebugOutput: DebugOutput; + DebugPage: DebugPage; + DebugParams: DebugParams; + DebugPayload: DebugPayload; + DebugPerformance: DebugPerformance; + DebugRecording: DebugRecording; + DebugReplay: DebugReplay; + DebugReplaySpec: DebugReplaySpec; + DebugRequest: DebugRequest; + DebugRequestIntegrity: DebugRequestIntegrity; + DebugRequestLink: DebugRequestLink; + DebugResult: DebugResult; + DebugRule: DebugRule; + DebugRuleEffect: DebugRuleEffect; + DebugRuleMatch: DebugRuleMatch; + DebugRuleSpec: DebugRuleSpec; + DebugRuleState: DebugRuleState; + DebugRun: DebugRun; + DebugRunState: DebugRunState; + DebugStorage: DebugStorage; + DebugTextChanges: DebugTextChanges; + DebugValue: DebugValue; + DebugVisibility: DebugVisibility; + DownloadParams: DownloadParams; + DownloadResult: DownloadResult; + EmulateOverrides: EmulateOverrides; + EmulateParams: EmulateParams; + EmulateResult: EmulateResult; + ErrorCode: ErrorCode; + EvaluateError: EvaluateError; + EvaluateParams: EvaluateParams; + EvaluateResult: EvaluateResult; + FillCommit: FillCommit; + FillParams: FillParams; + FillResult: FillResult; + FocusParams: FocusParams; + FocusResult: FocusResult; + GetHtmlParams: GetHtmlParams; + GetHtmlResult: GetHtmlResult; + HandshakeRequest: HandshakeRequest; + HandshakeResponse: HandshakeResponse; + HelpCompletedBy: HelpCompletedBy; + HelpCompletionCondition: HelpCompletionCondition; + HelpCompletionCriteria: HelpCompletionCriteria; + HelpOutcome: HelpOutcome; + HelpTarget: HelpTarget; + HoverParams: HoverParams; + HoverProbeReport: HoverProbeReport; + HoverResult: HoverResult; + InteractionPolicy: InteractionPolicy; + JavaScriptDialogHandledAction: JavaScriptDialogHandledAction; + JavaScriptDialogInfo: JavaScriptDialogInfo; + JavaScriptDialogType: JavaScriptDialogType; + KeyModifier: KeyModifier; + MouseButton: MouseButton; + NavigateBackParams: NavigateBackParams; + NavigateBackResult: NavigateBackResult; + NavigateForwardParams: NavigateForwardParams; + NavigateForwardResult: NavigateForwardResult; + NavigateParams: NavigateParams; + NavigateResult: NavigateResult; + NavigationCause: NavigationCause; + NetworkEntry: NetworkEntry; + NetworkEntryKind: NetworkEntryKind; + NetworkParams: NetworkParams; + NetworkResult: NetworkResult; + ObserveDebug: ObserveDebug; + ObserveParams: ObserveParams; + ObserveResult: ObserveResult; + PageRefV2: PageRefV2; + PingParams: PingParams; + PingResult: PingResult; + PressParams: PressParams; + PressResult: PressResult; + RecordAwaitParams: RecordAwaitParams; + RecordAwaitResult: RecordAwaitResult; + RecordStartParams: RecordStartParams; + RecordStartResult: RecordStartResult; + RecordStopParams: RecordStopParams; + RecordStopResult: RecordStopResult; + RecordedStep: RecordedStep; + RecordedTrace: RecordedTrace; + RecorderInfo: RecorderInfo; + ReloadParams: ReloadParams; + ReloadResult: ReloadResult; + RequestHelpParams: RequestHelpParams; + RequestHelpPolicy: RequestHelpPolicy; + RequestHelpResult: RequestHelpResult; + ResolvedTarget: ResolvedTarget; + ReturnFailure: ReturnFailure; + RpcError: RpcError; + ScreenshotFullPageParams: ScreenshotFullPageParams; + ScreenshotFullPageResult: ScreenshotFullPageResult; + ScreenshotParams: ScreenshotParams; + ScreenshotReadParams: ScreenshotReadParams; + ScreenshotReadResult: ScreenshotReadResult; + ScreenshotReleaseParams: ScreenshotReleaseParams; + ScreenshotReleaseResult: ScreenshotReleaseResult; + ScreenshotResult: ScreenshotResult; + ScreenshotScope: ScreenshotScope; + ScrollToParams: ScrollToParams; + ScrollToResult: ScrollToResult; + SelectParams: SelectParams; + SelectResult: SelectResult; + SelectedOptionV2: SelectedOptionV2; + SelectedOptionV3: SelectedOptionV3; + SessionStartParams: SessionStartParams; + SessionStartResult: SessionStartResult; + SessionStatusEntry: SessionStatusEntry; + SessionStopOutcome: SessionStopOutcome; + SessionStopParams: SessionStopParams; + SnapshotParams: SnapshotParams; + SnapshotResult: SnapshotResult; + StatusParams: StatusParams; + StatusResult: StatusResult; + StepEffectV2: StepEffectV2; + StepResultV3: StepResultV3; + StepV2: StepV2; + StepV3: StepV3; + StopReason: StopReason; + SurfaceProbeDebug: SurfaceProbeDebug; + SurfaceProbePoint: SurfaceProbePoint; + TabBorrowParams: TabBorrowParams; + TabBorrowResult: TabBorrowResult; + TabCloseParams: TabCloseParams; + TabCloseResult: TabCloseResult; + TabCreateParams: TabCreateParams; + TabCreateResult: TabCreateResult; + TabInfo: TabInfo; + TabListParams: TabListParams; + TabListResult: TabListResult; + TabReturnParams: TabReturnParams; + TabReturnResult: TabReturnResult; + TabScope: TabScope; + TabSelectParams: TabSelectParams; + TabSelectResult: TabSelectResult; + TargetDescriptorV2: TargetDescriptorV2; + TargetDescriptorV3: TargetDescriptorV3; + TraceEntry: TraceEntry; + TraceStateV3: TraceStateV3; + TraceV2: TraceV2; + TraceV3: TraceV3; + UploadFile: UploadFile; + UploadMode: UploadMode; + UploadParams: UploadParams; + UploadResult: UploadResult; + UserAgentBrandVersion: UserAgentBrandVersion; + UserAgentMetadata: UserAgentMetadata; + VersionSkewEntry: VersionSkewEntry; + WaitForNavigationParams: WaitForNavigationParams; + WaitForNavigationReached: WaitForNavigationReached; + WaitForNavigationResult: WaitForNavigationResult; + WaitMsParams: WaitMsParams; + WaitMsResult: WaitMsResult; + WaitUntil: WaitUntil; + WheelParams: WheelParams; + WheelResult: WheelResult; + WindowResizeParams: WindowResizeParams; + WindowResizeResult: WindowResizeResult; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BlurParams". + */ +export interface BlurParams { + /** + * Optional `@e` ref allocated by the last observation. + * Mutually exclusive with `selector`. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BlurResult". + */ +export interface BlurResult { + dialogs?: JavaScriptDialogInfo[]; + /** + * Always false for a successful blur; included for machine verification. + */ + focused: boolean; + tab_id: number; + used_ref?: string; + used_selector?: string; + /** + * Whether the target held focus before the call. + */ + was_focused: boolean; +} +/** + * One observed + handled JavaScript dialog during a tool call. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "JavaScriptDialogInfo". + */ +export interface JavaScriptDialogInfo { + default_prompt?: string; + handled: JavaScriptDialogHandledAction; + has_browser_handler?: boolean; + message: string; + /** + * Monotonic per-tab sequence for ordering within a session. + */ + sequence: number; + tab_id: number; + type: JavaScriptDialogType; + url?: string; +} +/** + * `browser.list` request payload. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BrowserListParams". + */ +export interface BrowserListParams { + /** + * When set, the daemon polls the browser registry for up to this many + * milliseconds before returning a list. Only applies while zero browsers + * are registered; an existing connection returns immediately. + */ + wait_for_browser_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BrowserPeerInfo". + */ +export interface BrowserPeerInfo { + name: string; + version: string; +} +/** + * Snapshot of a single connected extension (extension client view). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "BrowserStatusEntry". + */ +export interface BrowserStatusEntry { + browser_name: string; + browser_version: string; + /** + * Unix epoch milliseconds at which the extension completed the + * daemon handshake. Stable across reconnects only via the + * best-effort registry generation; clients should treat this as a + * rough "online since" hint, not a strong identity. + */ + connected_at_ms?: number; + /** + * Protocol version the extension advertised at handshake. + */ + extension_protocol_version?: string; + extension_version: string; + /** + * Stable id assigned by the extension; matches `HandshakeParams::instance_id`. + */ + instance_id: string; + label: string; + session_count: number; + /** + * The socket is still registered, but a call failed after this + * heartbeat-capable extension missed two heartbeats. Cleared when any + * frame arrives. + */ + unresponsive?: boolean; + /** + * `true` when the browser's `protocol_version` differs from the + * daemon's (same major, minor drift). Connection is still allowed. + */ + version_skew?: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "CancelParams". + */ +export interface CancelParams { + rpc_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "CancelResult". + */ +export interface CancelResult { + cancelled: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ClickParams". + */ +export interface ClickParams { + button?: MouseButton; + /** + * Single-use capture returned by a visual-ref screenshot; requires image coordinates. + */ + capture_id?: string; + /** + * Number of consecutive mouse presses (double-click = 2). + */ + click_count?: number; + image_x?: number; + image_y?: number; + modifiers?: KeyModifier[]; + /** + * Optional `@e` ref allocated by the last `tool.snapshot`. + * Mutually exclusive with `selector` (caller must supply exactly + * one). Accepts both `"e3"` and `"@e3"`. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ClickResult". + */ +export interface ClickResult { + /** + * Native JS dialogs observed and auto-handled during this call. + */ + dialogs?: JavaScriptDialogInfo[]; + tab_id: number; + used_ref?: string; + used_selector?: string; + /** + * Viewport-relative click coordinates (CSS pixels). Reported so + * agents can correlate with a follow-up `tool.screenshot`. + */ + x: number; + y: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ConsoleEntry". + */ +export interface ConsoleEntry { + column?: number; + kind: ConsoleEntryKind; + level: string; + line?: number; + sequence: number; + stack_trace?: ConsoleStackFrame[]; + text: string; + timestamp?: number; + truncated?: boolean; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ConsoleStackFrame". + */ +export interface ConsoleStackFrame { + column?: number; + function_name?: string; + line?: number; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ConsoleParams". + */ +export interface ConsoleParams { + /** + * Include structured stack frames. Defaults to false. + */ + include_stack?: boolean; + /** + * Maximum number of entries to return. Extension applies safe defaults and caps. + */ + limit?: number; + /** + * Maximum characters returned per entry text. Extension applies safe defaults and caps. + */ + max_text_chars?: number; + session_id: string; + /** + * Return entries with sequence strictly greater than this cursor. + */ + since?: number; + /** + * Optional target tab. Defaults to the Agent Window's currently active tab. + */ + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ConsoleResult". + */ +export interface ConsoleResult { + entries?: ConsoleEntry[]; + next_since: number; + tab_id: number; + truncated?: boolean; +} +/** + * Daemon-owned execution status. Waiting observes completion; it never resends a command. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugActivity". + */ +export interface DebugActivity { + command_id?: string; + elapsed_ms?: number; + method?: string; + started_at?: number; + state: string; + wait_complete?: boolean; + wait_timed_out?: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugAnalysis". + */ +export interface DebugAnalysis { + coverage: string[]; + excluded_controlled: number; + groups: number; + included: number; + matched: number; + retained: number; + semantics: string; + slow_ms: number; + suspected_extra_requests: number; + uncomparable: number; + window_ms: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugBody". + */ +export interface DebugBody { + chars?: number; + next_offset?: number; + offset?: number; + reason?: string; + redacted?: boolean; + /** + * True only for complete retained text identical to the captured body. + */ + replay_safe?: boolean; + state: string; + text?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugConsole". + */ +export interface DebugConsole { + at: number; + count: number; + id: string; + last_at: number; + level: string; + relation?: string; + source?: string; + source_url?: string; + stack?: string; + text: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugDuplicate". + */ +export interface DebugDuplicate { + count: number; + ended_at: number; + extra_requests: number; + id: string; + method: string; + operation_ids: string[]; + overlap_count: number; + possible_retry: boolean; + refs_truncated: boolean; + request_ids: string[]; + started_at: number; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugDurationStats". + */ +export interface DebugDurationStats { + max: number; + mean: number; + min: number; + p50: number; + p95: number; + total: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugEndpoint". + */ +export interface DebugEndpoint { + cached: number; + controlled: number; + count: number; + duration_ms?: DebugDurationStats; + endpoint: string; + failed: number; + http_errors: number; + id: string; + interrupted: number; + method: string; + pending: number; + refs_truncated: boolean; + replayed: number; + request_ids: string[]; + service_worker: number; + slow: number; + statuses: { + [k: string]: number; + }; + timing_samples: number; + transfer_bytes: number; + transfer_samples: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugEvidence". + */ +export interface DebugEvidence { + changes: DebugTextChanges; + fields: DebugFieldTrace[]; + gaps: string[]; + links: DebugRequestLink[]; + observations: DebugPage[]; + payloads: DebugPayload[]; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugTextChanges". + */ +export interface DebugTextChanges { + added: string[]; + removed: string[]; + truncated: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugFieldTrace". + */ +export interface DebugFieldTrace { + before: DebugValue; + input: DebugValue; + key: string; + label: string; + later: DebugValue; + response: DebugValue[]; + submitted: DebugValue[]; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugValue". + */ +export interface DebugValue { + at?: number; + source?: string; + state: string; + value?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRequestLink". + */ +export interface DebugRequestLink { + relation: string; + request_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugPage". + */ +export interface DebugPage { + at: number; + fields?: DebugField[]; + fields_partial?: boolean; + navigation?: string; + state: string; + text?: string; + title?: string; + truncated?: boolean; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugField". + */ +export interface DebugField { + key: string; + label: string; + name?: string; + state: string; + value?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugPayload". + */ +export interface DebugPayload { + part: string; + path: string; + request_id: string; + truncated?: boolean; + value: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugIntervention". + */ +export interface DebugIntervention { + changes?: string[]; + error?: string; + rule_id: string; + state: string; + type: DebugInterventionKind; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugJsonEdit". + */ +export interface DebugJsonEdit { + remove?: string[]; + rename?: { + [k: string]: string; + }; + set?: { + [k: string]: unknown; + }; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugLongTask". + */ +export interface DebugLongTask { + at: number; + duration_ms: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugMetric". + */ +export interface DebugMetric { + reasons: string[]; + state: string; + value?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugOperation". + */ +export interface DebugOperation { + after?: DebugPage; + before?: DebugPage; + console_ids: string[]; + error?: string; + finished_at?: number; + id: string; + method: string; + observation_end?: number; + observation_limited?: boolean; + observations?: DebugPage[]; + request_ids: string[]; + run_id: string; + sequence: number; + source?: string; + started_at: number; + state: DebugOperationState; + target?: string; + truncated: boolean; + window_end?: number; +} +/** + * Reports how the requested output budget affected a debug response. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugOutput". + */ +export interface DebugOutput { + budget: number; + omitted: string[]; + truncated: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugParams". + */ +export interface DebugParams { + action: DebugAction; + budget?: number; + command_id?: string; + fields?: string[]; + id?: string; + include_controlled?: boolean; + kind?: string; + limit?: number; + max_chars?: number; + method?: string; + name?: string; + offset?: number; + part?: string; + pointer?: string; + replay?: DebugReplaySpec; + resource_type?: string; + rule?: DebugRuleSpec; + run_id?: string; + session_id: string; + since?: number; + slow_ms?: number; + state?: string; + status?: number; + tab_id?: number; + url?: string; + wait_ms?: number; + window_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugReplaySpec". + */ +export interface DebugReplaySpec { + body?: string; + headers?: { + [k: string]: string | null; + }; + key: string; + method?: string; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRuleSpec". + */ +export interface DebugRuleSpec { + effect: DebugRuleEffect; + match: DebugRuleMatch; + name?: string; + times?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRuleMatch". + */ +export interface DebugRuleMatch { + method?: string; + resource_type?: string; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugPerformance". + */ +export interface DebugPerformance { + coverage: string[]; + document_key: string; + early: boolean; + id: string; + long_tasks: DebugLongTask[]; + long_tasks_truncated: boolean; + metrics: { + [k: string]: DebugMetric; + }; + navigation: string; + observed_at: number; + scope: string; + sequence: number; + started_at: number; + state: string; + time_origin: number; + url: string; + visibility: DebugVisibility[]; + visibility_truncated: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugVisibility". + */ +export interface DebugVisibility { + at: number; + state: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRecording". + */ +export interface DebugRecording { + console: DebugConsole[]; + operations: DebugOperation[]; + pages: DebugPage[]; + performance?: DebugPerformance[]; + replays?: DebugReplay[]; + requests: DebugRequest[]; + rules?: DebugRule[]; + run: DebugRun; + saved_at: number; + version: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugReplay". + */ +export interface DebugReplay { + error?: string; + id: string; + key: string; + request_id?: string; + source_request_id: string; + state: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRequest". + */ +export interface DebugRequest { + decoded_bytes?: number; + duration_ms?: number; + error?: string; + finished_at?: number; + frame_id?: string; + from_cache?: boolean; + from_service_worker?: boolean; + id: string; + initiator?: string; + integrity?: DebugRequestIntegrity; + intervention?: DebugIntervention; + loader_id?: string; + method: string; + mime_type?: string; + pinned?: boolean; + redirect_from?: string; + replay_from?: string; + replay_id?: string; + request_body: DebugBody; + request_headers?: { + [k: string]: string; + }; + resource_type?: string; + response_body: DebugBody; + response_headers?: { + [k: string]: string; + }; + run_id: string; + sequence: number; + started_at: number; + state: string; + status?: number; + timing?: { + [k: string]: number; + }; + transfer_bytes?: number; + truncated?: boolean; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRequestIntegrity". + */ +export interface DebugRequestIntegrity { + /** + * Request metadata needed for replay; excludes response headers. + */ + metadata: string; + response_headers?: string; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRule". + */ +export interface DebugRule { + created_at: number; + effect: DebugRuleEffect; + failures: number; + hits: number; + id: string; + last_error?: string; + match: DebugRuleMatch; + name?: string; + state: DebugRuleState; + times?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugRun". + */ +export interface DebugRun { + active_rules?: number; + coverage: string[]; + dropped_console: number; + dropped_operations: number; + dropped_requests: number; + environment?: { + [k: string]: string; + }; + errors: number; + id: string; + name: string; + next_since: number; + operations: number; + requests: number; + saved_at?: number; + session_id: string; + started_at: number; + state: DebugRunState; + stop_reason?: string; + stopped_at?: number; + storage?: DebugStorage; + storage_error?: string; + tab_id: number; + url: string; +} +/** + * Bounded local retention statistics included in debug run metadata. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugStorage". + */ +export interface DebugStorage { + bytes: number; + dropped: number; + pins: number; + requests: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DebugResult". + */ +export interface DebugResult { + activity?: DebugActivity; + aggregates?: DebugEndpoint[]; + analysis?: DebugAnalysis; + capabilities?: unknown; + console?: DebugConsole[]; + duplicates?: DebugDuplicate[]; + evidence?: DebugEvidence; + next_offset?: number; + next_since?: number; + operation?: DebugOperation; + operations?: DebugOperation[]; + output?: DebugOutput; + pages?: DebugPage[]; + performance?: DebugPerformance[]; + recording?: DebugRecording; + replay?: DebugReplay; + replays?: DebugReplay[]; + request?: DebugRequest; + requests?: DebugRequest[]; + rules?: DebugRule[]; + run?: DebugRun; + runs?: DebugRun[]; + session_id: string; + truncated?: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DownloadParams". + */ +export interface DownloadParams { + /** + * Daemon-injected relative directory beneath Chrome's Downloads root. + */ + browser_relative_dir?: string; + /** + * Daemon-injected authoritative transfer size limit. The extension uses + * it only for early cancellation; daemon import remains the final check. + */ + max_byte_size?: number; + ref?: string; + selector?: string; + session_id: string; + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "DownloadResult". + */ +export interface DownloadResult { + /** + * Extension-internal completed Chrome download path, stripped by the daemon. + */ + browser_path?: string; + byte_size: number; + danger?: string; + mime?: string; + suggested_filename: string; + tab_id: number; + /** + * Opaque id returned by the daemon to the CLI. + */ + transfer_id?: string; + used_ref?: string; + used_selector?: string; +} +/** + * Concrete emulation overrides for one tab. Field presence drives the + * extension: only the overrides whose fields are set are touched, so a + * call may change just the UA, just the viewport, or any combination. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EmulateOverrides". + */ +export interface EmulateOverrides { + /** + * `Accept-Language` header override. Requires `user_agent`. + */ + accept_language?: string; + /** + * Device scale factor (device pixel ratio). Only meaningful with + * `width`/`height`; the extension maps `None` to CDP's `0` + * ("use the display's native factor"). + */ + device_scale_factor?: number; + /** + * Viewport height in CSS pixels. Requires `width`. + */ + height?: number; + /** + * Touch points reported while touch emulation is on (CDP defaults + * to 1 when omitted). + */ + max_touch_points?: number; + /** + * Emulate a mobile viewport (meta-viewport handling, overlay + * scrollbars). Only meaningful with `width`/`height`. + */ + mobile?: boolean; + /** + * Enable/disable touch emulation + * (`Emulation.setTouchEmulationEnabled`). When omitted while + * `max_touch_points` is set, touch is enabled. + */ + touch?: boolean; + /** + * UA string for `Emulation.setUserAgentOverride`. + */ + user_agent?: string; + /** + * UA client-hints metadata. Requires `user_agent`. + */ + user_agent_metadata?: UserAgentMetadata; + /** + * Viewport width in CSS pixels. Requires `height`. + */ + width?: number; +} +/** + * Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional + * and only sent when present. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UserAgentMetadata". + */ +export interface UserAgentMetadata { + architecture?: string; + brands?: UserAgentBrandVersion[]; + full_version?: string; + mobile?: boolean; + model?: string; + platform?: string; + platform_version?: string; +} +/** + * One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UserAgentBrandVersion". + */ +export interface UserAgentBrandVersion { + brand: string; + version: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EmulateParams". + */ +export interface EmulateParams { + /** + * Clear every emulation override on the tab and restore its real + * environment. Mutually exclusive with `overrides`. + */ + off?: boolean; + /** + * Overrides to apply. Required unless `off` is set. + */ + overrides?: EmulateOverrides; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EmulateResult". + */ +export interface EmulateResult { + /** + * Echo of the overrides that were applied. Absent when cleared. + */ + applied?: EmulateOverrides; + /** + * True when overrides were cleared (`off`); false when applied. + */ + cleared: boolean; + /** + * Scope note: emulation overrides are per-tab (CDP target) and are + * not inherited by new tabs. + */ + note?: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EvaluateError". + */ +export interface EvaluateError { + column?: number; + line?: number; + text: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EvaluateParams". + */ +export interface EvaluateParams { + /** + * Await the expression when it resolves to a Promise (CDP + * `Runtime.evaluate(awaitPromise=...)`). Defaults to `true`. + */ + await_promise?: boolean; + expression: string; + /** + * Ask CDP to serialise the result by value (vs. returning a + * `RemoteObject` id we cannot use). Defaults to `true`. + */ + return_by_value?: boolean; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's currently active tab. + */ + tab_id?: number; + /** + * Hard upper bound on the evaluation. Defaults to 30s. + */ + timeout_ms?: number; +} +/** + * Outcome of an `evaluate` call. + * + * * `ok: true` → expression evaluated successfully; `value` holds the + * JSON-serialised return value (`null` is meaningful and distinct + * from "missing"). + * * `ok: false` → the expression threw; `error.text` holds the + * stringified `exceptionDetails.text` / `exception.description`. + * The RPC itself still succeeds — the daemon does NOT map JS throws + * to top-level RPC errors so agents can act on the throw text. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "EvaluateResult". + */ +export interface EvaluateResult { + /** + * Native JS dialogs observed and auto-handled during this call. + */ + dialogs?: JavaScriptDialogInfo[]; + error?: EvaluateError; + ok: boolean; + tab_id: number; + value?: unknown; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "FillParams". + */ +export interface FillParams { + /** + * Clear the field before typing. Defaults to `true`; pass `false` + * to append instead of replacing. + */ + clear_before?: boolean; + ref?: string; + selector?: string; + session_id: string; + tab_id?: number; + timeout_ms?: number; + value: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "FillResult". + */ +export interface FillResult { + dialogs?: JavaScriptDialogInfo[]; + tab_id: number; + used_ref?: string; + used_selector?: string; + /** + * UTF-16 code-unit length of the value that was finally typed + * (matches what `input.value.length` would report in the page). + */ + value_length: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "FocusParams". + */ +export interface FocusParams { + /** + * Optional `@e` ref allocated by the last observation. + * Mutually exclusive with `selector`. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "FocusResult". + */ +export interface FocusResult { + dialogs?: JavaScriptDialogInfo[]; + /** + * Whether the target holds DOM focus in its document or shadow root after the call. + */ + focused: boolean; + tab_id: number; + used_ref?: string; + used_selector?: string; +} +/** + * Parameters for `tool.get_html`. Either give a tab and (optionally) a + * snapshot ref to scope the dump to one subtree, or leave both empty + * to fall back to the Agent Window's active tab and the document + * root. + * + * The wire field is `"ref"` (a Rust keyword); the Rust binding lives + * in [`Self::ref_`] and uses serde rename / alias so JSON stays clean. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "GetHtmlParams". + */ +export interface GetHtmlParams { + /** + * Truncate the HTML to at most this many bytes. Optional; + * extension applies a sensible default (`524288` = 512 KiB) when + * omitted. + */ + max_bytes?: number; + /** + * Optional `@e` ref allocated by the last `tool.snapshot`. + * Accepts both `"e3"` and `"@e3"`. When given the extension calls + * `DOM.getOuterHTML({ backendNodeId })` for the matching node; + * otherwise it fetches the document element. + */ + ref?: string; + session_id: string; + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "GetHtmlResult". + */ +export interface GetHtmlResult { + /** + * Total byte length of the original (un-truncated) HTML payload. + */ + byte_size: number; + dialogs?: JavaScriptDialogInfo[]; + html: string; + tab_id: number; + /** + * True when `html` was truncated to honour `max_bytes`. Agents + * should treat the missing tail as elided. + */ + truncated?: boolean; +} +/** + * Current handshake envelope. The flattened identity remains source-compatible + * with older Rust callers constructing `HandshakeParams` directly. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HandshakeRequest". + */ +export interface HandshakeRequest { + audit_enabled?: boolean; + browser: BrowserPeerInfo; + client: string; + instance_id: string; + label: string; + /** + * **Deprecated** — legacy app-semver floor kept for wire compat with + * pre-protocol peers. New code sends `"0.0.0"` and ignores on read. + */ + min_compatible_peer?: string; + /** + * Lowest peer **protocol** version this side accepts (e.g. `"1.0"`). + */ + min_compatible_protocol?: string; + /** + * Logical protocol revision (for example `"1.0"`), independent of SemVer app releases. + */ + protocol_version: string; + version: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HandshakeResponse". + */ +export interface HandshakeResponse { + audit_ready?: boolean; + audit_version?: number; + /** + * **Deprecated** — legacy app-semver floor. New peers should use + * `min_compatible_protocol`; this field is optional and ignored. + */ + min_compatible_peer?: string; + /** + * Lowest peer protocol version this daemon accepts. + */ + min_compatible_protocol?: string; + protocol_version: string; + server: string; + version: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HelpCompletionCondition". + */ +export interface HelpCompletionCondition { + selector_exists?: string; + selector_missing?: string; + text_exists?: string; + text_missing?: string; + url_contains?: string; + /** + * RE2-compatible URL regex (maximum 128 characters). Backtracking-only syntax is rejected. + */ + url_matches?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HelpCompletionCriteria". + */ +export interface HelpCompletionCriteria { + /** + * @maxItems 8 + */ + all?: HelpCompletionCondition[]; + /** + * @maxItems 8 + */ + any?: HelpCompletionCondition[]; + stable_for_ms?: number; +} +/** + * One component the user is asked to look at / interact with. Exactly + * one of `ref` / `selector` should be supplied (mirrors the + * click/fill convention). When neither matches a live element the + * overlay still shows the prompt and reports the miss via + * [`ResolvedTarget`]. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HelpTarget". + */ +export interface HelpTarget { + ref?: string; + selector?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HoverParams". + */ +export interface HoverParams { + modifiers?: KeyModifier[]; + /** + * Optional `@e` ref allocated by the last observation. + * Mutually exclusive with `selector`. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Wait after the mouse move so hover-triggered UI can settle. + */ + settle_ms?: number; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * Reports what active hover probing did during an observation, so the agent + * can judge how far the live page may have drifted from the returned text. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HoverProbeReport". + */ +export interface HoverProbeReport { + /** + * The real cursor was moved over page content during this observation. + */ + performed: boolean; + /** + * Hovering surfaced content the static tree does not contain, so the page + * reacts to the cursor and may not have fully reverted. + */ + revealed_content: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "HoverResult". + */ +export interface HoverResult { + dialogs?: JavaScriptDialogInfo[]; + tab_id: number; + used_ref?: string; + used_selector?: string; + /** + * Viewport-relative hover coordinates (CSS pixels). + */ + x: number; + y: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "InteractionPolicy". + */ +export interface InteractionPolicy { + borrow_confirmation: BorrowConfirmationPolicy; + request_help: RequestHelpPolicy; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateBackParams". + */ +export interface NavigateBackParams { + session_id: string; + tab_id?: number; + timeout_ms?: number; + wait_until?: WaitUntil; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateBackResult". + */ +export interface NavigateBackResult { + dialogs?: JavaScriptDialogInfo[]; + error_text?: string; + final_url?: string; + previous_url?: string; + reached: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateForwardParams". + */ +export interface NavigateForwardParams { + session_id: string; + tab_id?: number; + timeout_ms?: number; + wait_until?: WaitUntil; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateForwardResult". + */ +export interface NavigateForwardResult { + dialogs?: JavaScriptDialogInfo[]; + error_text?: string; + final_url?: string; + previous_url?: string; + reached: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateParams". + */ +export interface NavigateParams { + session_id: string; + /** + * Target tab. Defaults to the Agent Window's currently active tab. + */ + tab_id?: number; + /** + * Hard upper bound on the wait; the extension also enforces its + * own AbortController hookup (M7 stops listening for further + * lifecycle events once exceeded). Defaults to 30s if omitted. + */ + timeout_ms?: number; + url: string; + /** + * Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]. + */ + wait_until?: WaitUntil; +} +/** + * Outcome of a navigation. `reached` is the lifecycle name the + * extension actually observed before returning — either the requested + * `wait_until` value, or `"timeout"` when the wait expired before + * that event fired. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NavigateResult". + */ +export interface NavigateResult { + dialogs?: JavaScriptDialogInfo[]; + error_text?: string; + /** + * Tab URL after the navigation settles. May differ from `url` if + * the server redirected (e.g. http → https) or `wait_until=commit` + * raced. + */ + final_url?: string; + reached: string; + tab_id: number; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NetworkEntry". + */ +export interface NetworkEntry { + /** + * CDP failure reason (`failure` entries only). + */ + error_text?: string; + kind: NetworkEntryKind; + method?: string; + mime_type?: string; + resource_type?: string; + sequence: number; + /** + * HTTP status code (`response` entries only). + */ + status?: number; + status_text?: string; + timestamp?: number; + truncated?: boolean; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NetworkParams". + */ +export interface NetworkParams { + /** + * Maximum number of entries to return. Extension applies safe defaults and caps. + */ + limit?: number; + /** + * Maximum characters returned per URL / error text. Extension applies safe defaults and caps. + */ + max_text_chars?: number; + session_id: string; + /** + * Return entries with sequence strictly greater than this cursor. + */ + since?: number; + /** + * Optional target tab. Defaults to the Agent Window's currently active tab. + */ + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "NetworkResult". + */ +export interface NetworkResult { + entries?: NetworkEntry[]; + next_since: number; + tab_id: number; + truncated?: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ObserveDebug". + */ +export interface ObserveDebug { + surface_probes?: SurfaceProbeDebug[]; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SurfaceProbeDebug". + */ +export interface SurfaceProbeDebug { + confidence?: string; + sub_items: string[]; + trigger_action: string; + trigger_backend_node_id: number; + trigger_point?: SurfaceProbePoint; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SurfaceProbePoint". + */ +export interface SurfaceProbePoint { + x: number; + y: number; +} +/** + * Parameters for `tool.observe` — produce a semantic VOM observation + * for one tab plus a fresh `@e` ref-store on the extension side. + * + * Unlike `tool.snapshot`, this path may run bounded perception probes + * such as hover-surface discovery, but only when `probe_hover` asks for + * them. It must not submit input, click, navigate, or otherwise commit + * page state. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ObserveParams". + */ +export interface ObserveParams { + /** + * Continue a retained observation; does not recapture the page. + */ + cursor?: string; + /** + * Include implementation diagnostics for conditional surface probes. + */ + debug_surfaces?: boolean; + /** + * Cap the depth of the rendered VOM tree. + */ + max_depth?: number; + /** + * Soft cap on rendered tokens (approximate; extension uses a + * best-effort heuristic based on character count). + */ + max_tokens?: number; + /** + * Opt in to active hover probing: the extension moves the real cursor + * over a bounded set of controls to discover hover-only menus and + * tooltips. + * + * Off by default. Probing costs seconds of wall clock, mutates the live + * page, and pays off only on pages whose content is genuinely hidden + * behind hover. Request it when a static observation looks like it is + * missing hover-revealed structure. + */ + probe_hover?: boolean; + session_id: string; + /** + * Optional target tab. Defaults to the Agent Window's currently + * active tab. + */ + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ObserveResult". + */ +export interface ObserveResult { + debug?: ObserveDebug; + dialogs?: JavaScriptDialogInfo[]; + /** + * Present only when `probe_hover` was requested and probing actually ran. + */ + hover_probe?: HoverProbeReport; + /** + * Continue omitted content from this same observation. + */ + next_cursor?: string; + /** + * Number of `@e` refs registered for this session by this + * observation. Equivalent to the size of the new ref-store map. + */ + ref_count: number; + /** + * Tab the observation was computed for. + */ + tab_id: number; + /** + * Semantic VOM observation text. Refs are rendered as `@e` so + * the agent can copy them into subsequent interaction tools. + */ + text: string; + /** + * Whether the rendered tree was truncated because of `max_depth` / + * `max_tokens`. Agents may re-run with looser caps. + */ + truncated?: boolean; +} +/** + * Page context dictionary entry — referenced by steps via `page` id. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "PageRefV2". + */ +export interface PageRefV2 { + id: string; + title?: string; + url: string; +} +/** + * `system.ping` request payload. Empty (the response carries `pong`). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "PingParams". + */ +export interface PingParams {} +/** + * `system.ping` response payload. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "PingResult". + */ +export interface PingResult { + pong: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "PressParams". + */ +export interface PressParams { + /** + * Hold the key down for this many milliseconds between `keyDown` + * and `keyUp`. Useful for testing long-press handlers. + */ + hold_ms?: number; + /** + * Logical key name. Accepts CDP `key` strings (`Enter`, `Escape`, + * `ArrowDown`, single characters like `a`), or a compound + * expression such as `Ctrl+A` / `Meta+Shift+P`. Modifiers in the + * compound form combine with anything supplied via `modifiers`. + */ + key: string; + modifiers?: KeyModifier[]; + /** + * Optional target to focus before dispatching the key. + */ + ref?: string; + selector?: string; + session_id: string; + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "PressResult". + */ +export interface PressResult { + code: string; + dialogs?: JavaScriptDialogInfo[]; + key: string; + modifiers?: KeyModifier[]; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordAwaitParams". + */ +export interface RecordAwaitParams { + session_id: string; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordAwaitResult". + */ +export interface RecordAwaitResult { + trace: RecordedTrace; +} +/** + * Wire trace returned by `tool.record_stop` / `await`. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TraceV3". + */ +export interface TraceV3 { + entry: TraceEntry; + purpose?: string; + recorded_at: string; + recorder: RecorderInfo; + started_at?: string; + states: TraceStateV3[]; + steps: StepV3[]; + stopped_by: StopReason; + version: 3; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TraceEntry". + */ +export interface TraceEntry { + start_url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecorderInfo". + */ +export interface RecorderInfo { + bsk: string; + vom: number; +} +/** + * Page observation dictionary entry — referenced by steps via `state` / `result.state`. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TraceStateV3". + */ +export interface TraceStateV3 { + /** + * Full page observation (front matter + VOM body + annotations). + */ + body: string; + id: string; + title?: string; + truncated?: boolean; + url: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StepResultV3". + */ +export interface StepResultV3 { + state: string; +} +/** + * Stable semantic handle for an interacted element within a page observation. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TargetDescriptorV3". + */ +export interface TargetDescriptorV3 { + ctx?: string; + name?: string; + ref?: string; + role?: string; + unmatched?: boolean; +} +/** + * One selected option (`select` op). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SelectedOptionV3". + */ +export interface SelectedOptionV3 { + label?: string; + value: string; +} +/** + * Persisted user-action trace exported by legacy `tool.record_stop` / `await`. + * + * Unknown extension fields are ignored so older traces remain readable. + * `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` + * classification — serde still ignores them, but the JSON Schema rejects them. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TraceV2". + */ +export interface TraceV2 { + entry: TraceEntry; + pages: PageRefV2[]; + purpose?: string; + /** + * RFC 3339 timestamp when recording stopped. + */ + recorded_at: string; + started_at?: string; + steps: StepV2[]; +} +/** + * Observed navigation after a step (objective fact only). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StepEffectV2". + */ +export interface StepEffectV2 { + /** + * Reference into `pages[]` for the destination page. + */ + navigated_to: string; +} +/** + * Stable semantic handle for an interacted element (v2). + * + * `name` and `nearby_label` are **untrusted page text**. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TargetDescriptorV2". + */ +export interface TargetDescriptorV2 { + name?: string; + name_attr?: string; + nearby_label?: string; + placeholder?: string; + role?: string; + tag: string; +} +/** + * One selected option (`select` op). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SelectedOptionV2". + */ +export interface SelectedOptionV2 { + label?: string; + value: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordStartParams". + */ +export interface RecordStartParams { + max_page_tokens?: number; + purpose?: string; + redact_values?: boolean; + session_id: string; + /** + * Client can decode the v3 `switch_tab` step variant. + */ + supports_tab_switch_steps?: boolean; + tab_id?: number; + /** + * Desired trace export format. Omitted means v2; `3` requests v3. + */ + trace_version?: number; + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordStartResult". + */ +export interface RecordStartResult { + recording: boolean; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordStopParams". + */ +export interface RecordStopParams { + session_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RecordStopResult". + */ +export interface RecordStopResult { + trace: RecordedTrace; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ReloadParams". + */ +export interface ReloadParams { + /** + * When `true`, bypass the HTTP cache (CDP `Page.reload(ignoreCache=true)`). + */ + hard?: boolean; + session_id: string; + tab_id?: number; + timeout_ms?: number; + wait_until?: WaitUntil; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ReloadResult". + */ +export interface ReloadResult { + dialogs?: JavaScriptDialogInfo[]; + error_text?: string; + final_url?: string; + previous_url?: string; + reached: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RequestHelpParams". + */ +export interface RequestHelpParams { + /** + * Optional explicit success detector. Navigation by itself is not a + * completion signal; these criteria must match before the tool can + * auto-complete without the user clicking Done. + */ + completion_criteria?: HelpCompletionCriteria; + /** + * Message shown to the user explaining what to do. + */ + prompt: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + /** + * Optional components to scroll to + flash-highlight. + */ + targets?: HelpTarget[]; + /** + * Hard upper bound on the wait. Defaults to 300000 (5 min), + * enforced daemon-side via the generic tool timeout. + */ + timeout_ms?: number; + /** + * Optional custom title for the help overlay. Falls back to the + * extension's default localized title when omitted. + */ + title?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RequestHelpResult". + */ +export interface RequestHelpResult { + completed_by?: HelpCompletedBy; + note?: string; + outcome: HelpOutcome; + resolved_targets?: ResolvedTarget[]; + tab_id: number; +} +/** + * Per-target resolution status echoed back so the agent can tell which + * `ref` / `selector` actually matched a live element. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ResolvedTarget". + */ +export interface ResolvedTarget { + matched: boolean; + ref?: string; + selector?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ReturnFailure". + */ +export interface ReturnFailure { + code: ErrorCode; + message: string; + tab_id: number; +} +/** + * Wire-format JSON-RPC error object carried inside [`crate::frame::ResponseFrame`]. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "RpcError". + */ +export interface RpcError { + code: ErrorCode; + data?: unknown; + message: string; +} +/** + * Scroll the session's active web page from top to bottom. PNG bytes are + * exported in bounded chunks through `tool.screenshot_read`, then released. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotFullPageParams". + */ +export interface ScreenshotFullPageParams { + /** + * Follow appended content (default), or capture the initial document height. + */ + scope?: ScreenshotScope; + session_id: string; + tab_id?: number; + /** + * Capture and PNG encoding deadline; defaults to 120000 milliseconds. + */ + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotFullPageResult". + */ +export interface ScreenshotFullPageResult { + byte_size: number; + /** + * Opaque, session-scoped export capability. Never an agent filesystem path. + */ + capture_id: string; + dialogs?: JavaScriptDialogInfo[]; + format: string; + height: number; + scope?: ScreenshotScope; + tab_id: number; + width: number; +} +/** + * Parameters for `tool.screenshot`. Omit `ref` to capture the visible + * tab; pass an `@e` ref from the last `tool.snapshot` to crop to + * that element. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotParams". + */ +export interface ScreenshotParams { + /** + * Optional `@e` ref allocated by the last `tool.snapshot`. + * Accepts both `"e3"` and `"@e3"`. + */ + ref?: string; + session_id: string; + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotReadParams". + */ +export interface ScreenshotReadParams { + capture_id: string; + /** + * Byte offset, allowing an interrupted chunk request to be retried. + */ + offset: number; + session_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotReadResult". + */ +export interface ScreenshotReadResult { + /** + * At most 256 KiB of PNG bytes, base64 encoded. + */ + data_base64: string; + eof: boolean; + next_offset: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotReleaseParams". + */ +export interface ScreenshotReleaseParams { + capture_id: string; + session_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotReleaseResult". + */ +export interface ScreenshotReleaseResult { + released: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScreenshotResult". + */ +export interface ScreenshotResult { + /** + * Single-use visual point-click capture, in the original PNG coordinate space. + */ + capture_id?: string; + /** + * Image remains viewable but cannot authorize a point click. + */ + capture_unavailable?: string; + dialogs?: JavaScriptDialogInfo[]; + /** + * Always `"png"` in v0.1; reserved for future JPEG / WebP support. + */ + format: string; + /** + * Pixel height (see [`Self::width`]). + */ + height?: number; + /** + * Base64-encoded PNG payload (no `data:` prefix). + */ + image_base64: string; + tab_id: number; + /** + * Pixel width parsed from the PNG IHDR. May be `0` when parsing + * fails (extension only logs a warning in that case so the agent + * still gets the image). + */ + width?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScrollToParams". + */ +export interface ScrollToParams { + /** + * Optional `@e` ref allocated by the last observation. + * Mutually exclusive with `selector`. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "ScrollToResult". + */ +export interface ScrollToResult { + dialogs?: JavaScriptDialogInfo[]; + height: number; + tab_id: number; + used_ref?: string; + used_selector?: string; + width: number; + /** + * Bounding rectangle of the element's visible border-box portion, in + * top-level viewport CSS pixels, after ancestor and viewport clipping. + * Partial visibility is sufficient. This is not an occlusion or hit test. + */ + x: number; + y: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SelectParams". + */ +export interface SelectParams { + /** + * Optional `@e` ref allocated by the last `tool.snapshot`. + * Mutually exclusive with `selector`. Accepts both `"e3"` and + * `"@e3"`. + */ + ref?: string; + /** + * CSS selector resolved against the live DOM. Mutually exclusive + * with `ref_`. + */ + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + /** + * Maximum time the daemon waits for the tool call before timing out. + */ + timeout_ms?: number; + /** + * Option `value` strings to set as the final selection. For a + * single-select `` the list replaces the current selection + * (an empty list clears all selections). + */ + values: string[]; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SelectResult". + */ +export interface SelectResult { + dialogs?: JavaScriptDialogInfo[]; + /** + * Whether the target `` exactly one value is required; for + * `` had the `multiple` attribute. + */ + multiple: boolean; + /** + * Visible labels of the selected options (same order as + * `selected_values`). + */ + selected_labels: string[]; + /** + * Final selected option `value` attributes after the call. + */ + selected_values: string[]; + tab_id: number; + used_ref?: string; + used_selector?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SessionStartParams". + */ +export interface SessionStartParams { + browser_instance_id?: string; + /** + * Whether the new Agent Window should take focus. Omitted means the + * extension's default (`true`) for compatibility with older clients. + */ + focused?: boolean; + /** + * Optional Agent Window outer height in CSS pixels (100..=7680). + */ + height?: number; + session_id: string; + /** + * Optional Agent Window outer width in CSS pixels (100..=7680). + */ + width?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SessionStartResult". + */ +export interface SessionStartResult { + agent_window_id?: number; + interaction?: InteractionPolicy; +} +/** + * Snapshot of a single live session. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SessionStatusEntry". + */ +export interface SessionStatusEntry { + agent_window_id?: number; + browser_instance_id: string; + /** + * Unix epoch milliseconds. + */ + created_at_ms: number; + interaction?: InteractionPolicy; + session_id: string; +} +/** + * Full extension response, including whether a window was left with the user. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SessionStopOutcome". + */ +export interface SessionStopOutcome { + return_failures?: ReturnFailure[]; + returned_tab_ids?: number[]; + window_released?: boolean; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SessionStopParams". + */ +export interface SessionStopParams { + session_id: string; +} +/** + * Parameters for `tool.snapshot` — produce an indented accessibility + * tree for one tab plus a fresh `@e` ref-store on the extension + * side (design §4 / §7). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SnapshotParams". + */ +export interface SnapshotParams { + /** + * Cap the depth of the rendered tree (defense against very deep + * pages). Implementation-defined default; agents typically use + * `Some(16)` for "browse and read" prompts. + */ + max_depth?: number; + /** + * Soft cap on rendered tokens (approximate; extension uses a + * best-effort heuristic based on character count). + */ + max_tokens?: number; + session_id: string; + /** + * Optional target tab. Defaults to the Agent Window's currently + * active tab. + */ + tab_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "SnapshotResult". + */ +export interface SnapshotResult { + dialogs?: JavaScriptDialogInfo[]; + /** + * Number of `@e` refs registered for this session by this + * snapshot. Equivalent to the size of the new ref-store map. + */ + ref_count: number; + /** + * Tab the snapshot was actually computed for (after resolving the + * optional `tab_id` default). + */ + tab_id: number; + /** + * Indented aria-snapshot text. Refs are rendered as `@e` so the + * agent can copy them into subsequent `tool.click` / `tool.fill` + * selectors. + */ + text: string; + /** + * Whether the rendered tree was truncated because of `max_depth` / + * `max_tokens`. Agents may re-run with looser caps. + */ + truncated: boolean; +} +/** + * `system.status` request payload. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StatusParams". + */ +export interface StatusParams { + /** + * When set, the daemon polls the browser registry for up to this many + * milliseconds before returning a snapshot. Only applies while zero + * browsers are registered; an existing connection returns immediately. + */ + wait_for_browser_ms?: number; +} +/** + * `system.status` reply: daemon meta + connected browsers + live sessions. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "StatusResult". + */ +export interface StatusResult { + /** + * Snapshot of connected extension clients. + */ + browsers: BrowserStatusEntry[]; + /** + * Semver of the daemon binary (`env!("CARGO_PKG_VERSION")`). + */ + daemon_version: string; + /** + * Daemon process id. + */ + pid: number; + /** + * Logical protocol revision (e.g. `"1.0"`). + */ + protocol_version: string; + /** + * Snapshot of live sessions. + */ + sessions: SessionStatusEntry[]; + /** + * Absolute path of the IPC socket / named pipe handle. + */ + sock_path: string; + /** + * Daemon uptime in whole seconds. + */ + uptime_secs: number; + /** + * Subset of `browsers` whose `protocol_version` differs from the + * daemon's (minor drift, same major). Entries mirror + * `BrowserStatusEntry.version_skew`. + */ + version_skew_browsers: VersionSkewEntry[]; + /** + * WS port the daemon listens on for extension clients. + */ + ws_port: number; +} +/** + * One entry per connected browser whose protocol version drifts from + * the daemon's (same major). Surfaced in `system.status` for + * `bsk status` / `bsk doctor` / popup "warn but allow" UX. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "VersionSkewEntry". + */ +export interface VersionSkewEntry { + browser_name: string; + /** + * Extension `protocol_version` from handshake. + */ + client_protocol_version: string; + /** + * Extension app semver at snapshot time (informational). + */ + client_version: string; + instance_id: string; + label: string; + /** + * Daemon `protocol_version` at snapshot time. + */ + server_protocol_version: string; + /** + * Daemon app semver at snapshot time (informational). + */ + server_version: string; +} +/** + * Params for `tool.tab_borrow`. Moves a *user* tab into the + * requesting session's Agent Window, recording its original window / + * index so `tab_return` (or session_stop) can put it back. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabBorrowParams". + */ +export interface TabBorrowParams { + /** + * Legacy input, ignored. Browser settings decide whether confirmation is required. + */ + confirm?: boolean; + /** + * Maximum time to wait for user confirmation (default 60 seconds). + */ + confirmation_timeout_ms?: number; + session_id: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabBorrowResult". + */ +export interface TabBorrowResult { + agent_window_id: number; + original_index: number; + original_window_id: number; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabCloseParams". + */ +export interface TabCloseParams { + session_id: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabCloseResult". + */ +export interface TabCloseResult { + tab_id: number; +} +/** + * Params for `tool.tab_create`. The new tab is always created inside + * the requesting session's Agent Window (design §6 sandbox rule — + * agents never spawn tabs in user windows). + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabCreateParams". + */ +export interface TabCreateParams { + /** + * Focus the new tab? Defaults to `true` (matches `chrome.tabs.create`). + */ + active?: boolean; + /** + * Insertion index within the Agent Window's tab strip. Omit to + * append at the end. + */ + index?: number; + session_id: string; + /** + * Destination URL. Defaults to `chrome://newtab` when omitted. + */ + url?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabCreateResult". + */ +export interface TabCreateResult { + tab_id: number; + /** + * Best-effort URL of the newly created tab. May be empty if Chrome + * has not yet committed the navigation (e.g. pending load). + */ + url: string; + window_id: number; +} +/** + * A single tab entry returned by [`TabListResult`]. + * + * `scope` reports how the requesting session sees this tab: tabs owned + * by the session's own Agent Window are tagged `agent`; everything + * else falls into `user`. (Other sessions' Agent Windows are filtered + * out before they reach this struct.) + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabInfo". + */ +export interface TabInfo { + active?: boolean; + /** + * Where the tab sits relative to the requesting session: `user` or + * `agent`. `all` is a request-side filter only and never appears + * on an individual tab entry. + */ + scope?: TabScope; + tab_id: number; + title?: string; + url?: string; + window_id?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabListParams". + */ +export interface TabListParams { + /** + * View scope for [`TabListParams`] (§6 sandbox table). + * + * * `User` — tabs that live in any window other than an Agent Window. + * * `Agent` — tabs in the requesting session's Agent Window only. + * * `All` — both of the above; never reveals other sessions' Agent + * Windows (cross-session isolation per §6). + */ + scope: "user" | "agent" | "all"; + session_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabListResult". + */ +export interface TabListResult { + tabs: TabInfo[]; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabReturnParams". + */ +export interface TabReturnParams { + session_id: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabReturnResult". + */ +export interface TabReturnResult { + /** + * True when the original window had been closed and we fell back + * to either the last focused normal window or a newly-created + * window. Lets the CLI surface "tab returned to a different + * window" hints. + */ + fallback?: boolean; + returned_to_index: number; + returned_to_window_id: number; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabSelectParams". + */ +export interface TabSelectParams { + session_id: string; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "TabSelectResult". + */ +export interface TabSelectResult { + tab_id: number; + window_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UploadFile". + */ +export interface UploadFile { + name: string; + staged_path?: string; + transfer_id: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UploadParams". + */ +export interface UploadParams { + files: UploadFile[]; + mode?: UploadMode; + ref?: string; + selector?: string; + session_id: string; + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "UploadResult". + */ +export interface UploadResult { + file_names: string[]; + tab_id: number; + used_ref?: string; + used_selector?: string; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitForNavigationParams". + */ +export interface WaitForNavigationParams { + session_id: string; + /** + * Target tab. Defaults to the Agent Window's currently active tab. + */ + tab_id?: number; + /** + * Hard upper bound on the wait. Defaults to 30s. + */ + timeout_ms?: number; + /** + * Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]. + */ + wait_until?: WaitUntil; +} +/** + * Outcome of a wait_for_navigation. `reached` is the wire name of the + * lifecycle phase the extension actually observed before returning — + * either the requested `wait_until`, or `"timeout"` when the wait + * expired before that event fired. + * + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitForNavigationResult". + */ +export interface WaitForNavigationResult { + dialogs?: JavaScriptDialogInfo[]; + error_text?: string; + reached: WaitForNavigationReached; + tab_id: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitMsParams". + */ +export interface WaitMsParams { + duration_ms: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WaitMsResult". + */ +export interface WaitMsResult { + waited_ms: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WheelParams". + */ +export interface WheelParams { + /** + * Native CDP wheel input in CSS pixels. Positive X means right. Not measured displacement. + */ + delta_x: number; + /** + * Native CDP wheel input in CSS pixels. Positive Y means down. Defaults to zero. + */ + delta_y: number; + modifiers?: KeyModifier[]; + /** + * Optional `@e` ref used as the wheel event's hit-test point. + * Mutually exclusive with `selector`. When neither is supplied, + * the event is dispatched at the viewport centre. + */ + ref?: string; + selector?: string; + session_id: string; + /** + * Target tab. Defaults to the Agent Window's active tab. + */ + tab_id?: number; + timeout_ms?: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WheelResult". + */ +export interface WheelResult { + /** + * Requested deltas, not measured scroll distance or completion. + */ + delta_x: number; + delta_y: number; + dialogs?: JavaScriptDialogInfo[]; + tab_id: number; + used_ref?: string; + used_selector?: string; + /** + * Top-level viewport coordinates where the real wheel event was dispatched. + */ + x: number; + y: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WindowResizeParams". + */ +export interface WindowResizeParams { + /** + * New Agent Window outer height in CSS pixels (100..=7680). + */ + height: number; + session_id: string; + /** + * New Agent Window outer width in CSS pixels (100..=7680). + */ + width: number; +} +/** + * This interface was referenced by `ProtocolTypes`'s JSON-Schema + * via the `definition` "WindowResizeResult". + */ +export interface WindowResizeResult { + height: number; + width: number; + window_id: number; +} diff --git a/apps/extension/src/transport/generated/types.ts b/apps/extension/src/transport/generated/types.ts new file mode 100644 index 000000000..99feb43b7 --- /dev/null +++ b/apps/extension/src/transport/generated/types.ts @@ -0,0 +1,194 @@ +// Generated by scripts/protocol.mjs from bsk-protocol. Do not edit. +export type { AnyValue } from './input'; +export type { BlurParams } from './input'; +export type { BlurResult } from './output'; +export type { BorrowConfirmationPolicy } from './output'; +export type { BrowserListParams } from './input'; +export type { BrowserPeerInfo } from './output'; +export type { BrowserStatusEntry } from './output'; +export type { CancelParams } from './input'; +export type { CancelResult } from './output'; +export type { ClickParams } from './input'; +export type { ClickResult } from './output'; +export type { ConsoleEntry } from './output'; +export type { ConsoleEntryKind } from './output'; +export type { ConsoleParams } from './input'; +export type { ConsoleResult } from './output'; +export type { ConsoleStackFrame } from './output'; +export type { DebugAction } from './output'; +export type { DebugActivity } from './output'; +export type { DebugAnalysis } from './output'; +export type { DebugBody } from './output'; +export type { DebugConsole } from './output'; +export type { DebugDuplicate } from './output'; +export type { DebugDurationStats } from './output'; +export type { DebugEndpoint } from './output'; +export type { DebugEvidence } from './output'; +export type { DebugField } from './output'; +export type { DebugFieldTrace } from './output'; +export type { DebugIntervention } from './output'; +export type { DebugInterventionKind } from './output'; +export type { DebugJsonEdit } from './output'; +export type { DebugLongTask } from './output'; +export type { DebugMetric } from './output'; +export type { DebugOperation } from './output'; +export type { DebugOperationState } from './output'; +export type { DebugOutput } from './output'; +export type { DebugPage } from './output'; +export type { DebugParams } from './input'; +export type { DebugPayload } from './output'; +export type { DebugPerformance } from './output'; +export type { DebugRecording } from './output'; +export type { DebugReplay } from './output'; +export type { DebugReplaySpec } from './output'; +export type { DebugRequest } from './output'; +export type { DebugRequestIntegrity } from './output'; +export type { DebugRequestLink } from './output'; +export type { DebugResult } from './output'; +export type { DebugRule } from './output'; +export type { DebugRuleEffect } from './output'; +export type { DebugRuleMatch } from './output'; +export type { DebugRuleSpec } from './output'; +export type { DebugRuleState } from './output'; +export type { DebugRun } from './output'; +export type { DebugRunState } from './output'; +export type { DebugStorage } from './output'; +export type { DebugTextChanges } from './output'; +export type { DebugValue } from './output'; +export type { DebugVisibility } from './output'; +export type { DownloadParams } from './input'; +export type { DownloadResult } from './output'; +export type { EmulateOverrides } from './output'; +export type { EmulateParams } from './input'; +export type { EmulateResult } from './output'; +export type { ErrorCode } from './output'; +export type { EvaluateError } from './output'; +export type { EvaluateParams } from './input'; +export type { EvaluateResult } from './output'; +export type { FillCommit } from './output'; +export type { FillParams } from './input'; +export type { FillResult } from './output'; +export type { FocusParams } from './input'; +export type { FocusResult } from './output'; +export type { GetHtmlParams } from './input'; +export type { GetHtmlResult } from './output'; +export type { HandshakeRequest } from './input'; +export type { HandshakeResponse } from './output'; +export type { HelpCompletedBy } from './output'; +export type { HelpCompletionCondition } from './output'; +export type { HelpCompletionCriteria } from './output'; +export type { HelpOutcome } from './output'; +export type { HelpTarget } from './output'; +export type { HoverParams } from './input'; +export type { HoverProbeReport } from './output'; +export type { HoverResult } from './output'; +export type { InteractionPolicy } from './output'; +export type { JavaScriptDialogHandledAction } from './output'; +export type { JavaScriptDialogInfo } from './output'; +export type { JavaScriptDialogType } from './output'; +export type { KeyModifier } from './output'; +export type { MouseButton } from './output'; +export type { NavigateBackParams } from './input'; +export type { NavigateBackResult } from './output'; +export type { NavigateForwardParams } from './input'; +export type { NavigateForwardResult } from './output'; +export type { NavigateParams } from './input'; +export type { NavigateResult } from './output'; +export type { NavigationCause } from './output'; +export type { NetworkEntry } from './output'; +export type { NetworkEntryKind } from './output'; +export type { NetworkParams } from './input'; +export type { NetworkResult } from './output'; +export type { ObserveDebug } from './output'; +export type { ObserveParams } from './input'; +export type { ObserveResult } from './output'; +export type { PageRefV2 } from './output'; +export type { PingParams } from './input'; +export type { PingResult } from './output'; +export type { PressParams } from './input'; +export type { PressResult } from './output'; +export type { RecordAwaitParams } from './input'; +export type { RecordAwaitResult } from './output'; +export type { RecordStartParams } from './input'; +export type { RecordStartResult } from './output'; +export type { RecordStopParams } from './input'; +export type { RecordStopResult } from './output'; +export type { RecordedStep } from './output'; +export type { RecordedTrace } from './output'; +export type { RecorderInfo } from './output'; +export type { ReloadParams } from './input'; +export type { ReloadResult } from './output'; +export type { RequestHelpParams } from './input'; +export type { RequestHelpPolicy } from './output'; +export type { RequestHelpResult } from './output'; +export type { ResolvedTarget } from './output'; +export type { ReturnFailure } from './output'; +export type { RpcError } from './output'; +export type { ScreenshotFullPageParams } from './input'; +export type { ScreenshotFullPageResult } from './output'; +export type { ScreenshotParams } from './input'; +export type { ScreenshotReadParams } from './input'; +export type { ScreenshotReadResult } from './output'; +export type { ScreenshotReleaseParams } from './input'; +export type { ScreenshotReleaseResult } from './output'; +export type { ScreenshotResult } from './output'; +export type { ScreenshotScope } from './output'; +export type { ScrollToParams } from './input'; +export type { ScrollToResult } from './output'; +export type { SelectParams } from './input'; +export type { SelectResult } from './output'; +export type { SelectedOptionV2 } from './output'; +export type { SelectedOptionV3 } from './output'; +export type { SessionStartParams } from './input'; +export type { SessionStartResult } from './output'; +export type { SessionStatusEntry } from './output'; +export type { SessionStopOutcome } from './output'; +export type { SessionStopParams } from './input'; +export type { SnapshotParams } from './input'; +export type { SnapshotResult } from './output'; +export type { StatusParams } from './input'; +export type { StatusResult } from './output'; +export type { StepEffectV2 } from './output'; +export type { StepResultV3 } from './output'; +export type { StepV2 } from './output'; +export type { StepV3 } from './output'; +export type { StopReason } from './output'; +export type { SurfaceProbeDebug } from './output'; +export type { SurfaceProbePoint } from './output'; +export type { TabBorrowParams } from './input'; +export type { TabBorrowResult } from './output'; +export type { TabCloseParams } from './input'; +export type { TabCloseResult } from './output'; +export type { TabCreateParams } from './input'; +export type { TabCreateResult } from './output'; +export type { TabInfo } from './output'; +export type { TabListParams } from './input'; +export type { TabListResult } from './output'; +export type { TabReturnParams } from './input'; +export type { TabReturnResult } from './output'; +export type { TabScope } from './output'; +export type { TabSelectParams } from './input'; +export type { TabSelectResult } from './output'; +export type { TargetDescriptorV2 } from './output'; +export type { TargetDescriptorV3 } from './output'; +export type { TraceEntry } from './output'; +export type { TraceStateV3 } from './output'; +export type { TraceV2 } from './output'; +export type { TraceV3 } from './output'; +export type { UploadFile } from './output'; +export type { UploadMode } from './output'; +export type { UploadParams } from './input'; +export type { UploadResult } from './output'; +export type { UserAgentBrandVersion } from './output'; +export type { UserAgentMetadata } from './output'; +export type { VersionSkewEntry } from './output'; +export type { WaitForNavigationParams } from './input'; +export type { WaitForNavigationReached } from './output'; +export type { WaitForNavigationResult } from './output'; +export type { WaitMsParams } from './input'; +export type { WaitMsResult } from './output'; +export type { WaitUntil } from './output'; +export type { WheelParams } from './input'; +export type { WheelResult } from './output'; +export type { WindowResizeParams } from './input'; +export type { WindowResizeResult } from './output'; diff --git a/apps/extension/src/transport/generated/validators.d.ts b/apps/extension/src/transport/generated/validators.d.ts new file mode 100644 index 000000000..ec036e47a --- /dev/null +++ b/apps/extension/src/transport/generated/validators.d.ts @@ -0,0 +1,160 @@ +// Generated by scripts/protocol.mjs from bsk-protocol. Do not edit. +export interface ValidationIssue { instancePath: string; message?: string; keyword: string; } +export interface Validator { (value: unknown): boolean; errors?: ValidationIssue[] | null; } +export const wire_BlurParams: Validator; +export const canonical_BlurParams: Validator; +export const wire_CancelParams: Validator; +export const canonical_CancelParams: Validator; +export const wire_ClickParams: Validator; +export const canonical_ClickParams: Validator; +export const wire_ConsoleParams: Validator; +export const canonical_ConsoleParams: Validator; +export const wire_DebugParams: Validator; +export const canonical_DebugParams: Validator; +export const wire_DownloadParams: Validator; +export const canonical_DownloadParams: Validator; +export const wire_EmulateParams: Validator; +export const canonical_EmulateParams: Validator; +export const wire_EvaluateParams: Validator; +export const canonical_EvaluateParams: Validator; +export const wire_FillParams: Validator; +export const canonical_FillParams: Validator; +export const wire_FocusParams: Validator; +export const canonical_FocusParams: Validator; +export const wire_GetHtmlParams: Validator; +export const canonical_GetHtmlParams: Validator; +export const wire_HandshakeResponse: Validator; +export const canonical_HandshakeResponse: Validator; +export const wire_HoverParams: Validator; +export const canonical_HoverParams: Validator; +export const wire_NavigateBackParams: Validator; +export const canonical_NavigateBackParams: Validator; +export const wire_NavigateForwardParams: Validator; +export const canonical_NavigateForwardParams: Validator; +export const wire_NavigateParams: Validator; +export const canonical_NavigateParams: Validator; +export const wire_NetworkParams: Validator; +export const canonical_NetworkParams: Validator; +export const wire_ObserveParams: Validator; +export const canonical_ObserveParams: Validator; +export const wire_PressParams: Validator; +export const canonical_PressParams: Validator; +export const wire_RecordAwaitParams: Validator; +export const canonical_RecordAwaitParams: Validator; +export const wire_RecordStartParams: Validator; +export const canonical_RecordStartParams: Validator; +export const wire_RecordStopParams: Validator; +export const canonical_RecordStopParams: Validator; +export const wire_ReloadParams: Validator; +export const canonical_ReloadParams: Validator; +export const wire_RequestHelpParams: Validator; +export const canonical_RequestHelpParams: Validator; +export const wire_ScreenshotFullPageParams: Validator; +export const canonical_ScreenshotFullPageParams: Validator; +export const wire_ScreenshotParams: Validator; +export const canonical_ScreenshotParams: Validator; +export const wire_ScreenshotReadParams: Validator; +export const canonical_ScreenshotReadParams: Validator; +export const wire_ScreenshotReleaseParams: Validator; +export const canonical_ScreenshotReleaseParams: Validator; +export const wire_ScrollToParams: Validator; +export const canonical_ScrollToParams: Validator; +export const wire_SelectParams: Validator; +export const canonical_SelectParams: Validator; +export const wire_SessionStartParams: Validator; +export const canonical_SessionStartParams: Validator; +export const wire_SessionStopParams: Validator; +export const canonical_SessionStopParams: Validator; +export const wire_SnapshotParams: Validator; +export const canonical_SnapshotParams: Validator; +export const wire_TabBorrowParams: Validator; +export const canonical_TabBorrowParams: Validator; +export const wire_TabCloseParams: Validator; +export const canonical_TabCloseParams: Validator; +export const wire_TabCreateParams: Validator; +export const canonical_TabCreateParams: Validator; +export const wire_TabListParams: Validator; +export const canonical_TabListParams: Validator; +export const wire_TabReturnParams: Validator; +export const canonical_TabReturnParams: Validator; +export const wire_TabSelectParams: Validator; +export const canonical_TabSelectParams: Validator; +export const wire_UploadParams: Validator; +export const canonical_UploadParams: Validator; +export const wire_WaitForNavigationParams: Validator; +export const canonical_WaitForNavigationParams: Validator; +export const wire_WheelParams: Validator; +export const canonical_WheelParams: Validator; +export const wire_WindowResizeParams: Validator; +export const canonical_WindowResizeParams: Validator; +export const canonical_BlurResult: Validator; +export const canonical_ClickResult: Validator; +export const canonical_ConsoleResult: Validator; +export const canonical_DebugResult: Validator; +export const canonical_DownloadResult: Validator; +export const canonical_EmulateResult: Validator; +export const canonical_EvaluateResult: Validator; +export const canonical_FillResult: Validator; +export const canonical_FocusResult: Validator; +export const canonical_GetHtmlResult: Validator; +export const canonical_HoverResult: Validator; +export const canonical_NavigateBackResult: Validator; +export const canonical_NavigateForwardResult: Validator; +export const canonical_NavigateResult: Validator; +export const canonical_NetworkResult: Validator; +export const canonical_ObserveResult: Validator; +export const canonical_PressResult: Validator; +export const canonical_RecordAwaitResult: Validator; +export const canonical_RecordStartResult: Validator; +export const canonical_RecordStopResult: Validator; +export const canonical_ReloadResult: Validator; +export const canonical_RequestHelpResult: Validator; +export const canonical_RpcError: Validator; +export const canonical_ScreenshotFullPageResult: Validator; +export const canonical_ScreenshotReadResult: Validator; +export const canonical_ScreenshotReleaseResult: Validator; +export const canonical_ScreenshotResult: Validator; +export const canonical_ScrollToResult: Validator; +export const canonical_SelectResult: Validator; +export const canonical_SessionStartResult: Validator; +export const canonical_SessionStopOutcome: Validator; +export const canonical_SnapshotResult: Validator; +export const canonical_TabBorrowResult: Validator; +export const canonical_TabCloseResult: Validator; +export const canonical_TabCreateResult: Validator; +export const canonical_TabListResult: Validator; +export const canonical_TabReturnResult: Validator; +export const canonical_TabSelectResult: Validator; +export const canonical_UploadResult: Validator; +export const canonical_WaitForNavigationResult: Validator; +export const canonical_WheelResult: Validator; +export const canonical_WindowResizeResult: Validator; +export const branch_128: Validator; +export const branch_129: Validator; +export const branch_130: Validator; +export const branch_131: Validator; +export const branch_132: Validator; +export const branch_133: Validator; +export const branch_134: Validator; +export const branch_135: Validator; +export const branch_136: Validator; +export const branch_137: Validator; +export const branch_138: Validator; +export const branch_139: Validator; +export const branch_140: Validator; +export const branch_141: Validator; +export const branch_142: Validator; +export const branch_143: Validator; +export const branch_144: Validator; +export const branch_145: Validator; +export const branch_146: Validator; +export const branch_147: Validator; +export const branch_148: Validator; +export const branch_149: Validator; +export const branch_150: Validator; +export const branch_151: Validator; +export const branch_152: Validator; +export const branch_153: Validator; +export const branch_154: Validator; +export const branch_155: Validator; +export const branch_156: Validator; diff --git a/apps/extension/src/transport/generated/validators.js b/apps/extension/src/transport/generated/validators.js new file mode 100644 index 000000000..84ca933d7 --- /dev/null +++ b/apps/extension/src/transport/generated/validators.js @@ -0,0 +1,30 @@ +// Generated by scripts/protocol.mjs from bsk-protocol. Do not edit. +var Ka=(r,s)=>()=>(s||r((s={exports:{}}).exports,s),s.exports);var $a=Ka(da=>{"use strict";Object.defineProperty(da,"__esModule",{value:!0});function Sa(r){let s=r.length,g=0,c=0,f;for(;c=55296&&f<=56319&&c` ref allocated by the last observation.\nMutually exclusive with `selector`.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"};function Mr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Mr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return Mr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:Bi.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.selector!==void 0){let a=r.selector,n=e;if(typeof a!="string"&&a!==null)return Mr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:Bi.properties.selector.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Mr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Mr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Bi.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Mr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Bi.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Mr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return Mr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Mr.errors=i,e===0}var Tn=Ur;function Ur(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ur.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return Ur.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector!==void 0){let a=e;if(typeof r.selector!="string")return Ur.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ur.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ur.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ur.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Ur.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return Ur.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ur.errors=i,e===0}var Cn=ji;function ji(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.rpc_id===void 0&&(t="rpc_id"))return ji.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.rpc_id!==void 0&&typeof r.rpc_id!="string")return ji.errors=[{instancePath:s+"/rpc_id",schemaPath:"#/properties/rpc_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return ji.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ji.errors=i,e===0}var Vn=xi;function xi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.rpc_id===void 0&&(t="rpc_id"))return xi.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.rpc_id!==void 0&&typeof r.rpc_id!="string")return xi.errors=[{instancePath:s+"/rpc_id",schemaPath:"#/properties/rpc_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return xi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return xi.errors=i,e===0}var Wn=ye,ds={properties:{button:{anyOf:[{$ref:"#/definitions/MouseButton"},{type:"null"}]},capture_id:{description:"Single-use capture returned by a visual-ref screenshot; requires image coordinates.",type:["string","null"]},click_count:{description:"Number of consecutive mouse presses (double-click = 2).",format:"uint32",minimum:1,type:["integer","null"]},image_x:{format:"double",type:["number","null"]},image_y:{format:"double",type:["number","null"]},modifiers:{items:{$ref:"#/definitions/KeyModifier"},type:["array","null"]},ref:{description:'Optional `@e` ref allocated by the last `tool.snapshot`.\nMutually exclusive with `selector` (caller must supply exactly\none). Accepts both `"e3"` and `"@e3"`.',type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"},Ja={description:"Mouse button selector for `tool.click`.",enum:["left","middle","right"],type:"string"};function Ht(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Ht.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="left"||r==="middle"||r==="right"?(Ht.errors=i,e===0):(Ht.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ja.enum},message:"must be equal to one of the allowed values"}],!1)}var Ga={description:"Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).",enum:["alt","ctrl","meta","shift"],type:"string"};function je(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(je.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="alt"||r==="ctrl"||r==="meta"||r==="shift"?(je.errors=i,e===0):(je.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ga.enum},message:"must be equal to one of the allowed values"}],!1)}function ye(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.session_id===void 0&&(n="session_id"))return ye.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.button!==void 0){let p=r.button,l=e,m=e,u=!1,y=e;Ht(p,{instancePath:s+"/button",parentData:r,parentDataProperty:"button",rootData:f})||(i=i===null?Ht.errors:i.concat(Ht.errors),e=i.length);var t=y===e;if(u=u||t,!u){let d=e;if(p!==null){let v={instancePath:s+"/button",schemaPath:"#/properties/button/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var t=d===e;u=u||t}if(u)e=m,i!==null&&(m?i.length=m:i=null);else{let d={instancePath:s+"/button",schemaPath:"#/properties/button/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,ye.errors=i,!1}var o=l===e}else var o=!0;if(o){if(r.capture_id!==void 0){let p=r.capture_id,l=e;if(typeof p!="string"&&p!==null)return ye.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:ds.properties.capture_id.type},message:"must be string,null"}],!1;var o=l===e}else var o=!0;if(o){if(r.click_count!==void 0){let p=r.click_count,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p))&&p!==null)return ye.errors=[{instancePath:s+"/click_count",schemaPath:"#/properties/click_count/type",keyword:"type",params:{type:ds.properties.click_count.type},message:"must be integer,null"}],!1;if(e===l&&typeof p=="number"&&(p<1||isNaN(p)))return ye.errors=[{instancePath:s+"/click_count",schemaPath:"#/properties/click_count/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0;if(o){if(r.image_x!==void 0){let p=r.image_x,l=e;if(typeof p!="number"&&p!==null)return ye.errors=[{instancePath:s+"/image_x",schemaPath:"#/properties/image_x/type",keyword:"type",params:{type:ds.properties.image_x.type},message:"must be number,null"}],!1;var o=l===e}else var o=!0;if(o){if(r.image_y!==void 0){let p=r.image_y,l=e;if(typeof p!="number"&&p!==null)return ye.errors=[{instancePath:s+"/image_y",schemaPath:"#/properties/image_y/type",keyword:"type",params:{type:ds.properties.image_y.type},message:"must be number,null"}],!1;var o=l===e}else var o=!0;if(o){if(r.modifiers!==void 0){let p=r.modifiers,l=e;if(!Array.isArray(p)&&p!==null)return ye.errors=[{instancePath:s+"/modifiers",schemaPath:"#/properties/modifiers/type",keyword:"type",params:{type:ds.properties.modifiers.type},message:"must be array,null"}],!1;if(e===l&&Array.isArray(p)){var a=!0;let u=p.length;for(let y=0;y=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0}}}}}}}}}}else return ye.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ye.errors=i,e===0}var Mn=de;var Xa={description:"Mouse button selector for `tool.click`.",enum:["left","middle","right"],type:"string"};function Bt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Bt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="left"||r==="middle"||r==="right"?(Bt.errors=i,e===0):(Bt.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Xa.enum},message:"must be equal to one of the allowed values"}],!1)}var Ya={description:"Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).",enum:["alt","ctrl","meta","shift"],type:"string"};function xe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(xe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="alt"||r==="ctrl"||r==="meta"||r==="shift"?(xe.errors=i,e===0):(xe.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ya.enum},message:"must be equal to one of the allowed values"}],!1)}function de(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.session_id===void 0&&(n="session_id"))return de.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.button!==void 0){let p=e,l=e,m=!1,u=e;Bt(r.button,{instancePath:s+"/button",parentData:r,parentDataProperty:"button",rootData:f})||(i=i===null?Bt.errors:i.concat(Bt.errors),e=i.length);var t=u===e;if(m=m||t,m)e=l,i!==null&&(l?i.length=l:i=null);else{let y={instancePath:s+"/button",schemaPath:"#/properties/button/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,de.errors=i,!1}var o=p===e}else var o=!0;if(o){if(r.capture_id!==void 0){let p=e;if(typeof r.capture_id!="string")return de.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0;if(o){if(r.click_count!==void 0){let p=r.click_count,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return de.errors=[{instancePath:s+"/click_count",schemaPath:"#/properties/click_count/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===l&&typeof p=="number"&&(p<1||isNaN(p)))return de.errors=[{instancePath:s+"/click_count",schemaPath:"#/properties/click_count/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0;if(o){if(r.image_x!==void 0){let p=e;if(e===p&&typeof r.image_x!="number")return de.errors=[{instancePath:s+"/image_x",schemaPath:"#/properties/image_x/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=p===e}else var o=!0;if(o){if(r.image_y!==void 0){let p=e;if(e===p&&typeof r.image_y!="number")return de.errors=[{instancePath:s+"/image_y",schemaPath:"#/properties/image_y/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=p===e}else var o=!0;if(o){if(r.modifiers!==void 0){let p=r.modifiers,l=e;if(e===l)if(Array.isArray(p)){var a=!0;let u=p.length;for(let y=0;y=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0}}}}}}}}}}else return de.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return de.errors=i,e===0}var Un=Me,ki={properties:{include_stack:{description:"Include structured stack frames. Defaults to false.",type:["boolean","null"]},limit:{description:"Maximum number of entries to return. Extension applies safe defaults and caps.",format:"uint32",minimum:1,type:["integer","null"]},max_text_chars:{description:"Maximum characters returned per entry text. Extension applies safe defaults and caps.",format:"uint32",minimum:1,type:["integer","null"]},session_id:{type:"string"},since:{description:"Return entries with sequence strictly greater than this cursor.",format:"uint64",minimum:0,type:["integer","null"]},tab_id:{description:"Optional target tab. Defaults to the Agent Window's currently active tab.",format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function Me(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Me.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.include_stack!==void 0){let a=r.include_stack,n=e;if(typeof a!="boolean"&&a!==null)return Me.errors=[{instancePath:s+"/include_stack",schemaPath:"#/properties/include_stack/type",keyword:"type",params:{type:ki.properties.include_stack.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.limit!==void 0){let a=r.limit,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Me.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/type",keyword:"type",params:{type:ki.properties.limit.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Me.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_text_chars!==void 0){let a=r.max_text_chars,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Me.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/type",keyword:"type",params:{type:ki.properties.max_text_chars.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Me.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Me.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.since!==void 0){let a=r.since,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Me.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:ki.properties.since.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Me.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Me.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ki.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}}}}else return Me.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Me.errors=i,e===0}var In=Ue;function Ue(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ue.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.include_stack!==void 0){let a=e;if(typeof r.include_stack!="boolean")return Ue.errors=[{instancePath:s+"/include_stack",schemaPath:"#/properties/include_stack/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.limit!==void 0){let a=r.limit,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ue.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Ue.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_text_chars!==void 0){let a=r.max_text_chars,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ue.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Ue.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ue.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.since!==void 0){let a=r.since,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ue.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ue.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ue.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}}}else return Ue.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ue.errors=i,e===0}var zn=M,ee={properties:{action:{$ref:"#/definitions/DebugAction"},budget:{format:"uint32",maximum:262144,minimum:4096,type:["integer","null"]},command_id:{type:["string","null"]},fields:{items:{type:"string"},type:["array","null"]},id:{type:["string","null"]},include_controlled:{type:["boolean","null"]},kind:{type:["string","null"]},limit:{format:"uint32",maximum:100,minimum:1,type:["integer","null"]},max_chars:{format:"uint32",maximum:16384,minimum:1,type:["integer","null"]},method:{type:["string","null"]},name:{type:["string","null"]},offset:{format:"uint32",maximum:65536,minimum:0,type:["integer","null"]},part:{type:["string","null"]},pointer:{type:["string","null"]},replay:{anyOf:[{$ref:"#/definitions/DebugReplaySpec"},{type:"null"}]},resource_type:{type:["string","null"]},rule:{anyOf:[{$ref:"#/definitions/DebugRuleSpec"},{type:"null"}]},run_id:{type:["string","null"]},session_id:{type:"string"},since:{format:"uint64",minimum:0,type:["integer","null"]},slow_ms:{format:"uint32",maximum:6e4,minimum:0,type:["integer","null"]},state:{type:["string","null"]},status:{format:"uint16",maximum:599,minimum:100,type:["integer","null"]},tab_id:{format:"int64",type:["integer","null"]},url:{type:["string","null"]},wait_ms:{format:"uint32",maximum:6e4,minimum:0,type:["integer","null"]},window_ms:{format:"uint32",maximum:1e4,minimum:100,type:["integer","null"]}},required:["session_id","action"],type:"object"},Qa={enum:["performance","aggregate","duplicates","capabilities","activity","wait","pin","unpin","start","stop","status","requests","request","operations","operation","console","pages","export","rules","rule_add","rule_enable","rule_disable","rule_remove","replay"],type:"string"};function Kt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Kt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="performance"||r==="aggregate"||r==="duplicates"||r==="capabilities"||r==="activity"||r==="wait"||r==="pin"||r==="unpin"||r==="start"||r==="stop"||r==="status"||r==="requests"||r==="request"||r==="operations"||r==="operation"||r==="console"||r==="pages"||r==="export"||r==="rules"||r==="rule_add"||r==="rule_enable"||r==="rule_disable"||r==="rule_remove"||r==="replay"?(Kt.errors=i,e===0):(Kt.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Qa.enum},message:"must be equal to one of the allowed values"}],!1)}var fs={additionalProperties:!1,properties:{body:{type:["string","null"]},headers:{additionalProperties:{type:["string","null"]},type:["object","null"]},key:{type:"string"},method:{type:["string","null"]},url:{type:["string","null"]}},required:["key"],type:"object"};function Qe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.key===void 0&&(a="key"))return Qe.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;{let n=e;for(let p in r)if(!(p==="body"||p==="headers"||p==="key"||p==="method"||p==="url")){return Qe.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.body!==void 0){let p=r.body,l=e;if(typeof p!="string"&&p!==null)return Qe.errors=[{instancePath:s+"/body",schemaPath:"#/properties/body/type",keyword:"type",params:{type:fs.properties.body.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0;if(t){if(r.headers!==void 0){let p=r.headers,l=e;if(!(p&&typeof p=="object"&&!Array.isArray(p))&&p!==null)return Qe.errors=[{instancePath:s+"/headers",schemaPath:"#/properties/headers/type",keyword:"type",params:{type:fs.properties.headers.type},message:"must be object,null"}],!1;if(e===l&&p&&typeof p=="object"&&!Array.isArray(p))for(let u in p){let y=p[u],d=e;if(typeof y!="string"&&y!==null)return Qe.errors=[{instancePath:s+"/headers/"+u.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/headers/additionalProperties/type",keyword:"type",params:{type:fs.properties.headers.additionalProperties.type},message:"must be string,null"}],!1;var o=d===e;if(!o)break}var t=l===e}else var t=!0;if(t){if(r.key!==void 0){let p=e;if(typeof r.key!="string")return Qe.errors=[{instancePath:s+"/key",schemaPath:"#/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.method!==void 0){let p=r.method,l=e;if(typeof p!="string"&&p!==null)return Qe.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:fs.properties.method.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0;if(t)if(r.url!==void 0){let p=r.url,l=e;if(typeof p!="string"&&p!==null)return Qe.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:fs.properties.url.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0}}}}}}else return Qe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Qe.errors=i,e===0}var ya={properties:{effect:{$ref:"#/definitions/DebugRuleEffect"},match:{$ref:"#/definitions/DebugRuleMatch"},name:{type:["string","null"]},times:{format:"uint32",minimum:0,type:["integer","null"]}},required:["match","effect"],type:"object"},bt={oneOf:[{additionalProperties:!1,properties:{type:{const:"block",type:"string"}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:["string","null"]},headers:{additionalProperties:{type:["string","null"]},type:["object","null"]},json:{anyOf:[{$ref:"#/definitions/DebugJsonEdit"},{type:"null"}]},method:{type:["string","null"]},type:{const:"modify",type:"string"},url:{type:["string","null"]}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:"string"},delay_ms:{format:"uint32",minimum:0,type:["integer","null"]},headers:{additionalProperties:{type:"string"},type:["object","null"]},status:{format:"uint16",maximum:65535,minimum:0,type:"integer"},type:{const:"mock",type:"string"}},required:["type","status","body"],type:"object"}]},Gt={additionalProperties:!1,properties:{remove:{items:{type:"string"},type:["array","null"]},rename:{additionalProperties:{type:"string"},type:["object","null"]},set:{additionalProperties:!0,type:["object","null"]}},type:"object"};function Ve(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n=e;for(let p in r)if(!(p==="remove"||p==="rename"||p==="set")){return Ve.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.remove!==void 0){let p=r.remove,l=e;if(!Array.isArray(p)&&p!==null)return Ve.errors=[{instancePath:s+"/remove",schemaPath:"#/properties/remove/type",keyword:"type",params:{type:Gt.properties.remove.type},message:"must be array,null"}],!1;if(e===l&&Array.isArray(p)){var t=!0;let m=p.length;for(let u=0;u=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0;if(d){if(r.headers!==void 0){let _=r.headers,D=e;if(!(_&&typeof _=="object"&&!Array.isArray(_))&&_!==null){let w={instancePath:s+"/headers",schemaPath:"#/oneOf/2/properties/headers/type",keyword:"type",params:{type:bt.oneOf[2].properties.headers.type},message:"must be object,null"};i===null?i=[w]:i.push(w),e++}if(e===D&&_&&typeof _=="object"&&!Array.isArray(_))for(let w in _){let V=e;if(typeof _[w]!="string"){let W={instancePath:s+"/headers/"+w.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/oneOf/2/properties/headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var b=V===e;if(!b)break}var d=D===e}else var d=!0;if(d){if(r.status!==void 0){let _=r.status,D=e;if(!(typeof _=="number"&&!(_%1)&&!isNaN(_))){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[w]:i.push(w),e++}if(e===D&&typeof _=="number"){if(_>65535||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:65535},message:"must be <= 65535"};i===null?i=[w]:i.push(w),e++}else if(_<0||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}}var d=D===e}else var d=!0;if(d)if(r.type!==void 0){let _=r.type,D=e;if(typeof _!="string"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[w]:i.push(w),e++}if(_!=="mock"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/const",keyword:"const",params:{allowedValue:"mock"},message:"must be equal to constant"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0}}}}}}else{let h={instancePath:s,schemaPath:"#/oneOf/2/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[h]:i.push(h),e++}var y=v===e;y&&o?(o=!1,a=[a,2]):y&&(o=!0,a=2)}if(o)e=t,i!==null&&(t?i.length=t:i=null);else{let v={instancePath:s,schemaPath:"#/oneOf",keyword:"oneOf",params:{passingSchemas:a},message:"must match exactly one schema in oneOf"};return i===null?i=[v]:i.push(v),e++,ht.errors=i,!1}return ht.errors=i,e===0}var Ra={additionalProperties:!1,properties:{method:{type:["string","null"]},resource_type:{type:["string","null"]},url:{type:"string"}},required:["url"],type:"object"};function rr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.url===void 0&&(o="url"))return rr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;{let a=e;for(let n in r)if(!(n==="method"||n==="resource_type"||n==="url")){return rr.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:n},message:"must NOT have additional properties"}],!1;break}if(a===e){if(r.method!==void 0){let n=r.method,p=e;if(typeof n!="string"&&n!==null)return rr.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:Ra.properties.method.type},message:"must be string,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.resource_type!==void 0){let n=r.resource_type,p=e;if(typeof n!="string"&&n!==null)return rr.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:Ra.properties.resource_type.type},message:"must be string,null"}],!1;var t=p===e}else var t=!0;if(t)if(r.url!==void 0){let n=e;if(typeof r.url!="string")return rr.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0}}}}else return rr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return rr.errors=i,e===0}function Vs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.match===void 0&&(o="match")||r.effect===void 0&&(o="effect"))return Vs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.effect!==void 0){let a=e;ht(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?ht.errors:i.concat(ht.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.match!==void 0){let a=e;rr(r.match,{instancePath:s+"/match",parentData:r,parentDataProperty:"match",rootData:f})||(i=i===null?rr.errors:i.concat(rr.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.name!==void 0){let a=r.name,n=e;if(typeof a!="string"&&a!==null)return Vs.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:ya.properties.name.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.times!==void 0){let a=r.times,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Vs.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/type",keyword:"type",params:{type:ya.properties.times.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Vs.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}else return Vs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Vs.errors=i,e===0}function M(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let p;if(r.session_id===void 0&&(p="session_id")||r.action===void 0&&(p="action"))return M.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:p},message:"must have required property '"+p+"'"}],!1;if(r.action!==void 0){let l=e;Kt(r.action,{instancePath:s+"/action",parentData:r,parentDataProperty:"action",rootData:f})||(i=i===null?Kt.errors:i.concat(Kt.errors),e=i.length);var t=l===e}else var t=!0;if(t){if(r.budget!==void 0){let l=r.budget,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/type",keyword:"type",params:{type:ee.properties.budget.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>262144||isNaN(l))return M.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/maximum",keyword:"maximum",params:{comparison:"<=",limit:262144},message:"must be <= 262144"}],!1;if(l<4096||isNaN(l))return M.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/minimum",keyword:"minimum",params:{comparison:">=",limit:4096},message:"must be >= 4096"}],!1}var t=m===e}else var t=!0;if(t){if(r.command_id!==void 0){let l=r.command_id,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/command_id",schemaPath:"#/properties/command_id/type",keyword:"type",params:{type:ee.properties.command_id.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.fields!==void 0){let l=r.fields,m=e;if(!Array.isArray(l)&&l!==null)return M.errors=[{instancePath:s+"/fields",schemaPath:"#/properties/fields/type",keyword:"type",params:{type:ee.properties.fields.type},message:"must be array,null"}],!1;if(e===m&&Array.isArray(l)){var o=!0;let y=l.length;for(let d=0;d100||isNaN(l))return M.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/maximum",keyword:"maximum",params:{comparison:"<=",limit:100},message:"must be <= 100"}],!1;if(l<1||isNaN(l))return M.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1}var t=m===e}else var t=!0;if(t){if(r.max_chars!==void 0){let l=r.max_chars,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/type",keyword:"type",params:{type:ee.properties.max_chars.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>16384||isNaN(l))return M.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/maximum",keyword:"maximum",params:{comparison:"<=",limit:16384},message:"must be <= 16384"}],!1;if(l<1||isNaN(l))return M.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1}var t=m===e}else var t=!0;if(t){if(r.method!==void 0){let l=r.method,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:ee.properties.method.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.name!==void 0){let l=r.name,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:ee.properties.name.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.offset!==void 0){let l=r.offset,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/type",keyword:"type",params:{type:ee.properties.offset.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>65536||isNaN(l))return M.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/maximum",keyword:"maximum",params:{comparison:"<=",limit:65536},message:"must be <= 65536"}],!1;if(l<0||isNaN(l))return M.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t){if(r.part!==void 0){let l=r.part,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/part",schemaPath:"#/properties/part/type",keyword:"type",params:{type:ee.properties.part.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.pointer!==void 0){let l=r.pointer,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/pointer",schemaPath:"#/properties/pointer/type",keyword:"type",params:{type:ee.properties.pointer.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.replay!==void 0){let l=r.replay,m=e,u=e,y=!1,d=e;Qe(l,{instancePath:s+"/replay",parentData:r,parentDataProperty:"replay",rootData:f})||(i=i===null?Qe.errors:i.concat(Qe.errors),e=i.length);var a=d===e;if(y=y||a,!y){let v=e;if(l!==null){let h={instancePath:s+"/replay",schemaPath:"#/properties/replay/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[h]:i.push(h),e++}var a=v===e;y=y||a}if(y)e=u,i!==null&&(u?i.length=u:i=null);else{let v={instancePath:s+"/replay",schemaPath:"#/properties/replay/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[v]:i.push(v),e++,M.errors=i,!1}var t=m===e}else var t=!0;if(t){if(r.resource_type!==void 0){let l=r.resource_type,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:ee.properties.resource_type.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.rule!==void 0){let l=r.rule,m=e,u=e,y=!1,d=e;Vs(l,{instancePath:s+"/rule",parentData:r,parentDataProperty:"rule",rootData:f})||(i=i===null?Vs.errors:i.concat(Vs.errors),e=i.length);var n=d===e;if(y=y||n,!y){let v=e;if(l!==null){let h={instancePath:s+"/rule",schemaPath:"#/properties/rule/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[h]:i.push(h),e++}var n=v===e;y=y||n}if(y)e=u,i!==null&&(u?i.length=u:i=null);else{let v={instancePath:s+"/rule",schemaPath:"#/properties/rule/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[v]:i.push(v),e++,M.errors=i,!1}var t=m===e}else var t=!0;if(t){if(r.run_id!==void 0){let l=r.run_id,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/run_id",schemaPath:"#/properties/run_id/type",keyword:"type",params:{type:ee.properties.run_id.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.session_id!==void 0){let l=e;if(typeof r.session_id!="string")return M.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.since!==void 0){let l=r.since,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:ee.properties.since.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return M.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.slow_ms!==void 0){let l=r.slow_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/type",keyword:"type",params:{type:ee.properties.slow_ms.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>6e4||isNaN(l))return M.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:6e4},message:"must be <= 60000"}],!1;if(l<0||isNaN(l))return M.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t){if(r.state!==void 0){let l=r.state,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:ee.properties.state.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.status!==void 0){let l=r.status,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/type",keyword:"type",params:{type:ee.properties.status.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>599||isNaN(l))return M.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:599},message:"must be <= 599"}],!1;if(l<100||isNaN(l))return M.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:100},message:"must be >= 100"}],!1}var t=m===e}else var t=!0;if(t){if(r.tab_id!==void 0){let l=r.tab_id,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ee.properties.tab_id.type},message:"must be integer,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.url!==void 0){let l=r.url,m=e;if(typeof l!="string"&&l!==null)return M.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:ee.properties.url.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.wait_ms!==void 0){let l=r.wait_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/type",keyword:"type",params:{type:ee.properties.wait_ms.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>6e4||isNaN(l))return M.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:6e4},message:"must be <= 60000"}],!1;if(l<0||isNaN(l))return M.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t)if(r.window_ms!==void 0){let l=r.window_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l))&&l!==null)return M.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/type",keyword:"type",params:{type:ee.properties.window_ms.type},message:"must be integer,null"}],!1;if(e===m&&typeof l=="number"){if(l>1e4||isNaN(l))return M.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:1e4},message:"must be <= 10000"}],!1;if(l<100||isNaN(l))return M.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:100},message:"must be >= 100"}],!1}var t=m===e}else var t=!0}}}}}}}}}}}}}}}}}}}}}}}}}}else return M.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return M.errors=i,e===0}var Ln=U;var Za={enum:["performance","aggregate","duplicates","capabilities","activity","wait","pin","unpin","start","stop","status","requests","request","operations","operation","console","pages","export","rules","rule_add","rule_enable","rule_disable","rule_remove","replay"],type:"string"};function Xt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Xt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="performance"||r==="aggregate"||r==="duplicates"||r==="capabilities"||r==="activity"||r==="wait"||r==="pin"||r==="unpin"||r==="start"||r==="stop"||r==="status"||r==="requests"||r==="request"||r==="operations"||r==="operation"||r==="console"||r==="pages"||r==="export"||r==="rules"||r==="rule_add"||r==="rule_enable"||r==="rule_disable"||r==="rule_remove"||r==="replay"?(Xt.errors=i,e===0):(Xt.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Za.enum},message:"must be equal to one of the allowed values"}],!1)}var en={additionalProperties:!1,properties:{body:{type:"string"},headers:{additionalProperties:{type:["string","null"]},type:"object"},key:{type:"string"},method:{type:"string"},url:{type:"string"}},required:["key"],type:"object"};function Ze(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.key===void 0&&(a="key"))return Ze.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;{let n=e;for(let p in r)if(!(p==="body"||p==="headers"||p==="key"||p==="method"||p==="url")){return Ze.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.body!==void 0){let p=e;if(typeof r.body!="string")return Ze.errors=[{instancePath:s+"/body",schemaPath:"#/properties/body/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.headers!==void 0){let p=r.headers,l=e;if(e===l)if(p&&typeof p=="object"&&!Array.isArray(p))for(let u in p){let y=p[u],d=e;if(typeof y!="string"&&y!==null)return Ze.errors=[{instancePath:s+"/headers/"+u.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/headers/additionalProperties/type",keyword:"type",params:{type:en.properties.headers.additionalProperties.type},message:"must be string,null"}],!1;var o=d===e;if(!o)break}else return Ze.errors=[{instancePath:s+"/headers",schemaPath:"#/properties/headers/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=l===e}else var t=!0;if(t){if(r.key!==void 0){let p=e;if(typeof r.key!="string")return Ze.errors=[{instancePath:s+"/key",schemaPath:"#/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.method!==void 0){let p=e;if(typeof r.method!="string")return Ze.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t)if(r.url!==void 0){let p=e;if(typeof r.url!="string")return Ze.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0}}}}}}else return Ze.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ze.errors=i,e===0}var rn={oneOf:[{additionalProperties:!1,properties:{type:{const:"block",type:"string"}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:"string"},headers:{additionalProperties:{type:["string","null"]},type:"object"},json:{anyOf:[{$ref:"#/definitions/DebugJsonEdit"}]},method:{type:"string"},type:{const:"modify",type:"string"},url:{type:"string"}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:"string"},delay_ms:{format:"uint32",minimum:0,type:"integer"},headers:{additionalProperties:{type:"string"},type:"object"},status:{format:"uint16",maximum:65535,minimum:0,type:"integer"},type:{const:"mock",type:"string"}},required:["type","status","body"],type:"object"}]};function xr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n=e;for(let p in r)if(!(p==="remove"||p==="rename"||p==="set")){return xr.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.remove!==void 0){let p=r.remove,l=e;if(e===l)if(Array.isArray(p)){var t=!0;let m=p.length;for(let u=0;u=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0;if(d){if(r.headers!==void 0){let _=r.headers,D=e;if(e===D)if(_&&typeof _=="object"&&!Array.isArray(_))for(let w in _){let V=e;if(typeof _[w]!="string"){let W={instancePath:s+"/headers/"+w.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/oneOf/2/properties/headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var b=V===e;if(!b)break}else{let w={instancePath:s+"/headers",schemaPath:"#/oneOf/2/properties/headers/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0;if(d){if(r.status!==void 0){let _=r.status,D=e;if(!(typeof _=="number"&&!(_%1)&&!isNaN(_))){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[w]:i.push(w),e++}if(e===D&&typeof _=="number"){if(_>65535||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:65535},message:"must be <= 65535"};i===null?i=[w]:i.push(w),e++}else if(_<0||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}}var d=D===e}else var d=!0;if(d)if(r.type!==void 0){let _=r.type,D=e;if(typeof _!="string"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[w]:i.push(w),e++}if(_!=="mock"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/const",keyword:"const",params:{allowedValue:"mock"},message:"must be equal to constant"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0}}}}}}else{let h={instancePath:s,schemaPath:"#/oneOf/2/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[h]:i.push(h),e++}var y=v===e;y&&o?(o=!1,a=[a,2]):y&&(o=!0,a=2)}if(o)e=t,i!==null&&(t?i.length=t:i=null);else{let v={instancePath:s,schemaPath:"#/oneOf",keyword:"oneOf",params:{passingSchemas:a},message:"must match exactly one schema in oneOf"};return i===null?i=[v]:i.push(v),e++,Ui.errors=i,!1}return Ui.errors=i,e===0}function ps(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.url===void 0&&(o="url"))return ps.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;{let a=e;for(let n in r)if(!(n==="method"||n==="resource_type"||n==="url")){return ps.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:n},message:"must NOT have additional properties"}],!1;break}if(a===e){if(r.method!==void 0){let n=e;if(typeof r.method!="string")return ps.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.resource_type!==void 0){let n=e;if(typeof r.resource_type!="string")return ps.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.url!==void 0){let n=e;if(typeof r.url!="string")return ps.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0}}}}else return ps.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ps.errors=i,e===0}function Ws(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.match===void 0&&(o="match")||r.effect===void 0&&(o="effect"))return Ws.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.effect!==void 0){let a=e;Ui(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?Ui.errors:i.concat(Ui.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.match!==void 0){let a=e;ps(r.match,{instancePath:s+"/match",parentData:r,parentDataProperty:"match",rootData:f})||(i=i===null?ps.errors:i.concat(ps.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.name!==void 0){let a=e;if(typeof r.name!="string")return Ws.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.times!==void 0){let a=r.times,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ws.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ws.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}else return Ws.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ws.errors=i,e===0}function U(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let p;if(r.session_id===void 0&&(p="session_id")||r.action===void 0&&(p="action"))return U.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:p},message:"must have required property '"+p+"'"}],!1;if(r.action!==void 0){let l=e;Xt(r.action,{instancePath:s+"/action",parentData:r,parentDataProperty:"action",rootData:f})||(i=i===null?Xt.errors:i.concat(Xt.errors),e=i.length);var t=l===e}else var t=!0;if(t){if(r.budget!==void 0){let l=r.budget,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>262144||isNaN(l))return U.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/maximum",keyword:"maximum",params:{comparison:"<=",limit:262144},message:"must be <= 262144"}],!1;if(l<4096||isNaN(l))return U.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/minimum",keyword:"minimum",params:{comparison:">=",limit:4096},message:"must be >= 4096"}],!1}var t=m===e}else var t=!0;if(t){if(r.command_id!==void 0){let l=e;if(typeof r.command_id!="string")return U.errors=[{instancePath:s+"/command_id",schemaPath:"#/properties/command_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.fields!==void 0){let l=r.fields,m=e;if(e===m)if(Array.isArray(l)){var o=!0;let y=l.length;for(let d=0;d100||isNaN(l))return U.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/maximum",keyword:"maximum",params:{comparison:"<=",limit:100},message:"must be <= 100"}],!1;if(l<1||isNaN(l))return U.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1}var t=m===e}else var t=!0;if(t){if(r.max_chars!==void 0){let l=r.max_chars,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>16384||isNaN(l))return U.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/maximum",keyword:"maximum",params:{comparison:"<=",limit:16384},message:"must be <= 16384"}],!1;if(l<1||isNaN(l))return U.errors=[{instancePath:s+"/max_chars",schemaPath:"#/properties/max_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1}var t=m===e}else var t=!0;if(t){if(r.method!==void 0){let l=e;if(typeof r.method!="string")return U.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.name!==void 0){let l=e;if(typeof r.name!="string")return U.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.offset!==void 0){let l=r.offset,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>65536||isNaN(l))return U.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/maximum",keyword:"maximum",params:{comparison:"<=",limit:65536},message:"must be <= 65536"}],!1;if(l<0||isNaN(l))return U.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t){if(r.part!==void 0){let l=e;if(typeof r.part!="string")return U.errors=[{instancePath:s+"/part",schemaPath:"#/properties/part/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.pointer!==void 0){let l=e;if(typeof r.pointer!="string")return U.errors=[{instancePath:s+"/pointer",schemaPath:"#/properties/pointer/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.replay!==void 0){let l=e,m=e,u=!1,y=e;Ze(r.replay,{instancePath:s+"/replay",parentData:r,parentDataProperty:"replay",rootData:f})||(i=i===null?Ze.errors:i.concat(Ze.errors),e=i.length);var a=y===e;if(u=u||a,u)e=m,i!==null&&(m?i.length=m:i=null);else{let b={instancePath:s+"/replay",schemaPath:"#/properties/replay/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[b]:i.push(b),e++,U.errors=i,!1}var t=l===e}else var t=!0;if(t){if(r.resource_type!==void 0){let l=e;if(typeof r.resource_type!="string")return U.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.rule!==void 0){let l=e,m=e,u=!1,y=e;Ws(r.rule,{instancePath:s+"/rule",parentData:r,parentDataProperty:"rule",rootData:f})||(i=i===null?Ws.errors:i.concat(Ws.errors),e=i.length);var n=y===e;if(u=u||n,u)e=m,i!==null&&(m?i.length=m:i=null);else{let b={instancePath:s+"/rule",schemaPath:"#/properties/rule/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[b]:i.push(b),e++,U.errors=i,!1}var t=l===e}else var t=!0;if(t){if(r.run_id!==void 0){let l=e;if(typeof r.run_id!="string")return U.errors=[{instancePath:s+"/run_id",schemaPath:"#/properties/run_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.session_id!==void 0){let l=e;if(typeof r.session_id!="string")return U.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.since!==void 0){let l=r.since,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return U.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.slow_ms!==void 0){let l=r.slow_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>6e4||isNaN(l))return U.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:6e4},message:"must be <= 60000"}],!1;if(l<0||isNaN(l))return U.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t){if(r.state!==void 0){let l=e;if(typeof r.state!="string")return U.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.status!==void 0){let l=r.status,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>599||isNaN(l))return U.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:599},message:"must be <= 599"}],!1;if(l<100||isNaN(l))return U.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:100},message:"must be >= 100"}],!1}var t=m===e}else var t=!0;if(t){if(r.tab_id!==void 0){let l=r.tab_id,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=m===e}else var t=!0;if(t){if(r.url!==void 0){let l=e;if(typeof r.url!="string")return U.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.wait_ms!==void 0){let l=r.wait_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>6e4||isNaN(l))return U.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:6e4},message:"must be <= 60000"}],!1;if(l<0||isNaN(l))return U.errors=[{instancePath:s+"/wait_ms",schemaPath:"#/properties/wait_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=m===e}else var t=!0;if(t)if(r.window_ms!==void 0){let l=r.window_ms,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return U.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"){if(l>1e4||isNaN(l))return U.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/maximum",keyword:"maximum",params:{comparison:"<=",limit:1e4},message:"must be <= 10000"}],!1;if(l<100||isNaN(l))return U.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:100},message:"must be >= 100"}],!1}var t=m===e}else var t=!0}}}}}}}}}}}}}}}}}}}}}}}}}}else return U.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return U.errors=i,e===0}var Fn=Ie,St={properties:{browser_relative_dir:{description:"Daemon-injected relative directory beneath Chrome's Downloads root.",type:["string","null"]},max_byte_size:{description:`Daemon-injected authoritative transfer size limit. The extension uses +it only for early cancellation; daemon import remains the final check.`,format:"uint64",minimum:0,type:["integer","null"]},ref:{type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:0,type:["integer","null"]}},required:["session_id"],type:"object"};function Ie(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ie.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.browser_relative_dir!==void 0){let a=r.browser_relative_dir,n=e;if(typeof a!="string"&&a!==null)return Ie.errors=[{instancePath:s+"/browser_relative_dir",schemaPath:"#/properties/browser_relative_dir/type",keyword:"type",params:{type:St.properties.browser_relative_dir.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_byte_size!==void 0){let a=r.max_byte_size,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ie.errors=[{instancePath:s+"/max_byte_size",schemaPath:"#/properties/max_byte_size/type",keyword:"type",params:{type:St.properties.max_byte_size.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ie.errors=[{instancePath:s+"/max_byte_size",schemaPath:"#/properties/max_byte_size/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return Ie.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:St.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.selector!==void 0){let a=r.selector,n=e;if(typeof a!="string"&&a!==null)return Ie.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:St.properties.selector.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ie.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ie.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:St.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ie.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:St.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ie.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}else return Ie.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ie.errors=i,e===0}var Jn=ze;function ze(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return ze.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.browser_relative_dir!==void 0){let a=e;if(typeof r.browser_relative_dir!="string")return ze.errors=[{instancePath:s+"/browser_relative_dir",schemaPath:"#/properties/browser_relative_dir/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.max_byte_size!==void 0){let a=r.max_byte_size,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ze.errors=[{instancePath:s+"/max_byte_size",schemaPath:"#/properties/max_byte_size/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ze.errors=[{instancePath:s+"/max_byte_size",schemaPath:"#/properties/max_byte_size/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return ze.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector!==void 0){let a=e;if(typeof r.selector!="string")return ze.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return ze.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ze.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ze.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ze.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}else return ze.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ze.errors=i,e===0}var Hn=Gs,Ta={properties:{off:{description:"Clear every emulation override on the tab and restore its real\nenvironment. Mutually exclusive with `overrides`.",type:["boolean","null"]},overrides:{anyOf:[{$ref:"#/definitions/EmulateOverrides"},{type:"null"}],description:"Overrides to apply. Required unless `off` is set."},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"},_e={description:`Concrete emulation overrides for one tab. Field presence drives the +extension: only the overrides whose fields are set are touched, so a +call may change just the UA, just the viewport, or any combination.`,properties:{accept_language:{description:"`Accept-Language` header override. Requires `user_agent`.",type:["string","null"]},device_scale_factor:{description:"Device scale factor (device pixel ratio). Only meaningful with\n`width`/`height`; the extension maps `None` to CDP's `0`\n(\"use the display's native factor\").",format:"double",type:["number","null"]},height:{description:"Viewport height in CSS pixels. Requires `width`.",format:"uint32",minimum:0,type:["integer","null"]},max_touch_points:{description:`Touch points reported while touch emulation is on (CDP defaults +to 1 when omitted).`,format:"uint32",minimum:0,type:["integer","null"]},mobile:{description:"Emulate a mobile viewport (meta-viewport handling, overlay\nscrollbars). Only meaningful with `width`/`height`.",type:["boolean","null"]},touch:{description:"Enable/disable touch emulation\n(`Emulation.setTouchEmulationEnabled`). When omitted while\n`max_touch_points` is set, touch is enabled.",type:["boolean","null"]},user_agent:{description:"UA string for `Emulation.setUserAgentOverride`.",type:["string","null"]},user_agent_metadata:{anyOf:[{$ref:"#/definitions/UserAgentMetadata"},{type:"null"}],description:"UA client-hints metadata. Requires `user_agent`."},width:{description:"Viewport width in CSS pixels. Requires `height`.",format:"uint32",minimum:0,type:["integer","null"]}},type:"object"},We={description:"Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional\nand only sent when present.",properties:{architecture:{type:["string","null"]},brands:{items:{$ref:"#/definitions/UserAgentBrandVersion"},type:["array","null"]},full_version:{type:["string","null"]},mobile:{type:["boolean","null"]},model:{type:["string","null"]},platform:{type:["string","null"]},platform_version:{type:["string","null"]}},type:"object"};function Wr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.brand===void 0&&(o="brand")||r.version===void 0&&(o="version"))return Wr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.brand!==void 0){let a=e;if(typeof r.brand!="string")return Wr.errors=[{instancePath:s+"/brand",schemaPath:"#/properties/brand/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.version!==void 0){let a=e;if(typeof r.version!="string")return Wr.errors=[{instancePath:s+"/version",schemaPath:"#/properties/version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return Wr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Wr.errors=i,e===0}function De(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.architecture!==void 0){let a=r.architecture,n=e;if(typeof a!="string"&&a!==null)return De.errors=[{instancePath:s+"/architecture",schemaPath:"#/properties/architecture/type",keyword:"type",params:{type:We.properties.architecture.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.brands!==void 0){let a=r.brands,n=e;if(!Array.isArray(a)&&a!==null)return De.errors=[{instancePath:s+"/brands",schemaPath:"#/properties/brands/type",keyword:"type",params:{type:We.properties.brands.type},message:"must be array,null"}],!1;if(e===n&&Array.isArray(a)){var o=!0;let l=a.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_touch_points!==void 0){let a=r.max_touch_points,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ce.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/type",keyword:"type",params:{type:_e.properties.max_touch_points.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ce.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.mobile!==void 0){let a=r.mobile,n=e;if(typeof a!="boolean"&&a!==null)return ce.errors=[{instancePath:s+"/mobile",schemaPath:"#/properties/mobile/type",keyword:"type",params:{type:_e.properties.mobile.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.touch!==void 0){let a=r.touch,n=e;if(typeof a!="boolean"&&a!==null)return ce.errors=[{instancePath:s+"/touch",schemaPath:"#/properties/touch/type",keyword:"type",params:{type:_e.properties.touch.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.user_agent!==void 0){let a=r.user_agent,n=e;if(typeof a!="string"&&a!==null)return ce.errors=[{instancePath:s+"/user_agent",schemaPath:"#/properties/user_agent/type",keyword:"type",params:{type:_e.properties.user_agent.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.user_agent_metadata!==void 0){let a=r.user_agent_metadata,n=e,p=e,l=!1,m=e;De(a,{instancePath:s+"/user_agent_metadata",parentData:r,parentDataProperty:"user_agent_metadata",rootData:f})||(i=i===null?De.errors:i.concat(De.errors),e=i.length);var o=m===e;if(l=l||o,!l){let y=e;if(a!==null){let b={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[b]:i.push(b),e++}var o=y===e;l=l||o}if(l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,ce.errors=i,!1}var t=n===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ce.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:_e.properties.width.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ce.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}}}else return ce.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ce.errors=i,e===0}function Gs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Gs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.off!==void 0){let n=r.off,p=e;if(typeof n!="boolean"&&n!==null)return Gs.errors=[{instancePath:s+"/off",schemaPath:"#/properties/off/type",keyword:"type",params:{type:Ta.properties.off.type},message:"must be boolean,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.overrides!==void 0){let n=r.overrides,p=e,l=e,m=!1,u=e;ce(n,{instancePath:s+"/overrides",parentData:r,parentDataProperty:"overrides",rootData:f})||(i=i===null?ce.errors:i.concat(ce.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/overrides",schemaPath:"#/properties/overrides/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/overrides",schemaPath:"#/properties/overrides/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,Gs.errors=i,!1}var t=p===e}else var t=!0;if(t){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Gs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Gs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ta.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0}}}else return Gs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Gs.errors=i,e===0}var Bn=Xs;function ot(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.brand===void 0&&(o="brand")||r.version===void 0&&(o="version"))return ot.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.brand!==void 0){let a=e;if(typeof r.brand!="string")return ot.errors=[{instancePath:s+"/brand",schemaPath:"#/properties/brand/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.version!==void 0){let a=e;if(typeof r.version!="string")return ot.errors=[{instancePath:s+"/version",schemaPath:"#/properties/version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return ot.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ot.errors=i,e===0}function dr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.architecture!==void 0){let a=e;if(typeof r.architecture!="string")return dr.errors=[{instancePath:s+"/architecture",schemaPath:"#/properties/architecture/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.brands!==void 0){let a=r.brands,n=e;if(e===n)if(Array.isArray(a)){var o=!0;let l=a.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_touch_points!==void 0){let a=r.max_touch_points,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ge.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ge.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.mobile!==void 0){let a=e;if(typeof r.mobile!="boolean")return ge.errors=[{instancePath:s+"/mobile",schemaPath:"#/properties/mobile/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.touch!==void 0){let a=e;if(typeof r.touch!="boolean")return ge.errors=[{instancePath:s+"/touch",schemaPath:"#/properties/touch/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.user_agent!==void 0){let a=e;if(typeof r.user_agent!="string")return ge.errors=[{instancePath:s+"/user_agent",schemaPath:"#/properties/user_agent/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.user_agent_metadata!==void 0){let a=e,n=e,p=!1,l=e;dr(r.user_agent_metadata,{instancePath:s+"/user_agent_metadata",parentData:r,parentDataProperty:"user_agent_metadata",rootData:f})||(i=i===null?dr.errors:i.concat(dr.errors),e=i.length);var o=l===e;if(p=p||o,p)e=n,i!==null&&(n?i.length=n:i=null);else{let u={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[u]:i.push(u),e++,ge.errors=i,!1}var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ge.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ge.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}}}else return ge.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ge.errors=i,e===0}function Xs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Xs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.off!==void 0){let n=e;if(typeof r.off!="boolean")return Xs.errors=[{instancePath:s+"/off",schemaPath:"#/properties/off/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=n===e}else var t=!0;if(t){if(r.overrides!==void 0){let n=e,p=e,l=!1,m=e;ge(r.overrides,{instancePath:s+"/overrides",parentData:r,parentDataProperty:"overrides",rootData:f})||(i=i===null?ge.errors:i.concat(ge.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/overrides",schemaPath:"#/properties/overrides/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,Xs.errors=i,!1}var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Xs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Xs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0}}}else return Xs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Xs.errors=i,e===0}var Kn=wr,Ki={properties:{await_promise:{description:"Await the expression when it resolves to a Promise (CDP\n`Runtime.evaluate(awaitPromise=...)`). Defaults to `true`.",type:["boolean","null"]},expression:{type:"string"},return_by_value:{description:"Ask CDP to serialise the result by value (vs. returning a\n`RemoteObject` id we cannot use). Defaults to `true`.",type:["boolean","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's currently active tab.",format:"int64",type:["integer","null"]},timeout_ms:{description:"Hard upper bound on the evaluation. Defaults to 30s.",format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id","expression"],type:"object"};function wr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.expression===void 0&&(o="expression"))return wr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.await_promise!==void 0){let a=r.await_promise,n=e;if(typeof a!="boolean"&&a!==null)return wr.errors=[{instancePath:s+"/await_promise",schemaPath:"#/properties/await_promise/type",keyword:"type",params:{type:Ki.properties.await_promise.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.expression!==void 0){let a=e;if(typeof r.expression!="string")return wr.errors=[{instancePath:s+"/expression",schemaPath:"#/properties/expression/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.return_by_value!==void 0){let a=r.return_by_value,n=e;if(typeof a!="boolean"&&a!==null)return wr.errors=[{instancePath:s+"/return_by_value",schemaPath:"#/properties/return_by_value/type",keyword:"type",params:{type:Ki.properties.return_by_value.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return wr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return wr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ki.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return wr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Ki.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return wr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}}else return wr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return wr.errors=i,e===0}var Gn=Pr;function Pr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.expression===void 0&&(o="expression"))return Pr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.await_promise!==void 0){let a=e;if(typeof r.await_promise!="boolean")return Pr.errors=[{instancePath:s+"/await_promise",schemaPath:"#/properties/await_promise/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.expression!==void 0){let a=e;if(typeof r.expression!="string")return Pr.errors=[{instancePath:s+"/expression",schemaPath:"#/properties/expression/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.return_by_value!==void 0){let a=e;if(typeof r.return_by_value!="boolean")return Pr.errors=[{instancePath:s+"/return_by_value",schemaPath:"#/properties/return_by_value/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Pr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Pr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Pr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Pr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}}else return Pr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Pr.errors=i,e===0}var Xn=sr,Ni={properties:{clear_before:{description:"Clear the field before typing. Defaults to `true`; pass `false`\nto append instead of replacing.",type:["boolean","null"]},ref:{type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]},value:{type:"string"}},required:["session_id","value"],type:"object"};function sr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.value===void 0&&(o="value"))return sr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.clear_before!==void 0){let a=r.clear_before,n=e;if(typeof a!="boolean"&&a!==null)return sr.errors=[{instancePath:s+"/clear_before",schemaPath:"#/properties/clear_before/type",keyword:"type",params:{type:Ni.properties.clear_before.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return sr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:Ni.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.selector!==void 0){let a=r.selector,n=e;if(typeof a!="string"&&a!==null)return sr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:Ni.properties.selector.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return sr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return sr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ni.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return sr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Ni.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return sr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t)if(r.value!==void 0){let a=e;if(typeof r.value!="string")return sr.errors=[{instancePath:s+"/value",schemaPath:"#/properties/value/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}else return sr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return sr.errors=i,e===0}var Yn=tr;function tr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.value===void 0&&(o="value"))return tr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.clear_before!==void 0){let a=e;if(typeof r.clear_before!="boolean")return tr.errors=[{instancePath:s+"/clear_before",schemaPath:"#/properties/clear_before/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return tr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector!==void 0){let a=e;if(typeof r.selector!="string")return tr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return tr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return tr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return tr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return tr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t)if(r.value!==void 0){let a=e;if(typeof r.value!="string")return tr.errors=[{instancePath:s+"/value",schemaPath:"#/properties/value/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}else return tr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return tr.errors=i,e===0}var Qn=Ir,Gi={properties:{ref:{description:"Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"};function Ir(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ir.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return Ir.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:Gi.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.selector!==void 0){let a=r.selector,n=e;if(typeof a!="string"&&a!==null)return Ir.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:Gi.properties.selector.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ir.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ir.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Gi.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ir.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Gi.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Ir.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return Ir.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ir.errors=i,e===0}var Zn=zr;function zr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return zr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return zr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector!==void 0){let a=e;if(typeof r.selector!="string")return zr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return zr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return zr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return zr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return zr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return zr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return zr.errors=i,e===0}var eo=cs,ca={description:`Parameters for \`tool.get_html\`. Either give a tab and (optionally) a +snapshot ref to scope the dump to one subtree, or leave both empty +to fall back to the Agent Window's active tab and the document +root. + +The wire field is \`"ref"\` (a Rust keyword); the Rust binding lives +in [\`Self::ref_\`] and uses serde rename / alias so JSON stays clean.`,properties:{max_bytes:{description:"Truncate the HTML to at most this many bytes. Optional;\nextension applies a sensible default (`524288` = 512 KiB) when\nomitted.",format:"uint32",minimum:0,type:["integer","null"]},ref:{description:'Optional `@e` ref allocated by the last `tool.snapshot`.\nAccepts both `"e3"` and `"@e3"`. When given the extension calls\n`DOM.getOuterHTML({ backendNodeId })` for the matching node;\notherwise it fetches the document element.',type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function cs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return cs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_bytes!==void 0){let a=r.max_bytes,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return cs.errors=[{instancePath:s+"/max_bytes",schemaPath:"#/properties/max_bytes/type",keyword:"type",params:{type:ca.properties.max_bytes.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return cs.errors=[{instancePath:s+"/max_bytes",schemaPath:"#/properties/max_bytes/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return cs.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:ca.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return cs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return cs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ca.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}}else return cs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return cs.errors=i,e===0}var ro=gs;function gs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return gs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_bytes!==void 0){let a=r.max_bytes,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return gs.errors=[{instancePath:s+"/max_bytes",schemaPath:"#/properties/max_bytes/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return gs.errors=[{instancePath:s+"/max_bytes",schemaPath:"#/properties/max_bytes/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return gs.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return gs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return gs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}else return gs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return gs.errors=i,e===0}var so=ir,Xi={properties:{audit_ready:{type:["boolean","null"]},audit_version:{format:"uint32",minimum:0,type:["integer","null"]},min_compatible_peer:{description:"**Deprecated** \u2014 legacy app-semver floor. New peers should use\n`min_compatible_protocol`; this field is optional and ignored.",type:["string","null"]},min_compatible_protocol:{description:"Lowest peer protocol version this daemon accepts.",type:["string","null"]},protocol_version:{type:"string"},server:{type:"string"},version:{type:"string"}},required:["server","version","protocol_version"],type:"object"};function ir(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.server===void 0&&(o="server")||r.version===void 0&&(o="version")||r.protocol_version===void 0&&(o="protocol_version"))return ir.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.audit_ready!==void 0){let a=r.audit_ready,n=e;if(typeof a!="boolean"&&a!==null)return ir.errors=[{instancePath:s+"/audit_ready",schemaPath:"#/properties/audit_ready/type",keyword:"type",params:{type:Xi.properties.audit_ready.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.audit_version!==void 0){let a=r.audit_version,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ir.errors=[{instancePath:s+"/audit_version",schemaPath:"#/properties/audit_version/type",keyword:"type",params:{type:Xi.properties.audit_version.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ir.errors=[{instancePath:s+"/audit_version",schemaPath:"#/properties/audit_version/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.min_compatible_peer!==void 0){let a=r.min_compatible_peer,n=e;if(typeof a!="string"&&a!==null)return ir.errors=[{instancePath:s+"/min_compatible_peer",schemaPath:"#/properties/min_compatible_peer/type",keyword:"type",params:{type:Xi.properties.min_compatible_peer.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.min_compatible_protocol!==void 0){let a=r.min_compatible_protocol,n=e;if(typeof a!="string"&&a!==null)return ir.errors=[{instancePath:s+"/min_compatible_protocol",schemaPath:"#/properties/min_compatible_protocol/type",keyword:"type",params:{type:Xi.properties.min_compatible_protocol.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.protocol_version!==void 0){let a=e;if(typeof r.protocol_version!="string")return ir.errors=[{instancePath:s+"/protocol_version",schemaPath:"#/properties/protocol_version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.server!==void 0){let a=e;if(typeof r.server!="string")return ir.errors=[{instancePath:s+"/server",schemaPath:"#/properties/server/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.version!==void 0){let a=e;if(typeof r.version!="string")return ir.errors=[{instancePath:s+"/version",schemaPath:"#/properties/version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}else return ir.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ir.errors=i,e===0}var to=ar;function ar(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.server===void 0&&(o="server")||r.version===void 0&&(o="version")||r.protocol_version===void 0&&(o="protocol_version"))return ar.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.audit_ready!==void 0){let a=e;if(typeof r.audit_ready!="boolean")return ar.errors=[{instancePath:s+"/audit_ready",schemaPath:"#/properties/audit_ready/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.audit_version!==void 0){let a=r.audit_version,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ar.errors=[{instancePath:s+"/audit_version",schemaPath:"#/properties/audit_version/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ar.errors=[{instancePath:s+"/audit_version",schemaPath:"#/properties/audit_version/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.min_compatible_peer!==void 0){let a=e;if(typeof r.min_compatible_peer!="string")return ar.errors=[{instancePath:s+"/min_compatible_peer",schemaPath:"#/properties/min_compatible_peer/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.min_compatible_protocol!==void 0){let a=e;if(typeof r.min_compatible_protocol!="string")return ar.errors=[{instancePath:s+"/min_compatible_protocol",schemaPath:"#/properties/min_compatible_protocol/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.protocol_version!==void 0){let a=e;if(typeof r.protocol_version!="string")return ar.errors=[{instancePath:s+"/protocol_version",schemaPath:"#/properties/protocol_version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.server!==void 0){let a=e;if(typeof r.server!="string")return ar.errors=[{instancePath:s+"/server",schemaPath:"#/properties/server/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.version!==void 0){let a=e;if(typeof r.version!="string")return ar.errors=[{instancePath:s+"/version",schemaPath:"#/properties/version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}else return ar.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ar.errors=i,e===0}var io=Le,$t={properties:{modifiers:{items:{$ref:"#/definitions/KeyModifier"},type:["array","null"]},ref:{description:"Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},settle_ms:{description:"Wait after the mouse move so hover-triggered UI can settle.",format:"uint32",minimum:0,type:["integer","null"]},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"};function Le(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Le.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(!Array.isArray(n)&&n!==null)return Le.errors=[{instancePath:s+"/modifiers",schemaPath:"#/properties/modifiers/type",keyword:"type",params:{type:$t.properties.modifiers.type},message:"must be array,null"}],!1;if(e===p&&Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Le.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:$t.properties.tab_id.type},message:"must be integer,null"}],!1;var o=p===e}else var o=!0;if(o)if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Le.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:$t.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Le.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var o=p===e}else var o=!0}}}}}}else return Le.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Le.errors=i,e===0}var ao=Fe;function Fe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Fe.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Fe.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0;if(o)if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Fe.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Fe.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var o=p===e}else var o=!0}}}}}}else return Fe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Fe.errors=i,e===0}var no=hs,Ca={properties:{session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]},wait_until:{anyOf:[{$ref:"#/definitions/WaitUntil"},{type:"null"}]}},required:["session_id"],type:"object"},Pi={description:"Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` \u2192 `load`\n* `DomContentLoaded` \u2192 `DOMContentLoaded`\n* `NetworkIdle` \u2192 `networkIdle`\n* `Commit` \u2192 `commit` (earliest event after the navigation actually\n commits to a new document)",enum:["load","domcontentloaded","networkidle","commit"],type:"string"};function ue(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ue.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="load"||r==="domcontentloaded"||r==="networkidle"||r==="commit"?(ue.errors=i,e===0):(ue.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Pi.enum},message:"must be equal to one of the allowed values"}],!1)}function hs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return hs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return hs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return hs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ca.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return hs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Ca.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return hs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=r.wait_until,p=e,l=e,m=!1,u=e;ue(n,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?ue.errors:i.concat(ue.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,hs.errors=i,!1}var t=p===e}else var t=!0}}}else return hs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return hs.errors=i,e===0}var oo=vs;var sn={description:"Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` \u2192 `load`\n* `DomContentLoaded` \u2192 `DOMContentLoaded`\n* `NetworkIdle` \u2192 `networkIdle`\n* `Commit` \u2192 `commit` (earliest event after the navigation actually\n commits to a new document)",enum:["load","domcontentloaded","networkidle","commit"],type:"string"};function fe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(fe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="load"||r==="domcontentloaded"||r==="networkidle"||r==="commit"?(fe.errors=i,e===0):(fe.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:sn.enum},message:"must be equal to one of the allowed values"}],!1)}function vs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return vs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return vs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return vs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return vs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return vs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=e,p=e,l=!1,m=e;fe(r.wait_until,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?fe.errors:i.concat(fe.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,vs.errors=i,!1}var t=n===e}else var t=!0}}}else return vs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return vs.errors=i,e===0}var po=bs,Va={properties:{session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]},wait_until:{anyOf:[{$ref:"#/definitions/WaitUntil"},{type:"null"}]}},required:["session_id"],type:"object"};function bs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return bs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return bs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return bs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Va.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return bs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Va.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return bs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=r.wait_until,p=e,l=e,m=!1,u=e;ue(n,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?ue.errors:i.concat(ue.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,bs.errors=i,!1}var t=p===e}else var t=!0}}}else return bs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return bs.errors=i,e===0}var lo=_s;function _s(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return _s.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return _s.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return _s.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return _s.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return _s.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=e,p=e,l=!1,m=e;fe(r.wait_until,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?fe.errors:i.concat(fe.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,_s.errors=i,!1}var t=n===e}else var t=!0}}}else return _s.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return _s.errors=i,e===0}var mo=Lr,Wa={properties:{session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's currently active tab.",format:"int64",type:["integer","null"]},timeout_ms:{description:`Hard upper bound on the wait; the extension also enforces its +own AbortController hookup (M7 stops listening for further +lifecycle events once exceeded). Defaults to 30s if omitted.`,format:"uint32",minimum:1,type:["integer","null"]},url:{type:"string"},wait_until:{anyOf:[{$ref:"#/definitions/WaitUntil"},{type:"null"}],description:"Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]."}},required:["session_id","url"],type:"object"};function Lr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.url===void 0&&(a="url"))return Lr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Lr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Lr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Wa.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Lr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Wa.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Lr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t){if(r.url!==void 0){let n=e;if(typeof r.url!="string")return Lr.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=r.wait_until,p=e,l=e,m=!1,u=e;ue(n,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?ue.errors:i.concat(ue.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,Lr.errors=i,!1}var t=p===e}else var t=!0}}}}else return Lr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Lr.errors=i,e===0}var uo=Fr;function Fr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.url===void 0&&(a="url"))return Fr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Fr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Fr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Fr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Fr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t){if(r.url!==void 0){let n=e;if(typeof r.url!="string")return Fr.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=e,p=e,l=!1,m=e;fe(r.wait_until,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?fe.errors:i.concat(fe.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,Fr.errors=i,!1}var t=n===e}else var t=!0}}}}else return Fr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Fr.errors=i,e===0}var fo=nr,Yi={properties:{limit:{description:"Maximum number of entries to return. Extension applies safe defaults and caps.",format:"uint32",minimum:1,type:["integer","null"]},max_text_chars:{description:"Maximum characters returned per URL / error text. Extension applies safe defaults and caps.",format:"uint32",minimum:1,type:["integer","null"]},session_id:{type:"string"},since:{description:"Return entries with sequence strictly greater than this cursor.",format:"uint64",minimum:0,type:["integer","null"]},tab_id:{description:"Optional target tab. Defaults to the Agent Window's currently active tab.",format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function nr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return nr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.limit!==void 0){let a=r.limit,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return nr.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/type",keyword:"type",params:{type:Yi.properties.limit.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return nr.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_text_chars!==void 0){let a=r.max_text_chars,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return nr.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/type",keyword:"type",params:{type:Yi.properties.max_text_chars.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return nr.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return nr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.since!==void 0){let a=r.since,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return nr.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:Yi.properties.since.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return nr.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return nr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Yi.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}}}else return nr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return nr.errors=i,e===0}var yo=or;function or(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return or.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.limit!==void 0){let a=r.limit,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return or.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return or.errors=[{instancePath:s+"/limit",schemaPath:"#/properties/limit/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_text_chars!==void 0){let a=r.max_text_chars,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return or.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return or.errors=[{instancePath:s+"/max_text_chars",schemaPath:"#/properties/max_text_chars/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return or.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.since!==void 0){let a=r.since,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return or.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return or.errors=[{instancePath:s+"/since",schemaPath:"#/properties/since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return or.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}}else return or.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return or.errors=i,e===0}var co=Je,Qi={description:"Parameters for `tool.observe` \u2014 produce a semantic VOM observation\nfor one tab plus a fresh `@e` ref-store on the extension side.\n\nUnlike `tool.snapshot`, this path may run bounded perception probes\nsuch as hover-surface discovery, but only when `probe_hover` asks for\nthem. It must not submit input, click, navigate, or otherwise commit\npage state.",properties:{cursor:{description:"Continue a retained observation; does not recapture the page.",type:["string","null"]},debug_surfaces:{default:!1,description:"Include implementation diagnostics for conditional surface probes.",type:"boolean"},max_depth:{description:"Cap the depth of the rendered VOM tree.",format:"uint32",minimum:0,type:["integer","null"]},max_tokens:{description:`Soft cap on rendered tokens (approximate; extension uses a +best-effort heuristic based on character count).`,format:"uint32",minimum:0,type:["integer","null"]},probe_hover:{default:!1,description:`Opt in to active hover probing: the extension moves the real cursor +over a bounded set of controls to discover hover-only menus and +tooltips. + +Off by default. Probing costs seconds of wall clock, mutates the live +page, and pays off only on pages whose content is genuinely hidden +behind hover. Request it when a static observation looks like it is +missing hover-revealed structure.`,type:"boolean"},session_id:{type:"string"},tab_id:{description:`Optional target tab. Defaults to the Agent Window's currently +active tab.`,format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function Je(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Je.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.cursor!==void 0){let a=r.cursor,n=e;if(typeof a!="string"&&a!==null)return Je.errors=[{instancePath:s+"/cursor",schemaPath:"#/properties/cursor/type",keyword:"type",params:{type:Qi.properties.cursor.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.debug_surfaces!==void 0){let a=e;if(typeof r.debug_surfaces!="boolean")return Je.errors=[{instancePath:s+"/debug_surfaces",schemaPath:"#/properties/debug_surfaces/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.max_depth!==void 0){let a=r.max_depth,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Je.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/type",keyword:"type",params:{type:Qi.properties.max_depth.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Je.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_tokens!==void 0){let a=r.max_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Je.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/type",keyword:"type",params:{type:Qi.properties.max_tokens.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Je.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.probe_hover!==void 0){let a=e;if(typeof r.probe_hover!="boolean")return Je.errors=[{instancePath:s+"/probe_hover",schemaPath:"#/properties/probe_hover/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Je.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Je.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Qi.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}}}}}else return Je.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Je.errors=i,e===0}var go=He;function He(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return He.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.cursor!==void 0){let a=e;if(typeof r.cursor!="string")return He.errors=[{instancePath:s+"/cursor",schemaPath:"#/properties/cursor/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.debug_surfaces!==void 0){let a=e;if(typeof r.debug_surfaces!="boolean")return He.errors=[{instancePath:s+"/debug_surfaces",schemaPath:"#/properties/debug_surfaces/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.max_depth!==void 0){let a=r.max_depth,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return He.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return He.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_tokens!==void 0){let a=r.max_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return He.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return He.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.probe_hover!==void 0){let a=e;if(typeof r.probe_hover!="boolean")return He.errors=[{instancePath:s+"/probe_hover",schemaPath:"#/properties/probe_hover/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return He.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return He.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}}}}else return He.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return He.errors=i,e===0}var ho=Ae,Rt={properties:{hold_ms:{description:"Hold the key down for this many milliseconds between `keyDown`\nand `keyUp`. Useful for testing long-press handlers.",format:"uint32",minimum:0,type:["integer","null"]},key:{description:"Logical key name. Accepts CDP `key` strings (`Enter`, `Escape`,\n`ArrowDown`, single characters like `a`), or a compound\nexpression such as `Ctrl+A` / `Meta+Shift+P`. Modifiers in the\ncompound form combine with anything supplied via `modifiers`.",type:"string"},modifiers:{items:{$ref:"#/definitions/KeyModifier"},type:["array","null"]},ref:{description:"Optional target to focus before dispatching the key.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id","key"],type:"object"};function Ae(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.key===void 0&&(a="key"))return Ae.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.hold_ms!==void 0){let n=r.hold_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Ae.errors=[{instancePath:s+"/hold_ms",schemaPath:"#/properties/hold_ms/type",keyword:"type",params:{type:Rt.properties.hold_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Ae.errors=[{instancePath:s+"/hold_ms",schemaPath:"#/properties/hold_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.key!==void 0){let n=e;if(typeof r.key!="string")return Ae.errors=[{instancePath:s+"/key",schemaPath:"#/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(!Array.isArray(n)&&n!==null)return Ae.errors=[{instancePath:s+"/modifiers",schemaPath:"#/properties/modifiers/type",keyword:"type",params:{type:Rt.properties.modifiers.type},message:"must be array,null"}],!1;if(e===p&&Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0}}}}}}}else return Ae.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ae.errors=i,e===0}var vo=Oe;function Oe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.key===void 0&&(a="key"))return Oe.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.hold_ms!==void 0){let n=r.hold_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Oe.errors=[{instancePath:s+"/hold_ms",schemaPath:"#/properties/hold_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Oe.errors=[{instancePath:s+"/hold_ms",schemaPath:"#/properties/hold_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.key!==void 0){let n=e;if(typeof r.key!="string")return Oe.errors=[{instancePath:s+"/key",schemaPath:"#/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0}}}}}}}else return Oe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Oe.errors=i,e===0}var bo=wt,tn={properties:{session_id:{type:"string"},timeout_ms:{format:"uint32",minimum:0,type:["integer","null"]}},required:["session_id"],type:"object"};function wt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return wt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return wt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return wt.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:tn.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return wt.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}else return wt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return wt.errors=i,e===0}var _o=Pt;function Pt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Pt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Pt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Pt.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Pt.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}else return Pt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Pt.errors=i,e===0}var wo=Ee,_t={properties:{max_page_tokens:{format:"uint32",minimum:0,type:["integer","null"]},purpose:{type:["string","null"]},redact_values:{type:["boolean","null"]},session_id:{type:"string"},supports_tab_switch_steps:{description:"Client can decode the v3 `switch_tab` step variant.",type:["boolean","null"]},tab_id:{format:"int64",type:["integer","null"]},trace_version:{description:"Desired trace export format. Omitted means v2; `3` requests v3.",format:"uint32",minimum:0,type:["integer","null"]},url:{type:["string","null"]}},required:["session_id"],type:"object"};function Ee(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ee.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_page_tokens!==void 0){let a=r.max_page_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ee.errors=[{instancePath:s+"/max_page_tokens",schemaPath:"#/properties/max_page_tokens/type",keyword:"type",params:{type:_t.properties.max_page_tokens.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ee.errors=[{instancePath:s+"/max_page_tokens",schemaPath:"#/properties/max_page_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.purpose!==void 0){let a=r.purpose,n=e;if(typeof a!="string"&&a!==null)return Ee.errors=[{instancePath:s+"/purpose",schemaPath:"#/properties/purpose/type",keyword:"type",params:{type:_t.properties.purpose.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.redact_values!==void 0){let a=r.redact_values,n=e;if(typeof a!="boolean"&&a!==null)return Ee.errors=[{instancePath:s+"/redact_values",schemaPath:"#/properties/redact_values/type",keyword:"type",params:{type:_t.properties.redact_values.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ee.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.supports_tab_switch_steps!==void 0){let a=r.supports_tab_switch_steps,n=e;if(typeof a!="boolean"&&a!==null)return Ee.errors=[{instancePath:s+"/supports_tab_switch_steps",schemaPath:"#/properties/supports_tab_switch_steps/type",keyword:"type",params:{type:_t.properties.supports_tab_switch_steps.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ee.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:_t.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.trace_version!==void 0){let a=r.trace_version,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Ee.errors=[{instancePath:s+"/trace_version",schemaPath:"#/properties/trace_version/type",keyword:"type",params:{type:_t.properties.trace_version.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ee.errors=[{instancePath:s+"/trace_version",schemaPath:"#/properties/trace_version/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.url!==void 0){let a=r.url,n=e;if(typeof a!="string"&&a!==null)return Ee.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:_t.properties.url.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0}}}}}}}else return Ee.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ee.errors=i,e===0}var Po=Se;function Se(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Se.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_page_tokens!==void 0){let a=r.max_page_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Se.errors=[{instancePath:s+"/max_page_tokens",schemaPath:"#/properties/max_page_tokens/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Se.errors=[{instancePath:s+"/max_page_tokens",schemaPath:"#/properties/max_page_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.purpose!==void 0){let a=e;if(typeof r.purpose!="string")return Se.errors=[{instancePath:s+"/purpose",schemaPath:"#/properties/purpose/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.redact_values!==void 0){let a=e;if(typeof r.redact_values!="boolean")return Se.errors=[{instancePath:s+"/redact_values",schemaPath:"#/properties/redact_values/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Se.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.supports_tab_switch_steps!==void 0){let a=e;if(typeof r.supports_tab_switch_steps!="boolean")return Se.errors=[{instancePath:s+"/supports_tab_switch_steps",schemaPath:"#/properties/supports_tab_switch_steps/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Se.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.trace_version!==void 0){let a=r.trace_version,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Se.errors=[{instancePath:s+"/trace_version",schemaPath:"#/properties/trace_version/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Se.errors=[{instancePath:s+"/trace_version",schemaPath:"#/properties/trace_version/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.url!==void 0){let a=e;if(typeof r.url!="string")return Se.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}else return Se.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Se.errors=i,e===0}var ko=Ai;function Ai(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.session_id===void 0&&(t="session_id"))return Ai.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.session_id!==void 0&&typeof r.session_id!="string")return Ai.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return Ai.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ai.errors=i,e===0}var No=Oi;function Oi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.session_id===void 0&&(t="session_id"))return Oi.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.session_id!==void 0&&typeof r.session_id!="string")return Oi.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return Oi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Oi.errors=i,e===0}var Do=Jr,ga={properties:{hard:{description:"When `true`, bypass the HTTP cache (CDP `Page.reload(ignoreCache=true)`).",type:["boolean","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]},wait_until:{anyOf:[{$ref:"#/definitions/WaitUntil"},{type:"null"}]}},required:["session_id"],type:"object"};function Jr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Jr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.hard!==void 0){let n=r.hard,p=e;if(typeof n!="boolean"&&n!==null)return Jr.errors=[{instancePath:s+"/hard",schemaPath:"#/properties/hard/type",keyword:"type",params:{type:ga.properties.hard.type},message:"must be boolean,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Jr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Jr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ga.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Jr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:ga.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Jr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=r.wait_until,p=e,l=e,m=!1,u=e;ue(n,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?ue.errors:i.concat(ue.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,Jr.errors=i,!1}var t=p===e}else var t=!0}}}}else return Jr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Jr.errors=i,e===0}var qo=Hr;function Hr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Hr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.hard!==void 0){let n=e;if(typeof r.hard!="boolean")return Hr.errors=[{instancePath:s+"/hard",schemaPath:"#/properties/hard/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Hr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Hr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Hr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Hr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=e,p=e,l=!1,m=e;fe(r.wait_until,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?fe.errors:i.concat(fe.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,Hr.errors=i,!1}var t=n===e}else var t=!0}}}}else return Hr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Hr.errors=i,e===0}var jo=pr,Zi={properties:{completion_criteria:{anyOf:[{$ref:"#/definitions/HelpCompletionCriteria"},{type:"null"}],description:`Optional explicit success detector. Navigation by itself is not a +completion signal; these criteria must match before the tool can +auto-complete without the user clicking Done.`},prompt:{description:"Message shown to the user explaining what to do.",type:"string"},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},targets:{description:"Optional components to scroll to + flash-highlight.",items:{$ref:"#/definitions/HelpTarget"},type:["array","null"]},timeout_ms:{description:`Hard upper bound on the wait. Defaults to 300000 (5 min), +enforced daemon-side via the generic tool timeout.`,format:"uint32",minimum:1,type:["integer","null"]},title:{description:`Optional custom title for the help overlay. Falls back to the +extension's default localized title when omitted.`,type:["string","null"]}},required:["session_id","prompt"],type:"object"},Yt={properties:{all:{items:{$ref:"#/definitions/HelpCompletionCondition"},maxItems:8,type:["array","null"]},any:{items:{$ref:"#/definitions/HelpCompletionCondition"},maxItems:8,type:["array","null"]},stable_for_ms:{format:"uint32",minimum:0,type:["integer","null"]}},type:"object"},Tt={properties:{selector_exists:{type:["string","null"]},selector_missing:{type:["string","null"]},text_exists:{type:["string","null"]},text_missing:{type:["string","null"]},url_contains:{type:["string","null"]},url_matches:{description:"RE2-compatible URL regex (maximum 128 characters). Backtracking-only syntax is rejected.",maxLength:128,type:["string","null"]}},type:"object"},Ha=$a().default;function ae(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.selector_exists!==void 0){let o=r.selector_exists,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/selector_exists",schemaPath:"#/properties/selector_exists/type",keyword:"type",params:{type:Tt.properties.selector_exists.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector_missing!==void 0){let o=r.selector_missing,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/selector_missing",schemaPath:"#/properties/selector_missing/type",keyword:"type",params:{type:Tt.properties.selector_missing.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t){if(r.text_exists!==void 0){let o=r.text_exists,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/text_exists",schemaPath:"#/properties/text_exists/type",keyword:"type",params:{type:Tt.properties.text_exists.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t){if(r.text_missing!==void 0){let o=r.text_missing,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/text_missing",schemaPath:"#/properties/text_missing/type",keyword:"type",params:{type:Tt.properties.text_missing.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t){if(r.url_contains!==void 0){let o=r.url_contains,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/url_contains",schemaPath:"#/properties/url_contains/type",keyword:"type",params:{type:Tt.properties.url_contains.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t)if(r.url_matches!==void 0){let o=r.url_matches,a=e;if(typeof o!="string"&&o!==null)return ae.errors=[{instancePath:s+"/url_matches",schemaPath:"#/properties/url_matches/type",keyword:"type",params:{type:Tt.properties.url_matches.type},message:"must be string,null"}],!1;if(e===a&&typeof o=="string"&&Ha(o)>128)return ae.errors=[{instancePath:s+"/url_matches",schemaPath:"#/properties/url_matches/maxLength",keyword:"maxLength",params:{limit:128},message:"must NOT have more than 128 characters"}],!1;var t=a===e}else var t=!0}}}}}else return ae.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ae.errors=i,e===0}function Ar(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.all!==void 0){let n=r.all,p=e;if(!Array.isArray(n)&&n!==null)return Ar.errors=[{instancePath:s+"/all",schemaPath:"#/properties/all/type",keyword:"type",params:{type:Yt.properties.all.type},message:"must be array,null"}],!1;if(e===p&&Array.isArray(n)){if(n.length>8)return Ar.errors=[{instancePath:s+"/all",schemaPath:"#/properties/all/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var t=!0;let l=n.length;for(let m=0;m8)return Ar.errors=[{instancePath:s+"/any",schemaPath:"#/properties/any/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var a=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}else return Ar.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ar.errors=i,e===0}var Ma={description:"One component the user is asked to look at / interact with. Exactly\none of `ref` / `selector` should be supplied (mirrors the\nclick/fill convention). When neither matches a live element the\noverlay still shows the prompt and reports the miss via\n[`ResolvedTarget`].",properties:{ref:{type:["string","null"]},selector:{type:["string","null"]}},type:"object"};function Ot(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.ref!==void 0){let o=r.ref,a=e;if(typeof o!="string"&&o!==null)return Ot.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:Ma.properties.ref.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0;if(t)if(r.selector!==void 0){let o=r.selector,a=e;if(typeof o!="string"&&o!==null)return Ot.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:Ma.properties.selector.type},message:"must be string,null"}],!1;var t=a===e}else var t=!0}else return Ot.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ot.errors=i,e===0}function pr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.session_id===void 0&&(n="session_id")||r.prompt===void 0&&(n="prompt"))return pr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.completion_criteria!==void 0){let p=r.completion_criteria,l=e,m=e,u=!1,y=e;Ar(p,{instancePath:s+"/completion_criteria",parentData:r,parentDataProperty:"completion_criteria",rootData:f})||(i=i===null?Ar.errors:i.concat(Ar.errors),e=i.length);var t=y===e;if(u=u||t,!u){let d=e;if(p!==null){let v={instancePath:s+"/completion_criteria",schemaPath:"#/properties/completion_criteria/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var t=d===e;u=u||t}if(u)e=m,i!==null&&(m?i.length=m:i=null);else{let d={instancePath:s+"/completion_criteria",schemaPath:"#/properties/completion_criteria/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,pr.errors=i,!1}var o=l===e}else var o=!0;if(o){if(r.prompt!==void 0){let p=e;if(typeof r.prompt!="string")return pr.errors=[{instancePath:s+"/prompt",schemaPath:"#/properties/prompt/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0;if(o){if(r.session_id!==void 0){let p=e;if(typeof r.session_id!="string")return pr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let p=r.tab_id,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p))&&p!==null)return pr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Zi.properties.tab_id.type},message:"must be integer,null"}],!1;var o=l===e}else var o=!0;if(o){if(r.targets!==void 0){let p=r.targets,l=e;if(!Array.isArray(p)&&p!==null)return pr.errors=[{instancePath:s+"/targets",schemaPath:"#/properties/targets/type",keyword:"type",params:{type:Zi.properties.targets.type},message:"must be array,null"}],!1;if(e===l&&Array.isArray(p)){var a=!0;let u=p.length;for(let y=0;y=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0;if(o)if(r.title!==void 0){let p=r.title,l=e;if(typeof p!="string"&&p!==null)return pr.errors=[{instancePath:s+"/title",schemaPath:"#/properties/title/type",keyword:"type",params:{type:Zi.properties.title.type},message:"must be string,null"}],!1;var o=l===e}else var o=!0}}}}}}else return pr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return pr.errors=i,e===0}var xo=lr;function qe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.selector_exists!==void 0){let o=e;if(typeof r.selector_exists!="string")return qe.errors=[{instancePath:s+"/selector_exists",schemaPath:"#/properties/selector_exists/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.selector_missing!==void 0){let o=e;if(typeof r.selector_missing!="string")return qe.errors=[{instancePath:s+"/selector_missing",schemaPath:"#/properties/selector_missing/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.text_exists!==void 0){let o=e;if(typeof r.text_exists!="string")return qe.errors=[{instancePath:s+"/text_exists",schemaPath:"#/properties/text_exists/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.text_missing!==void 0){let o=e;if(typeof r.text_missing!="string")return qe.errors=[{instancePath:s+"/text_missing",schemaPath:"#/properties/text_missing/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.url_contains!==void 0){let o=e;if(typeof r.url_contains!="string")return qe.errors=[{instancePath:s+"/url_contains",schemaPath:"#/properties/url_contains/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t)if(r.url_matches!==void 0){let o=r.url_matches,a=e;if(e===a)if(typeof o=="string"){if(Ha(o)>128)return qe.errors=[{instancePath:s+"/url_matches",schemaPath:"#/properties/url_matches/maxLength",keyword:"maxLength",params:{limit:128},message:"must NOT have more than 128 characters"}],!1}else return qe.errors=[{instancePath:s+"/url_matches",schemaPath:"#/properties/url_matches/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}else return qe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return qe.errors=i,e===0}function Or(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.all!==void 0){let n=r.all,p=e;if(e===p)if(Array.isArray(n)){if(n.length>8)return Or.errors=[{instancePath:s+"/all",schemaPath:"#/properties/all/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var t=!0;let l=n.length;for(let m=0;m8)return Or.errors=[{instancePath:s+"/any",schemaPath:"#/properties/any/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var a=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}else return Or.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Or.errors=i,e===0}function Et(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.ref!==void 0){let o=e;if(typeof r.ref!="string")return Et.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t)if(r.selector!==void 0){let o=e;if(typeof r.selector!="string")return Et.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0}else return Et.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Et.errors=i,e===0}function lr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.session_id===void 0&&(n="session_id")||r.prompt===void 0&&(n="prompt"))return lr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.completion_criteria!==void 0){let p=e,l=e,m=!1,u=e;Or(r.completion_criteria,{instancePath:s+"/completion_criteria",parentData:r,parentDataProperty:"completion_criteria",rootData:f})||(i=i===null?Or.errors:i.concat(Or.errors),e=i.length);var t=u===e;if(m=m||t,m)e=l,i!==null&&(l?i.length=l:i=null);else{let y={instancePath:s+"/completion_criteria",schemaPath:"#/properties/completion_criteria/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,lr.errors=i,!1}var o=p===e}else var o=!0;if(o){if(r.prompt!==void 0){let p=e;if(typeof r.prompt!="string")return lr.errors=[{instancePath:s+"/prompt",schemaPath:"#/properties/prompt/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0;if(o){if(r.session_id!==void 0){let p=e;if(typeof r.session_id!="string")return lr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let p=r.tab_id,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return lr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=l===e}else var o=!0;if(o){if(r.targets!==void 0){let p=r.targets,l=e;if(e===l)if(Array.isArray(p)){var a=!0;let u=p.length;for(let y=0;y=",limit:1},message:"must be >= 1"}],!1;var o=l===e}else var o=!0;if(o)if(r.title!==void 0){let p=e;if(typeof r.title!="string")return lr.errors=[{instancePath:s+"/title",schemaPath:"#/properties/title/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=p===e}else var o=!0}}}}}}else return lr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return lr.errors=i,e===0}var Ao=ws,Ua={description:"Scroll the session's active web page from top to bottom. PNG bytes are\nexported in bounded chunks through `tool.screenshot_read`, then released.",properties:{scope:{anyOf:[{$ref:"#/definitions/ScreenshotScope"},{type:"null"}],description:"Follow appended content (default), or capture the initial document height."},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{description:"Capture and PNG encoding deadline; defaults to 120000 milliseconds.",format:"uint32",minimum:0,type:["integer","null"]}},required:["session_id"],type:"object"},Ba={enum:["follow","current"],type:"string"};function Qt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Qt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="follow"||r==="current"?(Qt.errors=i,e===0):(Qt.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ba.enum},message:"must be equal to one of the allowed values"}],!1)}function ws(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return ws.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.scope!==void 0){let n=r.scope,p=e,l=e,m=!1,u=e;Qt(n,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?Qt.errors:i.concat(Qt.errors),e=i.length);var t=u===e;if(m=m||t,!m){let y=e;if(n!==null){let b={instancePath:s+"/scope",schemaPath:"#/properties/scope/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[b]:i.push(b),e++}var t=y===e;m=m||t}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let y={instancePath:s+"/scope",schemaPath:"#/properties/scope/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,ws.errors=i,!1}var o=p===e}else var o=!0;if(o){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return ws.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=n===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return ws.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ua.properties.tab_id.type},message:"must be integer,null"}],!1;var o=p===e}else var o=!0;if(o)if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return ws.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:Ua.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return ws.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}else return ws.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ws.errors=i,e===0}var Oo=Ps;var an={enum:["follow","current"],type:"string"};function Zt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(Zt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="follow"||r==="current"?(Zt.errors=i,e===0):(Zt.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:an.enum},message:"must be equal to one of the allowed values"}],!1)}function Ps(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Ps.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.scope!==void 0){let n=e,p=e,l=!1,m=e;Zt(r.scope,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?Zt.errors:i.concat(Zt.errors),e=i.length);var t=m===e;if(l=l||t,l)e=p,i!==null&&(p?i.length=p:i=null);else{let u={instancePath:s+"/scope",schemaPath:"#/properties/scope/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[u]:i.push(u),e++,Ps.errors=i,!1}var o=n===e}else var o=!0;if(o){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Ps.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=n===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Ps.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0;if(o)if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Ps.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Ps.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}else return Ps.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ps.errors=i,e===0}var Eo=kt,Ia={description:"Parameters for `tool.screenshot`. Omit `ref` to capture the visible\ntab; pass an `@e` ref from the last `tool.snapshot` to crop to\nthat element.",properties:{ref:{description:'Optional `@e` ref allocated by the last `tool.snapshot`.\nAccepts both `"e3"` and `"@e3"`.',type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function kt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return kt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return kt.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:Ia.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return kt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return kt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:Ia.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}else return kt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return kt.errors=i,e===0}var So=Nt;function Nt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Nt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return Nt.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Nt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Nt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}else return Nt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Nt.errors=i,e===0}var $o=Ys;function Ys(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.capture_id===void 0&&(o="capture_id")||r.offset===void 0&&(o="offset"))return Ys.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.capture_id!==void 0){let a=e;if(typeof r.capture_id!="string")return Ys.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.offset!==void 0){let a=r.offset,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ys.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ys.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ys.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}else return Ys.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ys.errors=i,e===0}var Ro=Qs;function Qs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.capture_id===void 0&&(o="capture_id")||r.offset===void 0&&(o="offset"))return Qs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.capture_id!==void 0){let a=e;if(typeof r.capture_id!="string")return Qs.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.offset!==void 0){let a=r.offset,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Qs.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Qs.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Qs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}else return Qs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Qs.errors=i,e===0}var To=Ct;function Ct(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.capture_id===void 0&&(o="capture_id"))return Ct.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.capture_id!==void 0){let a=e;if(typeof r.capture_id!="string")return Ct.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ct.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return Ct.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ct.errors=i,e===0}var Co=Vt;function Vt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.capture_id===void 0&&(o="capture_id"))return Vt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.capture_id!==void 0){let a=e;if(typeof r.capture_id!="string")return Vt.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Vt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return Vt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Vt.errors=i,e===0}var Vo=Br,ea={properties:{ref:{description:"Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"};function Br(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Br.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=r.ref,n=e;if(typeof a!="string"&&a!==null)return Br.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:ea.properties.ref.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.selector!==void 0){let a=r.selector,n=e;if(typeof a!="string"&&a!==null)return Br.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:ea.properties.selector.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Br.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Br.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ea.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Br.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:ea.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Br.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return Br.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Br.errors=i,e===0}var Wo=Kr;function Kr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Kr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.ref!==void 0){let a=e;if(typeof r.ref!="string")return Kr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.selector!==void 0){let a=e;if(typeof r.selector!="string")return Kr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Kr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Kr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.timeout_ms!==void 0){let a=r.timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Kr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<1||isNaN(a)))return Kr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=n===e}else var t=!0}}}}else return Kr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Kr.errors=i,e===0}var Mo=mr,ra={properties:{ref:{description:'Optional `@e` ref allocated by the last `tool.snapshot`.\nMutually exclusive with `selector`. Accepts both `"e3"` and\n`"@e3"`.',type:["string","null"]},selector:{description:"CSS selector resolved against the live DOM. Mutually exclusive\nwith `ref_`.",type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{description:"Maximum time the daemon waits for the tool call before timing out.",format:"uint32",minimum:1,type:["integer","null"]},values:{description:"Option `value` strings to set as the final selection. For a\nsingle-select `` the list replaces the current selection\n(an empty list clears all selections).",items:{type:"string"},type:"array"}},required:["session_id","values"],type:"object"};function mr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.values===void 0&&(a="values"))return mr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.ref!==void 0){let n=r.ref,p=e;if(typeof n!="string"&&n!==null)return mr.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:ra.properties.ref.type},message:"must be string,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.selector!==void 0){let n=r.selector,p=e;if(typeof n!="string"&&n!==null)return mr.errors=[{instancePath:s+"/selector",schemaPath:"#/properties/selector/type",keyword:"type",params:{type:ra.properties.selector.type},message:"must be string,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return mr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return mr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ra.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return mr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:ra.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return mr.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.values!==void 0){let n=r.values,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.values!==void 0){let n=r.values,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return kr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return kr.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:sa.properties.width.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return kr.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}else return kr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return kr.errors=i,e===0}var zo=Nr;function Nr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Nr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.browser_instance_id!==void 0){let a=e;if(typeof r.browser_instance_id!="string")return Nr.errors=[{instancePath:s+"/browser_instance_id",schemaPath:"#/properties/browser_instance_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.focused!==void 0){let a=e;if(typeof r.focused!="boolean")return Nr.errors=[{instancePath:s+"/focused",schemaPath:"#/properties/focused/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.height!==void 0){let a=r.height,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Nr.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Nr.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Nr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Nr.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Nr.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}else return Nr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Nr.errors=i,e===0}var Lo=Ei;function Ei(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.session_id===void 0&&(t="session_id"))return Ei.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.session_id!==void 0&&typeof r.session_id!="string")return Ei.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return Ei.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ei.errors=i,e===0}var Fo=Si;function Si(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.session_id===void 0&&(t="session_id"))return Si.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.session_id!==void 0&&typeof r.session_id!="string")return Si.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return Si.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Si.errors=i,e===0}var Jo=Gr,ha={description:"Parameters for `tool.snapshot` \u2014 produce an indented accessibility\ntree for one tab plus a fresh `@e` ref-store on the extension\nside (design \xA74 / \xA77).",properties:{max_depth:{description:'Cap the depth of the rendered tree (defense against very deep\npages). Implementation-defined default; agents typically use\n`Some(16)` for "browse and read" prompts.',format:"uint32",minimum:0,type:["integer","null"]},max_tokens:{description:`Soft cap on rendered tokens (approximate; extension uses a +best-effort heuristic based on character count).`,format:"uint32",minimum:0,type:["integer","null"]},session_id:{type:"string"},tab_id:{description:`Optional target tab. Defaults to the Agent Window's currently +active tab.`,format:"int64",type:["integer","null"]}},required:["session_id"],type:"object"};function Gr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Gr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_depth!==void 0){let a=r.max_depth,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Gr.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/type",keyword:"type",params:{type:ha.properties.max_depth.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Gr.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_tokens!==void 0){let a=r.max_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Gr.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/type",keyword:"type",params:{type:ha.properties.max_tokens.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Gr.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Gr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Gr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:ha.properties.tab_id.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0}}}else return Gr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Gr.errors=i,e===0}var Ho=Xr;function Xr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Xr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max_depth!==void 0){let a=r.max_depth,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Xr.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Xr.errors=[{instancePath:s+"/max_depth",schemaPath:"#/properties/max_depth/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_tokens!==void 0){let a=r.max_tokens,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Xr.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Xr.errors=[{instancePath:s+"/max_tokens",schemaPath:"#/properties/max_tokens/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Xr.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Xr.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}else return Xr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Xr.errors=i,e===0}var Bo=ks,za={description:"Params for `tool.tab_borrow`. Moves a *user* tab into the\nrequesting session's Agent Window, recording its original window /\nindex so `tab_return` (or session_stop) can put it back.",properties:{confirm:{description:"Legacy input, ignored. Browser settings decide whether confirmation is required.",type:["boolean","null"]},confirmation_timeout_ms:{description:"Maximum time to wait for user confirmation (default 60 seconds).",format:"uint32",minimum:0,type:["integer","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:"integer"}},required:["tab_id","session_id"],type:"object"};function ks(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return ks.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.confirm!==void 0){let a=r.confirm,n=e;if(typeof a!="boolean"&&a!==null)return ks.errors=[{instancePath:s+"/confirm",schemaPath:"#/properties/confirm/type",keyword:"type",params:{type:za.properties.confirm.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.confirmation_timeout_ms!==void 0){let a=r.confirmation_timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ks.errors=[{instancePath:s+"/confirmation_timeout_ms",schemaPath:"#/properties/confirmation_timeout_ms/type",keyword:"type",params:{type:za.properties.confirmation_timeout_ms.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ks.errors=[{instancePath:s+"/confirmation_timeout_ms",schemaPath:"#/properties/confirmation_timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return ks.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ks.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}else return ks.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ks.errors=i,e===0}var Ko=Ns;function Ns(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return Ns.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.confirm!==void 0){let a=e;if(typeof r.confirm!="boolean")return Ns.errors=[{instancePath:s+"/confirm",schemaPath:"#/properties/confirm/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.confirmation_timeout_ms!==void 0){let a=r.confirmation_timeout_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ns.errors=[{instancePath:s+"/confirmation_timeout_ms",schemaPath:"#/properties/confirmation_timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ns.errors=[{instancePath:s+"/confirmation_timeout_ms",schemaPath:"#/properties/confirmation_timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ns.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ns.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}else return Ns.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ns.errors=i,e===0}var Go=Wt;function Wt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return Wt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Wt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Wt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return Wt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Wt.errors=i,e===0}var Xo=Mt;function Mt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return Mt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Mt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Mt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return Mt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Mt.errors=i,e===0}var Yo=Zs,va={description:"Params for `tool.tab_create`. The new tab is always created inside\nthe requesting session's Agent Window (design \xA76 sandbox rule \u2014\nagents never spawn tabs in user windows).",properties:{active:{description:"Focus the new tab? Defaults to `true` (matches `chrome.tabs.create`).",type:["boolean","null"]},index:{description:`Insertion index within the Agent Window's tab strip. Omit to +append at the end.`,format:"int32",type:["integer","null"]},session_id:{type:"string"},url:{description:"Destination URL. Defaults to `chrome://newtab` when omitted.",type:["string","null"]}},required:["session_id"],type:"object"};function Zs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Zs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.active!==void 0){let a=r.active,n=e;if(typeof a!="boolean"&&a!==null)return Zs.errors=[{instancePath:s+"/active",schemaPath:"#/properties/active/type",keyword:"type",params:{type:va.properties.active.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.index!==void 0){let a=r.index,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return Zs.errors=[{instancePath:s+"/index",schemaPath:"#/properties/index/type",keyword:"type",params:{type:va.properties.index.type},message:"must be integer,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Zs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.url!==void 0){let a=r.url,n=e;if(typeof a!="string"&&a!==null)return Zs.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:va.properties.url.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0}}}else return Zs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Zs.errors=i,e===0}var Qo=et;function et(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return et.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.active!==void 0){let a=e;if(typeof r.active!="boolean")return et.errors=[{instancePath:s+"/active",schemaPath:"#/properties/active/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.index!==void 0){let a=r.index,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return et.errors=[{instancePath:s+"/index",schemaPath:"#/properties/index/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return et.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.url!==void 0){let a=e;if(typeof r.url!="string")return et.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}else return et.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return et.errors=i,e===0}var Zo=$i;var nn={description:"View scope for [`TabListParams`] (\xA76 sandbox table).\n\n* `User` \u2014 tabs that live in any window other than an Agent Window.\n* `Agent` \u2014 tabs in the requesting session's Agent Window only.\n* `All` \u2014 both of the above; never reveals other sessions' Agent\n Windows (cross-session isolation per \xA76).",enum:["user","agent","all"],type:"string"};function ei(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ei.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="user"||r==="agent"||r==="all"?(ei.errors=i,e===0):(ei.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:nn.enum},message:"must be equal to one of the allowed values"}],!1)}function $i(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return $i.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.scope!==void 0){let a=e;ei(r.scope,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?ei.errors:i.concat(ei.errors),e=i.length);var t=a===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return $i.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return $i.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return $i.errors=i,e===0}var ep=Ri;var on={description:"View scope for [`TabListParams`] (\xA76 sandbox table).\n\n* `User` \u2014 tabs that live in any window other than an Agent Window.\n* `Agent` \u2014 tabs in the requesting session's Agent Window only.\n* `All` \u2014 both of the above; never reveals other sessions' Agent\n Windows (cross-session isolation per \xA76).",enum:["user","agent","all"],type:"string"};function ri(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ri.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="user"||r==="agent"||r==="all"?(ri.errors=i,e===0):(ri.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:on.enum},message:"must be equal to one of the allowed values"}],!1)}function Ri(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id"))return Ri.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.scope!==void 0){let a=e;ri(r.scope,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?ri.errors:i.concat(ri.errors),e=i.length);var t=a===e}else var t=!0;if(t)if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ri.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return Ri.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ri.errors=i,e===0}var rp=Ut;function Ut(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return Ut.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Ut.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ut.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return Ut.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ut.errors=i,e===0}var sp=It;function It(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return It.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return It.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return It.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return It.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return It.errors=i,e===0}var tp=zt;function zt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return zt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return zt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return zt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return zt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return zt.errors=i,e===0}var ip=Lt;function Lt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.session_id===void 0&&(o="session_id"))return Lt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return Lt.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Lt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}else return Lt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Lt.errors=i,e===0}var ap=Dr,ta={properties:{files:{items:{$ref:"#/definitions/UploadFile"},type:"array"},mode:{$ref:"#/definitions/UploadMode"},ref:{type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:0,type:["integer","null"]}},required:["session_id","files"],type:"object"},pn={properties:{name:{type:"string"},staged_path:{type:["string","null"]},transfer_id:{type:"string"}},required:["transfer_id","name"],type:"object"};function Ms(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.transfer_id===void 0&&(o="transfer_id")||r.name===void 0&&(o="name"))return Ms.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.name!==void 0){let a=e;if(typeof r.name!="string")return Ms.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.staged_path!==void 0){let a=r.staged_path,n=e;if(typeof a!="string"&&a!==null)return Ms.errors=[{instancePath:s+"/staged_path",schemaPath:"#/properties/staged_path/type",keyword:"type",params:{type:pn.properties.staged_path.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.transfer_id!==void 0){let a=e;if(typeof r.transfer_id!="string")return Ms.errors=[{instancePath:s+"/transfer_id",schemaPath:"#/properties/transfer_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}else return Ms.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ms.errors=i,e===0}var ln={enum:["input","drop"],type:"string"};function si(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(si.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="input"||r==="drop"?(si.errors=i,e===0):(si.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:ln.enum},message:"must be equal to one of the allowed values"}],!1)}function Dr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.files===void 0&&(a="files"))return Dr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.files!==void 0){let n=r.files,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}}}}else return Dr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Dr.errors=i,e===0}var np=qr;function Us(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.transfer_id===void 0&&(o="transfer_id")||r.name===void 0&&(o="name"))return Us.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.name!==void 0){let a=e;if(typeof r.name!="string")return Us.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.staged_path!==void 0){let a=e;if(typeof r.staged_path!="string")return Us.errors=[{instancePath:s+"/staged_path",schemaPath:"#/properties/staged_path/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.transfer_id!==void 0){let a=e;if(typeof r.transfer_id!="string")return Us.errors=[{instancePath:s+"/transfer_id",schemaPath:"#/properties/transfer_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}else return Us.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Us.errors=i,e===0}var mn={enum:["input","drop"],type:"string"};function ti(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ti.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="input"||r==="drop"?(ti.errors=i,e===0):(ti.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:mn.enum},message:"must be equal to one of the allowed values"}],!1)}function qr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id")||r.files===void 0&&(a="files"))return qr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.files!==void 0){let n=r.files,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}}}}else return qr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return qr.errors=i,e===0}var op=Ds,La={properties:{session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's currently active tab.",format:"int64",type:["integer","null"]},timeout_ms:{description:"Hard upper bound on the wait. Defaults to 30s.",format:"uint32",minimum:1,type:["integer","null"]},wait_until:{anyOf:[{$ref:"#/definitions/WaitUntil"},{type:"null"}],description:"Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]."}},required:["session_id"],type:"object"};function Ds(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Ds.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return Ds.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Ds.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:La.properties.tab_id.type},message:"must be integer,null"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n))&&n!==null)return Ds.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:La.properties.timeout_ms.type},message:"must be integer,null"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return Ds.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=r.wait_until,p=e,l=e,m=!1,u=e;ue(n,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?ue.errors:i.concat(ue.errors),e=i.length);var o=u===e;if(m=m||o,!m){let d=e;if(n!==null){let v={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[v]:i.push(v),e++}var o=d===e;m=m||o}if(m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,Ds.errors=i,!1}var t=p===e}else var t=!0}}}else return Ds.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ds.errors=i,e===0}var pp=qs;function qs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return qs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.session_id!==void 0){let n=e;if(typeof r.session_id!="string")return qs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return qs.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.timeout_ms!==void 0){let n=r.timeout_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return qs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<1||isNaN(n)))return qs.errors=[{instancePath:s+"/timeout_ms",schemaPath:"#/properties/timeout_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0;if(t)if(r.wait_until!==void 0){let n=e,p=e,l=!1,m=e;fe(r.wait_until,{instancePath:s+"/wait_until",parentData:r,parentDataProperty:"wait_until",rootData:f})||(i=i===null?fe.errors:i.concat(fe.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/wait_until",schemaPath:"#/properties/wait_until/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,qs.errors=i,!1}var t=n===e}else var t=!0}}}else return qs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return qs.errors=i,e===0}var lp=Be,Di={properties:{delta_x:{default:0,description:"Native CDP wheel input in CSS pixels. Positive X means right. Not measured displacement.",format:"double",type:"number"},delta_y:{default:0,description:"Native CDP wheel input in CSS pixels. Positive Y means down. Defaults to zero.",format:"double",type:"number"},modifiers:{items:{$ref:"#/definitions/KeyModifier"},type:["array","null"]},ref:{description:"Optional `@e` ref used as the wheel event's hit-test point.\nMutually exclusive with `selector`. When neither is supplied,\nthe event is dispatched at the viewport centre.",type:["string","null"]},selector:{type:["string","null"]},session_id:{type:"string"},tab_id:{description:"Target tab. Defaults to the Agent Window's active tab.",format:"int64",type:["integer","null"]},timeout_ms:{format:"uint32",minimum:1,type:["integer","null"]}},required:["session_id"],type:"object"};function Be(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Be.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.delta_x!==void 0){let n=e;if(e===n&&typeof r.delta_x!="number")return Be.errors=[{instancePath:s+"/delta_x",schemaPath:"#/properties/delta_x/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=n===e}else var t=!0;if(t){if(r.delta_y!==void 0){let n=e;if(e===n&&typeof r.delta_y!="number")return Be.errors=[{instancePath:s+"/delta_y",schemaPath:"#/properties/delta_y/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=n===e}else var t=!0;if(t){if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(!Array.isArray(n)&&n!==null)return Be.errors=[{instancePath:s+"/modifiers",schemaPath:"#/properties/modifiers/type",keyword:"type",params:{type:Di.properties.modifiers.type},message:"must be array,null"}],!1;if(e===p&&Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0}}}}}}}else return Be.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Be.errors=i,e===0}var mp=Ke;function Ke(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.session_id===void 0&&(a="session_id"))return Ke.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.delta_x!==void 0){let n=e;if(e===n&&typeof r.delta_x!="number")return Ke.errors=[{instancePath:s+"/delta_x",schemaPath:"#/properties/delta_x/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=n===e}else var t=!0;if(t){if(r.delta_y!==void 0){let n=e;if(e===n&&typeof r.delta_y!="number")return Ke.errors=[{instancePath:s+"/delta_y",schemaPath:"#/properties/delta_y/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=n===e}else var t=!0;if(t){if(r.modifiers!==void 0){let n=r.modifiers,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:1},message:"must be >= 1"}],!1;var t=p===e}else var t=!0}}}}}}}else return Ke.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ke.errors=i,e===0}var up=js;function js(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.width===void 0&&(o="width")||r.height===void 0&&(o="height"))return js.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.height!==void 0){let a=r.height,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return js.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return js.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return js.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return js.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return js.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}else return js.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return js.errors=i,e===0}var fp=xs;function xs(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.session_id===void 0&&(o="session_id")||r.width===void 0&&(o="width")||r.height===void 0&&(o="height"))return xs.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.height!==void 0){let a=r.height,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return xs.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return xs.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.session_id!==void 0){let a=e;if(typeof r.session_id!="string")return xs.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return xs.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return xs.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}else return xs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return xs.errors=i,e===0}var yp=Yr;var un={description:"How the extension resolved the dialog so CDP could continue.",enum:["accepted","dismissed"],type:"string"};function ii(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ii.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="accepted"||r==="dismissed"?(ii.errors=i,e===0):(ii.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:un.enum},message:"must be equal to one of the allowed values"}],!1)}var fn={description:"Native JS dialog kind reported by CDP.",enum:["alert","confirm","prompt","beforeunload"],type:"string"};function ai(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ai.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="alert"||r==="confirm"||r==="prompt"||r==="beforeunload"?(ai.errors=i,e===0):(ai.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:fn.enum},message:"must be equal to one of the allowed values"}],!1)}function R(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.type===void 0&&(o="type")||r.message===void 0&&(o="message")||r.handled===void 0&&(o="handled")||r.sequence===void 0&&(o="sequence"))return R.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.default_prompt!==void 0){let a=e;if(typeof r.default_prompt!="string")return R.errors=[{instancePath:s+"/default_prompt",schemaPath:"#/properties/default_prompt/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.handled!==void 0){let a=e;ii(r.handled,{instancePath:s+"/handled",parentData:r,parentDataProperty:"handled",rootData:f})||(i=i===null?ii.errors:i.concat(ii.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.has_browser_handler!==void 0){let a=e;if(typeof r.has_browser_handler!="boolean")return R.errors=[{instancePath:s+"/has_browser_handler",schemaPath:"#/properties/has_browser_handler/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.message!==void 0){let a=e;if(typeof r.message!="string")return R.errors=[{instancePath:s+"/message",schemaPath:"#/properties/message/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.sequence!==void 0){let a=r.sequence,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return R.errors=[{instancePath:s+"/sequence",schemaPath:"#/properties/sequence/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return R.errors=[{instancePath:s+"/sequence",schemaPath:"#/properties/sequence/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return R.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.type!==void 0){let a=e;ai(r.type,{instancePath:s+"/type",parentData:r,parentDataProperty:"type",rootData:f})||(i=i===null?ai.errors:i.concat(ai.errors),e=i.length);var t=a===e}else var t=!0;if(t)if(r.url!==void 0){let a=e;if(typeof r.url!="string")return R.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}else return R.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return R.errors=i,e===0}function Yr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id")||r.was_focused===void 0&&(a="was_focused")||r.focused===void 0&&(a="focused"))return Yr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.dialogs!==void 0){let n=r.dialogs,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.stack_trace!==void 0){let n=r.stack_trace,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return As.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0;if(o)if(r.truncated!==void 0){let n=e;if(typeof r.truncated!="boolean")return As.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=n===e}else var o=!0}}}else return As.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return As.errors=i,e===0}var gp=G;function Ne(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.state===void 0&&(o="state"))return Ne.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.command_id!==void 0){let a=e;if(typeof r.command_id!="string")return Ne.errors=[{instancePath:s+"/command_id",schemaPath:"#/properties/command_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.elapsed_ms!==void 0){let a=r.elapsed_ms,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ne.errors=[{instancePath:s+"/elapsed_ms",schemaPath:"#/properties/elapsed_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ne.errors=[{instancePath:s+"/elapsed_ms",schemaPath:"#/properties/elapsed_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.method!==void 0){let a=e;if(typeof r.method!="string")return Ne.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.started_at!==void 0){let a=r.started_at,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ne.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Ne.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.state!==void 0){let a=e;if(typeof r.state!="string")return Ne.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.wait_complete!==void 0){let a=e;if(typeof r.wait_complete!="boolean")return Ne.errors=[{instancePath:s+"/wait_complete",schemaPath:"#/properties/wait_complete/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t)if(r.wait_timed_out!==void 0){let a=e;if(typeof r.wait_timed_out!="boolean")return Ne.errors=[{instancePath:s+"/wait_timed_out",schemaPath:"#/properties/wait_timed_out/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0}}}}}}else return Ne.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ne.errors=i,e===0}function cr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.min===void 0&&(o="min")||r.mean===void 0&&(o="mean")||r.p50===void 0&&(o="p50")||r.p95===void 0&&(o="p95")||r.max===void 0&&(o="max")||r.total===void 0&&(o="total"))return cr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.max!==void 0){let a=e;if(e===a&&typeof r.max!="number")return cr.errors=[{instancePath:s+"/max",schemaPath:"#/properties/max/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.mean!==void 0){let a=e;if(e===a&&typeof r.mean!="number")return cr.errors=[{instancePath:s+"/mean",schemaPath:"#/properties/mean/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.min!==void 0){let a=e;if(e===a&&typeof r.min!="number")return cr.errors=[{instancePath:s+"/min",schemaPath:"#/properties/min/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.p50!==void 0){let a=e;if(e===a&&typeof r.p50!="number")return cr.errors=[{instancePath:s+"/p50",schemaPath:"#/properties/p50/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.p95!==void 0){let a=e;if(e===a&&typeof r.p95!="number")return cr.errors=[{instancePath:s+"/p95",schemaPath:"#/properties/p95/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t)if(r.total!==void 0){let a=e;if(e===a&&typeof r.total!="number")return cr.errors=[{instancePath:s+"/total",schemaPath:"#/properties/total/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0}}}}}else return cr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return cr.errors=i,e===0}function F(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let p;if(r.id===void 0&&(p="id")||r.method===void 0&&(p="method")||r.endpoint===void 0&&(p="endpoint")||r.count===void 0&&(p="count")||r.failed===void 0&&(p="failed")||r.http_errors===void 0&&(p="http_errors")||r.pending===void 0&&(p="pending")||r.interrupted===void 0&&(p="interrupted")||r.statuses===void 0&&(p="statuses")||r.slow===void 0&&(p="slow")||r.timing_samples===void 0&&(p="timing_samples")||r.transfer_bytes===void 0&&(p="transfer_bytes")||r.transfer_samples===void 0&&(p="transfer_samples")||r.cached===void 0&&(p="cached")||r.service_worker===void 0&&(p="service_worker")||r.controlled===void 0&&(p="controlled")||r.replayed===void 0&&(p="replayed")||r.request_ids===void 0&&(p="request_ids")||r.refs_truncated===void 0&&(p="refs_truncated"))return F.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:p},message:"must have required property '"+p+"'"}],!1;if(r.cached!==void 0){let l=r.cached,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/cached",schemaPath:"#/properties/cached/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/cached",schemaPath:"#/properties/cached/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.controlled!==void 0){let l=r.controlled,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/controlled",schemaPath:"#/properties/controlled/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/controlled",schemaPath:"#/properties/controlled/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.count!==void 0){let l=r.count,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.duration_ms!==void 0){let l=e,m=e,u=!1,y=e;cr(r.duration_ms,{instancePath:s+"/duration_ms",parentData:r,parentDataProperty:"duration_ms",rootData:f})||(i=i===null?cr.errors:i.concat(cr.errors),e=i.length);var o=y===e;if(u=u||o,u)e=m,i!==null&&(m?i.length=m:i=null);else{let b={instancePath:s+"/duration_ms",schemaPath:"#/properties/duration_ms/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[b]:i.push(b),e++,F.errors=i,!1}var t=l===e}else var t=!0;if(t){if(r.endpoint!==void 0){let l=e;if(typeof r.endpoint!="string")return F.errors=[{instancePath:s+"/endpoint",schemaPath:"#/properties/endpoint/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.failed!==void 0){let l=r.failed,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/failed",schemaPath:"#/properties/failed/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/failed",schemaPath:"#/properties/failed/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.http_errors!==void 0){let l=r.http_errors,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/http_errors",schemaPath:"#/properties/http_errors/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/http_errors",schemaPath:"#/properties/http_errors/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.id!==void 0){let l=e;if(typeof r.id!="string")return F.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.interrupted!==void 0){let l=r.interrupted,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/interrupted",schemaPath:"#/properties/interrupted/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/interrupted",schemaPath:"#/properties/interrupted/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.method!==void 0){let l=e;if(typeof r.method!="string")return F.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.pending!==void 0){let l=r.pending,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/pending",schemaPath:"#/properties/pending/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/pending",schemaPath:"#/properties/pending/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.refs_truncated!==void 0){let l=e;if(typeof r.refs_truncated!="boolean")return F.errors=[{instancePath:s+"/refs_truncated",schemaPath:"#/properties/refs_truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=l===e}else var t=!0;if(t){if(r.replayed!==void 0){let l=r.replayed,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/replayed",schemaPath:"#/properties/replayed/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/replayed",schemaPath:"#/properties/replayed/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.request_ids!==void 0){let l=r.request_ids,m=e;if(e===m)if(Array.isArray(l)){var a=!0;let y=l.length;for(let d=0;d=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.slow!==void 0){let l=r.slow,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/slow",schemaPath:"#/properties/slow/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/slow",schemaPath:"#/properties/slow/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.statuses!==void 0){let l=r.statuses,m=e;if(e===m)if(l&&typeof l=="object"&&!Array.isArray(l))for(let y in l){let d=l[y],b=e;if(!(typeof d=="number"&&!(d%1)&&!isNaN(d)))return F.errors=[{instancePath:s+"/statuses/"+y.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/statuses/additionalProperties/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===b&&typeof d=="number"&&(d<0||isNaN(d)))return F.errors=[{instancePath:s+"/statuses/"+y.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/statuses/additionalProperties/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var n=b===e;if(!n)break}else return F.errors=[{instancePath:s+"/statuses",schemaPath:"#/properties/statuses/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=m===e}else var t=!0;if(t){if(r.timing_samples!==void 0){let l=r.timing_samples,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/timing_samples",schemaPath:"#/properties/timing_samples/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/timing_samples",schemaPath:"#/properties/timing_samples/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.transfer_bytes!==void 0){let l=e;if(e===l&&typeof r.transfer_bytes!="number")return F.errors=[{instancePath:s+"/transfer_bytes",schemaPath:"#/properties/transfer_bytes/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=l===e}else var t=!0;if(t)if(r.transfer_samples!==void 0){let l=r.transfer_samples,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return F.errors=[{instancePath:s+"/transfer_samples",schemaPath:"#/properties/transfer_samples/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return F.errors=[{instancePath:s+"/transfer_samples",schemaPath:"#/properties/transfer_samples/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0}}}}}}}}}}}}}}}}}}}else return F.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return F.errors=i,e===0}function Q(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.retained===void 0&&(a="retained")||r.matched===void 0&&(a="matched")||r.included===void 0&&(a="included")||r.excluded_controlled===void 0&&(a="excluded_controlled")||r.uncomparable===void 0&&(a="uncomparable")||r.groups===void 0&&(a="groups")||r.suspected_extra_requests===void 0&&(a="suspected_extra_requests")||r.window_ms===void 0&&(a="window_ms")||r.slow_ms===void 0&&(a="slow_ms")||r.coverage===void 0&&(a="coverage")||r.semantics===void 0&&(a="semantics"))return Q.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.coverage!==void 0){let n=r.coverage,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.groups!==void 0){let n=r.groups,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/groups",schemaPath:"#/properties/groups/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/groups",schemaPath:"#/properties/groups/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.included!==void 0){let n=r.included,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/included",schemaPath:"#/properties/included/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/included",schemaPath:"#/properties/included/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.matched!==void 0){let n=r.matched,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/matched",schemaPath:"#/properties/matched/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/matched",schemaPath:"#/properties/matched/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.retained!==void 0){let n=r.retained,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/retained",schemaPath:"#/properties/retained/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/retained",schemaPath:"#/properties/retained/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.semantics!==void 0){let n=e;if(typeof r.semantics!="string")return Q.errors=[{instancePath:s+"/semantics",schemaPath:"#/properties/semantics/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=n===e}else var o=!0;if(o){if(r.slow_ms!==void 0){let n=r.slow_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/slow_ms",schemaPath:"#/properties/slow_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.suspected_extra_requests!==void 0){let n=r.suspected_extra_requests,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/suspected_extra_requests",schemaPath:"#/properties/suspected_extra_requests/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/suspected_extra_requests",schemaPath:"#/properties/suspected_extra_requests/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.uncomparable!==void 0){let n=r.uncomparable,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/uncomparable",schemaPath:"#/properties/uncomparable/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/uncomparable",schemaPath:"#/properties/uncomparable/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o)if(r.window_ms!==void 0){let n=r.window_ms,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Q.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Q.errors=[{instancePath:s+"/window_ms",schemaPath:"#/properties/window_ms/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}}}}}}}}else return Q.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Q.errors=i,e===0}function ne(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.id===void 0&&(o="id")||r.at===void 0&&(o="at")||r.level===void 0&&(o="level")||r.text===void 0&&(o="text")||r.count===void 0&&(o="count")||r.last_at===void 0&&(o="last_at"))return ne.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.at!==void 0){let a=e;if(e===a&&typeof r.at!="number")return ne.errors=[{instancePath:s+"/at",schemaPath:"#/properties/at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.count!==void 0){let a=r.count,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return ne.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ne.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.id!==void 0){let a=e;if(typeof r.id!="string")return ne.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.last_at!==void 0){let a=e;if(e===a&&typeof r.last_at!="number")return ne.errors=[{instancePath:s+"/last_at",schemaPath:"#/properties/last_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.level!==void 0){let a=e;if(typeof r.level!="string")return ne.errors=[{instancePath:s+"/level",schemaPath:"#/properties/level/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.relation!==void 0){let a=e;if(typeof r.relation!="string")return ne.errors=[{instancePath:s+"/relation",schemaPath:"#/properties/relation/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.source!==void 0){let a=e;if(typeof r.source!="string")return ne.errors=[{instancePath:s+"/source",schemaPath:"#/properties/source/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.source_url!==void 0){let a=e;if(typeof r.source_url!="string")return ne.errors=[{instancePath:s+"/source_url",schemaPath:"#/properties/source_url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.stack!==void 0){let a=e;if(typeof r.stack!="string")return ne.errors=[{instancePath:s+"/stack",schemaPath:"#/properties/stack/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.text!==void 0){let a=e;if(typeof r.text!="string")return ne.errors=[{instancePath:s+"/text",schemaPath:"#/properties/text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}}}else return ne.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ne.errors=i,e===0}function re(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.id===void 0&&(n="id")||r.method===void 0&&(n="method")||r.url===void 0&&(n="url")||r.count===void 0&&(n="count")||r.extra_requests===void 0&&(n="extra_requests")||r.started_at===void 0&&(n="started_at")||r.ended_at===void 0&&(n="ended_at")||r.overlap_count===void 0&&(n="overlap_count")||r.possible_retry===void 0&&(n="possible_retry")||r.request_ids===void 0&&(n="request_ids")||r.operation_ids===void 0&&(n="operation_ids")||r.refs_truncated===void 0&&(n="refs_truncated"))return re.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.count!==void 0){let p=r.count,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return re.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===l&&typeof p=="number"&&(p<0||isNaN(p)))return re.errors=[{instancePath:s+"/count",schemaPath:"#/properties/count/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.ended_at!==void 0){let p=e;if(e===p&&typeof r.ended_at!="number")return re.errors=[{instancePath:s+"/ended_at",schemaPath:"#/properties/ended_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=p===e}else var t=!0;if(t){if(r.extra_requests!==void 0){let p=r.extra_requests,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return re.errors=[{instancePath:s+"/extra_requests",schemaPath:"#/properties/extra_requests/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===l&&typeof p=="number"&&(p<0||isNaN(p)))return re.errors=[{instancePath:s+"/extra_requests",schemaPath:"#/properties/extra_requests/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.id!==void 0){let p=e;if(typeof r.id!="string")return re.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.method!==void 0){let p=e;if(typeof r.method!="string")return re.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.operation_ids!==void 0){let p=r.operation_ids,l=e;if(e===l)if(Array.isArray(p)){var o=!0;let u=p.length;for(let y=0;y=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.possible_retry!==void 0){let p=e;if(typeof r.possible_retry!="boolean")return re.errors=[{instancePath:s+"/possible_retry",schemaPath:"#/properties/possible_retry/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=p===e}else var t=!0;if(t){if(r.refs_truncated!==void 0){let p=e;if(typeof r.refs_truncated!="boolean")return re.errors=[{instancePath:s+"/refs_truncated",schemaPath:"#/properties/refs_truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=p===e}else var t=!0;if(t){if(r.request_ids!==void 0){let p=r.request_ids,l=e;if(e===l)if(Array.isArray(p)){var a=!0;let u=p.length;for(let y=0;y=",limit:0},message:"must be >= 0"}],!1;var o=y===e}else var o=!0;if(o){if(r.source!==void 0){let u=e;if(typeof r.source!="string")return B.errors=[{instancePath:s+"/source",schemaPath:"#/properties/source/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=u===e}else var o=!0;if(o){if(r.started_at!==void 0){let u=e;if(e===u&&typeof r.started_at!="number")return B.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=u===e}else var o=!0;if(o){if(r.state!==void 0){let u=e;oi(r.state,{instancePath:s+"/state",parentData:r,parentDataProperty:"state",rootData:f})||(i=i===null?oi.errors:i.concat(oi.errors),e=i.length);var o=u===e}else var o=!0;if(o){if(r.target!==void 0){let u=e;if(typeof r.target!="string")return B.errors=[{instancePath:s+"/target",schemaPath:"#/properties/target/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=u===e}else var o=!0;if(o){if(r.truncated!==void 0){let u=e;if(typeof r.truncated!="boolean")return B.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=u===e}else var o=!0;if(o)if(r.window_end!==void 0){let u=e;if(e===u&&typeof r.window_end!="number")return B.errors=[{instancePath:s+"/window_end",schemaPath:"#/properties/window_end/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=u===e}else var o=!0}}}}}}}}}}}}}}}}}}else return B.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return B.errors=i,e===0}function Rr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.budget===void 0&&(a="budget")||r.truncated===void 0&&(a="truncated")||r.omitted===void 0&&(a="omitted"))return Rr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.budget!==void 0){let n=r.budget,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Rr.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Rr.errors=[{instancePath:s+"/budget",schemaPath:"#/properties/budget/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.omitted!==void 0){let n=r.omitted,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=u===e}else var o=!0;if(o){if(r.started_at!==void 0){let m=e;if(e===m&&typeof r.started_at!="number")return Y.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=m===e}else var o=!0;if(o){if(r.state!==void 0){let m=e;if(typeof r.state!="string")return Y.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=m===e}else var o=!0;if(o){if(r.time_origin!==void 0){let m=e;if(e===m&&typeof r.time_origin!="number")return Y.errors=[{instancePath:s+"/time_origin",schemaPath:"#/properties/time_origin/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var o=m===e}else var o=!0;if(o){if(r.url!==void 0){let m=e;if(typeof r.url!="string")return Y.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=m===e}else var o=!0;if(o){if(r.visibility!==void 0){let m=r.visibility,u=e;if(e===u)if(Array.isArray(m)){var p=!0;let d=m.length;for(let b=0;b=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.next_offset!==void 0){let a=r.next_offset,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return oe.errors=[{instancePath:s+"/next_offset",schemaPath:"#/properties/next_offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return oe.errors=[{instancePath:s+"/next_offset",schemaPath:"#/properties/next_offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.offset!==void 0){let a=r.offset,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return oe.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return oe.errors=[{instancePath:s+"/offset",schemaPath:"#/properties/offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.reason!==void 0){let a=e;if(typeof r.reason!="string")return oe.errors=[{instancePath:s+"/reason",schemaPath:"#/properties/reason/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.redacted!==void 0){let a=e;if(typeof r.redacted!="boolean")return oe.errors=[{instancePath:s+"/redacted",schemaPath:"#/properties/redacted/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.replay_safe!==void 0){let a=e;if(typeof r.replay_safe!="boolean")return oe.errors=[{instancePath:s+"/replay_safe",schemaPath:"#/properties/replay_safe/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.state!==void 0){let a=e;if(typeof r.state!="string")return oe.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.text!==void 0){let a=e;if(typeof r.text!="string")return oe.errors=[{instancePath:s+"/text",schemaPath:"#/properties/text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}else return oe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return oe.errors=i,e===0}function I(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let m;if(r.id===void 0&&(m="id")||r.run_id===void 0&&(m="run_id")||r.sequence===void 0&&(m="sequence")||r.started_at===void 0&&(m="started_at")||r.method===void 0&&(m="method")||r.url===void 0&&(m="url")||r.state===void 0&&(m="state")||r.request_body===void 0&&(m="request_body")||r.response_body===void 0&&(m="response_body"))return I.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:m},message:"must have required property '"+m+"'"}],!1;if(r.decoded_bytes!==void 0){let u=e;if(e===u&&typeof r.decoded_bytes!="number")return I.errors=[{instancePath:s+"/decoded_bytes",schemaPath:"#/properties/decoded_bytes/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=u===e}else var t=!0;if(t){if(r.duration_ms!==void 0){let u=e;if(e===u&&typeof r.duration_ms!="number")return I.errors=[{instancePath:s+"/duration_ms",schemaPath:"#/properties/duration_ms/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=u===e}else var t=!0;if(t){if(r.error!==void 0){let u=e;if(typeof r.error!="string")return I.errors=[{instancePath:s+"/error",schemaPath:"#/properties/error/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.finished_at!==void 0){let u=e;if(e===u&&typeof r.finished_at!="number")return I.errors=[{instancePath:s+"/finished_at",schemaPath:"#/properties/finished_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=u===e}else var t=!0;if(t){if(r.frame_id!==void 0){let u=e;if(typeof r.frame_id!="string")return I.errors=[{instancePath:s+"/frame_id",schemaPath:"#/properties/frame_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.from_cache!==void 0){let u=e;if(typeof r.from_cache!="boolean")return I.errors=[{instancePath:s+"/from_cache",schemaPath:"#/properties/from_cache/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=u===e}else var t=!0;if(t){if(r.from_service_worker!==void 0){let u=e;if(typeof r.from_service_worker!="boolean")return I.errors=[{instancePath:s+"/from_service_worker",schemaPath:"#/properties/from_service_worker/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=u===e}else var t=!0;if(t){if(r.id!==void 0){let u=e;if(typeof r.id!="string")return I.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.initiator!==void 0){let u=e;if(typeof r.initiator!="string")return I.errors=[{instancePath:s+"/initiator",schemaPath:"#/properties/initiator/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.integrity!==void 0){let u=e,y=e,d=!1,b=e;zs(r.integrity,{instancePath:s+"/integrity",parentData:r,parentDataProperty:"integrity",rootData:f})||(i=i===null?zs.errors:i.concat(zs.errors),e=i.length);var o=b===e;if(d=d||o,d)e=y,i!==null&&(y?i.length=y:i=null);else{let O={instancePath:s+"/integrity",schemaPath:"#/properties/integrity/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[O]:i.push(O),e++,I.errors=i,!1}var t=u===e}else var t=!0;if(t){if(r.intervention!==void 0){let u=e,y=e,d=!1,b=e;Tr(r.intervention,{instancePath:s+"/intervention",parentData:r,parentDataProperty:"intervention",rootData:f})||(i=i===null?Tr.errors:i.concat(Tr.errors),e=i.length);var a=b===e;if(d=d||a,d)e=y,i!==null&&(y?i.length=y:i=null);else{let O={instancePath:s+"/intervention",schemaPath:"#/properties/intervention/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[O]:i.push(O),e++,I.errors=i,!1}var t=u===e}else var t=!0;if(t){if(r.loader_id!==void 0){let u=e;if(typeof r.loader_id!="string")return I.errors=[{instancePath:s+"/loader_id",schemaPath:"#/properties/loader_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.method!==void 0){let u=e;if(typeof r.method!="string")return I.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.mime_type!==void 0){let u=e;if(typeof r.mime_type!="string")return I.errors=[{instancePath:s+"/mime_type",schemaPath:"#/properties/mime_type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.pinned!==void 0){let u=e;if(typeof r.pinned!="boolean")return I.errors=[{instancePath:s+"/pinned",schemaPath:"#/properties/pinned/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=u===e}else var t=!0;if(t){if(r.redirect_from!==void 0){let u=e;if(typeof r.redirect_from!="string")return I.errors=[{instancePath:s+"/redirect_from",schemaPath:"#/properties/redirect_from/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.replay_from!==void 0){let u=e;if(typeof r.replay_from!="string")return I.errors=[{instancePath:s+"/replay_from",schemaPath:"#/properties/replay_from/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.replay_id!==void 0){let u=e;if(typeof r.replay_id!="string")return I.errors=[{instancePath:s+"/replay_id",schemaPath:"#/properties/replay_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.request_body!==void 0){let u=e;oe(r.request_body,{instancePath:s+"/request_body",parentData:r,parentDataProperty:"request_body",rootData:f})||(i=i===null?oe.errors:i.concat(oe.errors),e=i.length);var t=u===e}else var t=!0;if(t){if(r.request_headers!==void 0){let u=r.request_headers,y=e;if(e===y)if(u&&typeof u=="object"&&!Array.isArray(u))for(let b in u){let v=e;if(typeof u[b]!="string")return I.errors=[{instancePath:s+"/request_headers/"+b.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/request_headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var n=v===e;if(!n)break}else return I.errors=[{instancePath:s+"/request_headers",schemaPath:"#/properties/request_headers/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=y===e}else var t=!0;if(t){if(r.resource_type!==void 0){let u=e;if(typeof r.resource_type!="string")return I.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.response_body!==void 0){let u=e;oe(r.response_body,{instancePath:s+"/response_body",parentData:r,parentDataProperty:"response_body",rootData:f})||(i=i===null?oe.errors:i.concat(oe.errors),e=i.length);var t=u===e}else var t=!0;if(t){if(r.response_headers!==void 0){let u=r.response_headers,y=e;if(e===y)if(u&&typeof u=="object"&&!Array.isArray(u))for(let b in u){let v=e;if(typeof u[b]!="string")return I.errors=[{instancePath:s+"/response_headers/"+b.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/response_headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var p=v===e;if(!p)break}else return I.errors=[{instancePath:s+"/response_headers",schemaPath:"#/properties/response_headers/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=y===e}else var t=!0;if(t){if(r.run_id!==void 0){let u=e;if(typeof r.run_id!="string")return I.errors=[{instancePath:s+"/run_id",schemaPath:"#/properties/run_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.sequence!==void 0){let u=r.sequence,y=e;if(!(typeof u=="number"&&!(u%1)&&!isNaN(u)))return I.errors=[{instancePath:s+"/sequence",schemaPath:"#/properties/sequence/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===y&&typeof u=="number"&&(u<0||isNaN(u)))return I.errors=[{instancePath:s+"/sequence",schemaPath:"#/properties/sequence/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=y===e}else var t=!0;if(t){if(r.started_at!==void 0){let u=e;if(e===u&&typeof r.started_at!="number")return I.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=u===e}else var t=!0;if(t){if(r.state!==void 0){let u=e;if(typeof r.state!="string")return I.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0;if(t){if(r.status!==void 0){let u=r.status,y=e;if(!(typeof u=="number"&&!(u%1)&&!isNaN(u)))return I.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===y&&typeof u=="number"&&(u<0||isNaN(u)))return I.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=y===e}else var t=!0;if(t){if(r.timing!==void 0){let u=r.timing,y=e;if(e===y)if(u&&typeof u=="object"&&!Array.isArray(u))for(let b in u){let v=e;if(e===v&&typeof u[b]!="number")return I.errors=[{instancePath:s+"/timing/"+b.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/timing/additionalProperties/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var l=v===e;if(!l)break}else return I.errors=[{instancePath:s+"/timing",schemaPath:"#/properties/timing/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=y===e}else var t=!0;if(t){if(r.transfer_bytes!==void 0){let u=e;if(e===u&&typeof r.transfer_bytes!="number")return I.errors=[{instancePath:s+"/transfer_bytes",schemaPath:"#/properties/transfer_bytes/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=u===e}else var t=!0;if(t){if(r.truncated!==void 0){let u=e;if(typeof r.truncated!="boolean")return I.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=u===e}else var t=!0;if(t)if(r.url!==void 0){let u=e;if(typeof r.url!="string")return I.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=u===e}else var t=!0}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}else return I.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return I.errors=i,e===0}var gn={oneOf:[{additionalProperties:!1,properties:{type:{const:"block",type:"string"}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:"string"},headers:{additionalProperties:{type:["string","null"]},type:"object"},json:{anyOf:[{$ref:"#/definitions/DebugJsonEdit"}]},method:{type:"string"},type:{const:"modify",type:"string"},url:{type:"string"}},required:["type"],type:"object"},{additionalProperties:!1,properties:{body:{type:"string"},delay_ms:{format:"uint32",minimum:0,type:"integer"},headers:{additionalProperties:{type:"string"},type:"object"},status:{format:"uint16",maximum:65535,minimum:0,type:"integer"},type:{const:"mock",type:"string"}},required:["type","status","body"],type:"object"}]};function Cr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n=e;for(let p in r)if(!(p==="remove"||p==="rename"||p==="set")){return Cr.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.remove!==void 0){let p=r.remove,l=e;if(e===l)if(Array.isArray(p)){var t=!0;let m=p.length;for(let u=0;u=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0;if(d){if(r.headers!==void 0){let _=r.headers,D=e;if(e===D)if(_&&typeof _=="object"&&!Array.isArray(_))for(let w in _){let V=e;if(typeof _[w]!="string"){let W={instancePath:s+"/headers/"+w.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/oneOf/2/properties/headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var b=V===e;if(!b)break}else{let w={instancePath:s+"/headers",schemaPath:"#/oneOf/2/properties/headers/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0;if(d){if(r.status!==void 0){let _=r.status,D=e;if(!(typeof _=="number"&&!(_%1)&&!isNaN(_))){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[w]:i.push(w),e++}if(e===D&&typeof _=="number"){if(_>65535||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:65535},message:"must be <= 65535"};i===null?i=[w]:i.push(w),e++}else if(_<0||isNaN(_)){let w={instancePath:s+"/status",schemaPath:"#/oneOf/2/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[w]:i.push(w),e++}}var d=D===e}else var d=!0;if(d)if(r.type!==void 0){let _=r.type,D=e;if(typeof _!="string"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[w]:i.push(w),e++}if(_!=="mock"){let w={instancePath:s+"/type",schemaPath:"#/oneOf/2/properties/type/const",keyword:"const",params:{allowedValue:"mock"},message:"must be equal to constant"};i===null?i=[w]:i.push(w),e++}var d=D===e}else var d=!0}}}}}}else{let h={instancePath:s,schemaPath:"#/oneOf/2/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[h]:i.push(h),e++}var y=v===e;y&&o?(o=!1,a=[a,2]):y&&(o=!0,a=2)}if(o)e=t,i!==null&&(t?i.length=t:i=null);else{let v={instancePath:s,schemaPath:"#/oneOf",keyword:"oneOf",params:{passingSchemas:a},message:"must match exactly one schema in oneOf"};return i===null?i=[v]:i.push(v),e++,Ii.errors=i,!1}return Ii.errors=i,e===0}function us(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.url===void 0&&(o="url"))return us.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;{let a=e;for(let n in r)if(!(n==="method"||n==="resource_type"||n==="url")){return us.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:n},message:"must NOT have additional properties"}],!1;break}if(a===e){if(r.method!==void 0){let n=e;if(typeof r.method!="string")return us.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.resource_type!==void 0){let n=e;if(typeof r.resource_type!="string")return us.errors=[{instancePath:s+"/resource_type",schemaPath:"#/properties/resource_type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.url!==void 0){let n=e;if(typeof r.url!="string")return us.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0}}}}else return us.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return us.errors=i,e===0}var hn={enum:["enabled","disabled","exhausted","removed","stopped"],type:"string"};function li(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(li.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="enabled"||r==="disabled"||r==="exhausted"||r==="removed"||r==="stopped"?(li.errors=i,e===0):(li.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:hn.enum},message:"must be equal to one of the allowed values"}],!1)}function pe(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.match===void 0&&(o="match")||r.effect===void 0&&(o="effect")||r.id===void 0&&(o="id")||r.state===void 0&&(o="state")||r.hits===void 0&&(o="hits")||r.failures===void 0&&(o="failures")||r.created_at===void 0&&(o="created_at"))return pe.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.created_at!==void 0){let a=e;if(e===a&&typeof r.created_at!="number")return pe.errors=[{instancePath:s+"/created_at",schemaPath:"#/properties/created_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.effect!==void 0){let a=e;Ii(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?Ii.errors:i.concat(Ii.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.failures!==void 0){let a=r.failures,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return pe.errors=[{instancePath:s+"/failures",schemaPath:"#/properties/failures/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return pe.errors=[{instancePath:s+"/failures",schemaPath:"#/properties/failures/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.hits!==void 0){let a=r.hits,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return pe.errors=[{instancePath:s+"/hits",schemaPath:"#/properties/hits/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return pe.errors=[{instancePath:s+"/hits",schemaPath:"#/properties/hits/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.id!==void 0){let a=e;if(typeof r.id!="string")return pe.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.last_error!==void 0){let a=e;if(typeof r.last_error!="string")return pe.errors=[{instancePath:s+"/last_error",schemaPath:"#/properties/last_error/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.match!==void 0){let a=e;us(r.match,{instancePath:s+"/match",parentData:r,parentDataProperty:"match",rootData:f})||(i=i===null?us.errors:i.concat(us.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.name!==void 0){let a=e;if(typeof r.name!="string")return pe.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.state!==void 0){let a=e;li(r.state,{instancePath:s+"/state",parentData:r,parentDataProperty:"state",rootData:f})||(i=i===null?li.errors:i.concat(li.errors),e=i.length);var t=a===e}else var t=!0;if(t)if(r.times!==void 0){let a=r.times,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return pe.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return pe.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}}}}else return pe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return pe.errors=i,e===0}var vn={enum:["capturing","stopped"],type:"string"};function mi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(mi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="capturing"||r==="stopped"?(mi.errors=i,e===0):(mi.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:vn.enum},message:"must be equal to one of the allowed values"}],!1)}function Te(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.requests===void 0&&(o="requests")||r.bytes===void 0&&(o="bytes")||r.dropped===void 0&&(o="dropped")||r.pins===void 0&&(o="pins"))return Te.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.bytes!==void 0){let a=r.bytes,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Te.errors=[{instancePath:s+"/bytes",schemaPath:"#/properties/bytes/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Te.errors=[{instancePath:s+"/bytes",schemaPath:"#/properties/bytes/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.dropped!==void 0){let a=r.dropped,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Te.errors=[{instancePath:s+"/dropped",schemaPath:"#/properties/dropped/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Te.errors=[{instancePath:s+"/dropped",schemaPath:"#/properties/dropped/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.pins!==void 0){let a=r.pins,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Te.errors=[{instancePath:s+"/pins",schemaPath:"#/properties/pins/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Te.errors=[{instancePath:s+"/pins",schemaPath:"#/properties/pins/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.requests!==void 0){let a=r.requests,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Te.errors=[{instancePath:s+"/requests",schemaPath:"#/properties/requests/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Te.errors=[{instancePath:s+"/requests",schemaPath:"#/properties/requests/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}else return Te.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Te.errors=i,e===0}function L(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let p;if(r.id===void 0&&(p="id")||r.session_id===void 0&&(p="session_id")||r.tab_id===void 0&&(p="tab_id")||r.name===void 0&&(p="name")||r.url===void 0&&(p="url")||r.started_at===void 0&&(p="started_at")||r.state===void 0&&(p="state")||r.requests===void 0&&(p="requests")||r.operations===void 0&&(p="operations")||r.errors===void 0&&(p="errors")||r.dropped_requests===void 0&&(p="dropped_requests")||r.dropped_operations===void 0&&(p="dropped_operations")||r.dropped_console===void 0&&(p="dropped_console")||r.coverage===void 0&&(p="coverage")||r.next_since===void 0&&(p="next_since"))return L.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:p},message:"must have required property '"+p+"'"}],!1;if(r.active_rules!==void 0){let l=r.active_rules,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/active_rules",schemaPath:"#/properties/active_rules/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/active_rules",schemaPath:"#/properties/active_rules/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.coverage!==void 0){let l=r.coverage,m=e;if(e===m)if(Array.isArray(l)){var o=!0;let y=l.length;for(let d=0;d=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.dropped_operations!==void 0){let l=r.dropped_operations,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/dropped_operations",schemaPath:"#/properties/dropped_operations/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/dropped_operations",schemaPath:"#/properties/dropped_operations/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.dropped_requests!==void 0){let l=r.dropped_requests,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/dropped_requests",schemaPath:"#/properties/dropped_requests/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/dropped_requests",schemaPath:"#/properties/dropped_requests/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.environment!==void 0){let l=r.environment,m=e;if(e===m)if(l&&typeof l=="object"&&!Array.isArray(l))for(let y in l){let d=e;if(typeof l[y]!="string")return L.errors=[{instancePath:s+"/environment/"+y.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/environment/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var a=d===e;if(!a)break}else return L.errors=[{instancePath:s+"/environment",schemaPath:"#/properties/environment/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;var t=m===e}else var t=!0;if(t){if(r.errors!==void 0){let l=r.errors,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/errors",schemaPath:"#/properties/errors/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/errors",schemaPath:"#/properties/errors/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.id!==void 0){let l=e;if(typeof r.id!="string")return L.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.name!==void 0){let l=e;if(typeof r.name!="string")return L.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.next_since!==void 0){let l=r.next_since,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/next_since",schemaPath:"#/properties/next_since/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/next_since",schemaPath:"#/properties/next_since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.operations!==void 0){let l=r.operations,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/operations",schemaPath:"#/properties/operations/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/operations",schemaPath:"#/properties/operations/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.requests!==void 0){let l=r.requests,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/requests",schemaPath:"#/properties/requests/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===m&&typeof l=="number"&&(l<0||isNaN(l)))return L.errors=[{instancePath:s+"/requests",schemaPath:"#/properties/requests/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=m===e}else var t=!0;if(t){if(r.saved_at!==void 0){let l=e;if(e===l&&typeof r.saved_at!="number")return L.errors=[{instancePath:s+"/saved_at",schemaPath:"#/properties/saved_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=l===e}else var t=!0;if(t){if(r.session_id!==void 0){let l=e;if(typeof r.session_id!="string")return L.errors=[{instancePath:s+"/session_id",schemaPath:"#/properties/session_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.started_at!==void 0){let l=e;if(e===l&&typeof r.started_at!="number")return L.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=l===e}else var t=!0;if(t){if(r.state!==void 0){let l=e;mi(r.state,{instancePath:s+"/state",parentData:r,parentDataProperty:"state",rootData:f})||(i=i===null?mi.errors:i.concat(mi.errors),e=i.length);var t=l===e}else var t=!0;if(t){if(r.stop_reason!==void 0){let l=e;if(typeof r.stop_reason!="string")return L.errors=[{instancePath:s+"/stop_reason",schemaPath:"#/properties/stop_reason/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.stopped_at!==void 0){let l=e;if(e===l&&typeof r.stopped_at!="number")return L.errors=[{instancePath:s+"/stopped_at",schemaPath:"#/properties/stopped_at/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=l===e}else var t=!0;if(t){if(r.storage!==void 0){let l=e,m=e,u=!1,y=e;Te(r.storage,{instancePath:s+"/storage",parentData:r,parentDataProperty:"storage",rootData:f})||(i=i===null?Te.errors:i.concat(Te.errors),e=i.length);var n=y===e;if(u=u||n,u)e=m,i!==null&&(m?i.length=m:i=null);else{let b={instancePath:s+"/storage",schemaPath:"#/properties/storage/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[b]:i.push(b),e++,L.errors=i,!1}var t=l===e}else var t=!0;if(t){if(r.storage_error!==void 0){let l=e;if(typeof r.storage_error!="string")return L.errors=[{instancePath:s+"/storage_error",schemaPath:"#/properties/storage_error/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.tab_id!==void 0){let l=r.tab_id,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return L.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=m===e}else var t=!0;if(t)if(r.url!==void 0){let l=e;if(typeof r.url!="string")return L.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0}}}}}}}}}}}}}}}}}}}}}else return L.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return L.errors=i,e===0}function be(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let y;if(r.version===void 0&&(y="version")||r.saved_at===void 0&&(y="saved_at")||r.run===void 0&&(y="run")||r.requests===void 0&&(y="requests")||r.operations===void 0&&(y="operations")||r.console===void 0&&(y="console")||r.pages===void 0&&(y="pages"))return be.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:y},message:"must have required property '"+y+"'"}],!1;if(r.console!==void 0){let d=r.console,b=e;if(e===b)if(Array.isArray(d)){var t=!0;let v=d.length;for(let O=0;O=",limit:0},message:"must be >= 0"}],!1;var o=b===e}else var o=!0}}}}}}}}}else return be.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return be.errors=i,e===0}function G(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let W;if(r.session_id===void 0&&(W="session_id"))return G.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:W},message:"must have required property '"+W+"'"}],!1;if(r.activity!==void 0){let P=e,N=e,A=!1,x=e;Ne(r.activity,{instancePath:s+"/activity",parentData:r,parentDataProperty:"activity",rootData:f})||(i=i===null?Ne.errors:i.concat(Ne.errors),e=i.length);var t=x===e;if(A=A||t,A)e=N,i!==null&&(N?i.length=N:i=null);else{let k={instancePath:s+"/activity",schemaPath:"#/properties/activity/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[k]:i.push(k),e++,G.errors=i,!1}var o=P===e}else var o=!0;if(o){if(r.aggregates!==void 0){let P=r.aggregates,N=e;if(e===N)if(Array.isArray(P)){var a=!0;let x=P.length;for(let k=0;k=",limit:0},message:"must be >= 0"}],!1;var o=N===e}else var o=!0;if(o){if(r.next_since!==void 0){let P=r.next_since,N=e;if(!(typeof P=="number"&&!(P%1)&&!isNaN(P)))return G.errors=[{instancePath:s+"/next_since",schemaPath:"#/properties/next_since/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===N&&typeof P=="number"&&(P<0||isNaN(P)))return G.errors=[{instancePath:s+"/next_since",schemaPath:"#/properties/next_since/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var o=N===e}else var o=!0;if(o){if(r.operation!==void 0){let P=e,N=e,A=!1,x=e;B(r.operation,{instancePath:s+"/operation",parentData:r,parentDataProperty:"operation",rootData:f})||(i=i===null?B.errors:i.concat(B.errors),e=i.length);var u=x===e;if(A=A||u,A)e=N,i!==null&&(N?i.length=N:i=null);else{let j={instancePath:s+"/operation",schemaPath:"#/properties/operation/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[j]:i.push(j),e++,G.errors=i,!1}var o=P===e}else var o=!0;if(o){if(r.operations!==void 0){let P=r.operations,N=e;if(e===N)if(Array.isArray(P)){var y=!0;let x=P.length;for(let k=0;k=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.danger!==void 0){let a=e;if(typeof r.danger!="string")return $e.errors=[{instancePath:s+"/danger",schemaPath:"#/properties/danger/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.mime!==void 0){let a=e;if(typeof r.mime!="string")return $e.errors=[{instancePath:s+"/mime",schemaPath:"#/properties/mime/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.suggested_filename!==void 0){let a=e;if(typeof r.suggested_filename!="string")return $e.errors=[{instancePath:s+"/suggested_filename",schemaPath:"#/properties/suggested_filename/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return $e.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.transfer_id!==void 0){let a=e;if(typeof r.transfer_id!="string")return $e.errors=[{instancePath:s+"/transfer_id",schemaPath:"#/properties/transfer_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.used_ref!==void 0){let a=e;if(typeof r.used_ref!="string")return $e.errors=[{instancePath:s+"/used_ref",schemaPath:"#/properties/used_ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.used_selector!==void 0){let a=e;if(typeof r.used_selector!="string")return $e.errors=[{instancePath:s+"/used_selector",schemaPath:"#/properties/used_selector/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}}else return $e.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return $e.errors=i,e===0}var vp=rt;function ut(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.brand===void 0&&(o="brand")||r.version===void 0&&(o="version"))return ut.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.brand!==void 0){let a=e;if(typeof r.brand!="string")return ut.errors=[{instancePath:s+"/brand",schemaPath:"#/properties/brand/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.version!==void 0){let a=e;if(typeof r.version!="string")return ut.errors=[{instancePath:s+"/version",schemaPath:"#/properties/version/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return ut.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ut.errors=i,e===0}function hr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.architecture!==void 0){let a=e;if(typeof r.architecture!="string")return hr.errors=[{instancePath:s+"/architecture",schemaPath:"#/properties/architecture/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.brands!==void 0){let a=r.brands,n=e;if(e===n)if(Array.isArray(a)){var o=!0;let l=a.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_touch_points!==void 0){let a=r.max_touch_points,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return he.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return he.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.mobile!==void 0){let a=e;if(typeof r.mobile!="boolean")return he.errors=[{instancePath:s+"/mobile",schemaPath:"#/properties/mobile/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.touch!==void 0){let a=e;if(typeof r.touch!="boolean")return he.errors=[{instancePath:s+"/touch",schemaPath:"#/properties/touch/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t){if(r.user_agent!==void 0){let a=e;if(typeof r.user_agent!="string")return he.errors=[{instancePath:s+"/user_agent",schemaPath:"#/properties/user_agent/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.user_agent_metadata!==void 0){let a=e,n=e,p=!1,l=e;hr(r.user_agent_metadata,{instancePath:s+"/user_agent_metadata",parentData:r,parentDataProperty:"user_agent_metadata",rootData:f})||(i=i===null?hr.errors:i.concat(hr.errors),e=i.length);var o=l===e;if(p=p||o,p)e=n,i!==null&&(n?i.length=n:i=null);else{let u={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[u]:i.push(u),e++,he.errors=i,!1}var t=a===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return he.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return he.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}}}else return he.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return he.errors=i,e===0}function rt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id")||r.cleared===void 0&&(a="cleared"))return rt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.applied!==void 0){let n=e,p=e,l=!1,m=e;he(r.applied,{instancePath:s+"/applied",parentData:r,parentDataProperty:"applied",rootData:f})||(i=i===null?he.errors:i.concat(he.errors),e=i.length);var t=m===e;if(l=l||t,l)e=p,i!==null&&(p?i.length=p:i=null);else{let u={instancePath:s+"/applied",schemaPath:"#/properties/applied/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[u]:i.push(u),e++,rt.errors=i,!1}var o=n===e}else var o=!0;if(o){if(r.cleared!==void 0){let n=e;if(typeof r.cleared!="boolean")return rt.errors=[{instancePath:s+"/cleared",schemaPath:"#/properties/cleared/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=n===e}else var o=!0;if(o){if(r.note!==void 0){let n=e;if(typeof r.note!="string")return rt.errors=[{instancePath:s+"/note",schemaPath:"#/properties/note/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=n===e}else var o=!0;if(o)if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return rt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0}}}else return rt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return rt.errors=i,e===0}var bp=st;function Ls(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.text===void 0&&(o="text"))return Ls.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.column!==void 0){let a=r.column,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ls.errors=[{instancePath:s+"/column",schemaPath:"#/properties/column/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.line!==void 0){let a=r.line,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Ls.errors=[{instancePath:s+"/line",schemaPath:"#/properties/line/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.text!==void 0){let a=e;if(typeof r.text!="string")return Ls.errors=[{instancePath:s+"/text",schemaPath:"#/properties/text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}else return Ls.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ls.errors=i,e===0}function st(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.ok===void 0&&(n="ok")||r.tab_id===void 0&&(n="tab_id"))return st.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.dialogs!==void 0){let p=r.dialogs,l=e;if(e===l)if(Array.isArray(p)){var t=!0;let m=p.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}}}else return Zr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Zr.errors=i,e===0}var wp=Os;function Os(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id")||r.focused===void 0&&(a="focused"))return Os.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.dialogs!==void 0){let n=r.dialogs,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.dialogs!==void 0){let n=r.dialogs,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.status!==void 0){let a=r.status,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return le.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return le.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.status_text!==void 0){let a=e;if(typeof r.status_text!="string")return le.errors=[{instancePath:s+"/status_text",schemaPath:"#/properties/status_text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.timestamp!==void 0){let a=e;if(e===a&&typeof r.timestamp!="number")return le.errors=[{instancePath:s+"/timestamp",schemaPath:"#/properties/timestamp/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t){if(r.truncated!==void 0){let a=e;if(typeof r.truncated!="boolean")return le.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t)if(r.url!==void 0){let a=e;if(typeof r.url!="string")return le.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}}}}}}}else return le.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return le.errors=i,e===0}function Es(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id")||r.entries===void 0&&(a="entries")||r.next_since===void 0&&(a="next_since")||r.truncated===void 0&&(a="truncated"))return Es.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.entries!==void 0){let n=r.entries,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Es.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0;if(o)if(r.truncated!==void 0){let n=e;if(typeof r.truncated!="boolean")return Es.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=n===e}else var o=!0}}}else return Es.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Es.errors=i,e===0}var xp=Ge;function ft(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.x===void 0&&(o="x")||r.y===void 0&&(o="y"))return ft.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.x!==void 0){let a=e;if(e===a&&typeof r.x!="number")return ft.errors=[{instancePath:s+"/x",schemaPath:"#/properties/x/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0;if(t)if(r.y!==void 0){let a=e;if(e===a&&typeof r.y!="number")return ft.errors=[{instancePath:s+"/y",schemaPath:"#/properties/y/type",keyword:"type",params:{type:"number"},message:"must be number"}],!1;var t=a===e}else var t=!0}else return ft.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ft.errors=i,e===0}function vr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.trigger_backend_node_id===void 0&&(n="trigger_backend_node_id")||r.trigger_action===void 0&&(n="trigger_action")||r.sub_items===void 0&&(n="sub_items"))return vr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.confidence!==void 0){let p=e;if(typeof r.confidence!="string")return vr.errors=[{instancePath:s+"/confidence",schemaPath:"#/properties/confidence/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.sub_items!==void 0){let p=r.sub_items,l=e;if(e===l)if(Array.isArray(p)){var o=!0;let u=p.length;for(let y=0;y=",limit:0},message:"must be >= 0"}],!1;var o=m===e}else var o=!0;if(o){if(r.tab_id!==void 0){let l=r.tab_id,m=e;if(!(typeof l=="number"&&!(l%1)&&!isNaN(l)))return Ge.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=m===e}else var o=!0;if(o){if(r.text!==void 0){let l=e;if(typeof r.text!="string")return Ge.errors=[{instancePath:s+"/text",schemaPath:"#/properties/text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=l===e}else var o=!0;if(o)if(r.truncated!==void 0){let l=e;if(typeof r.truncated!="boolean")return Ge.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=l===e}else var o=!0}}}}}}}else return Ge.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ge.errors=i,e===0}var Ap=Ss;var bn={description:"Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).",enum:["alt","ctrl","meta","shift"],type:"string"};function _r(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(_r.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="alt"||r==="ctrl"||r==="meta"||r==="shift"?(_r.errors=i,e===0):(_r.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:bn.enum},message:"must be equal to one of the allowed values"}],!1)}function Ss(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.tab_id===void 0&&(n="tab_id")||r.key===void 0&&(n="key")||r.code===void 0&&(n="code")||r.modifiers===void 0&&(n="modifiers"))return Ss.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;if(r.code!==void 0){let p=e;if(typeof r.code!="string")return Ss.errors=[{instancePath:s+"/code",schemaPath:"#/properties/code/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.dialogs!==void 0){let p=r.dialogs,l=e;if(e===l)if(Array.isArray(p)){var o=!0;let u=p.length;for(let y=0;y=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}else return Fs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Fs.errors=i,e===0}function Vr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.id===void 0&&(o="id")||r.url===void 0&&(o="url")||r.body===void 0&&(o="body"))return Vr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.body!==void 0){let a=e;if(typeof r.body!="string")return Vr.errors=[{instancePath:s+"/body",schemaPath:"#/properties/body/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.id!==void 0){let a=e;if(typeof r.id!="string")return Vr.errors=[{instancePath:s+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.title!==void 0){let a=e;if(typeof r.title!="string")return Vr.errors=[{instancePath:s+"/title",schemaPath:"#/properties/title/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.truncated!==void 0){let a=e;if(typeof r.truncated!="boolean")return Vr.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t)if(r.url!==void 0){let a=e;if(typeof r.url!="string")return Vr.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}}}}else return Vr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Vr.errors=i,e===0}var Pn={enum:["user_typed","link","form_submit","reload","history","script","browser"],type:"string"};function fi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(fi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="user_typed"||r==="link"||r==="form_submit"||r==="reload"||r==="history"||r==="script"||r==="browser"?(fi.errors=i,e===0):(fi.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Pn.enum},message:"must be equal to one of the allowed values"}],!1)}function X(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.state===void 0&&(t="state"))return X.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.state!==void 0&&typeof r.state!="string")return X.errors=[{instancePath:s+"/state",schemaPath:"#/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1}else return X.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return X.errors=i,e===0}function ie(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.ctx!==void 0){let o=e;if(typeof r.ctx!="string")return ie.errors=[{instancePath:s+"/ctx",schemaPath:"#/properties/ctx/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.name!==void 0){let o=e;if(typeof r.name!="string")return ie.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.ref!==void 0){let o=e;if(typeof r.ref!="string")return ie.errors=[{instancePath:s+"/ref",schemaPath:"#/properties/ref/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t){if(r.role!==void 0){let o=e;if(typeof r.role!="string")return ie.errors=[{instancePath:s+"/role",schemaPath:"#/properties/role/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=o===e}else var t=!0;if(t)if(r.unmatched!==void 0){let o=e;if(typeof r.unmatched!="boolean")return ie.errors=[{instancePath:s+"/unmatched",schemaPath:"#/properties/unmatched/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=o===e}else var t=!0}}}}else return ie.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ie.errors=i,e===0}var kn={enum:["enter","suggestion","blur"],type:"string"};function yi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(yi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="enter"||r==="suggestion"||r==="blur"?(yi.errors=i,e===0):(yi.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:kn.enum},message:"must be equal to one of the allowed values"}],!1)}function dt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.value===void 0&&(o="value"))return dt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.label!==void 0){let a=e;if(typeof r.label!="string")return dt.errors=[{instancePath:s+"/label",schemaPath:"#/properties/label/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.value!==void 0){let a=e;if(typeof r.value!="string")return dt.errors=[{instancePath:s+"/value",schemaPath:"#/properties/value/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0}else return dt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return dt.errors=i,e===0}function Li(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0,t=e,o=!1,a=null,n=e;if(e===n)if(r&&typeof r=="object"&&!Array.isArray(r)){let z;if(r.op===void 0&&(z="op")||r.id===void 0&&(z="id")||r.state===void 0&&(z="state")||r.result===void 0&&(z="result")||r.to===void 0&&(z="to")||r.cause===void 0&&(z="cause")){let w={instancePath:s,schemaPath:"#/oneOf/0/required",keyword:"required",params:{missingProperty:z},message:"must have required property '"+z+"'"};i===null?i=[w]:i.push(w),e++}else{if(r.cause!==void 0){let w=e;fi(r.cause,{instancePath:s+"/cause",parentData:r,parentDataProperty:"cause",rootData:f})||(i=i===null?fi.errors:i.concat(fi.errors),e=i.length);var p=w===e}else var p=!0;if(p){if(r.id!==void 0){let w=r.id,V=e;if(!(typeof w=="number"&&!(w%1)&&!isNaN(w))){let P={instancePath:s+"/id",schemaPath:"#/oneOf/0/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[P]:i.push(P),e++}if(e===V&&typeof w=="number"&&(w<0||isNaN(w))){let P={instancePath:s+"/id",schemaPath:"#/oneOf/0/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[P]:i.push(P),e++}var p=V===e}else var p=!0;if(p){if(r.op!==void 0){let w=r.op,V=e;if(typeof w!="string"){let P={instancePath:s+"/op",schemaPath:"#/oneOf/0/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[P]:i.push(P),e++}if(w!=="navigate"){let P={instancePath:s+"/op",schemaPath:"#/oneOf/0/properties/op/const",keyword:"const",params:{allowedValue:"navigate"},message:"must be equal to constant"};i===null?i=[P]:i.push(P),e++}var p=V===e}else var p=!0;if(p){if(r.result!==void 0){let w=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var p=w===e}else var p=!0;if(p){if(r.state!==void 0){let w=e;if(typeof r.state!="string"){let W={instancePath:s+"/state",schemaPath:"#/oneOf/0/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var p=w===e}else var p=!0;if(p)if(r.to!==void 0){let w=e;if(typeof r.to!="string"){let W={instancePath:s+"/to",schemaPath:"#/oneOf/0/properties/to/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var p=w===e}else var p=!0}}}}}}else{let z={instancePath:s,schemaPath:"#/oneOf/0/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[z]:i.push(z),e++}var u=n===e;u&&(o=!0,a=0);let l=e;if(e===l)if(r&&typeof r=="object"&&!Array.isArray(r)){let z;if(r.op===void 0&&(z="op")||r.id===void 0&&(z="id")||r.state===void 0&&(z="state")||r.result===void 0&&(z="result")){let w={instancePath:s,schemaPath:"#/oneOf/1/required",keyword:"required",params:{missingProperty:z},message:"must have required property '"+z+"'"};i===null?i=[w]:i.push(w),e++}else{if(r.id!==void 0){let w=r.id,V=e;if(!(typeof w=="number"&&!(w%1)&&!isNaN(w))){let W={instancePath:s+"/id",schemaPath:"#/oneOf/1/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[W]:i.push(W),e++}if(e===V&&typeof w=="number"&&(w<0||isNaN(w))){let W={instancePath:s+"/id",schemaPath:"#/oneOf/1/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[W]:i.push(W),e++}var m=V===e}else var m=!0;if(m){if(r.op!==void 0){let w=r.op,V=e;if(typeof w!="string"){let P={instancePath:s+"/op",schemaPath:"#/oneOf/1/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[P]:i.push(P),e++}if(w!=="switch_tab"){let P={instancePath:s+"/op",schemaPath:"#/oneOf/1/properties/op/const",keyword:"const",params:{allowedValue:"switch_tab"},message:"must be equal to constant"};i===null?i=[P]:i.push(P),e++}var m=V===e}else var m=!0;if(m){if(r.result!==void 0){let w=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var m=w===e}else var m=!0;if(m)if(r.state!==void 0){let w=e;if(typeof r.state!="string"){let W={instancePath:s+"/state",schemaPath:"#/oneOf/1/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[W]:i.push(W),e++}var m=w===e}else var m=!0}}}}else{let z={instancePath:s,schemaPath:"#/oneOf/1/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[z]:i.push(z),e++}var u=l===e;if(u&&o)o=!1,a=[a,1];else{u&&(o=!0,a=1);let z=e;if(e===z)if(r&&typeof r=="object"&&!Array.isArray(r)){let V;if(r.op===void 0&&(V="op")||r.id===void 0&&(V="id")||r.state===void 0&&(V="state")||r.result===void 0&&(V="result")||r.target===void 0&&(V="target")){let W={instancePath:s,schemaPath:"#/oneOf/2/required",keyword:"required",params:{missingProperty:V},message:"must have required property '"+V+"'"};i===null?i=[W]:i.push(W),e++}else{if(r.id!==void 0){let W=r.id,P=e;if(!(typeof W=="number"&&!(W%1)&&!isNaN(W))){let N={instancePath:s+"/id",schemaPath:"#/oneOf/2/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[N]:i.push(N),e++}if(e===P&&typeof W=="number"&&(W<0||isNaN(W))){let N={instancePath:s+"/id",schemaPath:"#/oneOf/2/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[N]:i.push(N),e++}var y=P===e}else var y=!0;if(y){if(r.op!==void 0){let W=r.op,P=e;if(typeof W!="string"){let A={instancePath:s+"/op",schemaPath:"#/oneOf/2/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[A]:i.push(A),e++}if(W!=="click"){let A={instancePath:s+"/op",schemaPath:"#/oneOf/2/properties/op/const",keyword:"const",params:{allowedValue:"click"},message:"must be equal to constant"};i===null?i=[A]:i.push(A),e++}var y=P===e}else var y=!0;if(y){if(r.result!==void 0){let W=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var y=W===e}else var y=!0;if(y){if(r.state!==void 0){let W=e;if(typeof r.state!="string"){let N={instancePath:s+"/state",schemaPath:"#/oneOf/2/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[N]:i.push(N),e++}var y=W===e}else var y=!0;if(y)if(r.target!==void 0){let W=e;ie(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?ie.errors:i.concat(ie.errors),e=i.length);var y=W===e}else var y=!0}}}}}else{let V={instancePath:s,schemaPath:"#/oneOf/2/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[V]:i.push(V),e++}var u=z===e;if(u&&o)o=!1,a=[a,2];else{u&&(o=!0,a=2);let V=e;if(e===V)if(r&&typeof r=="object"&&!Array.isArray(r)){let P;if(r.op===void 0&&(P="op")||r.id===void 0&&(P="id")||r.state===void 0&&(P="state")||r.result===void 0&&(P="result")||r.target===void 0&&(P="target")){let N={instancePath:s,schemaPath:"#/oneOf/3/required",keyword:"required",params:{missingProperty:P},message:"must have required property '"+P+"'"};i===null?i=[N]:i.push(N),e++}else{if(r.id!==void 0){let N=r.id,A=e;if(!(typeof N=="number"&&!(N%1)&&!isNaN(N))){let x={instancePath:s+"/id",schemaPath:"#/oneOf/3/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[x]:i.push(x),e++}if(e===A&&typeof N=="number"&&(N<0||isNaN(N))){let x={instancePath:s+"/id",schemaPath:"#/oneOf/3/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[x]:i.push(x),e++}var d=A===e}else var d=!0;if(d){if(r.op!==void 0){let N=r.op,A=e;if(typeof N!="string"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/3/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[k]:i.push(k),e++}if(N!=="hover"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/3/properties/op/const",keyword:"const",params:{allowedValue:"hover"},message:"must be equal to constant"};i===null?i=[k]:i.push(k),e++}var d=A===e}else var d=!0;if(d){if(r.result!==void 0){let N=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var d=N===e}else var d=!0;if(d){if(r.state!==void 0){let N=e;if(typeof r.state!="string"){let x={instancePath:s+"/state",schemaPath:"#/oneOf/3/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[x]:i.push(x),e++}var d=N===e}else var d=!0;if(d)if(r.target!==void 0){let N=e;ie(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?ie.errors:i.concat(ie.errors),e=i.length);var d=N===e}else var d=!0}}}}}else{let P={instancePath:s,schemaPath:"#/oneOf/3/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[P]:i.push(P),e++}var u=V===e;if(u&&o)o=!1,a=[a,3];else{u&&(o=!0,a=3);let P=e;if(e===P)if(r&&typeof r=="object"&&!Array.isArray(r)){let A;if(r.op===void 0&&(A="op")||r.id===void 0&&(A="id")||r.state===void 0&&(A="state")||r.result===void 0&&(A="result")||r.target===void 0&&(A="target")||r.value===void 0&&(A="value")||r.commit===void 0&&(A="commit")){let x={instancePath:s,schemaPath:"#/oneOf/4/required",keyword:"required",params:{missingProperty:A},message:"must have required property '"+A+"'"};i===null?i=[x]:i.push(x),e++}else{if(r.commit!==void 0){let x=e;yi(r.commit,{instancePath:s+"/commit",parentData:r,parentDataProperty:"commit",rootData:f})||(i=i===null?yi.errors:i.concat(yi.errors),e=i.length);var b=x===e}else var b=!0;if(b){if(r.id!==void 0){let x=r.id,k=e;if(!(typeof x=="number"&&!(x%1)&&!isNaN(x))){let $={instancePath:s+"/id",schemaPath:"#/oneOf/4/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[$]:i.push($),e++}if(e===k&&typeof x=="number"&&(x<0||isNaN(x))){let $={instancePath:s+"/id",schemaPath:"#/oneOf/4/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[$]:i.push($),e++}var b=k===e}else var b=!0;if(b){if(r.op!==void 0){let x=r.op,k=e;if(typeof x!="string"){let $={instancePath:s+"/op",schemaPath:"#/oneOf/4/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[$]:i.push($),e++}if(x!=="fill"){let $={instancePath:s+"/op",schemaPath:"#/oneOf/4/properties/op/const",keyword:"const",params:{allowedValue:"fill"},message:"must be equal to constant"};i===null?i=[$]:i.push($),e++}var b=k===e}else var b=!0;if(b){if(r.redacted!==void 0){let x=e;if(typeof r.redacted!="boolean"){let j={instancePath:s+"/redacted",schemaPath:"#/oneOf/4/properties/redacted/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"};i===null?i=[j]:i.push(j),e++}var b=x===e}else var b=!0;if(b){if(r.result!==void 0){let x=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var b=x===e}else var b=!0;if(b){if(r.state!==void 0){let x=e;if(typeof r.state!="string"){let j={instancePath:s+"/state",schemaPath:"#/oneOf/4/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[j]:i.push(j),e++}var b=x===e}else var b=!0;if(b){if(r.target!==void 0){let x=e;ie(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?ie.errors:i.concat(ie.errors),e=i.length);var b=x===e}else var b=!0;if(b)if(r.value!==void 0){let x=e;if(typeof r.value!="string"){let j={instancePath:s+"/value",schemaPath:"#/oneOf/4/properties/value/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[j]:i.push(j),e++}var b=x===e}else var b=!0}}}}}}}}else{let A={instancePath:s,schemaPath:"#/oneOf/4/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[A]:i.push(A),e++}var u=P===e;if(u&&o)o=!1,a=[a,4];else{u&&(o=!0,a=4);let A=e;if(e===A)if(r&&typeof r=="object"&&!Array.isArray(r)){let k;if(r.op===void 0&&(k="op")||r.id===void 0&&(k="id")||r.state===void 0&&(k="state")||r.result===void 0&&(k="result")||r.target===void 0&&(k="target")){let j={instancePath:s,schemaPath:"#/oneOf/5/required",keyword:"required",params:{missingProperty:k},message:"must have required property '"+k+"'"};i===null?i=[j]:i.push(j),e++}else{if(r.id!==void 0){let j=r.id,$=e;if(!(typeof j=="number"&&!(j%1)&&!isNaN(j))){let E={instancePath:s+"/id",schemaPath:"#/oneOf/5/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[E]:i.push(E),e++}if(e===$&&typeof j=="number"&&(j<0||isNaN(j))){let E={instancePath:s+"/id",schemaPath:"#/oneOf/5/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[E]:i.push(E),e++}var v=$===e}else var v=!0;if(v){if(r.op!==void 0){let j=r.op,$=e;if(typeof j!="string"){let T={instancePath:s+"/op",schemaPath:"#/oneOf/5/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[T]:i.push(T),e++}if(j!=="select"){let T={instancePath:s+"/op",schemaPath:"#/oneOf/5/properties/op/const",keyword:"const",params:{allowedValue:"select"},message:"must be equal to constant"};i===null?i=[T]:i.push(T),e++}var v=$===e}else var v=!0;if(v){if(r.result!==void 0){let j=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var v=j===e}else var v=!0;if(v){if(r.selection!==void 0){let j=r.selection,$=e;if(e===$)if(Array.isArray(j)){var O=!0;let T=j.length;for(let S=0;S=",limit:0},message:"must be >= 0"};i===null?i=[S]:i.push(S),e++}var h=T===e}else var h=!0;if(h){if(r.key!==void 0){let E=e;if(typeof r.key!="string"){let S={instancePath:s+"/key",schemaPath:"#/oneOf/6/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[S]:i.push(S),e++}var h=E===e}else var h=!0;if(h){if(r.modifiers!==void 0){let E=r.modifiers,T=e;if(e===T)if(Array.isArray(E)){var q=!0;let C=E.length;for(let J=0;J=",limit:0},message:"must be >= 0"};i===null?i=[J]:i.push(J),e++}var D=C===e}else var D=!0;if(D){if(r.op!==void 0){let S=r.op,C=e;if(typeof S!="string"){let H={instancePath:s+"/op",schemaPath:"#/oneOf/7/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[H]:i.push(H),e++}if(S!=="scroll"){let H={instancePath:s+"/op",schemaPath:"#/oneOf/7/properties/op/const",keyword:"const",params:{allowedValue:"scroll"},message:"must be equal to constant"};i===null?i=[H]:i.push(H),e++}var D=C===e}else var D=!0;if(D){if(r.result!==void 0){let S=e;X(r.result,{instancePath:s+"/result",parentData:r,parentDataProperty:"result",rootData:f})||(i=i===null?X.errors:i.concat(X.errors),e=i.length);var D=S===e}else var D=!0;if(D)if(r.state!==void 0){let S=e;if(typeof r.state!="string"){let J={instancePath:s+"/state",schemaPath:"#/oneOf/7/properties/state/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[J]:i.push(J),e++}var D=S===e}else var D=!0}}}}else{let T={instancePath:s,schemaPath:"#/oneOf/7/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[T]:i.push(T),e++}var u=$===e;u&&o?(o=!1,a=[a,7]):u&&(o=!0,a=7)}}}}}}if(o)e=t,i!==null&&(t?i.length=t:i=null);else{let z={instancePath:s,schemaPath:"#/oneOf",keyword:"oneOf",params:{passingSchemas:a},message:"must match exactly one schema in oneOf"};return i===null?i=[z]:i.push(z),e++,Li.errors=i,!1}return Li.errors=i,e===0}var Nn={enum:["user_finish","cli_stop"],type:"string"};function di(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(di.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="user_finish"||r==="cli_stop"?(di.errors=i,e===0):(di.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Nn.enum},message:"must be equal to one of the allowed values"}],!1)}function Ce(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.version===void 0&&(n="version")||r.recorded_at===void 0&&(n="recorded_at")||r.stopped_by===void 0&&(n="stopped_by")||r.entry===void 0&&(n="entry")||r.recorder===void 0&&(n="recorder")||r.states===void 0&&(n="states")||r.steps===void 0&&(n="steps"))return Ce.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;{let p=e;for(let l in r)if(!wn.call(_n.properties,l)){return Ce.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:l},message:"must NOT have additional properties"}],!1;break}if(p===e){if(r.entry!==void 0){let l=e;ys(r.entry,{instancePath:s+"/entry",parentData:r,parentDataProperty:"entry",rootData:f})||(i=i===null?ys.errors:i.concat(ys.errors),e=i.length);var t=l===e}else var t=!0;if(t){if(r.purpose!==void 0){let l=e;if(typeof r.purpose!="string")return Ce.errors=[{instancePath:s+"/purpose",schemaPath:"#/properties/purpose/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.recorded_at!==void 0){let l=e;if(typeof r.recorded_at!="string")return Ce.errors=[{instancePath:s+"/recorded_at",schemaPath:"#/properties/recorded_at/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.recorder!==void 0){let l=e;Fs(r.recorder,{instancePath:s+"/recorder",parentData:r,parentDataProperty:"recorder",rootData:f})||(i=i===null?Fs.errors:i.concat(Fs.errors),e=i.length);var t=l===e}else var t=!0;if(t){if(r.started_at!==void 0){let l=e;if(typeof r.started_at!="string")return Ce.errors=[{instancePath:s+"/started_at",schemaPath:"#/properties/started_at/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=l===e}else var t=!0;if(t){if(r.states!==void 0){let l=r.states,m=e;if(e===m)if(Array.isArray(l)){var o=!0;let y=l.length;for(let d=0;d=",limit:0},message:"must be >= 0"};i===null?i=[k]:i.push(k),e++}var l=A===e}else var l=!0;if(l){if(r.op!==void 0){let N=r.op,A=e;if(typeof N!="string"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/0/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[k]:i.push(k),e++}if(N!=="navigate"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/0/properties/op/const",keyword:"const",params:{allowedValue:"navigate"},message:"must be equal to constant"};i===null?i=[k]:i.push(k),e++}var l=A===e}else var l=!0;if(l){if(r.page!==void 0){let N=e;if(typeof r.page!="string"){let x={instancePath:s+"/page",schemaPath:"#/oneOf/0/properties/page/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[x]:i.push(x),e++}var l=N===e}else var l=!0;if(l)if(r.to!==void 0){let N=e;if(typeof r.to!="string"){let x={instancePath:s+"/to",schemaPath:"#/oneOf/0/properties/to/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[x]:i.push(x),e++}var l=N===e}else var l=!0}}}}}else{let P={instancePath:s,schemaPath:"#/oneOf/0/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[P]:i.push(P),e++}var d=n===e;d&&(o=!0,a=0);let m=e;if(e===m)if(r&&typeof r=="object"&&!Array.isArray(r)){let P;if(r.op===void 0&&(P="op")||r.id===void 0&&(P="id")||r.page===void 0&&(P="page")||r.target===void 0&&(P="target")){let N={instancePath:s,schemaPath:"#/oneOf/1/required",keyword:"required",params:{missingProperty:P},message:"must have required property '"+P+"'"};i===null?i=[N]:i.push(N),e++}else{if(r.effect!==void 0){let N=e,A=e,x=!1,k=e;se(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?se.errors:i.concat(se.errors),e=i.length);var u=k===e;if(x=x||u,x)e=A,i!==null&&(A?i.length=A:i=null);else{let j={instancePath:s+"/effect",schemaPath:"#/oneOf/1/properties/effect/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};i===null?i=[j]:i.push(j),e++}var y=N===e}else var y=!0;if(y){if(r.id!==void 0){let N=r.id,A=e;if(!(typeof N=="number"&&!(N%1)&&!isNaN(N))){let k={instancePath:s+"/id",schemaPath:"#/oneOf/1/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[k]:i.push(k),e++}if(e===A&&typeof N=="number"&&(N<0||isNaN(N))){let k={instancePath:s+"/id",schemaPath:"#/oneOf/1/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[k]:i.push(k),e++}var y=A===e}else var y=!0;if(y){if(r.op!==void 0){let N=r.op,A=e;if(typeof N!="string"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/1/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[k]:i.push(k),e++}if(N!=="click"){let k={instancePath:s+"/op",schemaPath:"#/oneOf/1/properties/op/const",keyword:"const",params:{allowedValue:"click"},message:"must be equal to constant"};i===null?i=[k]:i.push(k),e++}var y=A===e}else var y=!0;if(y){if(r.page!==void 0){let N=e;if(typeof r.page!="string"){let x={instancePath:s+"/page",schemaPath:"#/oneOf/1/properties/page/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[x]:i.push(x),e++}var y=N===e}else var y=!0;if(y)if(r.target!==void 0){let N=e;Z(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?Z.errors:i.concat(Z.errors),e=i.length);var y=N===e}else var y=!0}}}}}else{let P={instancePath:s,schemaPath:"#/oneOf/1/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[P]:i.push(P),e++}var d=m===e;if(d&&o)o=!1,a=[a,1];else{d&&(o=!0,a=1);let P=e;if(e===P)if(r&&typeof r=="object"&&!Array.isArray(r)){let A;if(r.op===void 0&&(A="op")||r.id===void 0&&(A="id")||r.page===void 0&&(A="page")||r.target===void 0&&(A="target")){let x={instancePath:s,schemaPath:"#/oneOf/2/required",keyword:"required",params:{missingProperty:A},message:"must have required property '"+A+"'"};i===null?i=[x]:i.push(x),e++}else{if(r.effect!==void 0){let x=e,k=e,j=!1,$=e;se(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?se.errors:i.concat(se.errors),e=i.length);var b=$===e;if(j=j||b,j)e=k,i!==null&&(k?i.length=k:i=null);else{let E={instancePath:s+"/effect",schemaPath:"#/oneOf/2/properties/effect/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};i===null?i=[E]:i.push(E),e++}var v=x===e}else var v=!0;if(v){if(r.id!==void 0){let x=r.id,k=e;if(!(typeof x=="number"&&!(x%1)&&!isNaN(x))){let $={instancePath:s+"/id",schemaPath:"#/oneOf/2/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[$]:i.push($),e++}if(e===k&&typeof x=="number"&&(x<0||isNaN(x))){let $={instancePath:s+"/id",schemaPath:"#/oneOf/2/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[$]:i.push($),e++}var v=k===e}else var v=!0;if(v){if(r.op!==void 0){let x=r.op,k=e;if(typeof x!="string"){let $={instancePath:s+"/op",schemaPath:"#/oneOf/2/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[$]:i.push($),e++}if(x!=="hover"){let $={instancePath:s+"/op",schemaPath:"#/oneOf/2/properties/op/const",keyword:"const",params:{allowedValue:"hover"},message:"must be equal to constant"};i===null?i=[$]:i.push($),e++}var v=k===e}else var v=!0;if(v){if(r.page!==void 0){let x=e;if(typeof r.page!="string"){let j={instancePath:s+"/page",schemaPath:"#/oneOf/2/properties/page/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[j]:i.push(j),e++}var v=x===e}else var v=!0;if(v)if(r.target!==void 0){let x=e;Z(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?Z.errors:i.concat(Z.errors),e=i.length);var v=x===e}else var v=!0}}}}}else{let A={instancePath:s,schemaPath:"#/oneOf/2/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[A]:i.push(A),e++}var d=P===e;if(d&&o)o=!1,a=[a,2];else{d&&(o=!0,a=2);let A=e;if(e===A)if(r&&typeof r=="object"&&!Array.isArray(r)){let k;if(r.op===void 0&&(k="op")||r.id===void 0&&(k="id")||r.page===void 0&&(k="page")||r.target===void 0&&(k="target")||r.value===void 0&&(k="value")){let j={instancePath:s,schemaPath:"#/oneOf/3/required",keyword:"required",params:{missingProperty:k},message:"must have required property '"+k+"'"};i===null?i=[j]:i.push(j),e++}else{if(r.effect!==void 0){let j=e,$=e,E=!1,T=e;se(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?se.errors:i.concat(se.errors),e=i.length);var O=T===e;if(E=E||O,E)e=$,i!==null&&($?i.length=$:i=null);else{let S={instancePath:s+"/effect",schemaPath:"#/oneOf/3/properties/effect/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};i===null?i=[S]:i.push(S),e++}var h=j===e}else var h=!0;if(h){if(r.id!==void 0){let j=r.id,$=e;if(!(typeof j=="number"&&!(j%1)&&!isNaN(j))){let T={instancePath:s+"/id",schemaPath:"#/oneOf/3/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[T]:i.push(T),e++}if(e===$&&typeof j=="number"&&(j<0||isNaN(j))){let T={instancePath:s+"/id",schemaPath:"#/oneOf/3/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[T]:i.push(T),e++}var h=$===e}else var h=!0;if(h){if(r.op!==void 0){let j=r.op,$=e;if(typeof j!="string"){let T={instancePath:s+"/op",schemaPath:"#/oneOf/3/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[T]:i.push(T),e++}if(j!=="fill"){let T={instancePath:s+"/op",schemaPath:"#/oneOf/3/properties/op/const",keyword:"const",params:{allowedValue:"fill"},message:"must be equal to constant"};i===null?i=[T]:i.push(T),e++}var h=$===e}else var h=!0;if(h){if(r.page!==void 0){let j=e;if(typeof r.page!="string"){let E={instancePath:s+"/page",schemaPath:"#/oneOf/3/properties/page/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[E]:i.push(E),e++}var h=j===e}else var h=!0;if(h){if(r.redacted!==void 0){let j=e;if(typeof r.redacted!="boolean"){let E={instancePath:s+"/redacted",schemaPath:"#/oneOf/3/properties/redacted/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"};i===null?i=[E]:i.push(E),e++}var h=j===e}else var h=!0;if(h){if(r.target!==void 0){let j=e;Z(r.target,{instancePath:s+"/target",parentData:r,parentDataProperty:"target",rootData:f})||(i=i===null?Z.errors:i.concat(Z.errors),e=i.length);var h=j===e}else var h=!0;if(h)if(r.value!==void 0){let j=e;if(typeof r.value!="string"){let E={instancePath:s+"/value",schemaPath:"#/oneOf/3/properties/value/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[E]:i.push(E),e++}var h=j===e}else var h=!0}}}}}}}else{let k={instancePath:s,schemaPath:"#/oneOf/3/type",keyword:"type",params:{type:"object"},message:"must be object"};i===null?i=[k]:i.push(k),e++}var d=A===e;if(d&&o)o=!1,a=[a,3];else{d&&(o=!0,a=3);let k=e;if(e===k)if(r&&typeof r=="object"&&!Array.isArray(r)){let $;if(r.op===void 0&&($="op")||r.id===void 0&&($="id")||r.page===void 0&&($="page")||r.target===void 0&&($="target")||r.selection===void 0&&($="selection")){let E={instancePath:s,schemaPath:"#/oneOf/4/required",keyword:"required",params:{missingProperty:$},message:"must have required property '"+$+"'"};i===null?i=[E]:i.push(E),e++}else{if(r.effect!==void 0){let E=e,T=e,S=!1,C=e;se(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?se.errors:i.concat(se.errors),e=i.length);var q=C===e;if(S=S||q,S)e=T,i!==null&&(T?i.length=T:i=null);else{let J={instancePath:s+"/effect",schemaPath:"#/oneOf/4/properties/effect/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};i===null?i=[J]:i.push(J),e++}var _=E===e}else var _=!0;if(_){if(r.id!==void 0){let E=r.id,T=e;if(!(typeof E=="number"&&!(E%1)&&!isNaN(E))){let C={instancePath:s+"/id",schemaPath:"#/oneOf/4/properties/id/type",keyword:"type",params:{type:"integer"},message:"must be integer"};i===null?i=[C]:i.push(C),e++}if(e===T&&typeof E=="number"&&(E<0||isNaN(E))){let C={instancePath:s+"/id",schemaPath:"#/oneOf/4/properties/id/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"};i===null?i=[C]:i.push(C),e++}var _=T===e}else var _=!0;if(_){if(r.op!==void 0){let E=r.op,T=e;if(typeof E!="string"){let C={instancePath:s+"/op",schemaPath:"#/oneOf/4/properties/op/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[C]:i.push(C),e++}if(E!=="select"){let C={instancePath:s+"/op",schemaPath:"#/oneOf/4/properties/op/const",keyword:"const",params:{allowedValue:"select"},message:"must be equal to constant"};i===null?i=[C]:i.push(C),e++}var _=T===e}else var _=!0;if(_){if(r.page!==void 0){let E=e;if(typeof r.page!="string"){let S={instancePath:s+"/page",schemaPath:"#/oneOf/4/properties/page/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[S]:i.push(S),e++}var _=E===e}else var _=!0;if(_){if(r.selection!==void 0){let E=r.selection,T=e;if(e===T)if(Array.isArray(E)){var D=!0;let C=E.length;for(let J=0;J=",limit:0},message:"must be >= 0"};i===null?i=[H]:i.push(H),e++}var w=C===e}else var w=!0;if(w){if(r.key!==void 0){let S=e;if(typeof r.key!="string"){let J={instancePath:s+"/key",schemaPath:"#/oneOf/5/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"};i===null?i=[J]:i.push(J),e++}var w=S===e}else var w=!0;if(w){if(r.modifiers!==void 0){let S=r.modifiers,C=e;if(e===C)if(Array.isArray(S)){var V=!0;let H=S.length;for(let Ks=0;Ks=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.capture_id!==void 0){let p=e;if(typeof r.capture_id!="string")return we.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.dialogs!==void 0){let p=r.dialogs,l=e;if(e===l)if(Array.isArray(p)){var o=!0;let u=p.length;for(let y=0;y=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.scope!==void 0){let p=e,l=e,m=!1,u=e;gi(r.scope,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?gi.errors:i.concat(gi.errors),e=i.length);var a=u===e;if(m=m||a,m)e=l,i!==null&&(l?i.length=l:i=null);else{let d={instancePath:s+"/scope",schemaPath:"#/properties/scope/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[d]:i.push(d),e++,we.errors=i,!1}var t=p===e}else var t=!0;if(t){if(r.tab_id!==void 0){let p=r.tab_id,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return we.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=l===e}else var t=!0;if(t)if(r.width!==void 0){let p=r.width,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return we.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===l&&typeof p=="number"&&(p<0||isNaN(p)))return we.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0}}}}}}}else return we.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return we.errors=i,e===0}var Vp=it;function it(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.data_base64===void 0&&(o="data_base64")||r.next_offset===void 0&&(o="next_offset")||r.eof===void 0&&(o="eof"))return it.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.data_base64!==void 0){let a=e;if(typeof r.data_base64!="string")return it.errors=[{instancePath:s+"/data_base64",schemaPath:"#/properties/data_base64/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t){if(r.eof!==void 0){let a=e;if(typeof r.eof!="boolean")return it.errors=[{instancePath:s+"/eof",schemaPath:"#/properties/eof/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=a===e}else var t=!0;if(t)if(r.next_offset!==void 0){let a=r.next_offset,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return it.errors=[{instancePath:s+"/next_offset",schemaPath:"#/properties/next_offset/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return it.errors=[{instancePath:s+"/next_offset",schemaPath:"#/properties/next_offset/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}else return it.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return it.errors=i,e===0}var Wp=Ci;function Ci(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.released===void 0&&(t="released"))return Ci.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.released!==void 0&&typeof r.released!="boolean")return Ci.errors=[{instancePath:s+"/released",schemaPath:"#/properties/released/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1}else return Ci.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ci.errors=i,e===0}var Mp=Re;function Re(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.image_base64===void 0&&(a="image_base64")||r.width===void 0&&(a="width")||r.height===void 0&&(a="height")||r.format===void 0&&(a="format")||r.tab_id===void 0&&(a="tab_id"))return Re.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.capture_id!==void 0){let n=e;if(typeof r.capture_id!="string")return Re.errors=[{instancePath:s+"/capture_id",schemaPath:"#/properties/capture_id/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.capture_unavailable!==void 0){let n=e;if(typeof r.capture_unavailable!="string")return Re.errors=[{instancePath:s+"/capture_unavailable",schemaPath:"#/properties/capture_unavailable/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.dialogs!==void 0){let n=r.dialogs,p=e;if(e===p)if(Array.isArray(n)){var o=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0;if(t){if(r.image_base64!==void 0){let n=e;if(typeof r.image_base64!="string")return Re.errors=[{instancePath:s+"/image_base64",schemaPath:"#/properties/image_base64/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Re.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t)if(r.width!==void 0){let n=r.width,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return Re.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===p&&typeof n=="number"&&(n<0||isNaN(n)))return Re.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=p===e}else var t=!0}}}}}}}else return Re.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Re.errors=i,e===0}var Up=fr;function fr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id")||r.x===void 0&&(a="x")||r.y===void 0&&(a="y")||r.width===void 0&&(a="width")||r.height===void 0&&(a="height"))return fr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.dialogs!==void 0){let n=r.dialogs,p=e;if(e===p)if(Array.isArray(n)){var t=!0;let l=n.length;for(let m=0;m=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0;if(o){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return ns.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var o=p===e}else var o=!0;if(o){if(r.text!==void 0){let n=e;if(typeof r.text!="string")return ns.errors=[{instancePath:s+"/text",schemaPath:"#/properties/text/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=n===e}else var o=!0;if(o)if(r.truncated!==void 0){let n=e;if(typeof r.truncated!="boolean")return ns.errors=[{instancePath:s+"/truncated",schemaPath:"#/properties/truncated/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var o=n===e}else var o=!0}}}}else return ns.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ns.errors=i,e===0}var Jp=at;function at(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.original_window_id===void 0&&(o="original_window_id")||r.original_index===void 0&&(o="original_index")||r.agent_window_id===void 0&&(o="agent_window_id"))return at.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.agent_window_id!==void 0){let a=r.agent_window_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return at.errors=[{instancePath:s+"/agent_window_id",schemaPath:"#/properties/agent_window_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.original_index!==void 0){let a=r.original_index,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return at.errors=[{instancePath:s+"/original_index",schemaPath:"#/properties/original_index/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.original_window_id!==void 0){let a=r.original_window_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return at.errors=[{instancePath:s+"/original_window_id",schemaPath:"#/properties/original_window_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t)if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return at.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}}else return at.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return at.errors=i,e===0}var Hp=Wi;function Wi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.tab_id===void 0&&(t="tab_id"))return Wi.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;if(r.tab_id!==void 0){let o=r.tab_id;if(!(typeof o=="number"&&!(o%1)&&!isNaN(o)))return Wi.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1}}else return Wi.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Wi.errors=i,e===0}var Bp=qt;function qt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tab_id===void 0&&(o="tab_id")||r.window_id===void 0&&(o="window_id")||r.url===void 0&&(o="url"))return qt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.tab_id!==void 0){let a=r.tab_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return qt.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0;if(t){if(r.url!==void 0){let a=e;if(typeof r.url!="string")return qt.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=a===e}else var t=!0;if(t)if(r.window_id!==void 0){let a=r.window_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return qt.errors=[{instancePath:s+"/window_id",schemaPath:"#/properties/window_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}else return qt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return qt.errors=i,e===0}var Kp=Mi;var On={description:"View scope for [`TabListParams`] (\xA76 sandbox table).\n\n* `User` \u2014 tabs that live in any window other than an Agent Window.\n* `Agent` \u2014 tabs in the requesting session's Agent Window only.\n* `All` \u2014 both of the above; never reveals other sessions' Agent\n Windows (cross-session isolation per \xA76).",enum:["user","agent","all"],type:"string"};function _i(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(_i.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="user"||r==="agent"||r==="all"?(_i.errors=i,e===0):(_i.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:On.enum},message:"must be equal to one of the allowed values"}],!1)}function br(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.tab_id===void 0&&(a="tab_id"))return br.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;if(r.active!==void 0){let n=e;if(typeof r.active!="boolean")return br.errors=[{instancePath:s+"/active",schemaPath:"#/properties/active/type",keyword:"type",params:{type:"boolean"},message:"must be boolean"}],!1;var t=n===e}else var t=!0;if(t){if(r.scope!==void 0){let n=e,p=e,l=!1,m=e;_i(r.scope,{instancePath:s+"/scope",parentData:r,parentDataProperty:"scope",rootData:f})||(i=i===null?_i.errors:i.concat(_i.errors),e=i.length);var o=m===e;if(l=l||o,l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/scope",schemaPath:"#/properties/scope/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,br.errors=i,!1}var t=n===e}else var t=!0;if(t){if(r.tab_id!==void 0){let n=r.tab_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return br.errors=[{instancePath:s+"/tab_id",schemaPath:"#/properties/tab_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0;if(t){if(r.title!==void 0){let n=e;if(typeof r.title!="string")return br.errors=[{instancePath:s+"/title",schemaPath:"#/properties/title/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t){if(r.url!==void 0){let n=e;if(typeof r.url!="string")return br.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=n===e}else var t=!0;if(t)if(r.window_id!==void 0){let n=r.window_id,p=e;if(!(typeof n=="number"&&!(n%1)&&!isNaN(n)))return br.errors=[{instancePath:s+"/window_id",schemaPath:"#/properties/window_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=p===e}else var t=!0}}}}}else return br.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return br.errors=i,e===0}function Mi(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.tabs===void 0&&(o="tabs"))return Mi.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.tabs!==void 0){let a=r.tabs;if(e===e)if(Array.isArray(a)){var t=!0;let p=a.length;for(let l=0;l=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Rs.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return Rs.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t)if(r.window_id!==void 0){let a=r.window_id,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a)))return Rs.errors=[{instancePath:s+"/window_id",schemaPath:"#/properties/window_id/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;var t=n===e}else var t=!0}}else return Rs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Rs.errors=i,e===0}var rl=na;function na(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(na.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="left"||r==="middle"||r==="right"?(na.errors=i,e===0):(na.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ja.enum},message:"must be equal to one of the allowed values"}],!1)}var sl=ba;function ba(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(ba.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(ba.errors=i,e===0)}var tl=jr;function jr(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let a;if(r.key===void 0&&(a="key"))return jr.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:a},message:"must have required property '"+a+"'"}],!1;{let n=e;for(let p in r)if(!(p==="body"||p==="headers"||p==="key"||p==="method"||p==="url")){return jr.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.body!==void 0){let p=r.body,l=e;if(typeof p!="string"&&p!==null)return jr.errors=[{instancePath:s+"/body",schemaPath:"#/properties/body/type",keyword:"type",params:{type:fs.properties.body.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0;if(t){if(r.headers!==void 0){let p=r.headers,l=e;if(!(p&&typeof p=="object"&&!Array.isArray(p))&&p!==null)return jr.errors=[{instancePath:s+"/headers",schemaPath:"#/properties/headers/type",keyword:"type",params:{type:fs.properties.headers.type},message:"must be object,null"}],!1;if(e===l&&p&&typeof p=="object"&&!Array.isArray(p))for(let u in p){let y=p[u],d=e;if(typeof y!="string"&&y!==null)return jr.errors=[{instancePath:s+"/headers/"+u.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/headers/additionalProperties/type",keyword:"type",params:{type:fs.properties.headers.additionalProperties.type},message:"must be string,null"}],!1;var o=d===e;if(!o)break}var t=l===e}else var t=!0;if(t){if(r.key!==void 0){let p=e;if(typeof r.key!="string")return jr.errors=[{instancePath:s+"/key",schemaPath:"#/properties/key/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var t=p===e}else var t=!0;if(t){if(r.method!==void 0){let p=r.method,l=e;if(typeof p!="string"&&p!==null)return jr.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:fs.properties.method.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0;if(t)if(r.url!==void 0){let p=r.url,l=e;if(typeof p!="string"&&p!==null)return jr.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:fs.properties.url.type},message:"must be string,null"}],!1;var t=l===e}else var t=!0}}}}}}else return jr.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return jr.errors=i,e===0}var il=_a;function _a(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(_a.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(_a.errors=i,e===0)}var al=xt;function xt(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let o;if(r.match===void 0&&(o="match")||r.effect===void 0&&(o="effect"))return xt.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:o},message:"must have required property '"+o+"'"}],!1;if(r.effect!==void 0){let a=e;ht(r.effect,{instancePath:s+"/effect",parentData:r,parentDataProperty:"effect",rootData:f})||(i=i===null?ht.errors:i.concat(ht.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.match!==void 0){let a=e;rr(r.match,{instancePath:s+"/match",parentData:r,parentDataProperty:"match",rootData:f})||(i=i===null?rr.errors:i.concat(rr.errors),e=i.length);var t=a===e}else var t=!0;if(t){if(r.name!==void 0){let a=r.name,n=e;if(typeof a!="string"&&a!==null)return xt.errors=[{instancePath:s+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type:ya.properties.name.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t)if(r.times!==void 0){let a=r.times,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return xt.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/type",keyword:"type",params:{type:ya.properties.times.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return xt.errors=[{instancePath:s+"/times",schemaPath:"#/properties/times/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}else return xt.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return xt.errors=i,e===0}var nl=At;function At(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let t;if(r.type===void 0&&(t="type"))return At.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:t},message:"must have required property '"+t+"'"}],!1;{let o=e;for(let a in r)if(a!=="type"){return At.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:a},message:"must NOT have additional properties"}],!1;break}if(o===e&&r.type!==void 0){let a=r.type;if(typeof a!="string")return At.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;if(a!=="block")return At.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/const",keyword:"const",params:{allowedValue:"block"},message:"must be equal to constant"}],!1}}}else return At.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return At.errors=i,e===0}var ol=Ye,qi={additionalProperties:!1,properties:{body:{type:["string","null"]},headers:{additionalProperties:{type:["string","null"]},type:["object","null"]},json:{anyOf:[{$ref:"#/definitions/DebugJsonEdit"},{type:"null"}]},method:{type:["string","null"]},type:{const:"modify",type:"string"},url:{type:["string","null"]}},required:["type"],type:"object"};function Ye(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n;if(r.type===void 0&&(n="type"))return Ye.errors=[{instancePath:s,schemaPath:"#/required",keyword:"required",params:{missingProperty:n},message:"must have required property '"+n+"'"}],!1;{let p=e;for(let l in r)if(!(l==="body"||l==="headers"||l==="json"||l==="method"||l==="type"||l==="url")){return Ye.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:l},message:"must NOT have additional properties"}],!1;break}if(p===e){if(r.body!==void 0){let l=r.body,m=e;if(typeof l!="string"&&l!==null)return Ye.errors=[{instancePath:s+"/body",schemaPath:"#/properties/body/type",keyword:"type",params:{type:qi.properties.body.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.headers!==void 0){let l=r.headers,m=e;if(!(l&&typeof l=="object"&&!Array.isArray(l))&&l!==null)return Ye.errors=[{instancePath:s+"/headers",schemaPath:"#/properties/headers/type",keyword:"type",params:{type:qi.properties.headers.type},message:"must be object,null"}],!1;if(e===m&&l&&typeof l=="object"&&!Array.isArray(l))for(let y in l){let d=l[y],b=e;if(typeof d!="string"&&d!==null)return Ye.errors=[{instancePath:s+"/headers/"+y.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/headers/additionalProperties/type",keyword:"type",params:{type:qi.properties.headers.additionalProperties.type},message:"must be string,null"}],!1;var o=b===e;if(!o)break}var t=m===e}else var t=!0;if(t){if(r.json!==void 0){let l=r.json,m=e,u=e,y=!1,d=e;Ve(l,{instancePath:s+"/json",parentData:r,parentDataProperty:"json",rootData:f})||(i=i===null?Ve.errors:i.concat(Ve.errors),e=i.length);var a=d===e;if(y=y||a,!y){let v=e;if(l!==null){let h={instancePath:s+"/json",schemaPath:"#/properties/json/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[h]:i.push(h),e++}var a=v===e;y=y||a}if(y)e=u,i!==null&&(u?i.length=u:i=null);else{let v={instancePath:s+"/json",schemaPath:"#/properties/json/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[v]:i.push(v),e++,Ye.errors=i,!1}var t=m===e}else var t=!0;if(t){if(r.method!==void 0){let l=r.method,m=e;if(typeof l!="string"&&l!==null)return Ye.errors=[{instancePath:s+"/method",schemaPath:"#/properties/method/type",keyword:"type",params:{type:qi.properties.method.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0;if(t){if(r.type!==void 0){let l=r.type,m=e;if(typeof l!="string")return Ye.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;if(l!=="modify")return Ye.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/const",keyword:"const",params:{allowedValue:"modify"},message:"must be equal to constant"}],!1;var t=m===e}else var t=!0;if(t)if(r.url!==void 0){let l=r.url,m=e;if(typeof l!="string"&&l!==null)return Ye.errors=[{instancePath:s+"/url",schemaPath:"#/properties/url/type",keyword:"type",params:{type:qi.properties.url.type},message:"must be string,null"}],!1;var t=m===e}else var t=!0}}}}}}}else return Ye.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Ye.errors=i,e===0}var pl=Ts;function Ts(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){let n=e;for(let p in r)if(!(p==="remove"||p==="rename"||p==="set")){return Ts.errors=[{instancePath:s,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty:p},message:"must NOT have additional properties"}],!1;break}if(n===e){if(r.remove!==void 0){let p=r.remove,l=e;if(!Array.isArray(p)&&p!==null)return Ts.errors=[{instancePath:s+"/remove",schemaPath:"#/properties/remove/type",keyword:"type",params:{type:Gt.properties.remove.type},message:"must be array,null"}],!1;if(e===l&&Array.isArray(p)){var t=!0;let m=p.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var t=l===e}else var t=!0;if(t){if(r.headers!==void 0){let p=r.headers,l=e;if(!(p&&typeof p=="object"&&!Array.isArray(p))&&p!==null)return Pe.errors=[{instancePath:s+"/headers",schemaPath:"#/properties/headers/type",keyword:"type",params:{type:Fa.properties.headers.type},message:"must be object,null"}],!1;if(e===l&&p&&typeof p=="object"&&!Array.isArray(p))for(let u in p){let y=e;if(typeof p[u]!="string")return Pe.errors=[{instancePath:s+"/headers/"+u.replace(/~/g,"~0").replace(/\//g,"~1"),schemaPath:"#/properties/headers/additionalProperties/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;var o=y===e;if(!o)break}var t=l===e}else var t=!0;if(t){if(r.status!==void 0){let p=r.status,l=e;if(!(typeof p=="number"&&!(p%1)&&!isNaN(p)))return Pe.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/type",keyword:"type",params:{type:"integer"},message:"must be integer"}],!1;if(e===l&&typeof p=="number"){if(p>65535||isNaN(p))return Pe.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/maximum",keyword:"maximum",params:{comparison:"<=",limit:65535},message:"must be <= 65535"}],!1;if(p<0||isNaN(p))return Pe.errors=[{instancePath:s+"/status",schemaPath:"#/properties/status/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1}var t=l===e}else var t=!0;if(t)if(r.type!==void 0){let p=r.type,l=e;if(typeof p!="string")return Pe.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1;if(p!=="mock")return Pe.errors=[{instancePath:s+"/type",schemaPath:"#/properties/type/const",keyword:"const",params:{allowedValue:"mock"},message:"must be equal to constant"}],!1;var t=l===e}else var t=!0}}}}}}else return Pe.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Pe.errors=i,e===0}var ul=Pa;function Pa(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(Pa.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(Pa.errors=i,e===0)}var fl=ke;function ke(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.accept_language!==void 0){let a=r.accept_language,n=e;if(typeof a!="string"&&a!==null)return ke.errors=[{instancePath:s+"/accept_language",schemaPath:"#/properties/accept_language/type",keyword:"type",params:{type:_e.properties.accept_language.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.device_scale_factor!==void 0){let a=r.device_scale_factor,n=e;if(typeof a!="number"&&a!==null)return ke.errors=[{instancePath:s+"/device_scale_factor",schemaPath:"#/properties/device_scale_factor/type",keyword:"type",params:{type:_e.properties.device_scale_factor.type},message:"must be number,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.height!==void 0){let a=r.height,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ke.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/type",keyword:"type",params:{type:_e.properties.height.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ke.errors=[{instancePath:s+"/height",schemaPath:"#/properties/height/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.max_touch_points!==void 0){let a=r.max_touch_points,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ke.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/type",keyword:"type",params:{type:_e.properties.max_touch_points.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ke.errors=[{instancePath:s+"/max_touch_points",schemaPath:"#/properties/max_touch_points/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0;if(t){if(r.mobile!==void 0){let a=r.mobile,n=e;if(typeof a!="boolean"&&a!==null)return ke.errors=[{instancePath:s+"/mobile",schemaPath:"#/properties/mobile/type",keyword:"type",params:{type:_e.properties.mobile.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.touch!==void 0){let a=r.touch,n=e;if(typeof a!="boolean"&&a!==null)return ke.errors=[{instancePath:s+"/touch",schemaPath:"#/properties/touch/type",keyword:"type",params:{type:_e.properties.touch.type},message:"must be boolean,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.user_agent!==void 0){let a=r.user_agent,n=e;if(typeof a!="string"&&a!==null)return ke.errors=[{instancePath:s+"/user_agent",schemaPath:"#/properties/user_agent/type",keyword:"type",params:{type:_e.properties.user_agent.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.user_agent_metadata!==void 0){let a=r.user_agent_metadata,n=e,p=e,l=!1,m=e;De(a,{instancePath:s+"/user_agent_metadata",parentData:r,parentDataProperty:"user_agent_metadata",rootData:f})||(i=i===null?De.errors:i.concat(De.errors),e=i.length);var o=m===e;if(l=l||o,!l){let y=e;if(a!==null){let b={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf/1/type",keyword:"type",params:{type:"null"},message:"must be null"};i===null?i=[b]:i.push(b),e++}var o=y===e;l=l||o}if(l)e=p,i!==null&&(p?i.length=p:i=null);else{let y={instancePath:s+"/user_agent_metadata",schemaPath:"#/properties/user_agent_metadata/anyOf",keyword:"anyOf",params:{},message:"must match a schema in anyOf"};return i===null?i=[y]:i.push(y),e++,ke.errors=i,!1}var t=n===e}else var t=!0;if(t)if(r.width!==void 0){let a=r.width,n=e;if(!(typeof a=="number"&&!(a%1)&&!isNaN(a))&&a!==null)return ke.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/type",keyword:"type",params:{type:_e.properties.width.type},message:"must be integer,null"}],!1;if(e===n&&typeof a=="number"&&(a<0||isNaN(a)))return ke.errors=[{instancePath:s+"/width",schemaPath:"#/properties/width/minimum",keyword:"minimum",params:{comparison:">=",limit:0},message:"must be >= 0"}],!1;var t=n===e}else var t=!0}}}}}}}}else return ke.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return ke.errors=i,e===0}var yl=os;function os(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;if(e===0)if(r&&typeof r=="object"&&!Array.isArray(r)){if(r.architecture!==void 0){let a=r.architecture,n=e;if(typeof a!="string"&&a!==null)return os.errors=[{instancePath:s+"/architecture",schemaPath:"#/properties/architecture/type",keyword:"type",params:{type:We.properties.architecture.type},message:"must be string,null"}],!1;var t=n===e}else var t=!0;if(t){if(r.brands!==void 0){let a=r.brands,n=e;if(!Array.isArray(a)&&a!==null)return os.errors=[{instancePath:s+"/brands",schemaPath:"#/properties/brands/type",keyword:"type",params:{type:We.properties.brands.type},message:"must be array,null"}],!1;if(e===n&&Array.isArray(a)){var o=!0;let l=a.length;for(let m=0;m8)return Cs.errors=[{instancePath:s+"/all",schemaPath:"#/properties/all/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var t=!0;let l=n.length;for(let m=0;m8)return Cs.errors=[{instancePath:s+"/any",schemaPath:"#/properties/any/maxItems",keyword:"maxItems",params:{limit:8},message:"must NOT have more than 8 items"}],!1;{var a=!0;let m=n.length;for(let u=0;u=",limit:0},message:"must be >= 0"}],!1;var o=p===e}else var o=!0}}else return Cs.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"object"},message:"must be object"}],!1;return Cs.errors=i,e===0}var Dl=Aa;function Aa(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(Aa.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(Aa.errors=i,e===0)}var ql=ua;function ua(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(ua.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="follow"||r==="current"?(ua.errors=i,e===0):(ua.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Ba.enum},message:"must be equal to one of the allowed values"}],!1)}var jl=Oa;function Oa(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(Oa.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(Oa.errors=i,e===0)}var xl=fa;function fa(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return typeof r!="string"?(fa.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"string"},message:"must be string"}],!1):r==="load"||r==="domcontentloaded"||r==="networkidle"||r==="commit"?(fa.errors=i,e===0):(fa.errors=[{instancePath:s,schemaPath:"#/enum",keyword:"enum",params:{allowedValues:Pi.enum},message:"must be equal to one of the allowed values"}],!1)}var Al=Ea;function Ea(r,{instancePath:s="",parentData:g,parentDataProperty:c,rootData:f=r}={}){let i=null,e=0;return r!==null?(Ea.errors=[{instancePath:s,schemaPath:"#/type",keyword:"type",params:{type:"null"},message:"must be null"}],!1):(Ea.errors=i,e===0)}export{rl as branch_128,sl as branch_129,tl as branch_130,il as branch_131,al as branch_132,nl as branch_133,ol as branch_134,pl as branch_135,ll as branch_136,ml as branch_137,ul as branch_138,fl as branch_139,yl as branch_140,dl as branch_141,cl as branch_142,gl as branch_143,hl as branch_144,vl as branch_145,bl as branch_146,_l as branch_147,wl as branch_148,Pl as branch_149,kl as branch_150,Nl as branch_151,Dl as branch_152,ql as branch_153,jl as branch_154,xl as branch_155,Al as branch_156,Tn as canonical_BlurParams,yp as canonical_BlurResult,Vn as canonical_CancelParams,Mn as canonical_ClickParams,dp as canonical_ClickResult,In as canonical_ConsoleParams,cp as canonical_ConsoleResult,Ln as canonical_DebugParams,gp as canonical_DebugResult,Jn as canonical_DownloadParams,hp as canonical_DownloadResult,Bn as canonical_EmulateParams,vp as canonical_EmulateResult,Gn as canonical_EvaluateParams,bp as canonical_EvaluateResult,Yn as canonical_FillParams,_p as canonical_FillResult,Zn as canonical_FocusParams,wp as canonical_FocusResult,ro as canonical_GetHtmlParams,Pp as canonical_GetHtmlResult,to as canonical_HandshakeResponse,ao as canonical_HoverParams,kp as canonical_HoverResult,oo as canonical_NavigateBackParams,Np as canonical_NavigateBackResult,lo as canonical_NavigateForwardParams,Dp as canonical_NavigateForwardResult,uo as canonical_NavigateParams,qp as canonical_NavigateResult,yo as canonical_NetworkParams,jp as canonical_NetworkResult,go as canonical_ObserveParams,xp as canonical_ObserveResult,vo as canonical_PressParams,Ap as canonical_PressResult,_o as canonical_RecordAwaitParams,Op as canonical_RecordAwaitResult,Po as canonical_RecordStartParams,Ep as canonical_RecordStartResult,No as canonical_RecordStopParams,Sp as canonical_RecordStopResult,qo as canonical_ReloadParams,$p as canonical_ReloadResult,xo as canonical_RequestHelpParams,Rp as canonical_RequestHelpResult,Tp as canonical_RpcError,Oo as canonical_ScreenshotFullPageParams,Cp as canonical_ScreenshotFullPageResult,So as canonical_ScreenshotParams,Ro as canonical_ScreenshotReadParams,Vp as canonical_ScreenshotReadResult,Co as canonical_ScreenshotReleaseParams,Wp as canonical_ScreenshotReleaseResult,Mp as canonical_ScreenshotResult,Wo as canonical_ScrollToParams,Up as canonical_ScrollToResult,Uo as canonical_SelectParams,Ip as canonical_SelectResult,zo as canonical_SessionStartParams,zp as canonical_SessionStartResult,Lp as canonical_SessionStopOutcome,Fo as canonical_SessionStopParams,Ho as canonical_SnapshotParams,Fp as canonical_SnapshotResult,Ko as canonical_TabBorrowParams,Jp as canonical_TabBorrowResult,Xo as canonical_TabCloseParams,Hp as canonical_TabCloseResult,Qo as canonical_TabCreateParams,Bp as canonical_TabCreateResult,ep as canonical_TabListParams,Kp as canonical_TabListResult,sp as canonical_TabReturnParams,Gp as canonical_TabReturnResult,ip as canonical_TabSelectParams,Xp as canonical_TabSelectResult,np as canonical_UploadParams,Yp as canonical_UploadResult,pp as canonical_WaitForNavigationParams,Qp as canonical_WaitForNavigationResult,mp as canonical_WheelParams,Zp as canonical_WheelResult,fp as canonical_WindowResizeParams,el as canonical_WindowResizeResult,Rn as wire_BlurParams,Cn as wire_CancelParams,Wn as wire_ClickParams,Un as wire_ConsoleParams,zn as wire_DebugParams,Fn as wire_DownloadParams,Hn as wire_EmulateParams,Kn as wire_EvaluateParams,Xn as wire_FillParams,Qn as wire_FocusParams,eo as wire_GetHtmlParams,so as wire_HandshakeResponse,io as wire_HoverParams,no as wire_NavigateBackParams,po as wire_NavigateForwardParams,mo as wire_NavigateParams,fo as wire_NetworkParams,co as wire_ObserveParams,ho as wire_PressParams,bo as wire_RecordAwaitParams,wo as wire_RecordStartParams,ko as wire_RecordStopParams,Do as wire_ReloadParams,jo as wire_RequestHelpParams,Ao as wire_ScreenshotFullPageParams,Eo as wire_ScreenshotParams,$o as wire_ScreenshotReadParams,To as wire_ScreenshotReleaseParams,Vo as wire_ScrollToParams,Mo as wire_SelectParams,Io as wire_SessionStartParams,Lo as wire_SessionStopParams,Jo as wire_SnapshotParams,Bo as wire_TabBorrowParams,Go as wire_TabCloseParams,Yo as wire_TabCreateParams,Zo as wire_TabListParams,rp as wire_TabReturnParams,tp as wire_TabSelectParams,ap as wire_UploadParams,op as wire_WaitForNavigationParams,lp as wire_WheelParams,up as wire_WindowResizeParams}; diff --git a/apps/extension/src/transport/handshake.ts b/apps/extension/src/transport/handshake.ts index c2536cb7f..89737b135 100644 --- a/apps/extension/src/transport/handshake.ts +++ b/apps/extension/src/transport/handshake.ts @@ -1,3 +1,5 @@ +import { MIN_COMPATIBLE_PROTOCOL, PROTOCOL_VERSION } from "./generated/methods"; +import { decodeHandshakeResult } from "./protocol"; import type { Transport } from "./transport"; import type { HandshakeParams, @@ -6,21 +8,15 @@ import type { RequestFrame, ResponseFrame, } from "./types"; +import { isResponseFrame } from "./types"; -export const PROTOCOL_VERSION = "1.3"; +export { MIN_COMPATIBLE_PROTOCOL, PROTOCOL_VERSION } from "./generated/methods"; /** * Extension semver, injected at build time from `package.json` via * Vite's `define` (see `wxt.config.ts` and `vitest.config.ts`). */ export const EXTENSION_VERSION: string = typeof __BSK_EXT_VERSION__ === "string" ? __BSK_EXT_VERSION__ : "0.0.0-unset"; -/** - * Lowest **protocol** version this extension accepts (e.g. `"1.0"`). - * Must stay in sync with daemon `MIN_COMPATIBLE_PROTOCOL`. - */ -// New interaction semantics do not break the base wire protocol. Older peers -// remain connected; the popup explains their local help-handling limitations. -export const MIN_COMPATIBLE_PROTOCOL = "1.0"; /** * **Deprecated** — legacy app-semver floor for wire compat with old * daemons. New code sends `"0.0.0"`; compat decisions ignore this. @@ -100,8 +96,11 @@ export function performHandshake( ); return; } - const result = r.result as HandshakeResult; - resolve({ params, result }); + try { + resolve({ params, result: decodeHandshakeResult(r.result) }); + } catch (error) { + reject(error); + } }); function cleanup() { @@ -126,11 +125,7 @@ export function performHandshake( } function isResponseFor(msg: ProtocolFrame, id: string): boolean { - return ( - typeof (msg as ResponseFrame).id === "string" && - (msg as ResponseFrame).id === id && - ("result" in (msg as object) || "error" in (msg as object)) - ); + return isResponseFrame(msg) && msg.id === id; } /** diff --git a/apps/extension/src/transport/protocol.ts b/apps/extension/src/transport/protocol.ts new file mode 100644 index 000000000..83e0fc5b9 --- /dev/null +++ b/apps/extension/src/transport/protocol.ts @@ -0,0 +1,101 @@ +import { + type ExtensionToolMethod, + methods, + type ParamsOf, + type ResultOf, +} from "./generated/methods"; +import { normalizers } from "./generated/normalizers"; +import * as validators from "./generated/validators.js"; +import type { CancelParams, HandshakeResult, RequestFrame, RpcError } from "./types"; + +export type ToolRequest = { + id: string; + method: M; + params: ParamsOf; +}; + +export type ToolHandlerMap = { + [M in ExtensionToolMethod]: ( + params: ParamsOf, + signal: AbortSignal, + onInputSent?: (tabId: number) => void, + ) => Promise | RpcError>; +}; + +const extensionMethods = new Map( + methods.filter((method) => method.owner === "extension").map((method) => [method.method, method]), +); + +export function isExtensionToolMethod(method: string): method is ExtensionToolMethod { + return extensionMethods.has(method as ExtensionToolMethod); +} + +function describe(validator: validators.Validator): string { + const issue = validator.errors?.[0]; + return issue + ? `${issue.instancePath || "/"} ${issue.message ?? issue.keyword}` + : "invalid payload"; +} + +export function validateCancelParams(value: unknown): value is CancelParams { + return validators.wire_CancelParams(value); +} + +export function decodeHandshakeResult(value: unknown): HandshakeResult { + if (!validators.wire_HandshakeResponse(value)) { + throw new Error( + `[handshake] invalid daemon response: ${describe(validators.wire_HandshakeResponse)}`, + ); + } + const result = normalizers.HandshakeResponse(value); + if (!validators.canonical_HandshakeResponse(result)) { + throw new Error( + `[handshake] invalid normalized response: ${describe(validators.canonical_HandshakeResponse)}`, + ); + } + return result as HandshakeResult; +} + +export function decodeToolRequest( + frame: RequestFrame, +): { ok: true; request: ToolRequest } | { ok: false; error: RpcError } { + if (!isExtensionToolMethod(frame.method)) { + return { + ok: false, + error: { code: "unknown_method", message: `${frame.method} not implemented in extension` }, + }; + } + const definition = extensionMethods.get(frame.method)!; + const wire = validators[`wire_${definition.params}`]; + if (!wire(frame.params)) { + return { + ok: false, + error: { code: "invalid_params", message: `${frame.method}: ${describe(wire)}` }, + }; + } + const params = normalizers[definition.params](frame.params); + const canonical = validators[`canonical_${definition.params}`]; + if (!canonical(params)) { + return { + ok: false, + error: { code: "invalid_params", message: `${frame.method}: ${describe(canonical)}` }, + }; + } + // The only raw-JSON assertion in tool dispatch follows both wire validation + // and normalization. Method and parameter schemas come from the same catalog. + return { ok: true, request: { id: frame.id, method: frame.method, params } as ToolRequest }; +} + +export function validateToolResult( + method: ExtensionToolMethod, + result: unknown, +): RpcError | undefined { + const definition = extensionMethods.get(method)!; + const validator = validators[`canonical_${definition.result}`]; + if (validator(result)) return; + return { + code: "protocol_error", + message: `${method} returned an invalid result: ${describe(validator)}`, + data: { phase: "result_validation", effect_state: "unknown" }, + }; +} diff --git a/apps/extension/src/transport/types.ts b/apps/extension/src/transport/types.ts index 37c014918..8069b112b 100644 --- a/apps/extension/src/transport/types.ts +++ b/apps/extension/src/transport/types.ts @@ -1,25 +1,23 @@ -// Wire-protocol shapes mirroring bsk-protocol (see crates/bsk-protocol/schema/*.json). The -// daemon serialises Rust structs via serde; these TS types intentionally -// stay structural (interface, not class) so the same JSON parses on both -// sides without extra adapters. - +// Public protocol payloads are generated from bsk-protocol. +// Transport envelopes deliberately admit unknown method/event names for versioned peers. +import type { + ErrorCode, + HandshakeRequest, + NavigateBackResult, + SessionStopOutcome, + TabScope, +} from "./generated/types"; + +export { TRACE_VERSION_V2, TRACE_VERSION_V3, VOM_FORMAT_VERSION } from "./generated/methods"; +export type * from "./generated/types"; +export type HandshakeParams = HandshakeRequest; +export type HandshakeResult = import("./generated/input").HandshakeResponse; +export type SessionStopResult = SessionStopOutcome; export type RpcId = string; +export type NavigateHistoryResult = NavigateBackResult; +export type TabScopeFilter = TabScope; +export type ConnectionState = "disconnected" | "connecting" | "connected" | "version_skew"; -export type ErrorCode = - | "unknown_method" - | "unsupported" - | "invalid_params" - | "not_found" - | "permission_denied" - | "timeout" - | "cdp_failed" - | "protocol_error" - | "cancelled" - | "version_too_old" - | "multiple_browsers_online" - | "no_browser_connected"; - -/** Stable `RpcError.data.reason` values for CLI hint selection. */ export type RpcErrorReason = | "ui_lookup_failed" | "task_unavailable" @@ -120,957 +118,43 @@ export interface EventFrame { export type ProtocolFrame = RequestFrame | ResponseFrame | EventFrame; -export function isRequestFrame(f: ProtocolFrame): f is RequestFrame { - return typeof (f as RequestFrame).method === "string"; +function isObject(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); } -export function isResponseFrame(f: ProtocolFrame): f is ResponseFrame { +export function isRequestFrame(f: unknown): f is RequestFrame { return ( - typeof (f as ResponseFrame).id === "string" && - ("result" in (f as object) || "error" in (f as object)) + isObject(f) && + typeof f.id === "string" && + typeof f.method === "string" && + !("result" in f) && + !("error" in f) && + !("event" in f) ); } -export function isEventFrame(f: ProtocolFrame): f is EventFrame { - return typeof (f as EventFrame).event === "string"; -} - -export interface InteractionPolicy { - borrow_confirmation: "always" | "never"; - request_help: "enabled" | "disabled"; -} - -export interface BrowserPeerInfo { - name: string; - version: string; -} - -export interface HandshakeParams { - audit_enabled?: boolean; - client: string; - version: string; - protocol_version: string; - instance_id: string; - browser: BrowserPeerInfo; - label: string; - /** - * **Deprecated** — legacy app-semver floor for old daemons. New code - * sends `"0.0.0"` and ignores on read. - */ - min_compatible_peer?: string; - /** Lowest daemon **protocol** version this extension accepts. */ - min_compatible_protocol?: string; -} - -export interface HandshakeResult { - audit_version?: number; - audit_ready?: boolean; - server: string; - version: string; - protocol_version: string; - /** Deprecated legacy app-semver floor; absent on newer daemons. */ - min_compatible_peer?: string; - /** Protocol floor advertised by the daemon; absent on legacy daemons. */ - min_compatible_protocol?: string; -} - -export type ConnectionState = "disconnected" | "connecting" | "connected" | "version_skew"; - -// -------------------------------------------------------------------------- -// M6 tool payloads — mirror bsk-protocol (crates/bsk-protocol/src/tools/*.rs) -// -------------------------------------------------------------------------- - -export type JavaScriptDialogType = "alert" | "confirm" | "prompt" | "beforeunload"; -export type JavaScriptDialogHandledAction = "accepted" | "dismissed"; - -export interface JavaScriptDialogInfo { - tab_id: number; - type: JavaScriptDialogType; - message: string; - url?: string; - default_prompt?: string; - has_browser_handler?: boolean; - handled: JavaScriptDialogHandledAction; - sequence: number; -} - -export type ConsoleEntryKind = "console" | "exception" | "log"; - -export interface ConsoleStackFrame { - function_name?: string; - url?: string; - line?: number; - column?: number; -} - -export interface ConsoleEntry { - sequence: number; - kind: ConsoleEntryKind; - level: string; - text: string; - url?: string; - line?: number; - column?: number; - timestamp?: number; - stack_trace?: ConsoleStackFrame[]; - truncated: boolean; -} - -export interface ConsoleParams { - session_id: string; - tab_id?: number; - since?: number; - limit?: number; - max_text_chars?: number; - include_stack?: boolean; -} - -export interface ConsoleResult { - tab_id: number; - entries: ConsoleEntry[]; - next_since: number; - truncated: boolean; -} - -export type NetworkEntryKind = "response" | "failure"; - -export interface NetworkEntry { - sequence: number; - kind: NetworkEntryKind; - method?: string; - url?: string; - status?: number; - status_text?: string; - mime_type?: string; - resource_type?: string; - error_text?: string; - timestamp?: number; - truncated: boolean; -} - -export interface NetworkParams { - session_id: string; - tab_id?: number; - since?: number; - limit?: number; - max_text_chars?: number; -} - -export interface NetworkResult { - tab_id: number; - entries: NetworkEntry[]; - next_since: number; - truncated: boolean; -} - -export type TabScopeFilter = "user" | "agent" | "all"; - -export interface TabInfo { - tab_id: number; - title?: string; - url?: string; - window_id?: number; - active?: boolean; - scope?: "user" | "agent"; -} - -export interface TabListParams { - session_id: string; - scope?: TabScopeFilter; -} - -export interface TabListResult { - tabs: TabInfo[]; -} - -// --- M8 tab management payloads (M8.1) --- - -export interface TabCreateParams { - session_id: string; - url?: string; - active?: boolean; - index?: number; -} - -export interface TabCreateResult { - tab_id: number; - window_id: number; - url: string; -} - -export interface TabCloseParams { - session_id: string; - tab_id: number; -} - -export interface TabCloseResult { - tab_id: number; -} - -export interface TabSelectParams { - session_id: string; - tab_id: number; -} - -export interface TabSelectResult { - tab_id: number; - window_id: number; -} - -export interface TabBorrowParams { - session_id: string; - tab_id: number; - confirm?: boolean; -} - -export interface TabBorrowResult { - tab_id: number; - original_window_id: number; - original_index: number; - agent_window_id: number; -} - -export interface TabReturnParams { - session_id: string; - tab_id: number; -} - -export interface TabReturnResult { - tab_id: number; - returned_to_window_id: number; - returned_to_index: number; - fallback?: boolean; -} - -export interface ScreenshotParams { - session_id: string; - tab_id?: number; - /** `@eN` ref from the last `tool.snapshot`. */ - ref?: string; -} - -export interface ScreenshotResult { - capture_id?: string; - capture_unavailable?: string; - image_base64: string; - width: number; - height: number; - format: string; - tab_id: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface ScreenshotFullPageParams { - scope?: "follow" | "current"; - session_id: string; - tab_id?: number; - timeout_ms?: number; -} -export interface ScreenshotFullPageResult { - scope?: "follow" | "current"; - capture_id: string; - width: number; - height: number; - format: "png"; - tab_id: number; - byte_size: number; - dialogs?: JavaScriptDialogInfo[]; -} -export interface ScreenshotReadParams { - session_id: string; - capture_id: string; - offset: number; -} -export interface ScreenshotReadResult { - data_base64: string; - next_offset: number; - eof: boolean; -} -export interface ScreenshotReleaseParams { - session_id: string; - capture_id: string; -} -export interface ScreenshotReleaseResult { - released: boolean; -} - -export interface SnapshotParams { - session_id: string; - tab_id?: number; - max_depth?: number; - max_tokens?: number; -} - -export interface SnapshotResult { - text: string; - ref_count: number; - tab_id: number; - truncated?: boolean; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface ObserveParams extends SnapshotParams { - cursor?: string; - debug_surfaces?: boolean; - probe_hover?: boolean; -} - -export interface ObserveResult extends SnapshotResult { - next_cursor?: string; - hover_probe?: { - performed: boolean; - revealed_content: boolean; - }; - debug?: { - surface_probes?: Array<{ - trigger_backend_node_id: number; - trigger_point?: { x: number; y: number }; - trigger_action: string; - sub_items: string[]; - confidence?: string; - }>; - }; -} - -export interface GetHtmlParams { - session_id: string; - tab_id?: number; - ref?: string; - max_bytes?: number; -} - -export interface GetHtmlResult { - html: string; - truncated?: boolean; - byte_size: number; - tab_id: number; - dialogs?: JavaScriptDialogInfo[]; -} - -// -------------------------------------------------------------------------- -// M7 tool payloads — navigation (mirror bsk-protocol) -// -------------------------------------------------------------------------- - -export type WaitUntil = "load" | "domcontentloaded" | "networkidle" | "commit"; - -export interface NavigateParams { - session_id: string; - url: string; - tab_id?: number; - wait_until?: WaitUntil; - timeout_ms?: number; -} - -export interface NavigateResult { - tab_id: number; - url: string; - final_url?: string; - reached: string; - error_text?: string; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface NavigateBackParams { - session_id: string; - tab_id?: number; - wait_until?: WaitUntil; - timeout_ms?: number; -} - -export interface NavigateForwardParams extends NavigateBackParams {} - -export interface NavigateHistoryResult { - tab_id: number; - previous_url?: string; - final_url?: string; - reached: string; - error_text?: string; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface ReloadParams { - session_id: string; - tab_id?: number; - wait_until?: WaitUntil; - timeout_ms?: number; - hard?: boolean; -} - -export type ReloadResult = NavigateHistoryResult; - -// -------------------------------------------------------------------------- -// M7 tool payloads — interaction (mirror bsk-protocol) -// -------------------------------------------------------------------------- - -export type MouseButton = "left" | "middle" | "right"; -export type KeyModifier = "alt" | "ctrl" | "meta" | "shift"; - -export interface ClickParams { - capture_id?: string; - image_x?: number; - image_y?: number; - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - button?: MouseButton; - click_count?: number; - modifiers?: KeyModifier[]; - timeout_ms?: number; -} - -export interface ClickResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - x: number; - y: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface HoverParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - modifiers?: KeyModifier[]; - settle_ms?: number; - timeout_ms?: number; -} - -export interface HoverResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - x: number; - y: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface WheelParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - delta_x?: number; - delta_y?: number; - modifiers?: KeyModifier[]; - timeout_ms?: number; -} - -export interface WheelResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - x: number; - y: number; - delta_x: number; - delta_y: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface ScrollToParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - timeout_ms?: number; -} - -export interface ScrollToResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - /** Clipped border-box bounds in top-level viewport CSS pixels; not an occlusion test. */ - x: number; - y: number; - width: number; - height: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface FocusParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - timeout_ms?: number; -} - -export interface FocusResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - focused: boolean; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface BlurParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - timeout_ms?: number; -} - -export interface BlurResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - was_focused: boolean; - focused: boolean; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface FillParams { - session_id: string; - value: string; - ref?: string; - selector?: string; - tab_id?: number; - clear_before?: boolean; - timeout_ms?: number; -} - -export interface FillResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - value_length: number; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface PressParams { - session_id: string; - key: string; - modifiers?: KeyModifier[]; - ref?: string; - selector?: string; - tab_id?: number; - hold_ms?: number; - timeout_ms?: number; -} - -export interface PressResult { - tab_id: number; - key: string; - code: string; - modifiers: KeyModifier[]; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface SelectParams { - session_id: string; - values: string[]; - ref?: string; - selector?: string; - tab_id?: number; - timeout_ms?: number; -} - -export interface SelectResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - multiple: boolean; - selected_values: string[]; - selected_labels: string[]; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface UploadFile { - transfer_id: string; - name: string; - staged_path?: string; -} - -export type UploadMode = "input" | "drop"; - -export interface UploadParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - files: UploadFile[]; - mode?: UploadMode; - timeout_ms?: number; -} - -export interface UploadResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - file_names: string[]; -} - -export interface DownloadParams { - session_id: string; - ref?: string; - selector?: string; - tab_id?: number; - timeout_ms?: number; - browser_relative_dir?: string; - max_byte_size?: number; -} - -export interface DownloadResult { - tab_id: number; - used_ref?: string; - used_selector?: string; - suggested_filename: string; - byte_size: number; - mime?: string; - danger?: string; - browser_path?: string; - transfer_id?: string; -} - -// -------------------------------------------------------------------------- -// M9 tool payloads — evaluate / wait_for_navigation / wait_ms -// -------------------------------------------------------------------------- - -export interface EvaluateParams { - session_id: string; - expression: string; - tab_id?: number; - await_promise?: boolean; - return_by_value?: boolean; - timeout_ms?: number; -} - -export interface EvaluateError { - text: string; - line?: number; - column?: number; -} - -export interface EvaluateResult { - ok: boolean; - tab_id: number; - value?: unknown; - error?: EvaluateError; - dialogs?: JavaScriptDialogInfo[]; -} - -export interface WaitForNavigationParams { - session_id: string; - tab_id?: number; - wait_until?: WaitUntil; - timeout_ms?: number; -} - -export type WaitForNavigationReached = WaitUntil | "timeout"; - -export interface WaitForNavigationResult { - tab_id: number; - reached: WaitForNavigationReached; - error_text?: string; - dialogs?: JavaScriptDialogInfo[]; -} - -// -------------------------------------------------------------------------- -// Human-in-loop payloads — request_help (mirror bsk-protocol) -// -------------------------------------------------------------------------- - -export interface HelpTarget { - ref?: string; - selector?: string; -} - -export type HelpOutcome = - | "continued" - | "cancelled" - | "timed_out" - | "completed" - | "navigated" - | "disabled"; - -export interface HelpCompletionCondition { - url_contains?: string; - url_matches?: string | null; - selector_exists?: string; - selector_missing?: string; - text_exists?: string; - text_missing?: string; -} - -export interface HelpCompletionCriteria { - any?: HelpCompletionCondition[]; - all?: HelpCompletionCondition[]; - stable_for_ms?: number; -} - -export interface ResolvedTarget { - matched: boolean; - ref?: string; - selector?: string; -} - -export interface RequestHelpParams { - session_id: string; - tab_id?: number; - prompt: string; - title?: string; - targets?: HelpTarget[]; - completion_criteria?: HelpCompletionCriteria; - timeout_ms?: number; -} - -export interface RequestHelpResult { - outcome: HelpOutcome; - completed_by?: "system"; - note?: string; - tab_id: number; - resolved_targets?: ResolvedTarget[]; -} - -// -------------------------------------------------------------------------- -// Device-emulation payloads — tool.emulate (mirror bsk-protocol emulate.rs) -// -------------------------------------------------------------------------- - -export interface UserAgentBrandVersion { - brand: string; - version: string; -} - -/** Mirror of CDP `Emulation.UserAgentMetadata`; all fields optional. */ -export interface UserAgentMetadata { - brands?: UserAgentBrandVersion[]; - full_version?: string; - platform?: string; - platform_version?: string; - architecture?: string; - model?: string; - mobile?: boolean; -} - -/** - * Concrete emulation overrides for one tab. The extension merges each - * request field by field onto the tab's remembered emulation state: - * fields present here overwrite the stored value, absent fields keep - * it, and the merged state is applied as a whole. - */ -export interface EmulateOverrides { - width?: number; - height?: number; - device_scale_factor?: number; - mobile?: boolean; - user_agent?: string; - accept_language?: string; - user_agent_metadata?: UserAgentMetadata; - touch?: boolean; - max_touch_points?: number; -} - -export interface EmulateParams { - session_id: string; - tab_id?: number; - /** Clear every emulation override on the tab. Exclusive with `overrides`. */ - off?: boolean; - /** Overrides to apply. Required unless `off` is set. */ - overrides?: EmulateOverrides; -} - -export interface EmulateResult { - tab_id: number; - /** True when overrides were cleared (`off`); false when applied. */ - cleared: boolean; - /** Echo of the overrides that were applied. Absent when cleared. */ - applied?: EmulateOverrides; - /** Scope note: overrides are per-tab (CDP target), not inherited by new tabs. */ - note?: string; -} - -// -------------------------------------------------------------------------- -// Semantic record payloads mirror the versioned Rust protocol models. -// -------------------------------------------------------------------------- - -export const TRACE_VERSION_V3 = 3; -/** Logical v2 identifier. Not a wire field — v2 envelopes omit `version`. */ -export const TRACE_VERSION_V2 = 2; -export const VOM_FORMAT_VERSION = 1; - -export interface TargetDescriptorV3 { - ref?: string; - role?: string; - name?: string; - ctx?: string; - unmatched?: boolean; -} - -export interface RecorderInfo { - bsk: string; - vom: number; -} - -export type StopReason = "user_finish" | "cli_stop"; - -export interface TraceStateV3 { - id: string; - url: string; - title?: string; - body: string; - truncated?: boolean; -} - -export interface StepResultV3 { - state: string; -} - -export interface StepCommonV3 { - id: number; - state: string; - result: StepResultV3; -} - -export type NavigationCause = - | "user_typed" - | "link" - | "form_submit" - | "reload" - | "history" - | "script" - | "browser"; - -export type FillCommit = "enter" | "suggestion" | "blur"; - -/** Legacy v2 target shape retained for existing record producers. */ -export interface TargetDescriptorV2 { - role?: string; - name?: string; - tag: string; - name_attr?: string; - placeholder?: string; - nearby_label?: string; -} - -export interface TraceEntry { - start_url: string; -} - -export interface PageRefV2 { - id: string; - url: string; - title?: string; -} - -export interface SelectedOptionV2 { - value: string; - label?: string; -} - -export interface StepEffectV2 { - navigated_to: string; -} - -export interface StepCommonV2 { - id: number; - page: string; - effect?: StepEffectV2; -} - -/** Exported record-only step (trace v2). */ -export type StepV2 = - | ({ op: "navigate" } & StepCommonV2 & { to: string }) - | ({ op: "click" } & StepCommonV2 & { target: TargetDescriptorV2 }) - | ({ op: "hover" } & StepCommonV2 & { target: TargetDescriptorV2 }) - | ({ op: "fill" } & StepCommonV2 & { - target: TargetDescriptorV2; - value: string; - redacted?: boolean; - }) - | ({ op: "select" } & StepCommonV2 & { - target: TargetDescriptorV2; - selection: SelectedOptionV2[]; - }) - | ({ op: "press" } & StepCommonV2 & { - key: string; - modifiers?: KeyModifier[]; - target?: TargetDescriptorV2; - }); - -export interface TraceV2 { - recorded_at: string; - started_at?: string; - purpose?: string; - entry: TraceEntry; - pages: PageRefV2[]; - steps: StepV2[]; -} - -export interface SelectedOptionV3 { - value: string; - label?: string; -} - -export type StepV3 = - | ({ op: "navigate" } & StepCommonV3 & { to: string; cause: NavigationCause }) - | ({ op: "switch_tab" } & StepCommonV3) - | ({ op: "click" } & StepCommonV3 & { target: TargetDescriptorV3 }) - | ({ op: "hover" } & StepCommonV3 & { target: TargetDescriptorV3 }) - | ({ op: "fill" } & StepCommonV3 & { - target: TargetDescriptorV3; - value: string; - commit: FillCommit; - redacted?: boolean; - }) - | ({ op: "select" } & StepCommonV3 & { - target: TargetDescriptorV3; - selection?: SelectedOptionV3[]; - }) - | ({ op: "press" } & StepCommonV3 & { - key: string; - modifiers?: KeyModifier[]; - target?: TargetDescriptorV3; - }) - | ({ op: "scroll" } & StepCommonV3); - -export interface TraceV3 { - version: typeof TRACE_VERSION_V3; - recorded_at: string; - started_at?: string; - purpose?: string; - stopped_by: StopReason; - entry: TraceEntry; - recorder: RecorderInfo; - states: TraceStateV3[]; - steps: StepV3[]; -} - -export type RecordedTrace = TraceV2 | TraceV3; -export type RecordedStep = StepV2 | StepV3; - -export interface RecordStartParams { - session_id: string; - tab_id?: number; - url?: string; - purpose?: string; - max_page_tokens?: number; - redact_values?: boolean; - /** Omitted means v2; `3` requests a state-linked v3 trace. */ - trace_version?: number; - /** Client can decode the v3 `switch_tab` step variant. */ - supports_tab_switch_steps?: boolean; -} - -export interface RecordStartResult { - tab_id: number; - recording: boolean; -} - -export interface RecordStopParams { - session_id: string; -} - -export interface RecordStopResult { - trace: RecordedTrace; +export function isResponseFrame(f: unknown): f is ResponseFrame { + if (!isObject(f) || typeof f.id !== "string" || "method" in f || "event" in f) return false; + if ("result" in f) return !("error" in f); + return ( + isObject(f.error) && + typeof f.error.code === "string" && + typeof f.error.message === "string" && + (f.error.data === undefined || isObject(f.error.data)) + ); } -export interface RecordAwaitParams { - session_id: string; - timeout_ms?: number; +export function isEventFrame(f: unknown): f is EventFrame { + return ( + isObject(f) && + typeof f.event === "string" && + !("id" in f) && + !("method" in f) && + !("result" in f) && + !("error" in f) + ); } -export interface RecordAwaitResult { - trace: RecordedTrace; +export function isProtocolFrame(f: unknown): f is ProtocolFrame { + return isRequestFrame(f) || isResponseFrame(f) || isEventFrame(f); } diff --git a/apps/extension/src/transport/ws-transport.ts b/apps/extension/src/transport/ws-transport.ts index 2248dd0bf..0bb919fe5 100644 --- a/apps/extension/src/transport/ws-transport.ts +++ b/apps/extension/src/transport/ws-transport.ts @@ -1,5 +1,6 @@ import type { ConnectionStateHandler, Disposable, FrameHandler, Transport } from "./transport"; import type { ConnectionState, ProtocolFrame } from "./types"; +import { isProtocolFrame } from "./types"; const DEFAULT_INITIAL_DELAY_MS = 1_000; const DEFAULT_MAX_DELAY_MS = 5_000; @@ -202,12 +203,13 @@ export class WSTransport implements Transport { private handleInbound(data: unknown): void { if (typeof data !== "string") return; - let parsed: ProtocolFrame; + let parsed: unknown; try { - parsed = JSON.parse(data) as ProtocolFrame; + parsed = JSON.parse(data); } catch { return; } + if (!isProtocolFrame(parsed)) return; for (const h of this.messageHandlers) { try { h(parsed); diff --git a/biome.json b/biome.json index ecfaf947d..0a62d0b15 100644 --- a/biome.json +++ b/biome.json @@ -50,7 +50,8 @@ "!**/.output/**", "!**/pnpm-lock.yaml", "!**/Cargo.lock", - "!crates/**/schema/**" + "!crates/**/schema/**", + "!apps/extension/src/transport/generated/**" ] } } diff --git a/crates/bsk-cli/src/cli/debug.rs b/crates/bsk-cli/src/cli/debug.rs index 52efa8513..b2bfcf32a 100644 --- a/crates/bsk-cli/src/cli/debug.rs +++ b/crates/bsk-cli/src/cli/debug.rs @@ -12,7 +12,7 @@ use clap::Args; #[derive(Debug, Clone, Args)] pub struct DebugArgs { /// Capture/inspect evidence, manage request rules, or replay a recorded request. - #[arg(value_parser = ["performance", "aggregate", "duplicates", "start", "stop", "status", "requests", "request", "operations", "operation", "console", "pages", "export", "rules", "rule_add", "rule_enable", "rule_disable", "rule_remove", "replay", "capabilities", "activity", "wait", "pin", "unpin"])] + #[arg(value_parser = clap::builder::PossibleValuesParser::new(DebugAction::ALL.iter().map(DebugAction::wire_name)))] pub action: String, /// Request, operation or rule ID returned by an earlier debug action. pub id: Option, diff --git a/crates/bsk-cli/src/daemon/ipc.rs b/crates/bsk-cli/src/daemon/ipc.rs index 7f15fb683..26b0c305a 100644 --- a/crates/bsk-cli/src/daemon/ipc.rs +++ b/crates/bsk-cli/src/daemon/ipc.rs @@ -832,7 +832,8 @@ fn tool_dispatch_timeout(params: &Value) -> Result { } fn tool_dispatch_transport_timeout(method: &Method, params: &Value) -> Result { - if *method == Method::ToolTabBorrow { + let policy = super::tool_policy::execution_policy(method); + if policy.deadline == super::tool_policy::Deadline::BorrowConfirmation { let ms = params .get("confirmation_timeout_ms") .map_or(Some(60_000), Value::as_u64) @@ -843,24 +844,15 @@ fn tool_dispatch_transport_timeout(method: &Method, params: &Value) -> Result Ok(v), Err(err) => Err(DispatchError::Rpc(err)), } @@ -570,13 +579,68 @@ async fn run_worker( ) { debug!(session = %sid, "tool queue worker started"); while let Some(job) = rx.recv().await { - let result = forward_one(&sid, &browsers, &sessions, &job).await; - clear_busy(&state); - let _ = job.respond.send(result); + let mut settlement = Settlement::Complete; + let result = forward_one(&sid, &browsers, &sessions, &job, &mut settlement).await; + if let Settlement::Pending(mut pending) = settlement { + if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() { + active.state = "settling".into(); + } + let _ = job.respond.send(result); + // Keep the original receiver registered. A deadline replies to the + // caller, but does not release the session or replay the expression. + let response = loop { + tokio::select! { + response = &mut pending.waiter => break Some(response), + next = rx.recv() => match next { + None => break None, + Some(next) => { let _ = next.respond.send(Err(session_busy_rpc())); } + } + } + }; + pending + .client + .pending + .lock() + .unwrap() + .cancel(&pending.rpc_id); + let Some(response) = response else { + break; + }; + let settled = matches!(response, Ok(ref frame) if !matches!(&frame.body, + ResponseBody::Err(error) if super::browsers::is_link_failure(error))); + if settled { + clear_busy(&state); + } else if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() + { + // Losing the link is not evidence that page execution stopped. + active.state = "unconfirmed".into(); + } + } else { + if matches!(settlement, Settlement::Unconfirmed) { + if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() { + active.state = "unconfirmed".into(); + } + } else { + clear_busy(&state); + } + let _ = job.respond.send(result); + } } debug!(session = %sid, "tool queue worker exiting"); } +enum Settlement { + Complete, + Pending(PendingSettlement), + Unconfirmed, +} + +struct PendingSettlement { + waiter: oneshot::Receiver, + client: Arc, + rpc_id: RpcId, +} + /// Forward a single [`ToolJob`] over WS to the extension that owns the /// session and decode the structured response. async fn forward_one( @@ -584,6 +648,7 @@ async fn forward_one( browsers: &Arc, sessions: &Arc, job: &ToolJob, + settlement: &mut Settlement, ) -> Result { // Pre-flight: a cancel that landed while this job was still in // the per-session channel must short-circuit before any session @@ -685,7 +750,7 @@ async fn forward_one( job.lifecycle_cancel.clone() } }; - let waiter = match dispatched { + let mut waiter = match dispatched { Some(Ok(waiter)) => waiter, other => return Err(not_dispatched_error(other)), }; @@ -718,15 +783,54 @@ async fn forward_one( }; let deadline_cancel: Option<&(dyn Fn() -> bool + Sync)> = waits_for_deadline_cleanup(&job.method).then_some(&send_deadline_cancel); - let waited = await_with_optional_cancel( + let waited = wait_for_response( job.timeout, job.cancel_cleanup_timeout, - waiter, + &mut waiter, cancel_token.as_ref(), on_abort, deadline_cancel, ) .await; + let retains_execution = execution_policy(&job.method).retain_until_settled; + let link_lost = match &waited { + WaitOutcome::WaiterClosed => true, + WaitOutcome::Response(frame) + | WaitOutcome::CancelledAfterResponse(frame) + | WaitOutcome::TimedOutAfterResponse(frame) => { + matches!(&frame.body, ResponseBody::Err(error) if super::browsers::is_link_failure(error)) + } + _ => false, + }; + if retains_execution && link_lost { + *settlement = Settlement::Unconfirmed; + return Err(unconfirmed_evaluation(ErrorCode::ProtocolError)); + } + if retains_execution + && matches!( + waited, + WaitOutcome::Timeout | WaitOutcome::CleanupTimeout | WaitOutcome::TimeoutCleanupFailed + ) + { + if waiter.is_terminated() { + *settlement = Settlement::Unconfirmed; + return Err(unconfirmed_evaluation(ErrorCode::ProtocolError)); + } + *settlement = Settlement::Pending(PendingSettlement { + waiter, + client: Arc::clone(&client), + rpc_id, + }); + return Err(RpcError { + code: ErrorCode::Timeout, + message: + "Evaluation has not settled; the session remains busy until its final response" + .into(), + data: Some(serde_json::json!({ + "reason": "execution_pending", "effect_state": "unknown", "execution_state": "settling" + })), + }); + } // Record what this call implies about the control plane before shaping // its error. Health and business errors are decided separately: the // mark is diagnostic, every arm below keeps its own contract. @@ -1023,11 +1127,19 @@ fn not_dispatched_error( } } +fn unconfirmed_evaluation(code: ErrorCode) -> RpcError { + RpcError { + code, + message: "Evaluation lost its connection before completion; execution may still be running" + .into(), + data: Some(serde_json::json!({ + "reason": "execution_outcome_unknown", "effect_state": "unknown", "execution_state": "unconfirmed" + })), + } +} + fn is_native_input(method: &Method) -> bool { - matches!( - method, - Method::ToolClick | Method::ToolPress | Method::ToolWheel - ) + execution_policy(method).outcome == Outcome::NativeInput } // Preserve the extension's knowledge of whether input was sent. A missing @@ -1049,11 +1161,7 @@ fn input_effect_data(response: Option<&ResponseBody>) -> Value { // deadlines cannot account for transit delays. Keep the queue held for cleanup. // Human interaction deadlines also dismiss their pending UI before releasing the queue. fn waits_for_deadline_cleanup(method: &Method) -> bool { - matches!( - method, - Method::ToolScreenshotFullPage | Method::ToolTabBorrow | Method::ToolRequestHelp - ) || is_native_input(method) - || is_effect_aware_transfer(method) + execution_policy(method).cancel_at_deadline } fn unknown_borrow_error(code: ErrorCode) -> RpcError { @@ -1069,7 +1177,7 @@ fn unknown_borrow_error(code: ErrorCode) -> RpcError { } fn is_effect_aware_transfer(method: &Method) -> bool { - matches!(method, Method::ToolUpload | Method::ToolDownload) + execution_policy(method).outcome == Outcome::FileTransfer } fn transfer_effect(err: &RpcError) -> Option<&str> { @@ -1131,10 +1239,30 @@ enum WaitOutcome { Timeout, } +#[cfg(test)] async fn await_with_optional_cancel( timeout: Duration, cleanup_timeout: Duration, - mut waiter: oneshot::Receiver, + mut waiter: oneshot::Receiver, + cancel: Option<&super::abort::AbortToken>, + on_abort: Option<&(dyn Fn() + Sync)>, + on_deadline: Option<&(dyn Fn() -> bool + Sync)>, +) -> WaitOutcome { + wait_for_response( + timeout, + cleanup_timeout, + &mut waiter, + cancel, + on_abort, + on_deadline, + ) + .await +} + +async fn wait_for_response( + timeout: Duration, + cleanup_timeout: Duration, + waiter: &mut oneshot::Receiver, cancel: Option<&super::abort::AbortToken>, on_abort: Option<&(dyn Fn() + Sync)>, on_deadline: Option<&(dyn Fn() -> bool + Sync)>, @@ -1152,20 +1280,20 @@ async fn await_with_optional_cancel( if let Some(on_abort) = on_abort { on_abort(); } - match tokio::time::timeout(cleanup_timeout, &mut waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { Ok(Ok(resp)) => WaitOutcome::CancelledAfterResponse(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => WaitOutcome::CleanupTimeout, } }, - outcome = &mut waiter => match outcome { + outcome = &mut *waiter => match outcome { Ok(resp) => WaitOutcome::Response(resp), Err(_) => WaitOutcome::WaiterClosed, }, _ = &mut deadline => { if let Some(send_cancel) = on_deadline { return if send_cancel() { - match tokio::time::timeout(cleanup_timeout, &mut waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) | Err(_) => WaitOutcome::TimeoutCleanupFailed, } @@ -1177,7 +1305,7 @@ async fn await_with_optional_cancel( return WaitOutcome::Timeout; }; on_abort(); - match tokio::time::timeout(cleanup_timeout, &mut waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => WaitOutcome::CleanupTimeout, @@ -1185,12 +1313,12 @@ async fn await_with_optional_cancel( }, } } - None => match tokio::time::timeout(timeout, &mut waiter).await { + None => match tokio::time::timeout(timeout, &mut *waiter).await { Ok(Ok(resp)) => WaitOutcome::Response(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => match on_deadline { Some(send_cancel) if send_cancel() => { - match tokio::time::timeout(cleanup_timeout, &mut waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) | Err(_) => WaitOutcome::TimeoutCleanupFailed, } diff --git a/crates/bsk-cli/src/daemon/state.rs b/crates/bsk-cli/src/daemon/state.rs index dffb96d81..48b014f77 100644 --- a/crates/bsk-cli/src/daemon/state.rs +++ b/crates/bsk-cli/src/daemon/state.rs @@ -17,9 +17,7 @@ use super::start::DaemonConfig; use super::ws::WsHandle; pub const DAEMON_VERSION: &str = env!("CARGO_PKG_VERSION"); -pub const PROTOCOL_VERSION: &str = "1.3"; -/// Base wire compatibility. New interaction semantics are checked per operation. -pub const MIN_COMPATIBLE_PROTOCOL: &str = "1.0"; +pub use bsk_protocol::catalog::{MIN_COMPATIBLE_PROTOCOL, PROTOCOL_VERSION}; /// Legacy app-semver floor used only when `HandshakeResult.min_compatible_peer` /// is emitted for old extensions. New code ignores this on read. pub const LEGACY_MIN_COMPATIBLE_PEER: &str = "0.0.0"; diff --git a/crates/bsk-cli/src/daemon/tool_policy.rs b/crates/bsk-cli/src/daemon/tool_policy.rs new file mode 100644 index 000000000..a997a4392 --- /dev/null +++ b/crates/bsk-cli/src/daemon/tool_policy.rs @@ -0,0 +1,107 @@ +//! Daemon scheduling policy. Exhaustive matching makes every new method choose +//! a timeout and settlement policy independently of its browser effect class. +use bsk_protocol::Method; + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Deadline { + Standard, + FullPage, + BorrowConfirmation, +} + +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum Outcome { + Ordinary, + NativeInput, + FileTransfer, + Evaluation, +} + +#[derive(Clone, Copy)] +pub struct ExecutionPolicy { + pub deadline: Deadline, + pub response_grace: bool, + pub cancel_at_deadline: bool, + pub outcome: Outcome, + /// A caller deadline cannot prove that arbitrary page JavaScript has stopped. + pub retain_until_settled: bool, +} + +pub fn execution_policy(method: &Method) -> ExecutionPolicy { + use Method::*; + let (deadline, response_grace, cancel_at_deadline, outcome, retain_until_settled) = match method + { + ToolTabBorrow => ( + Deadline::BorrowConfirmation, + false, + true, + Outcome::Ordinary, + false, + ), + ToolNavigate => (Deadline::Standard, true, false, Outcome::Ordinary, false), + ToolNavigateBack => (Deadline::Standard, true, false, Outcome::Ordinary, false), + ToolNavigateForward => (Deadline::Standard, true, false, Outcome::Ordinary, false), + ToolReload => (Deadline::Standard, true, false, Outcome::Ordinary, false), + ToolClick => (Deadline::Standard, false, true, Outcome::NativeInput, false), + ToolWheel => (Deadline::Standard, false, true, Outcome::NativeInput, false), + ToolPress => (Deadline::Standard, false, true, Outcome::NativeInput, false), + ToolUpload => (Deadline::Standard, true, true, Outcome::FileTransfer, false), + ToolDownload => (Deadline::Standard, true, true, Outcome::FileTransfer, false), + ToolScreenshotFullPage => (Deadline::FullPage, false, true, Outcome::Ordinary, false), + ToolEvaluate => (Deadline::Standard, false, true, Outcome::Evaluation, true), + ToolWaitForNavigation => (Deadline::Standard, true, false, Outcome::Ordinary, false), + ToolRequestHelp => (Deadline::Standard, true, true, Outcome::Ordinary, false), + AuditRequest + | SystemHandshake + | SystemPing + | SystemStatus + | SessionStart + | SessionStartTracked + | SessionRequest + | SessionStop + | SessionStopAll + | SessionList + | BrowserList + | ToolSessionStart + | ToolSessionStop + | ToolWindowResize + | ToolEmulate + | ToolTabList + | ToolTabCreate + | ToolTabClose + | ToolTabReturn + | ToolTabSelect + | ToolHover + | ToolScrollTo + | ToolFocus + | ToolBlur + | ToolFill + | ToolSelect + | ToolSnapshot + | ToolObserve + | ToolGetHtml + | ToolScreenshot + | ToolScreenshotRead + | ToolScreenshotRelease + | ToolConsole + | ToolDebug + | ToolNetwork + | ToolWaitMs + | ToolRecordStart + | ToolRecordStop + | ToolRecordAwait + | TransferBegin + | TransferChunk + | TransferFinish + | TransferRead + | TransferRelease + | Cancel => (Deadline::Standard, false, false, Outcome::Ordinary, false), + }; + ExecutionPolicy { + deadline, + response_grace, + cancel_at_deadline, + outcome, + retain_until_settled, + } +} diff --git a/crates/bsk-cli/src/daemon/ws.rs b/crates/bsk-cli/src/daemon/ws.rs index 8e48598f0..ca7757436 100644 --- a/crates/bsk-cli/src/daemon/ws.rs +++ b/crates/bsk-cli/src/daemon/ws.rs @@ -11,9 +11,7 @@ use std::sync::Arc; use std::time::Duration; use anyhow::{Context, anyhow}; -use bsk_protocol::system::{ - HandshakeCompat, HandshakeParams, HandshakeResult, evaluate_handshake_compat, -}; +use bsk_protocol::system::{HandshakeCompat, HandshakeResult, evaluate_handshake_compat}; use bsk_protocol::tools::ReturnFailure; use bsk_protocol::{Frame, RequestFrame, ResponseBody, ResponseFrame, RpcError}; use futures_util::{SinkExt, StreamExt}; @@ -243,12 +241,10 @@ pub(super) async fn drive_connection`; shared effects come from generated metadata | +| Daemon deadlines, grace and settlement | `crates/bsk-cli/src/daemon/tool_policy.rs` | Exhaustive `Method` match consumed by IPC and the queue | + +Adding an extension method requires choosing its Rust payloads and effects, generating the contract, +and implementing its handler and local policies. Missing cases produce compilation errors. Browser +permissions, session ownership, readiness and value-dependent behavior still belong in handlers; +JSON Schema cannot establish those facts about a running browser. + +Daemon-local session lifecycle payloads deliberately remain private to the daemon. Their catalog +entries use arbitrary JSON and are not advertised as validated extension contracts. Extension +payloads, handshake metadata, cancellation and error codes are included in the export. + +## Receiving and sending are different contracts + +Serde may accept an omitted defaulted field while always serializing it. Schemars therefore exports +both input and output contracts. The generated `input.ts` represents normalized tool parameters; +`output.ts` represents tool results. The small `types.ts` facade selects the appropriate direction. +The existing transport module reexports them and retains only transport envelopes and local error +interpretation helpers. Handshake audit fields and session-stop window-release metadata have named +Rust wire envelopes, so they no longer depend on ad hoc JSON insertion. + +At the WebSocket boundary, envelope guards reject scalars, arrays and ambiguous frames. Before +dispatch, a static validator checks the raw payload. Generated immutable normalizers convert `null` +on optional typed fields to omission; arbitrary JSON and dictionary values retain their `null`. +A second check verifies the normalized representation. Handshake responses follow the same input +path. Unknown methods fail explicitly. Results are checked against the sender contract before being +sent; invalid results report `protocol_error` with an unknown effect, not a safe-to-retry promise. + +Validators are compiled ahead of time into browser-compatible JavaScript. No runtime schema compiler, +`eval`, network schema loading, or Node dependency is shipped into the MV3 extension. TypeScript uses +arrays for bounded collections and unions for conditional schemas; runtime validators retain length, +numeric and conditional constraints that TypeScript cannot express. String formats are descriptive; +semantic URL/regex/session checks remain in the existing handlers. + +## Evaluation deadlines and settlement + +A deadline or cancel acknowledgement does not prove that arbitrary JavaScript has stopped. The +daemon sends cancellation at an evaluation deadline, allows the cleanup grace, then can return +`execution_pending` while retaining the original response receiver and the session's busy state. +`debug activity` reports `settling`; `debug wait` observes the original operation without replaying it. +Only its final response releases the queue. Other sessions remain independent. + +If the connection disappears before completion, an operation whose session survives becomes +`unconfirmed`. The existing disconnect/replacement lifecycle may instead invalidate the entire +session. Neither path makes the old session available for new commands. Inspect the page and end +the affected browser task before starting a new one. This deliberately avoids pretending +that `Runtime.evaluate` cancellation rolls back page effects. Scripts may also schedule independent +work after returning; settlement tracks the awaited evaluation, not all future page activity. +Other tools retain their existing bounded compensation behavior, described by the daemon policy. + +## Compatibility and verification limits + +The wire protocol version remains unchanged. Optional-field normalization accepts the legacy null +forms while preserving arbitrary JSON nulls, and the Rust handshake/session wrapper types preserve +existing Rust callers. Enum additions such as `user_aborted` now reach TypeScript automatically. +An empty console/network result consistently emits an empty `entries` array while readers still +accept omission through Serde defaults. + +Generation checks prove source synchronization, not compatibility with every previously released +binary or successful browser effects. Existing Rust and extension suites, targeted contract probes, +and browser tests must verify those separate boundaries. New diagnostics or repro material should +remain outside the source tree. diff --git a/crates/bsk-protocol/src/bin/dump-schema.rs b/crates/bsk-protocol/src/bin/dump-schema.rs index 0d5db1bd4..8400971a2 100644 --- a/crates/bsk-protocol/src/bin/dump-schema.rs +++ b/crates/bsk-protocol/src/bin/dump-schema.rs @@ -3,17 +3,62 @@ use std::fs; use std::path::PathBuf; -use bsk_protocol::system::{ - BrowserListParams, HandshakeParams, HandshakeResult, PingParams, PingResult, StatusParams, - StatusResult, -}; -use bsk_protocol::tools::*; -use bsk_protocol::{CancelParams, CancelResult}; -use schemars::schema_for; +use bsk_protocol::catalog; +use serde_json::{Map, Value}; +use std::collections::BTreeSet; + +fn references(value: &Value, names: &mut BTreeSet) { + match value { + Value::Object(object) => { + if let Some(name) = object + .get("$ref") + .and_then(Value::as_str) + .and_then(|s| s.strip_prefix("#/definitions/")) + { + names.insert(name.to_owned()); + } + for value in object.values() { + references(value, names); + } + } + Value::Array(values) => { + for value in values { + references(value, names); + } + } + _ => {} + } +} + +fn standalone(catalog: &Value, name: &str) -> Value { + let definitions = catalog["schema"]["definitions"] + .as_object() + .expect("definitions"); + let mut root = definitions[name].clone(); + let mut pending = BTreeSet::new(); + let mut included = Map::new(); + references(&root, &mut pending); + while let Some(next) = pending.pop_first() { + if included.contains_key(&next) { + continue; + } + let schema = definitions + .get(&next) + .expect("referenced definition") + .clone(); + references(&schema, &mut pending); + included.insert(next, schema); + } + root["$schema"] = catalog["schema"]["$schema"].clone(); + root["title"] = Value::String(name.to_owned()); + if !included.is_empty() { + root["definitions"] = Value::Object(included); + } + root +} -fn write_schema(name: &str, schema: impl serde::Serialize) { - let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("schema"); - fs::create_dir_all(&dir).expect("create schema dir"); +fn write_schema(dir: &std::path::Path, name: &str, schema: impl serde::Serialize) { + fs::create_dir_all(dir).expect("create schema dir"); let path = dir.join(format!("{name}.json")); let json = serde_json::to_string_pretty(&schema).expect("serialize schema"); let mut json = json; @@ -21,128 +66,50 @@ fn write_schema(name: &str, schema: impl serde::Serialize) { fs::write(&path, json).unwrap_or_else(|e| panic!("write {}: {e}", path.display())); } -macro_rules! dump { - ($ty:ty, $file:literal) => { - write_schema($file, schema_for!($ty)); - }; -} - fn main() { - dump!(HandshakeParams, "handshake_params"); - dump!(HandshakeResult, "handshake_result"); - - dump!(PingParams, "system_ping_params"); - dump!(PingResult, "system_ping_result"); - dump!(StatusParams, "system_status_params"); - dump!(StatusResult, "system_status_result"); - dump!(BrowserListParams, "browser_list_params"); - - dump!(CancelParams, "cancel_params"); - dump!(CancelResult, "cancel_result"); - - dump!(SessionStartParams, "tool_session_start_params"); - dump!(SessionStartResult, "tool_session_start_result"); - dump!(SessionStopParams, "tool_session_stop_params"); - dump!(SessionStopResult, "tool_session_stop_result"); - - dump!(WindowResizeParams, "tool_window_resize_params"); - dump!(WindowResizeResult, "tool_window_resize_result"); - - dump!(EmulateParams, "tool_emulate_params"); - dump!(EmulateResult, "tool_emulate_result"); - dump!(EmulateOverrides, "tool_emulate_overrides"); - dump!(UserAgentMetadata, "tool_emulate_user_agent_metadata"); - - dump!(TabListParams, "tool_tab_list_params"); - dump!(TabListResult, "tool_tab_list_result"); - dump!(TabCreateParams, "tool_tab_create_params"); - dump!(TabCreateResult, "tool_tab_create_result"); - dump!(TabCloseParams, "tool_tab_close_params"); - dump!(TabCloseResult, "tool_tab_close_result"); - dump!(TabBorrowParams, "tool_tab_borrow_params"); - dump!(TabBorrowResult, "tool_tab_borrow_result"); - dump!(TabReturnParams, "tool_tab_return_params"); - dump!(TabReturnResult, "tool_tab_return_result"); - dump!(TabSelectParams, "tool_tab_select_params"); - dump!(TabSelectResult, "tool_tab_select_result"); - - dump!(NavigateParams, "tool_navigate_params"); - dump!(NavigateResult, "tool_navigate_result"); - dump!(NavigateBackParams, "tool_navigate_back_params"); - dump!(NavigateBackResult, "tool_navigate_back_result"); - dump!(NavigateForwardParams, "tool_navigate_forward_params"); - dump!(NavigateForwardResult, "tool_navigate_forward_result"); - dump!(ReloadParams, "tool_reload_params"); - dump!(ReloadResult, "tool_reload_result"); - - dump!(ClickParams, "tool_click_params"); - dump!(ClickResult, "tool_click_result"); - dump!(HoverParams, "tool_hover_params"); - dump!(HoverResult, "tool_hover_result"); - dump!(WheelParams, "tool_wheel_params"); - dump!(WheelResult, "tool_wheel_result"); - dump!(ScrollToParams, "tool_scroll_to_params"); - dump!(ScrollToResult, "tool_scroll_to_result"); - dump!(FocusParams, "tool_focus_params"); - dump!(FocusResult, "tool_focus_result"); - dump!(BlurParams, "tool_blur_params"); - dump!(BlurResult, "tool_blur_result"); - dump!(FillParams, "tool_fill_params"); - dump!(FillResult, "tool_fill_result"); - dump!(PressParams, "tool_press_params"); - dump!(PressResult, "tool_press_result"); - dump!(SelectParams, "tool_select_params"); - dump!(SelectResult, "tool_select_result"); - dump!(UploadParams, "tool_upload_params"); - dump!(UploadResult, "tool_upload_result"); - dump!(DownloadParams, "tool_download_params"); - dump!(DownloadResult, "tool_download_result"); - - dump!(SnapshotParams, "tool_snapshot_params"); - dump!(SnapshotResult, "tool_snapshot_result"); - dump!(ObserveParams, "tool_observe_params"); - dump!(ObserveResult, "tool_observe_result"); - dump!(GetHtmlParams, "tool_get_html_params"); - dump!(GetHtmlResult, "tool_get_html_result"); - dump!(ScreenshotParams, "tool_screenshot_params"); - dump!(ScreenshotResult, "tool_screenshot_result"); - dump!(ScreenshotFullPageParams, "tool_screenshot_full_page_params"); - dump!(ScreenshotFullPageResult, "tool_screenshot_full_page_result"); - dump!(ScreenshotReadParams, "tool_screenshot_read_params"); - dump!(ScreenshotReadResult, "tool_screenshot_read_result"); - dump!(ScreenshotReleaseParams, "tool_screenshot_release_params"); - dump!(ScreenshotReleaseResult, "tool_screenshot_release_result"); - dump!(ConsoleParams, "tool_console_params"); - dump!(ConsoleResult, "tool_console_result"); - dump!(ConsoleEntry, "tool_console_entry"); - dump!(ConsoleStackFrame, "tool_console_stack_frame"); - dump!(DebugParams, "tool_debug_params"); - dump!(DebugResult, "tool_debug_result"); - dump!(NetworkParams, "tool_network_params"); - dump!(NetworkResult, "tool_network_result"); - dump!(NetworkEntry, "tool_network_entry"); - - dump!(EvaluateParams, "tool_evaluate_params"); - dump!(EvaluateResult, "tool_evaluate_result"); - dump!(EvaluateError, "tool_evaluate_error"); - - dump!(WaitForNavigationParams, "tool_wait_for_navigation_params"); - dump!(WaitForNavigationResult, "tool_wait_for_navigation_result"); - dump!(WaitMsParams, "tool_wait_ms_params"); - dump!(WaitMsResult, "tool_wait_ms_result"); - dump!(RequestHelpParams, "tool_request_help_params"); - dump!(RequestHelpResult, "tool_request_help_result"); - - dump!(TraceV2, "trace_v2"); - dump!(TraceV3, "trace_v3"); - dump!(RecordedTrace, "trace"); - dump!(StepV2, "trace_step_v2"); - dump!(StepV3, "trace_step_v3"); - dump!(RecordedStep, "trace_step"); - dump!(RecordStartParams, "tool_record_start_params"); - dump!(RecordStartResult, "tool_record_start_result"); - dump!(RecordStopParams, "tool_record_stop_params"); - dump!(RecordStopResult, "tool_record_stop_result"); - dump!(RecordAwaitParams, "tool_record_await_params"); - dump!(RecordAwaitResult, "tool_record_await_result"); + let mut args = std::env::args_os().skip(1); + let dir = match args.next() { + None => PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("schema"), + Some(flag) if flag == "--out-dir" => { + let dir = PathBuf::from(args.next().expect("--out-dir requires a directory")); + assert!(args.next().is_none(), "usage: dump-schema [--out-dir DIR]"); + dir + } + Some(_) => panic!("usage: dump-schema [--out-dir DIR]"), + }; + let catalog = catalog::export(); + for method in catalog["methods"].as_array().expect("method catalog") { + let wire = method["method"].as_str().expect("wire method"); + let base = if wire == "system.handshake" { + "handshake".to_owned() + } else { + wire.replace('.', "_") + }; + for part in ["params", "result"] { + let name = method[part].as_str().expect("contract name"); + // Daemon-private payloads are intentionally not extension contracts. + if name == "Value" { + continue; + } + write_schema(&dir, &format!("{base}_{part}"), standalone(&catalog, name)); + } + } + // Stable file aliases for reusable CLI/documentation schemas. Their shapes + // still come from the catalog; this list cannot hide a method from generation. + for (name, file) in [ + ("EmulateOverrides", "tool_emulate_overrides"), + ("UserAgentMetadata", "tool_emulate_user_agent_metadata"), + ("ConsoleEntry", "tool_console_entry"), + ("ConsoleStackFrame", "tool_console_stack_frame"), + ("NetworkEntry", "tool_network_entry"), + ("EvaluateError", "tool_evaluate_error"), + ("TraceV2", "trace_v2"), + ("TraceV3", "trace_v3"), + ("RecordedTrace", "trace"), + ("StepV2", "trace_step_v2"), + ("StepV3", "trace_step_v3"), + ("RecordedStep", "trace_step"), + ] { + write_schema(&dir, file, standalone(&catalog, name)); + } } diff --git a/crates/bsk-protocol/src/bin/export-protocol.rs b/crates/bsk-protocol/src/bin/export-protocol.rs new file mode 100644 index 000000000..2efea72c2 --- /dev/null +++ b/crates/bsk-protocol/src/bin/export-protocol.rs @@ -0,0 +1,8 @@ +//! Machine-readable input for protocol generation and compatibility checks. + +fn main() { + println!( + "{}", + serde_json::to_string_pretty(&bsk_protocol::catalog::export()).unwrap() + ); +} diff --git a/crates/bsk-protocol/src/catalog.rs b/crates/bsk-protocol/src/catalog.rs new file mode 100644 index 000000000..f93f77028 --- /dev/null +++ b/crates/bsk-protocol/src/catalog.rs @@ -0,0 +1,119 @@ +//! Export the protocol from the same catalog used by Rust dispatch. +//! +//! Daemon-local payloads deliberately remain outside the extension contract. +//! Shared and extension methods, plus handshake/error roots, are exported in full. + +use schemars::{JsonSchema, Schema, SchemaGenerator, generate::SchemaSettings}; +use serde::Serialize; +use serde_json::{Value, json}; + +use crate::{ErrorCode, Method, RpcError, method::MethodEffect}; + +pub const PROTOCOL_VERSION: &str = "1.3"; +pub const MIN_COMPATIBLE_PROTOCOL: &str = "1.0"; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum MethodOwner { + Daemon, + Extension, + Shared, +} + +#[derive(Debug, Serialize)] +pub struct MethodDescriptor { + pub method: &'static str, + pub owner: MethodOwner, + pub effect: MethodEffect, + pub params: String, + pub result: String, +} + +impl MethodDescriptor { + pub fn new( + method: &'static str, + owner: MethodOwner, + effect: MethodEffect, + generator: &mut SchemaGenerator, + ) -> Self { + Self { + method, + owner, + effect, + params: register::

(generator), + result: register::(generator), + } + } +} + +fn register(generator: &mut SchemaGenerator) -> String { + let name = T::schema_name().into_owned(); + let schema = generator.subschema_for::(); + if let Some(reference) = schema + .get("$ref") + .and_then(Value::as_str) + .and_then(|value| value.strip_prefix("#/definitions/")) + { + return reference.to_owned(); + } + generator + .definitions_mut() + .entry(name.clone()) + .or_insert_with(|| schema.to_value()); + name +} + +/// Draft-07 remains the on-disk schema format for CLI consumers. +pub fn schema_for() -> Schema { + SchemaSettings::draft07() + .for_deserialize() + .into_generator() + .into_root_schema_for::() +} + +fn describe(settings: SchemaSettings) -> (Vec, Value) { + let mut generator = settings.into_generator(); + let methods = Method::ALL + .iter() + .map(|method| method.describe(&mut generator)) + .collect(); + register::(&mut generator); + register::(&mut generator); + register::(&mut generator); + register::(&mut generator); + register::(&mut generator); + register::(&mut generator); + register::(&mut generator); + ( + methods, + json!({ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": generator.take_definitions(false), + }), + ) +} + +/// A single shared generator also prevents unrelated schemas from silently +/// assigning different shapes to the same definition name. +pub fn export() -> Value { + let (methods, input) = describe(SchemaSettings::draft07().for_deserialize()); + let (_, output) = describe(SchemaSettings::draft07().for_serialize()); + json!({ + "format_version": 1, + "protocol_version": PROTOCOL_VERSION, + "min_compatible_protocol": MIN_COMPATIBLE_PROTOCOL, + "methods": methods, + "constants": { + "TRACE_VERSION_V2": crate::tools::TRACE_VERSION_V2, + "TRACE_VERSION_V3": crate::tools::TRACE_VERSION_V3, + "VOM_FORMAT_VERSION": crate::tools::VOM_FORMAT_VERSION, + }, + "debug_actions": crate::tools::DebugAction::ALL.iter().map(|action| json!({ + "action": action, + "effect": action.effect(), + "owner": action.owner(), + })).collect::>(), + "schema": input, + "output_schema": output, + }) +} diff --git a/crates/bsk-protocol/src/error.rs b/crates/bsk-protocol/src/error.rs index 3749433ba..e7671fea1 100644 --- a/crates/bsk-protocol/src/error.rs +++ b/crates/bsk-protocol/src/error.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; /// Wire-format JSON-RPC error object carried inside [`crate::frame::ResponseFrame`]. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct RpcError { pub code: ErrorCode, diff --git a/crates/bsk-protocol/src/lib.rs b/crates/bsk-protocol/src/lib.rs index 3da5eb081..16c919ec4 100644 --- a/crates/bsk-protocol/src/lib.rs +++ b/crates/bsk-protocol/src/lib.rs @@ -1,6 +1,7 @@ //! browser-skill wire protocol — frames, methods, tool payloads, handshake. pub mod cancel; +pub mod catalog; pub mod error; pub mod frame; pub mod method; diff --git a/crates/bsk-protocol/src/method.rs b/crates/bsk-protocol/src/method.rs index 9a6d6b5db..2dcad4915 100644 --- a/crates/bsk-protocol/src/method.rs +++ b/crates/bsk-protocol/src/method.rs @@ -1,9 +1,16 @@ //! Namespaced RPC methods (§4.3). +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use crate::catalog::{MethodDescriptor, MethodOwner}; +use crate::system::*; +use crate::tools::*; +use crate::{CancelParams, CancelResult}; + /// Observable browser-side effect class for a protocol method. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)] +#[serde(rename_all = "snake_case")] pub enum MethodEffect { /// Reads browser/session state without dispatching page input. PassiveRead, @@ -18,251 +25,121 @@ pub enum MethodEffect { ControlPlane, } -/// Namespaced method string (`system.handshake`, `tool.tab_list`, …). -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum Method { - /// Extension-only local history API; browser identity comes from the peer. - #[serde(rename = "audit.request")] - AuditRequest, - #[serde(rename = "system.handshake")] - SystemHandshake, - #[serde(rename = "system.ping")] - SystemPing, - #[serde(rename = "system.status")] - SystemStatus, +/// The method catalog is the only list of wire methods and their payloads. +/// Adding a method requires an owner, an effect classification and both payload types. +macro_rules! methods { + ($($variant:ident => ($wire:literal, $owner:ident, $effect:ident, $params:ty, $result:ty)),* $(,)?) => { + #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] + pub enum Method { + $(#[serde(rename = $wire)] $variant,)* + } - #[serde(rename = "session.start")] - SessionStart, - /// Recoverable CLI start; distinct method prevents unsafe fallback on old daemons. - #[serde(rename = "session.start_tracked")] - SessionStartTracked, - #[serde(rename = "session.request")] - SessionRequest, - #[serde(rename = "session.stop")] - SessionStop, - #[serde(rename = "session.stop_all")] - SessionStopAll, - #[serde(rename = "session.list")] - SessionList, + impl Method { + pub const ALL: &'static [Method] = &[$(Self::$variant,)*]; - #[serde(rename = "browser.list")] - BrowserList, + pub const fn wire_name(&self) -> &'static str { + match self { $(Self::$variant => $wire,)* } + } - #[serde(rename = "tool.session_start")] - ToolSessionStart, - #[serde(rename = "tool.session_stop")] - ToolSessionStop, - #[serde(rename = "tool.window_resize")] - ToolWindowResize, - #[serde(rename = "tool.emulate")] - ToolEmulate, - #[serde(rename = "tool.tab_list")] - ToolTabList, - #[serde(rename = "tool.tab_create")] - ToolTabCreate, - #[serde(rename = "tool.tab_close")] - ToolTabClose, - #[serde(rename = "tool.tab_borrow")] - ToolTabBorrow, - #[serde(rename = "tool.tab_return")] - ToolTabReturn, - #[serde(rename = "tool.tab_select")] - ToolTabSelect, - #[serde(rename = "tool.navigate")] - ToolNavigate, - #[serde(rename = "tool.navigate_back")] - ToolNavigateBack, - #[serde(rename = "tool.navigate_forward")] - ToolNavigateForward, - #[serde(rename = "tool.reload")] - ToolReload, - #[serde(rename = "tool.click")] - ToolClick, - #[serde(rename = "tool.hover")] - ToolHover, - #[serde(rename = "tool.wheel")] - ToolWheel, - #[serde(rename = "tool.scroll_to")] - ToolScrollTo, - #[serde(rename = "tool.focus")] - ToolFocus, - #[serde(rename = "tool.blur")] - ToolBlur, - #[serde(rename = "tool.fill")] - ToolFill, - #[serde(rename = "tool.press")] - ToolPress, - #[serde(rename = "tool.select")] - ToolSelect, - #[serde(rename = "tool.upload")] - ToolUpload, - #[serde(rename = "tool.download")] - ToolDownload, - #[serde(rename = "tool.snapshot")] - ToolSnapshot, - #[serde(rename = "tool.observe")] - ToolObserve, - #[serde(rename = "tool.get_html")] - ToolGetHtml, - #[serde(rename = "tool.screenshot")] - ToolScreenshot, - #[serde(rename = "tool.screenshot_full_page")] - ToolScreenshotFullPage, - #[serde(rename = "tool.screenshot_read")] - ToolScreenshotRead, - #[serde(rename = "tool.screenshot_release")] - ToolScreenshotRelease, - #[serde(rename = "tool.console")] - ToolConsole, - #[serde(rename = "tool.debug")] - ToolDebug, - #[serde(rename = "tool.network")] - ToolNetwork, - #[serde(rename = "tool.evaluate")] - ToolEvaluate, - #[serde(rename = "tool.wait_for_navigation")] - ToolWaitForNavigation, - #[serde(rename = "tool.wait_ms")] - ToolWaitMs, - #[serde(rename = "tool.request_help")] - ToolRequestHelp, - #[serde(rename = "tool.record_start")] - ToolRecordStart, - #[serde(rename = "tool.record_stop")] - ToolRecordStop, - #[serde(rename = "tool.record_await")] - ToolRecordAwait, + pub const fn owner(&self) -> MethodOwner { + match self { $(Self::$variant => MethodOwner::$owner,)* } + } - #[serde(rename = "transfer.begin")] - TransferBegin, - #[serde(rename = "transfer.chunk")] - TransferChunk, - #[serde(rename = "transfer.finish")] - TransferFinish, - #[serde(rename = "transfer.read")] - TransferRead, - #[serde(rename = "transfer.release")] - TransferRelease, + pub const fn effect(&self) -> MethodEffect { + match self { $(Self::$variant => MethodEffect::$effect,)* } + } - #[serde(rename = "cancel")] - Cancel, + pub fn describe(&self, generator: &mut schemars::SchemaGenerator) -> MethodDescriptor { + match self { + $(Self::$variant => MethodDescriptor::new::<$params, $result>( + $wire, MethodOwner::$owner, MethodEffect::$effect, generator, + ),)* + } + } + } + }; } -impl Method { - /// Browser-side effect classification for this method. - /// - /// Used by the daemon's pending-interrupt machinery: when the - /// user has clicked the agent-window mask's stop button, the - /// next tool call that dispatches browser/page input for that - /// session is rejected with `ErrorCode::UserAborted`. Passive reads - /// and control-plane RPCs pass through transparently. - /// - /// **Compile-time enforcement.** The match below is exhaustive - /// (no `_ =>` fallthrough). Adding a new `Method` variant is a - /// compile error here, so classification cannot silently be - /// skipped — the author has to make a deliberate choice. - /// - /// **Judgment calls** (read these before adding new variants): - /// - /// * `tool.evaluate` is classified as browser-mutating because the - /// daemon cannot statically distinguish a `document.title` - /// read from a `form.submit()` write. - /// * `tool.observe` is classified as transient input: its bounded - /// hover probes do not commit browser state, but they dispatch real - /// page input events and therefore must be gated like automation. - /// * `tool.wait_*` are classified as read-only: they do not - /// initiate any browser action; they observe state only. - /// * `session.*` and `tool.session_*` are NOT gated. Blocking - /// `session.stop` would prevent the agent from gracefully - /// tearing down after observing the user's interrupt. - /// * `cancel` is NOT gated. It's a control-plane operation - /// (stops another in-flight RPC), not a browser action. - pub fn effect(&self) -> MethodEffect { - match self { - // Browser/page mutations — gated by pending-interrupt. - Method::ToolTabCreate - | Method::ToolTabClose - | Method::ToolTabBorrow - | Method::ToolTabReturn - | Method::ToolTabSelect - | Method::ToolWindowResize - | Method::ToolEmulate - | Method::ToolNavigate - | Method::ToolNavigateBack - | Method::ToolNavigateForward - | Method::ToolReload - | Method::ToolClick - | Method::ToolWheel - | Method::ToolScrollTo - | Method::ToolFocus - | Method::ToolBlur - | Method::ToolFill - | Method::ToolPress - | Method::ToolSelect - | Method::ToolUpload - | Method::ToolDownload - | Method::ToolEvaluate - // May navigate via optional `url` and changes Agent Window - // chrome; gate behind pending-interrupt like other writes. - | Method::ToolRecordStart => MethodEffect::BrowserMutation, - - // Transient input — no committed browser action, but still page - // input. It must be stopped by pending user interrupts. - Method::ToolHover | Method::ToolObserve | Method::ToolScreenshotFullPage => MethodEffect::TransientInput, - - // Passive reads — transparent. - // `record_stop` / `record_await` observe / finish a recording - // without driving new automation gestures, so they stay - // ungated (teardown after interrupt must still work). - Method::ToolTabList - | Method::ToolSnapshot - | Method::ToolGetHtml - | Method::ToolScreenshot - | Method::ToolScreenshotRead - | Method::ToolConsole - | Method::ToolNetwork - | Method::ToolWaitForNavigation - | Method::ToolWaitMs - | Method::ToolRequestHelp - | Method::ToolRecordStop - | Method::ToolRecordAwait => MethodEffect::PassiveRead, - - // Session lifecycle — not gated. - Method::SessionStart - | Method::SessionStartTracked - | Method::SessionRequest - | Method::SessionStop - | Method::SessionStopAll - | Method::SessionList - | Method::ToolSessionStart - | Method::ToolSessionStop => MethodEffect::ControlPlane, - - // System / control — not gated. - Method::ToolDebug - | Method::AuditRequest - | Method::SystemHandshake - | Method::SystemPing - | Method::SystemStatus - | Method::BrowserList - | Method::TransferBegin - | Method::TransferChunk - | Method::TransferFinish - | Method::TransferRead - | Method::TransferRelease - | Method::ToolScreenshotRelease - | Method::Cancel => MethodEffect::ControlPlane, - } - } +methods! { + AuditRequest => ("audit.request", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SystemHandshake => ("system.handshake", Daemon, ControlPlane, HandshakeRequest, HandshakeResponse), + SystemPing => ("system.ping", Daemon, ControlPlane, PingParams, PingResult), + SystemStatus => ("system.status", Daemon, ControlPlane, StatusParams, StatusResult), + SessionStart => ("session.start", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SessionStartTracked => ("session.start_tracked", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SessionRequest => ("session.request", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SessionStop => ("session.stop", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SessionStopAll => ("session.stop_all", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + SessionList => ("session.list", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + BrowserList => ("browser.list", Daemon, ControlPlane, BrowserListParams, serde_json::Value), + ToolSessionStart => ("tool.session_start", Extension, ControlPlane, SessionStartParams, SessionStartResult), + ToolSessionStop => ("tool.session_stop", Extension, ControlPlane, SessionStopParams, SessionStopOutcome), + ToolWindowResize => ("tool.window_resize", Extension, BrowserMutation, WindowResizeParams, WindowResizeResult), + ToolEmulate => ("tool.emulate", Extension, BrowserMutation, EmulateParams, EmulateResult), + ToolTabList => ("tool.tab_list", Extension, PassiveRead, TabListParams, TabListResult), + ToolTabCreate => ("tool.tab_create", Extension, BrowserMutation, TabCreateParams, TabCreateResult), + ToolTabClose => ("tool.tab_close", Extension, BrowserMutation, TabCloseParams, TabCloseResult), + ToolTabBorrow => ("tool.tab_borrow", Extension, BrowserMutation, TabBorrowParams, TabBorrowResult), + ToolTabReturn => ("tool.tab_return", Extension, BrowserMutation, TabReturnParams, TabReturnResult), + ToolTabSelect => ("tool.tab_select", Extension, BrowserMutation, TabSelectParams, TabSelectResult), + ToolNavigate => ("tool.navigate", Extension, BrowserMutation, NavigateParams, NavigateResult), + ToolNavigateBack => ("tool.navigate_back", Extension, BrowserMutation, NavigateBackParams, NavigateBackResult), + ToolNavigateForward => ("tool.navigate_forward", Extension, BrowserMutation, NavigateForwardParams, NavigateForwardResult), + ToolReload => ("tool.reload", Extension, BrowserMutation, ReloadParams, ReloadResult), + ToolClick => ("tool.click", Extension, BrowserMutation, ClickParams, ClickResult), + ToolHover => ("tool.hover", Extension, TransientInput, HoverParams, HoverResult), + ToolWheel => ("tool.wheel", Extension, BrowserMutation, WheelParams, WheelResult), + ToolScrollTo => ("tool.scroll_to", Extension, BrowserMutation, ScrollToParams, ScrollToResult), + ToolFocus => ("tool.focus", Extension, BrowserMutation, FocusParams, FocusResult), + ToolBlur => ("tool.blur", Extension, BrowserMutation, BlurParams, BlurResult), + ToolFill => ("tool.fill", Extension, BrowserMutation, FillParams, FillResult), + ToolPress => ("tool.press", Extension, BrowserMutation, PressParams, PressResult), + ToolSelect => ("tool.select", Extension, BrowserMutation, SelectParams, SelectResult), + ToolUpload => ("tool.upload", Extension, BrowserMutation, UploadParams, UploadResult), + ToolDownload => ("tool.download", Extension, BrowserMutation, DownloadParams, DownloadResult), + ToolSnapshot => ("tool.snapshot", Extension, PassiveRead, SnapshotParams, SnapshotResult), + ToolObserve => ("tool.observe", Extension, TransientInput, ObserveParams, ObserveResult), + ToolGetHtml => ("tool.get_html", Extension, PassiveRead, GetHtmlParams, GetHtmlResult), + ToolScreenshot => ("tool.screenshot", Extension, PassiveRead, ScreenshotParams, ScreenshotResult), + ToolScreenshotFullPage => ("tool.screenshot_full_page", Extension, TransientInput, ScreenshotFullPageParams, ScreenshotFullPageResult), + ToolScreenshotRead => ("tool.screenshot_read", Extension, PassiveRead, ScreenshotReadParams, ScreenshotReadResult), + ToolScreenshotRelease => ("tool.screenshot_release", Extension, ControlPlane, ScreenshotReleaseParams, ScreenshotReleaseResult), + ToolConsole => ("tool.console", Extension, PassiveRead, ConsoleParams, ConsoleResult), + ToolDebug => ("tool.debug", Extension, ControlPlane, DebugParams, DebugResult), + ToolNetwork => ("tool.network", Extension, PassiveRead, NetworkParams, NetworkResult), + ToolEvaluate => ("tool.evaluate", Extension, BrowserMutation, EvaluateParams, EvaluateResult), + ToolWaitForNavigation => ("tool.wait_for_navigation", Extension, PassiveRead, WaitForNavigationParams, WaitForNavigationResult), + ToolWaitMs => ("tool.wait_ms", Daemon, PassiveRead, WaitMsParams, WaitMsResult), + ToolRequestHelp => ("tool.request_help", Extension, PassiveRead, RequestHelpParams, RequestHelpResult), + ToolRecordStart => ("tool.record_start", Extension, BrowserMutation, RecordStartParams, RecordStartResult), + ToolRecordStop => ("tool.record_stop", Extension, PassiveRead, RecordStopParams, RecordStopResult), + ToolRecordAwait => ("tool.record_await", Extension, PassiveRead, RecordAwaitParams, RecordAwaitResult), + TransferBegin => ("transfer.begin", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + TransferChunk => ("transfer.chunk", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + TransferFinish => ("transfer.finish", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + TransferRead => ("transfer.read", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + TransferRelease => ("transfer.release", Daemon, ControlPlane, serde_json::Value, serde_json::Value), + Cancel => ("cancel", Shared, ControlPlane, CancelParams, CancelResult), +} +impl Method { /// Debug reads/teardown remain available after interruption, while explicit /// network interventions and replay are gated like other browser writes. pub fn requires_interrupt_gate_with_params(&self, params: &serde_json::Value) -> bool { - self.requires_interrupt_gate() - || (matches!(self, Method::ToolDebug) - && matches!( - params.get("action").and_then(|value| value.as_str()), - Some("rule_add" | "rule_enable" | "replay") - )) + let effect = if matches!(self, Method::ToolDebug) { + params + .get("action") + .cloned() + .and_then(|action| serde_json::from_value::(action).ok()) + .map(|action| action.effect()) + .unwrap_or(self.effect()) + } else { + self.effect() + }; + matches!( + effect, + MethodEffect::BrowserMutation | MethodEffect::TransientInput + ) } /// Whether this RPC drives browser/page state in the traditional sense. diff --git a/crates/bsk-protocol/src/system.rs b/crates/bsk-protocol/src/system.rs index 1e98c0634..f649165ea 100644 --- a/crates/bsk-protocol/src/system.rs +++ b/crates/bsk-protocol/src/system.rs @@ -466,6 +466,26 @@ pub struct HandshakeResult { pub min_compatible_protocol: Option, } +/// Current handshake envelope. The flattened identity remains source-compatible +/// with older Rust callers constructing `HandshakeParams` directly. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +pub struct HandshakeRequest { + #[serde(flatten)] + pub identity: HandshakeParams, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audit_enabled: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +pub struct HandshakeResponse { + #[serde(flatten)] + pub identity: HandshakeResult, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audit_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub audit_ready: Option, +} + #[cfg(test)] mod handshake_payload_tests { use super::*; diff --git a/crates/bsk-protocol/src/tools/console.rs b/crates/bsk-protocol/src/tools/console.rs index 54d843ada..afe5f8639 100644 --- a/crates/bsk-protocol/src/tools/console.rs +++ b/crates/bsk-protocol/src/tools/console.rs @@ -78,7 +78,7 @@ pub struct ConsoleEntry { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct ConsoleResult { pub tab_id: i64, - #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[serde(default)] pub entries: Vec, pub next_since: u64, #[serde(default)] diff --git a/crates/bsk-protocol/src/tools/debug.rs b/crates/bsk-protocol/src/tools/debug.rs index a8c31f159..58361211e 100644 --- a/crates/bsk-protocol/src/tools/debug.rs +++ b/crates/bsk-protocol/src/tools/debug.rs @@ -3,33 +3,50 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum DebugAction { - Performance, - Aggregate, - Duplicates, - Capabilities, - Activity, - Wait, - Pin, - Unpin, - Start, - Stop, - Status, - Requests, - Request, - Operations, - Operation, - Console, - Pages, - Export, - Rules, - RuleAdd, - RuleEnable, - RuleDisable, - RuleRemove, - Replay, +macro_rules! debug_actions { + ($($action:ident => ($wire:literal, $effect:ident, $owner:ident)),* $(,)?) => { + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] + pub enum DebugAction { $(#[serde(rename = $wire)] $action,)* } + impl DebugAction { + pub const ALL: &'static [Self] = &[$(Self::$action,)*]; + pub const fn wire_name(&self) -> &'static str { + match self { $(Self::$action => $wire,)* } + } + pub const fn effect(&self) -> crate::method::MethodEffect { + match self { $(Self::$action => crate::method::MethodEffect::$effect,)* } + } + pub const fn owner(&self) -> crate::catalog::MethodOwner { + match self { $(Self::$action => crate::catalog::MethodOwner::$owner,)* } + } + } + }; +} + +debug_actions! { + Performance => ("performance", ControlPlane, Extension), + Aggregate => ("aggregate", ControlPlane, Extension), + Duplicates => ("duplicates", ControlPlane, Extension), + Capabilities => ("capabilities", ControlPlane, Extension), + Activity => ("activity", ControlPlane, Daemon), + Wait => ("wait", ControlPlane, Daemon), + Pin => ("pin", ControlPlane, Extension), + Unpin => ("unpin", ControlPlane, Extension), + Start => ("start", ControlPlane, Extension), + Stop => ("stop", ControlPlane, Extension), + Status => ("status", ControlPlane, Extension), + Requests => ("requests", ControlPlane, Extension), + Request => ("request", ControlPlane, Extension), + Operations => ("operations", ControlPlane, Extension), + Operation => ("operation", ControlPlane, Extension), + Console => ("console", ControlPlane, Extension), + Pages => ("pages", ControlPlane, Extension), + Export => ("export", ControlPlane, Extension), + Rules => ("rules", ControlPlane, Extension), + RuleAdd => ("rule_add", BrowserMutation, Extension), + RuleEnable => ("rule_enable", BrowserMutation, Extension), + RuleDisable => ("rule_disable", ControlPlane, Extension), + RuleRemove => ("rule_remove", ControlPlane, Extension), + Replay => ("replay", BrowserMutation, Extension), } #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] @@ -243,7 +260,7 @@ pub struct DebugOperation { pub finished_at: Option, #[serde(skip_serializing_if = "Option::is_none")] pub window_end: Option, - pub state: String, + pub state: DebugOperationState, #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -260,6 +277,13 @@ pub struct DebugOperation { pub console_ids: Vec, pub truncated: bool, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DebugRunState { + Capturing, + Stopped, +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct DebugRun { pub id: String, @@ -270,7 +294,7 @@ pub struct DebugRun { pub started_at: f64, #[serde(skip_serializing_if = "Option::is_none")] pub stopped_at: Option, - pub state: String, + pub state: DebugRunState, #[serde(skip_serializing_if = "Option::is_none")] pub stop_reason: Option, pub requests: u64, @@ -288,7 +312,7 @@ pub struct DebugRun { #[serde(skip_serializing_if = "Option::is_none")] pub storage_error: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub storage: Option, + pub storage: Option, #[serde(skip_serializing_if = "Option::is_none")] pub environment: Option>, } @@ -403,11 +427,21 @@ pub struct DebugResult { #[serde(skip_serializing_if = "Option::is_none")] pub capabilities: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub output: Option, + pub output: Option, #[serde(skip_serializing_if = "Option::is_none")] pub activity: Option, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DebugRuleState { + Enabled, + Disabled, + Exhausted, + Removed, + Stopped, +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] #[serde(deny_unknown_fields)] pub struct DebugRuleMatch { @@ -467,7 +501,7 @@ pub struct DebugRule { #[serde(flatten)] pub spec: DebugRuleSpec, pub id: String, - pub state: String, + pub state: DebugRuleState, pub hits: u32, pub failures: u32, pub created_at: f64, @@ -498,11 +532,19 @@ pub struct DebugReplay { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DebugInterventionKind { + Block, + Modify, + Mock, +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct DebugIntervention { pub rule_id: String, #[serde(rename = "type")] - pub kind: String, + pub kind: DebugInterventionKind, pub state: String, #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, @@ -529,7 +571,8 @@ pub struct DebugActivity { } pub fn debug_parameter_schema() -> serde_json::Value { - serde_json::to_value(schemars::schema_for!(DebugParams)).expect("debug schema serializes") + serde_json::to_value(crate::catalog::schema_for::()) + .expect("debug schema serializes") } #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] @@ -676,3 +719,29 @@ mod fidelity_tests { assert_eq!(to_value(legacy).unwrap(), value); } } + +/// Bounded local retention statistics included in debug run metadata. +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub struct DebugStorage { + pub requests: u64, + pub bytes: u64, + pub dropped: u64, + pub pins: u64, +} + +/// Reports how the requested output budget affected a debug response. +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +pub struct DebugOutput { + pub budget: u64, + pub truncated: bool, + pub omitted: Vec, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DebugOperationState { + Running, + Completed, + Error, + Interrupted, +} diff --git a/crates/bsk-protocol/src/tools/network.rs b/crates/bsk-protocol/src/tools/network.rs index 52ece7692..af860f256 100644 --- a/crates/bsk-protocol/src/tools/network.rs +++ b/crates/bsk-protocol/src/tools/network.rs @@ -60,7 +60,7 @@ pub struct NetworkEntry { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] pub struct NetworkResult { pub tab_id: i64, - #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[serde(default)] pub entries: Vec, pub next_since: u64, #[serde(default)] diff --git a/crates/bsk-protocol/src/tools/record.rs b/crates/bsk-protocol/src/tools/record.rs index 8ffee1603..c9628d7eb 100644 --- a/crates/bsk-protocol/src/tools/record.rs +++ b/crates/bsk-protocol/src/tools/record.rs @@ -114,46 +114,17 @@ impl<'de> Deserialize<'de> for RecordedTrace { } impl JsonSchema for RecordedTrace { - fn schema_name() -> String { + fn schema_name() -> std::borrow::Cow<'static, str> { "RecordedTrace".into() } - fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::schema::Schema { - // Mirror classify_value: a numeric `version` selects v3; otherwise v2. - // TraceV2 stays open for unknown extension fields but forbids `states[]` - // and a numeric `version`. TraceV3 already denies `pages[]`. - let mut version_props = schemars::Map::new(); - version_props.insert( - "version".into(), - schemars::schema::SchemaObject { - instance_type: Some(schemars::schema::InstanceType::Integer.into()), - ..Default::default() - } - .into(), - ); - let mut required = schemars::Set::new(); - required.insert("version".into()); - - schemars::schema::SchemaObject { - subschemas: Some(Box::new(schemars::schema::SubschemaValidation { - if_schema: Some(Box::new( - schemars::schema::SchemaObject { - object: Some(Box::new(schemars::schema::ObjectValidation { - properties: version_props, - required, - ..Default::default() - })), - ..Default::default() - } - .into(), - )), - then_schema: Some(Box::new(generator.subschema_for::())), - else_schema: Some(Box::new(generator.subschema_for::())), - ..Default::default() - })), - ..Default::default() - } - .into() + fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema { + // Keep the classifier identical to classify_value, including its v2 fallback. + schemars::json_schema!({ + "if": {"properties": {"version": {"type": "integer"}}, "required": ["version"]}, + "then": generator.subschema_for::(), + "else": generator.subschema_for::() + }) } } @@ -209,49 +180,17 @@ impl<'de> Deserialize<'de> for RecordedStep { } impl JsonSchema for RecordedStep { - fn schema_name() -> String { + fn schema_name() -> std::borrow::Cow<'static, str> { "RecordedStep".into() } - fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::schema::Schema { - // Mirror classify_value: `state` selects v3; otherwise v2. - // Mixed page + state is rejected at this layer because StepV2/StepV3 - // still allow unknown extension fields. - let mut required = schemars::Set::new(); - required.insert("state".into()); - let mut mixed_keys = schemars::Set::new(); - mixed_keys.insert("page".into()); - mixed_keys.insert("state".into()); - - schemars::schema::SchemaObject { - subschemas: Some(Box::new(schemars::schema::SubschemaValidation { - if_schema: Some(Box::new( - schemars::schema::SchemaObject { - object: Some(Box::new(schemars::schema::ObjectValidation { - required, - ..Default::default() - })), - ..Default::default() - } - .into(), - )), - then_schema: Some(Box::new(generator.subschema_for::())), - else_schema: Some(Box::new(generator.subschema_for::())), - not: Some(Box::new( - schemars::schema::SchemaObject { - object: Some(Box::new(schemars::schema::ObjectValidation { - required: mixed_keys, - ..Default::default() - })), - ..Default::default() - } - .into(), - )), - ..Default::default() - })), - ..Default::default() - } - .into() + fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema!({ + "if": {"required": ["state"]}, + "then": generator.subschema_for::(), + "else": generator.subschema_for::(), + "not": {"required": ["page", "state"]} + }) } } @@ -597,7 +536,8 @@ mod tests { #[test] fn recorded_trace_schema_includes_v2_and_v3() { - let schema = serde_json::to_value(schemars::schema_for!(RecordStopResult)).unwrap(); + let schema = + serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_classifies_by_integer_version(&schema["definitions"]["RecordedTrace"]); assert_eq!( schema["definitions"]["TraceV3"]["properties"]["version"]["const"], @@ -607,18 +547,20 @@ mod tests { #[test] fn recorded_trace_schema_follows_classify_value() { - let standalone = serde_json::to_value(schemars::schema_for!(RecordedTrace)).unwrap(); + let standalone = + serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_classifies_by_integer_version(&standalone); assert!(standalone["definitions"].get("TraceV2").is_some()); assert!(standalone["definitions"].get("TraceV3").is_some()); - let stop_result = serde_json::to_value(schemars::schema_for!(RecordStopResult)).unwrap(); + let stop_result = + serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_classifies_by_integer_version(&stop_result["definitions"]["RecordedTrace"]); } #[test] fn standalone_trace_schema_is_recorded_trace_union() { - let schema = serde_json::to_value(schemars::schema_for!(RecordedTrace)).unwrap(); + let schema = serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_eq!(schema["title"], "RecordedTrace"); assert_classifies_by_integer_version(&schema); assert!(schema["definitions"].get("TraceV2").is_some()); @@ -699,7 +641,7 @@ mod tests { #[test] fn recorded_step_schema_follows_classify_value() { - let schema = serde_json::to_value(schemars::schema_for!(RecordedStep)).unwrap(); + let schema = serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_eq!(schema["title"], "RecordedStep"); assert_step_classifies_by_state(&schema); assert!(schema["definitions"].get("StepV2").is_some()); diff --git a/crates/bsk-protocol/src/tools/record_v2.rs b/crates/bsk-protocol/src/tools/record_v2.rs index 23923815f..08437a0da 100644 --- a/crates/bsk-protocol/src/tools/record_v2.rs +++ b/crates/bsk-protocol/src/tools/record_v2.rs @@ -109,7 +109,8 @@ pub enum StepV2 { /// Unknown extension fields are ignored so older traces remain readable. /// `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` /// classification — serde still ignores them, but the JSON Schema rejects them. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +#[schemars(transform = constrain_trace_v2_schema)] pub struct TraceV2 { /// RFC 3339 timestamp when recording stopped. pub recorded_at: String, @@ -122,68 +123,16 @@ pub struct TraceV2 { pub steps: Vec, } -fn constrain_trace_v2_schema(mut schema: schemars::schema::Schema) -> schemars::schema::Schema { - let schemars::schema::Schema::Object(obj) = &mut schema else { - return schema; - }; - obj.metadata().title = Some("TraceV2".into()); - obj.metadata().description = Some( - "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\n\ - Unknown extension fields are ignored so older traces remain readable. \ - `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` classification." - .into(), - ); - - let object = obj.object.get_or_insert_with(Default::default); - object - .properties - .insert("states".into(), schemars::schema::Schema::Bool(false)); - object.properties.insert( - "version".into(), - schemars::schema::SchemaObject { - metadata: Some(Box::new(schemars::schema::Metadata { - description: Some( - "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.".into(), - ), - ..Default::default() - })), - subschemas: Some(Box::new(schemars::schema::SubschemaValidation { - not: Some(Box::new( - schemars::schema::SchemaObject { - instance_type: Some(schemars::schema::InstanceType::Integer.into()), - ..Default::default() - } - .into(), - )), - ..Default::default() - })), - ..Default::default() - } - .into(), - ); - schema -} - -impl JsonSchema for TraceV2 { - fn schema_name() -> String { - "TraceV2".into() - } - - fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::schema::Schema { - #[derive(JsonSchema)] - #[allow(dead_code)] - struct TraceV2Shape { - /// RFC 3339 timestamp when recording stopped. - recorded_at: String, - started_at: Option, - purpose: Option, - entry: TraceEntry, - pages: Vec, - steps: Vec, - } - - constrain_trace_v2_schema(TraceV2Shape::json_schema(generator)) - } +fn constrain_trace_v2_schema(schema: &mut schemars::Schema) { + let properties = schema + .ensure_object() + .entry("properties") + .or_insert_with(|| serde_json::json!({})); + properties["states"] = serde_json::json!(false); + properties["version"] = serde_json::json!({ + "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", + "not": {"type": "integer"} + }); } #[cfg(test)] @@ -306,7 +255,7 @@ mod tests { #[test] fn trace_v2_schema_allows_additional_properties() { - let schema = serde_json::to_value(schemars::schema_for!(TraceV2)).unwrap(); + let schema = serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_ne!( schema.get("additionalProperties"), Some(&serde_json::Value::Bool(false)), @@ -316,7 +265,7 @@ mod tests { #[test] fn trace_v2_schema_forbids_classification_keys() { - let schema = serde_json::to_value(schemars::schema_for!(TraceV2)).unwrap(); + let schema = serde_json::to_value(crate::catalog::schema_for::()).unwrap(); assert_eq!( schema["properties"]["states"], json!(false), diff --git a/crates/bsk-protocol/src/tools/record_v3.rs b/crates/bsk-protocol/src/tools/record_v3.rs index 9af00d1c1..bdfcab66e 100644 --- a/crates/bsk-protocol/src/tools/record_v3.rs +++ b/crates/bsk-protocol/src/tools/record_v3.rs @@ -24,13 +24,8 @@ where Ok(version) } -fn trace_v3_version_schema(_: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema { - schemars::schema::SchemaObject { - instance_type: Some(schemars::schema::InstanceType::Integer.into()), - const_value: Some(serde_json::json!(TRACE_VERSION_V3)), - ..Default::default() - } - .into() +fn trace_v3_version_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { + schemars::json_schema!({ "type": "integer", "const": TRACE_VERSION_V3 }) } /// Stable semantic handle for an interacted element within a page observation. diff --git a/crates/bsk-protocol/src/tools/session.rs b/crates/bsk-protocol/src/tools/session.rs index aa945e14e..25af57d14 100644 --- a/crates/bsk-protocol/src/tools/session.rs +++ b/crates/bsk-protocol/src/tools/session.rs @@ -87,6 +87,15 @@ pub struct SessionStopResult { pub return_failures: Vec, } +/// Full extension response, including whether a window was left with the user. +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)] +pub struct SessionStopOutcome { + #[serde(flatten)] + pub returned: SessionStopResult, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub window_released: Option, +} + #[cfg(test)] mod tests { use super::*; @@ -94,8 +103,8 @@ mod tests { #[test] fn legacy_unattended_is_accepted_but_never_forwarded() { - let schema = schemars::schema_for!(SessionStartParams); - let object = schema.schema.object.unwrap(); + let schema = crate::catalog::schema_for::(); + let object = schema.as_object().unwrap(); for unattended in [false, true] { let params: SessionStartParams = serde_json::from_value(json!({ "session_id": "abcd", "unattended": unattended @@ -103,14 +112,20 @@ mod tests { .unwrap(); let encoded = serde_json::to_value(params).unwrap(); assert_eq!(encoded, json!({"session_id": "abcd"})); - for required in &object.required { + for required in object["required"].as_array().unwrap() { + let required = required.as_str().unwrap(); assert!( encoded.get(required).is_some(), "schema requires omitted field {required}" ); } } - assert!(!object.properties.contains_key("unattended")); + assert!( + !object["properties"] + .as_object() + .unwrap() + .contains_key("unattended") + ); } #[test] diff --git a/package.json b/package.json index dbc588fae..1ac4c8cd7 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "packageManager": "pnpm@10.17.0", "scripts": { "cli:build": "cargo run -p bsk-protocol --bin dump-schema --locked && pnpm -r build", + "protocol:check": "node scripts/protocol.mjs --check", "eval:browser": "node evals/browser/cli.mjs", "eval:browser:check": "node evals/browser/cli.mjs validate && node --test evals/browser/tests/*.test.mjs", "eval:browser:test": "node --test evals/browser/tests/*.test.mjs", @@ -13,10 +14,14 @@ "ext:test": "pnpm --filter @browser-skill/extension test", "vom:test": "pnpm --filter @browser-skill/vom test", "lint": "biome check . && stylelint \"**/*.css\" && pnpm --filter @wxg-prc-cpg/browser-skill-dsh-plugin typecheck && pnpm --filter @wxg-prc-cpg/browser-skill-dsh-plugin test", - "format": "biome format --write ." + "format": "biome format --write .", + "protocol:generate": "node scripts/protocol.mjs" }, "devDependencies": { "@biomejs/biome": "^2.3.14", + "ajv": "8.20.0", + "esbuild": "0.27.7", + "json-schema-to-typescript": "16.0.0", "stylelint": "^16.0.0", "stylelint-config-standard": "^37.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 486791fd0..af05a4d13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,6 +13,15 @@ importers: '@biomejs/biome': specifier: ^2.3.14 version: 2.4.15 + ajv: + specifier: 8.20.0 + version: 8.20.0 + esbuild: + specifier: 0.27.7 + version: 0.27.7 + json-schema-to-typescript: + specifier: 16.0.0 + version: 16.0.0 stylelint: specifier: ^16.0.0 version: 16.26.1(typescript@5.9.3) @@ -275,6 +284,10 @@ packages: rollup: optional: true + '@apidevtools/json-schema-ref-parser@11.9.3': + resolution: {integrity: sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==} + engines: {node: '>= 16'} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1071,6 +1084,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@keyv/bigmap@1.3.1': resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} engines: {node: '>= 18'} @@ -1781,9 +1797,15 @@ packages: '@types/hast@3.0.5': resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/katex@0.16.8': resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + '@types/lodash@4.17.25': + resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -2835,14 +2857,14 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} - js-yaml@4.2.0: - resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} - hasBin: true - js-yaml@4.3.2: resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true + js-yaml@5.4.2: + resolution: {integrity: sha512-m+aqu+LwO1O6sIopafj8HUVl5aawITwZQe/yHpMCKjaWBaA/d07B/QdMb3529REftiU+RMMHL3Vlsw3hON7vWg==} + hasBin: true + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -2850,6 +2872,11 @@ packages: resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + json-schema-to-typescript@16.0.0: + resolution: {integrity: sha512-Ah6kK4q6SjlMzWBH1eNOQkdRh5Qhr5T/RCFwfjQqWZA7UDW+N47A8wfyoiN0L884s4L4bAEI54IjIuN3/u0B/A==} + engines: {node: '>=16.0.0'} + hasBin: true + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -3027,6 +3054,9 @@ packages: lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + log-update@6.1.0: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} @@ -3402,6 +3432,11 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} + prettier@3.9.9: + resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==} + engines: {node: '>=14'} + hasBin: true + pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4228,6 +4263,12 @@ snapshots: optionalDependencies: rollup: 4.60.4 + '@apidevtools/json-schema-ref-parser@11.9.3': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.3.2 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -4919,6 +4960,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jsdevtools/ono@7.1.3': {} + '@keyv/bigmap@1.3.1(keyv@5.6.0)': dependencies: hashery: 1.5.1 @@ -5458,8 +5501,12 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/json-schema@7.0.15': {} + '@types/katex@0.16.8': {} + '@types/lodash@4.17.25': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -5898,7 +5945,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.2.0 + js-yaml: 4.3.2 parse-json: 5.2.0 optionalDependencies: typescript: 5.9.3 @@ -6378,11 +6425,11 @@ snapshots: js-tokens@9.0.1: {} - js-yaml@4.2.0: + js-yaml@4.3.2: dependencies: argparse: 2.0.1 - js-yaml@4.3.2: + js-yaml@5.4.2: dependencies: argparse: 2.0.1 @@ -6390,6 +6437,17 @@ snapshots: json-parse-even-better-errors@3.0.2: {} + json-schema-to-typescript@16.0.0: + dependencies: + '@apidevtools/json-schema-ref-parser': 11.9.3 + '@types/json-schema': 7.0.15 + '@types/lodash': 4.17.25 + js-yaml: 5.4.2 + lodash: 4.18.1 + minimist: 1.2.8 + prettier: 3.9.9 + tinyglobby: 0.2.17 + json-schema-traverse@1.0.0: {} json5@2.2.3: {} @@ -6555,6 +6613,8 @@ snapshots: lodash.truncate@4.4.2: {} + lodash@4.18.1: {} + log-update@6.1.0: dependencies: ansi-escapes: 7.3.0 @@ -7138,6 +7198,8 @@ snapshots: powershell-utils@0.1.0: {} + prettier@3.9.9: {} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -7702,7 +7764,7 @@ snapshots: pkg-types: 2.3.1 scule: 1.3.0 strip-literal: 3.1.0 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 unplugin: 3.0.0 unplugin-utils: 0.3.1 optionalDependencies: @@ -7741,12 +7803,12 @@ snapshots: unplugin-utils@0.3.1: dependencies: pathe: 2.0.3 - picomatch: 4.0.4 + picomatch: 4.0.5 unplugin@3.0.0: dependencies: '@jridgewell/remapping': 2.3.5 - picomatch: 4.0.4 + picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 update-notifier@7.3.1: @@ -7805,7 +7867,7 @@ snapshots: picomatch: 4.0.4 postcss: 8.5.14 rolldown: 1.0.1 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 esbuild: 0.27.7 @@ -7818,7 +7880,7 @@ snapshots: picomatch: 4.0.4 postcss: 8.5.14 rolldown: 1.0.1 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.8.0 esbuild: 0.27.7 diff --git a/scripts/protocol.mjs b/scripts/protocol.mjs new file mode 100644 index 000000000..98d0de978 --- /dev/null +++ b/scripts/protocol.mjs @@ -0,0 +1,343 @@ +#!/usr/bin/env node +// Generate the extension contract from the Rust method catalog. --check never writes source files. +import { spawnSync } from "node:child_process"; +import { createHash } from "node:crypto"; +import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import Ajv from "ajv"; +import standalone from "ajv/dist/standalone/index.js"; +import { build } from "esbuild"; +import { compile } from "json-schema-to-typescript"; + +const root = fileURLToPath(new URL("../", import.meta.url)); +const destination = join(root, "apps/extension/src/transport/generated"); +const banner = "// Generated by scripts/protocol.mjs from bsk-protocol. Do not edit.\n"; +const args = new Set(process.argv.slice(2)); +if ([...args].some((arg) => !["--check", "--json"].includes(arg))) { + throw new Error("Usage: node scripts/protocol.mjs [--check] [--json]"); +} +const exported = spawnSync( + "cargo", + [ + "run", + "--quiet", + "--locked", + "--target-dir", + join(root, "target/protocol"), + "-p", + "bsk-protocol", + "--bin", + "export-protocol", + ], + { cwd: root, encoding: "utf8", maxBuffer: 32 * 1024 * 1024, timeout: 300_000 }, +); +if (exported.status !== 0) throw new Error(exported.error?.message ?? exported.stderr); +const catalog = JSON.parse(exported.stdout); +if (catalog.format_version !== 1 || !catalog.methods.length) + throw new Error("Invalid protocol catalog"); +const definitions = catalog.schema.definitions; +const names = Object.keys(definitions).sort(); +const methods = catalog.methods.filter((method) => method.owner === "extension"); +if ( + !methods.length || + new Set(catalog.methods.map((method) => method.method)).size !== catalog.methods.length +) { + throw new Error("Empty or duplicate method catalog"); +} +for (const method of catalog.methods) { + for (const name of [method.params, method.result]) { + if (!(name in definitions)) throw new Error(`Missing contract ${method.method}: ${name}`); + } +} + +// The wire accepts legacy null for optional typed fields. Internally these are +// represented by omission. Arbitrary JSON (including null), required nullable +// values, and dictionary values retain their original meaning. +function permitsNull(schema) { + if (!schema || typeof schema !== "object") return false; + return ( + schema.type === "null" || + (Array.isArray(schema.type) && schema.type.includes("null")) || + (schema.anyOf ?? schema.oneOf ?? []).some((part) => part.type === "null") + ); +} +function canonical(schema) { + if (!schema || typeof schema !== "object") return schema; + const result = structuredClone(schema); + const visit = (node) => { + if (!node || typeof node !== "object") return; + if (node.properties) { + const required = new Set(node.required ?? []); + for (const [key, property] of Object.entries(node.properties)) { + if (!required.has(key) && permitsNull(property)) { + if (Array.isArray(property.type)) { + property.type = property.type.filter((type) => type !== "null"); + if (property.type.length === 1) property.type = property.type[0]; + } + for (const union of ["anyOf", "oneOf"]) { + if (property[union]) + property[union] = property[union].filter((part) => part.type !== "null"); + } + } + } + } + for (const value of Object.values(node)) { + if (Array.isArray(value)) value.forEach(visit); + else if (value && typeof value === "object") visit(value); + } + }; + visit(result); + return result; +} + +const normalized = canonical(catalog.schema); +const outputSchema = canonical(catalog.output_schema); +// Conditional schema constraints remain in runtime validators. TypeScript can +// represent the union of their outcomes, but cannot express arbitrary predicates. +function typeProjection(schema) { + if (!schema || typeof schema !== "object") return schema; + if (Array.isArray(schema)) return schema.map(typeProjection); + const result = Object.fromEntries( + Object.entries(schema).map(([key, value]) => [key, typeProjection(value)]), + ); + if (result.properties) { + result.properties = Object.fromEntries( + Object.entries(result.properties).filter( + ([, value]) => value !== false && !(value?.not && !value.type && !value.$ref), + ), + ); + // Wire readers may ignore extension fields. They are not fields produced by our tools. + result.additionalProperties ??= false; + } + if (result.if) { + const alternatives = { anyOf: [result.then ?? {}, result.else ?? {}] }; + delete result.if; + delete result.then; + delete result.else; + result.allOf = [...(result.allOf ?? []), alternatives]; + } + return result; +} +async function compileTypes(schema) { + const projected = typeProjection(schema); + const typeSchema = { + ...projected, + definitions: Object.fromEntries( + Object.entries(projected.definitions).map(([name, schema]) => [ + name, + schema === true ? {} : schema === false ? { not: {}, tsType: "never" } : schema, + ]), + ), + title: "ProtocolTypes", + type: "object", + properties: Object.fromEntries(names.map((name) => [name, { $ref: `#/definitions/${name}` }])), + required: names, + additionalProperties: false, + }; + return compile(typeSchema, "ProtocolTypes", { + bannerComment: banner.trim(), + additionalProperties: false, + unreachableDefinitions: true, + unknownAny: true, + ignoreMinAndMaxItems: true, + format: true, + style: { printWidth: 100, tabWidth: 2 }, + }); +} +const inputTypes = await compileTypes(normalized); +const outputTypes = await compileTypes(outputSchema); +const paramNames = new Set(catalog.methods.map((method) => method.params)); +const types = + banner + + names + .map((name) => `export type { ${name} } from './${paramNames.has(name) ? "input" : "output"}';`) + .join("\n") + + "\n"; + +const wireId = "urn:bsk:wire"; +const canonicalId = "urn:bsk:canonical"; +const ajv = new Ajv({ + strict: false, + validateFormats: false, + inlineRefs: false, + code: { source: true, esm: true, lines: true }, +}); +ajv.addSchema({ ...catalog.schema, $id: wireId }); +ajv.addSchema({ ...normalized, $id: canonicalId }); +const outputId = "urn:bsk:output"; +ajv.addSchema({ ...outputSchema, $id: outputId }); +const validators = {}; +const inputRoots = [ + ...new Set([...methods.map((method) => method.params), "CancelParams", "HandshakeResponse"]), +].sort(); +for (const name of inputRoots) { + validators[`wire_${name}`] = `${wireId}#/definitions/${name}`; + validators[`canonical_${name}`] = `${canonicalId}#/definitions/${name}`; +} +for (const name of [...new Set([...methods.map((method) => method.result), "RpcError"])].sort()) { + validators[`canonical_${name}`] = `${outputId}#/definitions/${name}`; +} + +// Emit ordinary functions, including branch selection against the wire schema. +// This keeps normalization immutable and preserves tagged unions and dictionaries. +const normalizers = []; +let nextNormalizer = 0; +const normalizedDefinitions = new Set(); +function normalizeDefinition(name) { + if (normalizedDefinitions.has(name)) return; + normalizedDefinitions.add(name); + normalizer(definitions[name], `#/definitions/${name}`, `normalize_${name}`); +} +function normalizer(schema, pointer, name = `normalize_${nextNormalizer++}`) { + const lines = []; + if (!schema || typeof schema !== "object") { + normalizers.push(`function ${name}(value: unknown): unknown { return value; }`); + return name; + } + const call = (child, path, expression) => `${normalizer(child, path)}(${expression})`; + if (schema.$ref) { + const reference = schema.$ref.split("/").at(-1); + normalizeDefinition(reference); + lines.push(`return normalize_${reference}(value);`); + } else { + lines.push("let result = value;"); + if (schema.properties || schema.additionalProperties) { + lines.push( + "if (typeof result === 'object' && result !== null && !Array.isArray(result)) {", + "const object: Record = { ...result };", + ); + const required = new Set(schema.required ?? []); + for (const [key, child] of Object.entries(schema.properties ?? {})) { + const field = `object[${JSON.stringify(key)}]`; + const path = `${pointer}/properties/${key.replaceAll("~", "~0").replaceAll("/", "~1")}`; + if (!required.has(key) && permitsNull(child)) + lines.push(`if (${field} === null) delete ${field};`); + lines.push( + `if (Object.hasOwn(object, ${JSON.stringify(key)})) ${field} = ${call(child, path, field)};`, + ); + } + if (typeof schema.additionalProperties === "object") { + const child = normalizer(schema.additionalProperties, `${pointer}/additionalProperties`); + lines.push( + `for (const key of Object.keys(object)) { if (!new Set(${JSON.stringify(Object.keys(schema.properties ?? {}))}).has(key)) object[key] = ${child}(object[key]); }`, + ); + } + lines.push("result = object;", "}"); + } + if (schema.items && !Array.isArray(schema.items)) { + const child = normalizer(schema.items, `${pointer}/items`); + lines.push(`if (Array.isArray(result)) result = result.map(${child});`); + } + for (const [index, child] of (schema.allOf ?? []).entries()) { + lines.push(`result = ${call(child, `${pointer}/allOf/${index}`, "result")};`); + } + for (const union of ["anyOf", "oneOf"]) { + if (!schema[union]) continue; + schema[union].forEach((child, index) => { + const path = `${pointer}/${union}/${index}`; + const validator = `branch_${Object.keys(validators).length}`; + validators[validator] = `${wireId}${path}`; + lines.push( + `${index ? "else " : ""}if (validators.${validator}(value)) result = ${call(child, path, "result")};`, + ); + }); + } + if (schema.if) { + const validator = `branch_${Object.keys(validators).length}`; + validators[validator] = `${wireId}${pointer}/if`; + const yes = schema.then ? call(schema.then, `${pointer}/then`, "result") : "result"; + const no = schema.else ? call(schema.else, `${pointer}/else`, "result") : "result"; + lines.push(`result = validators.${validator}(value) ? ${yes} : ${no};`); + } + lines.push("return result;"); + } + normalizers.push(`function ${name}(value: unknown): unknown {\n${lines.join("\n")}\n}`); + return name; +} +for (const name of inputRoots) normalizeDefinition(name); +const validatorSource = standalone(ajv, validators); +const bundled = await build({ + stdin: { contents: validatorSource, resolveDir: root, sourcefile: "protocol-validators.js" }, + bundle: true, + format: "esm", + platform: "browser", + target: "es2022", + minify: true, + write: false, + legalComments: "none", +}); +const validationTypes = + banner + + "export interface ValidationIssue { instancePath: string; message?: string; keyword: string; }\n" + + "export interface Validator { (value: unknown): boolean; errors?: ValidationIssue[] | null; }\n" + + Object.keys(validators) + .map((name) => `export const ${name}: Validator;`) + .join("\n") + + "\n"; +const normalizationSource = + banner + + "import * as validators from './validators.js';\n" + + normalizers.join("\n\n") + + `\nexport const normalizers = { ${inputRoots.map((name) => `${name}: normalize_${name}`).join(", ")} } as const;\n`; +const methodSource = + banner + + "import type * as Types from './types';\n" + + `export const PROTOCOL_VERSION = ${JSON.stringify(catalog.protocol_version)};\n` + + `export const MIN_COMPATIBLE_PROTOCOL = ${JSON.stringify(catalog.min_compatible_protocol)};\n` + + Object.entries(catalog.constants) + .map(([name, value]) => `export const ${name} = ${JSON.stringify(value)};\n`) + .join("") + + `export const debugActions = ${JSON.stringify(catalog.debug_actions, null, 2)} as const;\n` + + `export const methods = ${JSON.stringify(catalog.methods, null, 2)} as const;\n` + + `export interface ToolMap {\n${methods.map((method) => ` ${JSON.stringify(method.method)}: { params: Types.${method.params}; result: Types.${method.result} };`).join("\n")}\n}\n` + + "export type ExtensionToolMethod = keyof ToolMap;\n" + + "export type ParamsOf = ToolMap[M]['params'];\n" + + "export type ResultOf = ToolMap[M]['result'];\n"; +const fingerprint = createHash("sha256").update(JSON.stringify(catalog)).digest("hex"); +const outputs = new Map([ + ["types.ts", types], + ["input.ts", inputTypes], + ["output.ts", outputTypes], + ["methods.ts", methodSource], + ["validators.js", banner + bundled.outputFiles[0].text], + ["validators.d.ts", validationTypes], + ["normalizers.ts", normalizationSource], + [ + "manifest.json", + JSON.stringify( + { + source: "bsk-protocol", + fingerprint, + methods: methods.map((m) => m.method), + contracts: names, + }, + null, + 2, + ) + "\n", + ], +]); +const changed = []; +for (const [name, source] of outputs) { + let existing; + try { + existing = readFileSync(join(destination, name), "utf8"); + } catch {} + if (existing !== source) changed.push(name); + if (!args.has("--check")) { + mkdirSync(destination, { recursive: true }); + writeFileSync(join(destination, name), source); + } +} +let unexpected = []; +try { + unexpected = readdirSync(destination).filter((name) => !outputs.has(name)); +} catch {} +if (unexpected.length) throw new Error(`Unexpected generated files: ${unexpected.join(", ")}`); +const report = { methods: methods.length, contracts: names.length, fingerprint, stale: changed }; +console.log( + args.has("--json") + ? JSON.stringify(report, null, 2) + : `${args.has("--check") ? "Checked" : "Generated"} ${methods.length} extension methods and ${names.length} contracts.${args.has("--check") && changed.length ? ` Stale: ${changed.join(", ")}. Run pnpm protocol:generate.` : ""}`, +); +if (args.has("--check") && changed.length) process.exitCode = 1; From 9e7e7b1a1f4e4e22caab7c1a609ea80fb64040ae Mon Sep 17 00:00:00 2001 From: NianJiuZst <3235467914@qq.com> Date: Wed, 7 Oct 2026 13:05:54 -0500 Subject: [PATCH 2/5] fix(daemon): preserve bounded evaluation timeout behavior --- crates/bsk-cli/src/daemon/queue.rs | 162 ++--------------------- crates/bsk-cli/src/daemon/tool_policy.rs | 78 ++++++----- crates/bsk-protocol/README.md | 27 ++-- crates/bsk-protocol/src/method.rs | 15 +++ 4 files changed, 84 insertions(+), 198 deletions(-) diff --git a/crates/bsk-cli/src/daemon/queue.rs b/crates/bsk-cli/src/daemon/queue.rs index 488c49649..b261c78b1 100644 --- a/crates/bsk-cli/src/daemon/queue.rs +++ b/crates/bsk-cli/src/daemon/queue.rs @@ -439,15 +439,7 @@ impl ToolQueueRegistry { cancel_cleanup_timeout: CANCEL_CLEANUP_TIMEOUT, session_id: sid.clone(), }; - match forward_one( - sid, - &self.browsers, - &self.sessions, - &job, - &mut Settlement::Complete, - ) - .await - { + match forward_one(sid, &self.browsers, &self.sessions, &job).await { Ok(v) => Ok(v), Err(err) => Err(DispatchError::Rpc(err)), } @@ -579,68 +571,13 @@ async fn run_worker( ) { debug!(session = %sid, "tool queue worker started"); while let Some(job) = rx.recv().await { - let mut settlement = Settlement::Complete; - let result = forward_one(&sid, &browsers, &sessions, &job, &mut settlement).await; - if let Settlement::Pending(mut pending) = settlement { - if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() { - active.state = "settling".into(); - } - let _ = job.respond.send(result); - // Keep the original receiver registered. A deadline replies to the - // caller, but does not release the session or replay the expression. - let response = loop { - tokio::select! { - response = &mut pending.waiter => break Some(response), - next = rx.recv() => match next { - None => break None, - Some(next) => { let _ = next.respond.send(Err(session_busy_rpc())); } - } - } - }; - pending - .client - .pending - .lock() - .unwrap() - .cancel(&pending.rpc_id); - let Some(response) = response else { - break; - }; - let settled = matches!(response, Ok(ref frame) if !matches!(&frame.body, - ResponseBody::Err(error) if super::browsers::is_link_failure(error))); - if settled { - clear_busy(&state); - } else if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() - { - // Losing the link is not evidence that page execution stopped. - active.state = "unconfirmed".into(); - } - } else { - if matches!(settlement, Settlement::Unconfirmed) { - if let Some(active) = state.lock().expect("queue state poisoned").active.as_mut() { - active.state = "unconfirmed".into(); - } - } else { - clear_busy(&state); - } - let _ = job.respond.send(result); - } + let result = forward_one(&sid, &browsers, &sessions, &job).await; + clear_busy(&state); + let _ = job.respond.send(result); } debug!(session = %sid, "tool queue worker exiting"); } -enum Settlement { - Complete, - Pending(PendingSettlement), - Unconfirmed, -} - -struct PendingSettlement { - waiter: oneshot::Receiver, - client: Arc, - rpc_id: RpcId, -} - /// Forward a single [`ToolJob`] over WS to the extension that owns the /// session and decode the structured response. async fn forward_one( @@ -648,7 +585,6 @@ async fn forward_one( browsers: &Arc, sessions: &Arc, job: &ToolJob, - settlement: &mut Settlement, ) -> Result { // Pre-flight: a cancel that landed while this job was still in // the per-session channel must short-circuit before any session @@ -750,7 +686,7 @@ async fn forward_one( job.lifecycle_cancel.clone() } }; - let mut waiter = match dispatched { + let waiter = match dispatched { Some(Ok(waiter)) => waiter, other => return Err(not_dispatched_error(other)), }; @@ -783,54 +719,15 @@ async fn forward_one( }; let deadline_cancel: Option<&(dyn Fn() -> bool + Sync)> = waits_for_deadline_cleanup(&job.method).then_some(&send_deadline_cancel); - let waited = wait_for_response( + let waited = await_with_optional_cancel( job.timeout, job.cancel_cleanup_timeout, - &mut waiter, + waiter, cancel_token.as_ref(), on_abort, deadline_cancel, ) .await; - let retains_execution = execution_policy(&job.method).retain_until_settled; - let link_lost = match &waited { - WaitOutcome::WaiterClosed => true, - WaitOutcome::Response(frame) - | WaitOutcome::CancelledAfterResponse(frame) - | WaitOutcome::TimedOutAfterResponse(frame) => { - matches!(&frame.body, ResponseBody::Err(error) if super::browsers::is_link_failure(error)) - } - _ => false, - }; - if retains_execution && link_lost { - *settlement = Settlement::Unconfirmed; - return Err(unconfirmed_evaluation(ErrorCode::ProtocolError)); - } - if retains_execution - && matches!( - waited, - WaitOutcome::Timeout | WaitOutcome::CleanupTimeout | WaitOutcome::TimeoutCleanupFailed - ) - { - if waiter.is_terminated() { - *settlement = Settlement::Unconfirmed; - return Err(unconfirmed_evaluation(ErrorCode::ProtocolError)); - } - *settlement = Settlement::Pending(PendingSettlement { - waiter, - client: Arc::clone(&client), - rpc_id, - }); - return Err(RpcError { - code: ErrorCode::Timeout, - message: - "Evaluation has not settled; the session remains busy until its final response" - .into(), - data: Some(serde_json::json!({ - "reason": "execution_pending", "effect_state": "unknown", "execution_state": "settling" - })), - }); - } // Record what this call implies about the control plane before shaping // its error. Health and business errors are decided separately: the // mark is diagnostic, every arm below keeps its own contract. @@ -1127,17 +1024,6 @@ fn not_dispatched_error( } } -fn unconfirmed_evaluation(code: ErrorCode) -> RpcError { - RpcError { - code, - message: "Evaluation lost its connection before completion; execution may still be running" - .into(), - data: Some(serde_json::json!({ - "reason": "execution_outcome_unknown", "effect_state": "unknown", "execution_state": "unconfirmed" - })), - } -} - fn is_native_input(method: &Method) -> bool { execution_policy(method).outcome == Outcome::NativeInput } @@ -1239,30 +1125,10 @@ enum WaitOutcome { Timeout, } -#[cfg(test)] async fn await_with_optional_cancel( timeout: Duration, cleanup_timeout: Duration, - mut waiter: oneshot::Receiver, - cancel: Option<&super::abort::AbortToken>, - on_abort: Option<&(dyn Fn() + Sync)>, - on_deadline: Option<&(dyn Fn() -> bool + Sync)>, -) -> WaitOutcome { - wait_for_response( - timeout, - cleanup_timeout, - &mut waiter, - cancel, - on_abort, - on_deadline, - ) - .await -} - -async fn wait_for_response( - timeout: Duration, - cleanup_timeout: Duration, - waiter: &mut oneshot::Receiver, + mut waiter: oneshot::Receiver, cancel: Option<&super::abort::AbortToken>, on_abort: Option<&(dyn Fn() + Sync)>, on_deadline: Option<&(dyn Fn() -> bool + Sync)>, @@ -1280,20 +1146,20 @@ async fn wait_for_response( if let Some(on_abort) = on_abort { on_abort(); } - match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut waiter).await { Ok(Ok(resp)) => WaitOutcome::CancelledAfterResponse(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => WaitOutcome::CleanupTimeout, } }, - outcome = &mut *waiter => match outcome { + outcome = &mut waiter => match outcome { Ok(resp) => WaitOutcome::Response(resp), Err(_) => WaitOutcome::WaiterClosed, }, _ = &mut deadline => { if let Some(send_cancel) = on_deadline { return if send_cancel() { - match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) | Err(_) => WaitOutcome::TimeoutCleanupFailed, } @@ -1305,7 +1171,7 @@ async fn wait_for_response( return WaitOutcome::Timeout; }; on_abort(); - match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => WaitOutcome::CleanupTimeout, @@ -1313,12 +1179,12 @@ async fn wait_for_response( }, } } - None => match tokio::time::timeout(timeout, &mut *waiter).await { + None => match tokio::time::timeout(timeout, &mut waiter).await { Ok(Ok(resp)) => WaitOutcome::Response(resp), Ok(Err(_)) => WaitOutcome::WaiterClosed, Err(_) => match on_deadline { Some(send_cancel) if send_cancel() => { - match tokio::time::timeout(cleanup_timeout, &mut *waiter).await { + match tokio::time::timeout(cleanup_timeout, &mut waiter).await { Ok(Ok(resp)) => WaitOutcome::TimedOutAfterResponse(resp), Ok(Err(_)) | Err(_) => WaitOutcome::TimeoutCleanupFailed, } diff --git a/crates/bsk-cli/src/daemon/tool_policy.rs b/crates/bsk-cli/src/daemon/tool_policy.rs index a997a4392..3b39c258d 100644 --- a/crates/bsk-cli/src/daemon/tool_policy.rs +++ b/crates/bsk-cli/src/daemon/tool_policy.rs @@ -1,5 +1,5 @@ //! Daemon scheduling policy. Exhaustive matching makes every new method choose -//! a timeout and settlement policy independently of its browser effect class. +//! a timeout and cancellation policy independently of its browser effect class. use bsk_protocol::Method; #[derive(Clone, Copy, PartialEq, Eq)] @@ -14,7 +14,6 @@ pub enum Outcome { Ordinary, NativeInput, FileTransfer, - Evaluation, } #[derive(Clone, Copy)] @@ -23,34 +22,51 @@ pub struct ExecutionPolicy { pub response_grace: bool, pub cancel_at_deadline: bool, pub outcome: Outcome, - /// A caller deadline cannot prove that arbitrary page JavaScript has stopped. - pub retain_until_settled: bool, } pub fn execution_policy(method: &Method) -> ExecutionPolicy { use Method::*; - let (deadline, response_grace, cancel_at_deadline, outcome, retain_until_settled) = match method - { - ToolTabBorrow => ( - Deadline::BorrowConfirmation, - false, - true, - Outcome::Ordinary, - false, - ), - ToolNavigate => (Deadline::Standard, true, false, Outcome::Ordinary, false), - ToolNavigateBack => (Deadline::Standard, true, false, Outcome::Ordinary, false), - ToolNavigateForward => (Deadline::Standard, true, false, Outcome::Ordinary, false), - ToolReload => (Deadline::Standard, true, false, Outcome::Ordinary, false), - ToolClick => (Deadline::Standard, false, true, Outcome::NativeInput, false), - ToolWheel => (Deadline::Standard, false, true, Outcome::NativeInput, false), - ToolPress => (Deadline::Standard, false, true, Outcome::NativeInput, false), - ToolUpload => (Deadline::Standard, true, true, Outcome::FileTransfer, false), - ToolDownload => (Deadline::Standard, true, true, Outcome::FileTransfer, false), - ToolScreenshotFullPage => (Deadline::FullPage, false, true, Outcome::Ordinary, false), - ToolEvaluate => (Deadline::Standard, false, true, Outcome::Evaluation, true), - ToolWaitForNavigation => (Deadline::Standard, true, false, Outcome::Ordinary, false), - ToolRequestHelp => (Deadline::Standard, true, true, Outcome::Ordinary, false), + const ORDINARY: ExecutionPolicy = ExecutionPolicy { + deadline: Deadline::Standard, + response_grace: false, + cancel_at_deadline: false, + outcome: Outcome::Ordinary, + }; + match method { + ToolTabBorrow => ExecutionPolicy { + deadline: Deadline::BorrowConfirmation, + cancel_at_deadline: true, + ..ORDINARY + }, + ToolNavigate + | ToolNavigateBack + | ToolNavigateForward + | ToolReload + | ToolWaitForNavigation => ExecutionPolicy { + response_grace: true, + ..ORDINARY + }, + ToolClick | ToolWheel | ToolPress => ExecutionPolicy { + cancel_at_deadline: true, + outcome: Outcome::NativeInput, + ..ORDINARY + }, + ToolUpload | ToolDownload => ExecutionPolicy { + response_grace: true, + cancel_at_deadline: true, + outcome: Outcome::FileTransfer, + ..ORDINARY + }, + ToolScreenshotFullPage => ExecutionPolicy { + deadline: Deadline::FullPage, + cancel_at_deadline: true, + ..ORDINARY + }, + ToolRequestHelp => ExecutionPolicy { + response_grace: true, + cancel_at_deadline: true, + ..ORDINARY + }, AuditRequest | SystemHandshake | SystemPing @@ -86,6 +102,7 @@ pub fn execution_policy(method: &Method) -> ExecutionPolicy { | ToolConsole | ToolDebug | ToolNetwork + | ToolEvaluate | ToolWaitMs | ToolRecordStart | ToolRecordStop @@ -95,13 +112,6 @@ pub fn execution_policy(method: &Method) -> ExecutionPolicy { | TransferFinish | TransferRead | TransferRelease - | Cancel => (Deadline::Standard, false, false, Outcome::Ordinary, false), - }; - ExecutionPolicy { - deadline, - response_grace, - cancel_at_deadline, - outcome, - retain_until_settled, + | Cancel => ORDINARY, } } diff --git a/crates/bsk-protocol/README.md b/crates/bsk-protocol/README.md index 49f135aec..6de98284c 100644 --- a/crates/bsk-protocol/README.md +++ b/crates/bsk-protocol/README.md @@ -32,7 +32,7 @@ Reusable trace and documentation filenames are compatibility aliases, not a seco | Debug action owner and effect | `src/tools/debug.rs` | The CLI parser and generated extension metadata consume the same actions | | Extension implementations | `apps/extension/src/tools/dispatcher.ts` | `ToolHandlerMap` requires every extension method with its own parameter/result types | | Background targeting, popup tracking, remote support | `apps/extension/src/tools/policy.ts` | Complete `Record`; shared effects come from generated metadata | -| Daemon deadlines, grace and settlement | `crates/bsk-cli/src/daemon/tool_policy.rs` | Exhaustive `Method` match consumed by IPC and the queue | +| Daemon deadlines, grace and cancellation | `crates/bsk-cli/src/daemon/tool_policy.rs` | Exhaustive `Method` match consumed by IPC and the queue | Adding an extension method requires choosing its Rust payloads and effects, generating the contract, and implementing its handler and local policies. Missing cases produce compilation errors. Browser @@ -65,21 +65,16 @@ arrays for bounded collections and unions for conditional schemas; runtime valid numeric and conditional constraints that TypeScript cannot express. String formats are descriptive; semantic URL/regex/session checks remain in the existing handlers. -## Evaluation deadlines and settlement - -A deadline or cancel acknowledgement does not prove that arbitrary JavaScript has stopped. The -daemon sends cancellation at an evaluation deadline, allows the cleanup grace, then can return -`execution_pending` while retaining the original response receiver and the session's busy state. -`debug activity` reports `settling`; `debug wait` observes the original operation without replaying it. -Only its final response releases the queue. Other sessions remain independent. - -If the connection disappears before completion, an operation whose session survives becomes -`unconfirmed`. The existing disconnect/replacement lifecycle may instead invalidate the entire -session. Neither path makes the old session available for new commands. Inspect the page and end -the affected browser task before starting a new one. This deliberately avoids pretending -that `Runtime.evaluate` cancellation rolls back page effects. Scripts may also schedule independent -work after returning; settlement tracks the awaited evaluation, not all future page activity. -Other tools retain their existing bounded compensation behavior, described by the daemon policy. +## Evaluation deadlines and cancellation + +Evaluation retains the existing bounded timeout and cancellation behavior. A caller deadline or +cancel acknowledgement does not prove that arbitrary page JavaScript stopped, and cancellation +cannot roll back browser effects. Scripts can also schedule independent work after returning. + +This contract refactor does not retain an evaluation's queue lock indefinitely after the caller's +wait ends. An unresolving promise therefore does not permanently prevent later commands, session +stop, or idle cleanup. Execution settlement and recovery require a separate lifecycle design with +an explicit teardown path; generated contracts do not establish execution safety after a timeout. ## Compatibility and verification limits diff --git a/crates/bsk-protocol/src/method.rs b/crates/bsk-protocol/src/method.rs index 2dcad4915..a088db0f2 100644 --- a/crates/bsk-protocol/src/method.rs +++ b/crates/bsk-protocol/src/method.rs @@ -45,6 +45,21 @@ macro_rules! methods { match self { $(Self::$variant => MethodOwner::$owner,)* } } + /// **Judgment calls** (read these before adding new variants): + /// + /// * `tool.evaluate` is classified as browser-mutating because the + /// daemon cannot statically distinguish a `document.title` + /// read from a `form.submit()` write. + /// * `tool.observe` is classified as transient input: its bounded + /// hover probes do not commit browser state, but they dispatch real + /// page input events and therefore must be gated like automation. + /// * `tool.wait_*` are classified as read-only: they do not + /// initiate any browser action; they observe state only. + /// * `session.*` and `tool.session_*` are NOT gated. Blocking + /// `session.stop` would prevent the agent from gracefully + /// tearing down after observing the user's interrupt. + /// * `cancel` is NOT gated. It's a control-plane operation + /// (stops another in-flight RPC), not a browser action. pub const fn effect(&self) -> MethodEffect { match self { $(Self::$variant => MethodEffect::$effect,)* } } From 11a0a845798697460bc6e5d76920a7362d67339a Mon Sep 17 00:00:00 2001 From: NianJiuZst <3235467914@qq.com> Date: Wed, 7 Oct 2026 13:06:05 -0500 Subject: [PATCH 3/5] fix(protocol): synchronize standalone schema exports and checks --- crates/bsk-protocol/README.md | 5 +- .../schema/browser_list_params.json | 14 +- crates/bsk-protocol/schema/cancel_params.json | 12 +- crates/bsk-protocol/schema/cancel_result.json | 12 +- .../bsk-protocol/schema/handshake_params.json | 63 +- .../bsk-protocol/schema/handshake_result.json | 32 +- .../schema/system_ping_params.json | 2 +- .../schema/system_ping_result.json | 12 +- .../schema/system_status_params.json | 14 +- .../schema/system_status_result.json | 239 +-- .../bsk-protocol/schema/tool_blur_params.json | 24 +- .../bsk-protocol/schema/tool_blur_result.json | 112 +- .../schema/tool_click_params.json | 86 +- .../schema/tool_click_result.json | 116 +- .../schema/tool_console_entry.json | 118 +- .../schema/tool_console_params.json | 34 +- .../schema/tool_console_result.json | 109 +- .../schema/tool_console_stack_frame.json | 14 +- .../schema/tool_debug_params.json | 559 +++--- .../schema/tool_debug_result.json | 1696 +++++++++-------- .../schema/tool_download_params.json | 30 +- .../schema/tool_download_result.json | 24 +- .../schema/tool_emulate_overrides.json | 178 +- .../schema/tool_emulate_params.json | 140 +- .../schema/tool_emulate_result.json | 136 +- .../tool_emulate_user_agent_metadata.json | 50 +- .../schema/tool_evaluate_error.json | 20 +- .../schema/tool_evaluate_params.json | 28 +- .../schema/tool_evaluate_result.json | 122 +- .../bsk-protocol/schema/tool_fill_params.json | 26 +- .../bsk-protocol/schema/tool_fill_result.json | 106 +- .../schema/tool_focus_params.json | 24 +- .../schema/tool_focus_result.json | 102 +- .../schema/tool_get_html_params.json | 28 +- .../schema/tool_get_html_result.json | 102 +- .../schema/tool_hover_params.json | 60 +- .../schema/tool_hover_result.json | 114 +- .../schema/tool_navigate_back_params.json | 44 +- .../schema/tool_navigate_back_result.json | 112 +- .../schema/tool_navigate_forward_params.json | 44 +- .../schema/tool_navigate_forward_result.json | 112 +- .../schema/tool_navigate_params.json | 52 +- .../schema/tool_navigate_result.json | 112 +- .../schema/tool_network_entry.json | 62 +- .../schema/tool_network_params.json | 34 +- .../schema/tool_network_result.json | 95 +- .../schema/tool_observe_params.json | 38 +- .../schema/tool_observe_result.json | 226 +-- .../schema/tool_press_params.json | 64 +- .../schema/tool_press_result.json | 106 +- .../schema/tool_record_await_params.json | 18 +- .../schema/tool_record_await_result.json | 605 +++--- .../schema/tool_record_start_params.json | 28 +- .../schema/tool_record_start_result.json | 18 +- .../schema/tool_record_stop_params.json | 12 +- .../schema/tool_record_stop_result.json | 605 +++--- .../schema/tool_reload_params.json | 44 +- .../schema/tool_reload_result.json | 112 +- .../schema/tool_request_help_params.json | 164 +- .../schema/tool_request_help_result.json | 138 +- .../tool_screenshot_full_page_params.json | 44 +- .../tool_screenshot_full_page_result.json | 146 +- .../schema/tool_screenshot_params.json | 20 +- .../schema/tool_screenshot_read_params.json | 20 +- .../schema/tool_screenshot_read_result.json | 20 +- .../tool_screenshot_release_params.json | 14 +- .../tool_screenshot_release_result.json | 12 +- .../schema/tool_screenshot_result.json | 144 +- .../schema/tool_scroll_to_params.json | 24 +- .../schema/tool_scroll_to_result.json | 134 +- .../schema/tool_select_params.json | 34 +- .../schema/tool_select_result.json | 134 +- .../schema/tool_session_start_params.json | 26 +- .../schema/tool_session_start_result.json | 62 +- .../schema/tool_session_stop_params.json | 12 +- .../schema/tool_session_stop_result.json | 65 +- .../schema/tool_snapshot_params.json | 36 +- .../schema/tool_snapshot_result.json | 106 +- .../schema/tool_tab_borrow_params.json | 26 +- .../schema/tool_tab_borrow_result.json | 34 +- .../schema/tool_tab_close_params.json | 18 +- .../schema/tool_tab_close_result.json | 16 +- .../schema/tool_tab_create_params.json | 20 +- .../schema/tool_tab_create_result.json | 24 +- .../schema/tool_tab_list_params.json | 40 +- .../schema/tool_tab_list_result.json | 58 +- .../schema/tool_tab_return_params.json | 18 +- .../schema/tool_tab_return_result.json | 30 +- .../schema/tool_tab_select_params.json | 18 +- .../schema/tool_tab_select_result.json | 22 +- .../schema/tool_upload_params.json | 86 +- .../schema/tool_upload_result.json | 22 +- .../tool_wait_for_navigation_params.json | 48 +- .../tool_wait_for_navigation_result.json | 94 +- .../schema/tool_wait_ms_params.json | 16 +- .../schema/tool_wait_ms_result.json | 16 +- .../schema/tool_wheel_params.json | 66 +- .../schema/tool_wheel_result.json | 136 +- .../schema/tool_window_resize_params.json | 24 +- .../schema/tool_window_resize_result.json | 28 +- crates/bsk-protocol/schema/trace.json | 605 +++--- crates/bsk-protocol/schema/trace_step.json | 490 +++-- crates/bsk-protocol/schema/trace_step_v2.json | 332 ++-- crates/bsk-protocol/schema/trace_step_v3.json | 410 ++-- crates/bsk-protocol/schema/trace_v2.json | 318 ++-- crates/bsk-protocol/schema/trace_v3.json | 414 ++-- crates/bsk-protocol/src/bin/dump-schema.rs | 11 +- scripts/protocol.mjs | 97 +- 108 files changed, 5987 insertions(+), 6011 deletions(-) diff --git a/crates/bsk-protocol/README.md b/crates/bsk-protocol/README.md index 6de98284c..9759f8a14 100644 --- a/crates/bsk-protocol/README.md +++ b/crates/bsk-protocol/README.md @@ -14,8 +14,9 @@ cargo run -p bsk-protocol --bin dump-schema --locked -- --out-dir /tmp/bsk-schem ``` `protocol:generate` builds the current Rust exporter with the locked Cargo dependencies, then writes -`apps/extension/src/transport/generated/`. Commit those generated files with the Rust change. -`protocol:check` regenerates in memory and compares every expected file byte for byte. Missing, +`apps/extension/src/transport/generated/` and `crates/bsk-protocol/schema/`. Commit those generated +files with the Rust change. `protocol:check` regenerates extension files in memory and standalone +schemas in a temporary directory, then compares every expected file byte for byte. Missing, modified, or unexpected generated files fail the check. Frontend CI runs it before typechecking. There is no hand-maintained type-name intersection that can silently lose method coverage. diff --git a/crates/bsk-protocol/schema/browser_list_params.json b/crates/bsk-protocol/schema/browser_list_params.json index e42912b55..57f94607c 100644 --- a/crates/bsk-protocol/schema/browser_list_params.json +++ b/crates/bsk-protocol/schema/browser_list_params.json @@ -1,17 +1,17 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BrowserListParams", "description": "`browser.list` request payload.", - "type": "object", "properties": { "wait_for_browser_ms": { - "description": "When set, the daemon polls the browser registry for up to this many milliseconds before returning a list. Only applies while zero browsers are registered; an existing connection returns immediately.", + "description": "When set, the daemon polls the browser registry for up to this many\nmilliseconds before returning a list. Only applies while zero browsers\nare registered; an existing connection returns immediately.", + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] } - } + }, + "title": "BrowserListParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/cancel_params.json b/crates/bsk-protocol/schema/cancel_params.json index 0c833730f..72d328c96 100644 --- a/crates/bsk-protocol/schema/cancel_params.json +++ b/crates/bsk-protocol/schema/cancel_params.json @@ -1,13 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CancelParams", - "type": "object", - "required": [ - "rpc_id" - ], "properties": { "rpc_id": { "type": "string" } - } + }, + "required": [ + "rpc_id" + ], + "title": "CancelParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/cancel_result.json b/crates/bsk-protocol/schema/cancel_result.json index ddcda7852..33a5235c6 100644 --- a/crates/bsk-protocol/schema/cancel_result.json +++ b/crates/bsk-protocol/schema/cancel_result.json @@ -1,13 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CancelResult", - "type": "object", - "required": [ - "cancelled" - ], "properties": { "cancelled": { "type": "boolean" } - } + }, + "required": [ + "cancelled" + ], + "title": "CancelResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/handshake_params.json b/crates/bsk-protocol/schema/handshake_params.json index 9e6b531f7..3f2a8ecbb 100644 --- a/crates/bsk-protocol/schema/handshake_params.json +++ b/crates/bsk-protocol/schema/handshake_params.json @@ -1,16 +1,30 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "HandshakeParams", - "type": "object", - "required": [ - "browser", - "client", - "instance_id", - "label", - "protocol_version", - "version" - ], + "definitions": { + "BrowserPeerInfo": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "name", + "version" + ], + "type": "object" + } + }, + "description": "Current handshake envelope. The flattened identity remains source-compatible\nwith older Rust callers constructing `HandshakeParams` directly.", "properties": { + "audit_enabled": { + "type": [ + "boolean", + "null" + ] + }, "browser": { "$ref": "#/definitions/BrowserPeerInfo" }, @@ -24,7 +38,7 @@ "type": "string" }, "min_compatible_peer": { - "description": "**Deprecated** — legacy app-semver floor kept for wire compat with pre-protocol peers. New code sends `\"0.0.0\"` and ignores on read.", + "description": "**Deprecated** — legacy app-semver floor kept for wire compat with\npre-protocol peers. New code sends `\"0.0.0\"` and ignores on read.", "type": [ "string", "null" @@ -45,21 +59,14 @@ "type": "string" } }, - "definitions": { - "BrowserPeerInfo": { - "type": "object", - "required": [ - "name", - "version" - ], - "properties": { - "name": { - "type": "string" - }, - "version": { - "type": "string" - } - } - } - } + "required": [ + "client", + "version", + "protocol_version", + "instance_id", + "browser", + "label" + ], + "title": "HandshakeRequest", + "type": "object" } diff --git a/crates/bsk-protocol/schema/handshake_result.json b/crates/bsk-protocol/schema/handshake_result.json index 493e7a2ca..1f16655bc 100644 --- a/crates/bsk-protocol/schema/handshake_result.json +++ b/crates/bsk-protocol/schema/handshake_result.json @@ -1,15 +1,22 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "HandshakeResult", - "type": "object", - "required": [ - "protocol_version", - "server", - "version" - ], "properties": { + "audit_ready": { + "type": [ + "boolean", + "null" + ] + }, + "audit_version": { + "format": "uint32", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, "min_compatible_peer": { - "description": "**Deprecated** — legacy app-semver floor. New peers should use `min_compatible_protocol`; this field is optional and ignored.", + "description": "**Deprecated** — legacy app-semver floor. New peers should use\n`min_compatible_protocol`; this field is optional and ignored.", "type": [ "string", "null" @@ -31,5 +38,12 @@ "version": { "type": "string" } - } + }, + "required": [ + "server", + "version", + "protocol_version" + ], + "title": "HandshakeResponse", + "type": "object" } diff --git a/crates/bsk-protocol/schema/system_ping_params.json b/crates/bsk-protocol/schema/system_ping_params.json index 9d9152c99..25d751f35 100644 --- a/crates/bsk-protocol/schema/system_ping_params.json +++ b/crates/bsk-protocol/schema/system_ping_params.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PingParams", "description": "`system.ping` request payload. Empty (the response carries `pong`).", + "title": "PingParams", "type": "object" } diff --git a/crates/bsk-protocol/schema/system_ping_result.json b/crates/bsk-protocol/schema/system_ping_result.json index ff6abbd4c..00d6b39ff 100644 --- a/crates/bsk-protocol/schema/system_ping_result.json +++ b/crates/bsk-protocol/schema/system_ping_result.json @@ -1,14 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PingResult", "description": "`system.ping` response payload.", - "type": "object", - "required": [ - "pong" - ], "properties": { "pong": { "type": "boolean" } - } + }, + "required": [ + "pong" + ], + "title": "PingResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/system_status_params.json b/crates/bsk-protocol/schema/system_status_params.json index 379383824..212fc4759 100644 --- a/crates/bsk-protocol/schema/system_status_params.json +++ b/crates/bsk-protocol/schema/system_status_params.json @@ -1,17 +1,17 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StatusParams", "description": "`system.status` request payload.", - "type": "object", "properties": { "wait_for_browser_ms": { - "description": "When set, the daemon polls the browser registry for up to this many milliseconds before returning a snapshot. Only applies while zero browsers are registered; an existing connection returns immediately.", + "description": "When set, the daemon polls the browser registry for up to this many\nmilliseconds before returning a snapshot. Only applies while zero\nbrowsers are registered; an existing connection returns immediately.", + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] } - } + }, + "title": "StatusParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/system_status_result.json b/crates/bsk-protocol/schema/system_status_result.json index 75d331671..947727122 100644 --- a/crates/bsk-protocol/schema/system_status_result.json +++ b/crates/bsk-protocol/schema/system_status_result.json @@ -1,91 +1,15 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StatusResult", - "description": "`system.status` reply: daemon meta + connected browsers + live sessions.", - "type": "object", - "required": [ - "browsers", - "daemon_version", - "pid", - "protocol_version", - "sessions", - "sock_path", - "uptime_secs", - "ws_port" - ], - "properties": { - "browsers": { - "description": "Snapshot of connected extension clients.", - "type": "array", - "items": { - "$ref": "#/definitions/BrowserStatusEntry" - } - }, - "daemon_version": { - "description": "Semver of the daemon binary (`env!(\"CARGO_PKG_VERSION\")`).", - "type": "string" - }, - "pid": { - "description": "Daemon process id.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "protocol_version": { - "description": "Logical protocol revision (e.g. `\"1.0\"`).", - "type": "string" - }, - "sessions": { - "description": "Snapshot of live sessions.", - "type": "array", - "items": { - "$ref": "#/definitions/SessionStatusEntry" - } - }, - "sock_path": { - "description": "Absolute path of the IPC socket / named pipe handle.", - "type": "string" - }, - "uptime_secs": { - "description": "Daemon uptime in whole seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "version_skew_browsers": { - "description": "Subset of `browsers` whose `protocol_version` differs from the daemon's (minor drift, same major). Entries mirror `BrowserStatusEntry.version_skew`.", - "default": [], - "type": "array", - "items": { - "$ref": "#/definitions/VersionSkewEntry" - } - }, - "ws_port": { - "description": "WS port the daemon listens on for extension clients.", - "type": "integer", - "format": "uint16", - "minimum": 0.0 - } - }, "definitions": { "BorrowConfirmationPolicy": { - "type": "string", "enum": [ "always", "never" - ] + ], + "type": "string" }, "BrowserStatusEntry": { "description": "Snapshot of a single connected extension (extension client view).", - "type": "object", - "required": [ - "browser_name", - "browser_version", - "extension_version", - "instance_id", - "label", - "session_count" - ], "properties": { "browser_name": { "type": "string" @@ -94,14 +18,14 @@ "type": "string" }, "connected_at_ms": { - "description": "Unix epoch milliseconds at which the extension completed the daemon handshake. Stable across reconnects only via the best-effort registry generation; clients should treat this as a rough \"online since\" hint, not a strong identity.", "default": 0, - "type": "integer", - "format": "int64" + "description": "Unix epoch milliseconds at which the extension completed the\ndaemon handshake. Stable across reconnects only via the\nbest-effort registry generation; clients should treat this as a\nrough \"online since\" hint, not a strong identity.", + "format": "int64", + "type": "integer" }, "extension_protocol_version": { - "description": "Protocol version the extension advertised at handshake.", "default": "", + "description": "Protocol version the extension advertised at handshake.", "type": "string" }, "extension_version": { @@ -115,28 +39,32 @@ "type": "string" }, "session_count": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "unresponsive": { - "description": "The socket is still registered, but a call failed after this heartbeat-capable extension missed two heartbeats. Cleared when any frame arrives.", "default": false, + "description": "The socket is still registered, but a call failed after this\nheartbeat-capable extension missed two heartbeats. Cleared when any\nframe arrives.", "type": "boolean" }, "version_skew": { - "description": "`true` when the browser's `protocol_version` differs from the daemon's (same major, minor drift). Connection is still allowed.", "default": false, + "description": "`true` when the browser's `protocol_version` differs from the\ndaemon's (same major, minor drift). Connection is still allowed.", "type": "boolean" } - } - }, - "InteractionPolicy": { - "type": "object", + }, "required": [ - "borrow_confirmation", - "request_help" + "instance_id", + "browser_name", + "browser_version", + "extension_version", + "label", + "session_count" ], + "type": "object" + }, + "InteractionPolicy": { "properties": { "borrow_confirmation": { "$ref": "#/definitions/BorrowConfirmationPolicy" @@ -144,38 +72,37 @@ "request_help": { "$ref": "#/definitions/RequestHelpPolicy" } - } + }, + "required": [ + "borrow_confirmation", + "request_help" + ], + "type": "object" }, "RequestHelpPolicy": { - "type": "string", "enum": [ "enabled", "disabled" - ] + ], + "type": "string" }, "SessionStatusEntry": { "description": "Snapshot of a single live session.", - "type": "object", - "required": [ - "browser_instance_id", - "created_at_ms", - "session_id" - ], "properties": { "agent_window_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "browser_instance_id": { "type": "string" }, "created_at_ms": { "description": "Unix epoch milliseconds.", - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "interaction": { "anyOf": [ @@ -190,25 +117,23 @@ "session_id": { "type": "string" } - } - }, - "VersionSkewEntry": { - "description": "One entry per connected browser whose protocol version drifts from the daemon's (same major). Surfaced in `system.status` for `bsk status` / `bsk doctor` / popup \"warn but allow\" UX.", - "type": "object", + }, "required": [ - "browser_name", - "client_version", - "instance_id", - "label", - "server_version" + "session_id", + "browser_instance_id", + "created_at_ms" ], + "type": "object" + }, + "VersionSkewEntry": { + "description": "One entry per connected browser whose protocol version drifts from\nthe daemon's (same major). Surfaced in `system.status` for\n`bsk status` / `bsk doctor` / popup \"warn but allow\" UX.", "properties": { "browser_name": { "type": "string" }, "client_protocol_version": { - "description": "Extension `protocol_version` from handshake.", "default": "", + "description": "Extension `protocol_version` from handshake.", "type": "string" }, "client_version": { @@ -222,15 +147,91 @@ "type": "string" }, "server_protocol_version": { - "description": "Daemon `protocol_version` at snapshot time.", "default": "", + "description": "Daemon `protocol_version` at snapshot time.", "type": "string" }, "server_version": { "description": "Daemon app semver at snapshot time (informational).", "type": "string" } - } + }, + "required": [ + "instance_id", + "browser_name", + "label", + "server_version", + "client_version" + ], + "type": "object" } - } + }, + "description": "`system.status` reply: daemon meta + connected browsers + live sessions.", + "properties": { + "browsers": { + "description": "Snapshot of connected extension clients.", + "items": { + "$ref": "#/definitions/BrowserStatusEntry" + }, + "type": "array" + }, + "daemon_version": { + "description": "Semver of the daemon binary (`env!(\"CARGO_PKG_VERSION\")`).", + "type": "string" + }, + "pid": { + "description": "Daemon process id.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "protocol_version": { + "description": "Logical protocol revision (e.g. `\"1.0\"`).", + "type": "string" + }, + "sessions": { + "description": "Snapshot of live sessions.", + "items": { + "$ref": "#/definitions/SessionStatusEntry" + }, + "type": "array" + }, + "sock_path": { + "description": "Absolute path of the IPC socket / named pipe handle.", + "type": "string" + }, + "uptime_secs": { + "description": "Daemon uptime in whole seconds.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "version_skew_browsers": { + "default": [], + "description": "Subset of `browsers` whose `protocol_version` differs from the\ndaemon's (minor drift, same major). Entries mirror\n`BrowserStatusEntry.version_skew`.", + "items": { + "$ref": "#/definitions/VersionSkewEntry" + }, + "type": "array" + }, + "ws_port": { + "description": "WS port the daemon listens on for extension clients.", + "format": "uint16", + "maximum": 65535, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "daemon_version", + "protocol_version", + "pid", + "uptime_secs", + "ws_port", + "sock_path", + "browsers", + "sessions" + ], + "title": "StatusResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_blur_params.json b/crates/bsk-protocol/schema/tool_blur_params.json index 525886ebe..b04b776f2 100644 --- a/crates/bsk-protocol/schema/tool_blur_params.json +++ b/crates/bsk-protocol/schema/tool_blur_params.json @@ -1,13 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlurParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "ref": { - "description": "Optional `@e` ref allocated by the last observation. Mutually exclusive with `selector`.", + "description": "Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.", "type": [ "string", "null" @@ -24,19 +19,24 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "BlurParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_blur_result.json b/crates/bsk-protocol/schema/tool_blur_result.json index fa2e353bb..8925ebe0c 100644 --- a/crates/bsk-protocol/schema/tool_blur_result.json +++ b/crates/bsk-protocol/schema/tool_blur_result.json @@ -1,63 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlurResult", - "type": "object", - "required": [ - "focused", - "tab_id", - "was_focused" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "focused": { - "description": "Always false for a successful blur; included for machine verification.", - "type": "boolean" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "was_focused": { - "description": "Whether the target held focus before the call.", - "type": "boolean" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -79,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -96,17 +49,64 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "focused": { + "description": "Always false for a successful blur; included for machine verification.", + "type": "boolean" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" + ] + }, + "used_selector": { + "type": [ + "string", + "null" ] + }, + "was_focused": { + "description": "Whether the target held focus before the call.", + "type": "boolean" } - } + }, + "required": [ + "tab_id", + "was_focused", + "focused" + ], + "title": "BlurResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_click_params.json b/crates/bsk-protocol/schema/tool_click_params.json index 5a341e573..857ce03a5 100644 --- a/crates/bsk-protocol/schema/tool_click_params.json +++ b/crates/bsk-protocol/schema/tool_click_params.json @@ -1,10 +1,26 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClickParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + }, + "MouseButton": { + "description": "Mouse button selector for `tool.click`.", + "enum": [ + "left", + "middle", + "right" + ], + "type": "string" + } + }, "properties": { "button": { "anyOf": [ @@ -25,38 +41,38 @@ }, "click_count": { "description": "Number of consecutive mouse presses (double-click = 2).", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "image_x": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "image_y": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "ref": { - "description": "Optional `@e` ref allocated by the last `tool.snapshot`. Mutually exclusive with `selector` (caller must supply exactly one). Accepts both `\"e3\"` and `\"@e3\"`.", + "description": "Optional `@e` ref allocated by the last `tool.snapshot`.\nMutually exclusive with `selector` (caller must supply exactly\none). Accepts both `\"e3\"` and `\"@e3\"`.", "type": [ "string", "null" @@ -73,40 +89,24 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 - } - }, - "definitions": { - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" - ] - }, - "MouseButton": { - "description": "Mouse button selector for `tool.click`.", - "type": "string", - "enum": [ - "left", - "middle", - "right" ] } - } + }, + "required": [ + "session_id" + ], + "title": "ClickParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_click_result.json b/crates/bsk-protocol/schema/tool_click_result.json index 3ee6f752a..901676c61 100644 --- a/crates/bsk-protocol/schema/tool_click_result.json +++ b/crates/bsk-protocol/schema/tool_click_result.json @@ -1,65 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ClickResult", - "type": "object", - "required": [ - "tab_id", - "x", - "y" - ], - "properties": { - "dialogs": { - "description": "Native JS dialogs observed and auto-handled during this call.", - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "x": { - "description": "Viewport-relative click coordinates (CSS pixels). Reported so agents can correlate with a follow-up `tool.screenshot`.", - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -81,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -98,17 +49,66 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "description": "Native JS dialogs observed and auto-handled during this call.", + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" ] + }, + "used_selector": { + "type": [ + "string", + "null" + ] + }, + "x": { + "description": "Viewport-relative click coordinates (CSS pixels). Reported so\nagents can correlate with a follow-up `tool.screenshot`.", + "format": "double", + "type": "number" + }, + "y": { + "format": "double", + "type": "number" } - } + }, + "required": [ + "tab_id", + "x", + "y" + ], + "title": "ClickResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_console_entry.json b/crates/bsk-protocol/schema/tool_console_entry.json index fdab718d6..d88204643 100644 --- a/crates/bsk-protocol/schema/tool_console_entry.json +++ b/crates/bsk-protocol/schema/tool_console_entry.json @@ -1,20 +1,53 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConsoleEntry", - "type": "object", - "required": [ - "kind", - "level", - "sequence", - "text" - ], + "definitions": { + "ConsoleEntryKind": { + "enum": [ + "console", + "exception", + "log" + ], + "type": "string" + }, + "ConsoleStackFrame": { + "properties": { + "column": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "function_name": { + "type": [ + "string", + "null" + ] + }, + "line": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + } + }, "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "kind": { "$ref": "#/definitions/ConsoleEntryKind" @@ -23,32 +56,32 @@ "type": "string" }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "stack_trace": { - "type": "array", "items": { "$ref": "#/definitions/ConsoleStackFrame" - } + }, + "type": "array" }, "text": { "type": "string" }, "timestamp": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "truncated": { "default": false, @@ -61,45 +94,12 @@ ] } }, - "definitions": { - "ConsoleEntryKind": { - "type": "string", - "enum": [ - "console", - "exception", - "log" - ] - }, - "ConsoleStackFrame": { - "type": "object", - "properties": { - "column": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "function_name": { - "type": [ - "string", - "null" - ] - }, - "line": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "url": { - "type": [ - "string", - "null" - ] - } - } - } - } + "required": [ + "sequence", + "kind", + "level", + "text" + ], + "title": "ConsoleEntry", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_console_params.json b/crates/bsk-protocol/schema/tool_console_params.json index ff66a2cf8..9a48347f8 100644 --- a/crates/bsk-protocol/schema/tool_console_params.json +++ b/crates/bsk-protocol/schema/tool_console_params.json @@ -1,10 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConsoleParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "include_stack": { "description": "Include structured stack frames. Defaults to false.", @@ -15,41 +10,46 @@ }, "limit": { "description": "Maximum number of entries to return. Extension applies safe defaults and caps.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "max_text_chars": { "description": "Maximum characters returned per entry text. Extension applies safe defaults and caps.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "session_id": { "type": "string" }, "since": { "description": "Return entries with sequence strictly greater than this cursor.", + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "tab_id": { "description": "Optional target tab. Defaults to the Agent Window's currently active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "ConsoleParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_console_result.json b/crates/bsk-protocol/schema/tool_console_result.json index 73f96a6e4..5d41c49c2 100644 --- a/crates/bsk-protocol/schema/tool_console_result.json +++ b/crates/bsk-protocol/schema/tool_console_result.json @@ -1,48 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConsoleResult", - "type": "object", - "required": [ - "next_since", - "tab_id" - ], - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/ConsoleEntry" - } - }, - "next_since": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "truncated": { - "default": false, - "type": "boolean" - } - }, "definitions": { "ConsoleEntry": { - "type": "object", - "required": [ - "kind", - "level", - "sequence", - "text" - ], "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "kind": { "$ref": "#/definitions/ConsoleEntryKind" @@ -51,32 +17,32 @@ "type": "string" }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "stack_trace": { - "type": "array", "items": { "$ref": "#/definitions/ConsoleStackFrame" - } + }, + "type": "array" }, "text": { "type": "string" }, "timestamp": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "truncated": { "default": false, @@ -88,25 +54,31 @@ "null" ] } - } + }, + "required": [ + "sequence", + "kind", + "level", + "text" + ], + "type": "object" }, "ConsoleEntryKind": { - "type": "string", "enum": [ "console", "exception", "log" - ] + ], + "type": "string" }, "ConsoleStackFrame": { - "type": "object", "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "function_name": { "type": [ @@ -115,11 +87,11 @@ ] }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "url": { "type": [ @@ -127,7 +99,36 @@ "null" ] } - } + }, + "type": "object" } - } + }, + "properties": { + "entries": { + "default": [], + "items": { + "$ref": "#/definitions/ConsoleEntry" + }, + "type": "array" + }, + "next_since": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "truncated": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "tab_id", + "next_since" + ], + "title": "ConsoleResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_console_stack_frame.json b/crates/bsk-protocol/schema/tool_console_stack_frame.json index a3628004c..1c8a0e404 100644 --- a/crates/bsk-protocol/schema/tool_console_stack_frame.json +++ b/crates/bsk-protocol/schema/tool_console_stack_frame.json @@ -1,14 +1,12 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConsoleStackFrame", - "type": "object", "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "function_name": { "type": [ @@ -17,11 +15,11 @@ ] }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "url": { "type": [ @@ -29,5 +27,7 @@ "null" ] } - } + }, + "title": "ConsoleStackFrame", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_debug_params.json b/crates/bsk-protocol/schema/tool_debug_params.json index ab6bed8a2..30f4308c7 100644 --- a/crates/bsk-protocol/schema/tool_debug_params.json +++ b/crates/bsk-protocol/schema/tool_debug_params.json @@ -1,210 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DebugParams", - "type": "object", - "required": [ - "action", - "session_id" - ], - "properties": { - "action": { - "$ref": "#/definitions/DebugAction" - }, - "budget": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 262144.0, - "minimum": 4096.0 - }, - "command_id": { - "type": [ - "string", - "null" - ] - }, - "fields": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "id": { - "type": [ - "string", - "null" - ] - }, - "include_controlled": { - "type": [ - "boolean", - "null" - ] - }, - "kind": { - "type": [ - "string", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 100.0, - "minimum": 1.0 - }, - "max_chars": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 16384.0, - "minimum": 1.0 - }, - "method": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": [ - "string", - "null" - ] - }, - "offset": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 65536.0, - "minimum": 0.0 - }, - "part": { - "type": [ - "string", - "null" - ] - }, - "pointer": { - "type": [ - "string", - "null" - ] - }, - "replay": { - "anyOf": [ - { - "$ref": "#/definitions/DebugReplaySpec" - }, - { - "type": "null" - } - ] - }, - "resource_type": { - "type": [ - "string", - "null" - ] - }, - "rule": { - "anyOf": [ - { - "$ref": "#/definitions/DebugRuleSpec" - }, - { - "type": "null" - } - ] - }, - "run_id": { - "type": [ - "string", - "null" - ] - }, - "session_id": { - "type": "string" - }, - "since": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "slow_ms": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 60000.0, - "minimum": 0.0 - }, - "state": { - "type": [ - "string", - "null" - ] - }, - "status": { - "type": [ - "integer", - "null" - ], - "format": "uint16", - "maximum": 599.0, - "minimum": 100.0 - }, - "tab_id": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "url": { - "type": [ - "string", - "null" - ] - }, - "wait_ms": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 60000.0, - "minimum": 0.0 - }, - "window_ms": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "maximum": 10000.0, - "minimum": 100.0 - } - }, "definitions": { "DebugAction": { - "type": "string", "enum": [ "performance", "aggregate", @@ -230,44 +27,42 @@ "rule_disable", "rule_remove", "replay" - ] + ], + "type": "string" }, "DebugJsonEdit": { - "type": "object", + "additionalProperties": false, "properties": { "remove": { + "items": { + "type": "string" + }, "type": [ "array", "null" - ], - "items": { - "type": "string" - } + ] }, "rename": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "set": { + "additionalProperties": true, "type": [ "object", "null" - ], - "additionalProperties": true + ] } }, - "additionalProperties": false + "type": "object" }, "DebugReplaySpec": { - "type": "object", - "required": [ - "key" - ], + "additionalProperties": false, "properties": { "body": { "type": [ @@ -276,16 +71,16 @@ ] }, "headers": { - "type": [ - "object", - "null" - ], "additionalProperties": { "type": [ "string", "null" ] - } + }, + "type": [ + "object", + "null" + ] }, "key": { "type": "string" @@ -303,30 +98,28 @@ ] } }, - "additionalProperties": false + "required": [ + "key" + ], + "type": "object" }, "DebugRuleEffect": { "oneOf": [ { - "type": "object", - "required": [ - "type" - ], + "additionalProperties": false, "properties": { "type": { - "type": "string", - "enum": [ - "block" - ] + "const": "block", + "type": "string" } }, - "additionalProperties": false - }, - { - "type": "object", "required": [ "type" ], + "type": "object" + }, + { + "additionalProperties": false, "properties": { "body": { "type": [ @@ -335,16 +128,16 @@ ] }, "headers": { - "type": [ - "object", - "null" - ], "additionalProperties": { "type": [ "string", "null" ] - } + }, + "type": [ + "object", + "null" + ] }, "json": { "anyOf": [ @@ -363,10 +156,8 @@ ] }, "type": { - "type": "string", - "enum": [ - "modify" - ] + "const": "modify", + "type": "string" }, "url": { "type": [ @@ -375,57 +166,56 @@ ] } }, - "additionalProperties": false - }, - { - "type": "object", "required": [ - "body", - "status", "type" ], + "type": "object" + }, + { + "additionalProperties": false, "properties": { "body": { "type": "string" }, "delay_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "headers": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "status": { - "type": "integer", "format": "uint16", - "minimum": 0.0 + "maximum": 65535, + "minimum": 0, + "type": "integer" }, "type": { - "type": "string", - "enum": [ - "mock" - ] + "const": "mock", + "type": "string" } }, - "additionalProperties": false + "required": [ + "type", + "status", + "body" + ], + "type": "object" } ] }, "DebugRuleMatch": { - "type": "object", - "required": [ - "url" - ], + "additionalProperties": false, "properties": { "method": { "type": [ @@ -443,14 +233,12 @@ "type": "string" } }, - "additionalProperties": false - }, - "DebugRuleSpec": { - "type": "object", "required": [ - "effect", - "match" + "url" ], + "type": "object" + }, + "DebugRuleSpec": { "properties": { "effect": { "$ref": "#/definitions/DebugRuleEffect" @@ -465,14 +253,221 @@ ] }, "times": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "required": [ + "match", + "effect" + ], + "type": "object" } - } + }, + "properties": { + "action": { + "$ref": "#/definitions/DebugAction" + }, + "budget": { + "format": "uint32", + "maximum": 262144, + "minimum": 4096, + "type": [ + "integer", + "null" + ] + }, + "command_id": { + "type": [ + "string", + "null" + ] + }, + "fields": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "id": { + "type": [ + "string", + "null" + ] + }, + "include_controlled": { + "type": [ + "boolean", + "null" + ] + }, + "kind": { + "type": [ + "string", + "null" + ] + }, + "limit": { + "format": "uint32", + "maximum": 100, + "minimum": 1, + "type": [ + "integer", + "null" + ] + }, + "max_chars": { + "format": "uint32", + "maximum": 16384, + "minimum": 1, + "type": [ + "integer", + "null" + ] + }, + "method": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "offset": { + "format": "uint32", + "maximum": 65536, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "part": { + "type": [ + "string", + "null" + ] + }, + "pointer": { + "type": [ + "string", + "null" + ] + }, + "replay": { + "anyOf": [ + { + "$ref": "#/definitions/DebugReplaySpec" + }, + { + "type": "null" + } + ] + }, + "resource_type": { + "type": [ + "string", + "null" + ] + }, + "rule": { + "anyOf": [ + { + "$ref": "#/definitions/DebugRuleSpec" + }, + { + "type": "null" + } + ] + }, + "run_id": { + "type": [ + "string", + "null" + ] + }, + "session_id": { + "type": "string" + }, + "since": { + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "slow_ms": { + "format": "uint32", + "maximum": 60000, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "state": { + "type": [ + "string", + "null" + ] + }, + "status": { + "format": "uint16", + "maximum": 599, + "minimum": 100, + "type": [ + "integer", + "null" + ] + }, + "tab_id": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "url": { + "type": [ + "string", + "null" + ] + }, + "wait_ms": { + "format": "uint32", + "maximum": 60000, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "window_ms": { + "format": "uint32", + "maximum": 10000, + "minimum": 100, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "session_id", + "action" + ], + "title": "DebugParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_debug_result.json b/crates/bsk-protocol/schema/tool_debug_result.json index 5afed77d8..0e3413529 100644 --- a/crates/bsk-protocol/schema/tool_debug_result.json +++ b/crates/bsk-protocol/schema/tool_debug_result.json @@ -1,216 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DebugResult", - "type": "object", - "required": [ - "session_id" - ], - "properties": { - "activity": { - "anyOf": [ - { - "$ref": "#/definitions/DebugActivity" - }, - { - "type": "null" - } - ] - }, - "aggregates": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugEndpoint" - } - }, - "analysis": { - "anyOf": [ - { - "$ref": "#/definitions/DebugAnalysis" - }, - { - "type": "null" - } - ] - }, - "capabilities": true, - "console": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugConsole" - } - }, - "duplicates": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugDuplicate" - } - }, - "evidence": { - "anyOf": [ - { - "$ref": "#/definitions/DebugEvidence" - }, - { - "type": "null" - } - ] - }, - "next_offset": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "next_since": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "operation": { - "anyOf": [ - { - "$ref": "#/definitions/DebugOperation" - }, - { - "type": "null" - } - ] - }, - "operations": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugOperation" - } - }, - "output": true, - "pages": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugPage" - } - }, - "performance": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugPerformance" - } - }, - "recording": { - "anyOf": [ - { - "$ref": "#/definitions/DebugRecording" - }, - { - "type": "null" - } - ] - }, - "replay": { - "anyOf": [ - { - "$ref": "#/definitions/DebugReplay" - }, - { - "type": "null" - } - ] - }, - "replays": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugReplay" - } - }, - "request": { - "anyOf": [ - { - "$ref": "#/definitions/DebugRequest" - }, - { - "type": "null" - } - ] - }, - "requests": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugRequest" - } - }, - "rules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugRule" - } - }, - "run": { - "anyOf": [ - { - "$ref": "#/definitions/DebugRun" - }, - { - "type": "null" - } - ] - }, - "runs": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/DebugRun" - } - }, - "session_id": { - "type": "string" - }, - "truncated": { - "type": [ - "boolean", - "null" - ] - } - }, "definitions": { "DebugActivity": { "description": "Daemon-owned execution status. Waiting observes completion; it never resends a command.", - "type": "object", - "required": [ - "state" - ], "properties": { "command_id": { "type": [ @@ -219,12 +11,12 @@ ] }, "elapsed_ms": { + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "method": { "type": [ @@ -233,12 +25,12 @@ ] }, "started_at": { + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "state": { "type": "string" @@ -255,109 +47,109 @@ "null" ] } - } - }, - "DebugAnalysis": { - "type": "object", + }, "required": [ - "coverage", - "excluded_controlled", - "groups", - "included", - "matched", - "retained", - "semantics", - "slow_ms", - "suspected_extra_requests", - "uncomparable", - "window_ms" + "state" ], + "type": "object" + }, + "DebugAnalysis": { "properties": { "coverage": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "excluded_controlled": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "groups": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "included": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "matched": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "retained": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "semantics": { "type": "string" }, "slow_ms": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "suspected_extra_requests": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "uncomparable": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "window_ms": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } - }, - "DebugBody": { - "type": "object", + }, "required": [ - "state" + "retained", + "matched", + "included", + "excluded_controlled", + "uncomparable", + "groups", + "suspected_extra_requests", + "window_ms", + "slow_ms", + "coverage", + "semantics" ], + "type": "object" + }, + "DebugBody": { "properties": { "chars": { + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "next_offset": { + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "offset": { + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "reason": { "type": [ @@ -387,34 +179,29 @@ "null" ] } - } - }, - "DebugConsole": { - "type": "object", + }, "required": [ - "at", - "count", - "id", - "last_at", - "level", - "text" + "state" ], + "type": "object" + }, + "DebugConsole": { "properties": { "at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "count": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "id": { "type": "string" }, "last_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "level": { "type": "string" @@ -446,38 +233,32 @@ "text": { "type": "string" } - } - }, - "DebugDuplicate": { - "type": "object", + }, "required": [ - "count", - "ended_at", - "extra_requests", "id", - "method", - "operation_ids", - "overlap_count", - "possible_retry", - "refs_truncated", - "request_ids", - "started_at", - "url" + "at", + "level", + "text", + "count", + "last_at" ], + "type": "object" + }, + "DebugDuplicate": { "properties": { "count": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "ended_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "extra_requests": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "id": { "type": "string" @@ -486,15 +267,15 @@ "type": "string" }, "operation_ids": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "overlap_count": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "possible_retry": { "type": "boolean" @@ -503,95 +284,88 @@ "type": "boolean" }, "request_ids": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "started_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "url": { "type": "string" } - } - }, - "DebugDurationStats": { - "type": "object", + }, "required": [ - "max", - "mean", - "min", - "p50", - "p95", - "total" + "id", + "method", + "url", + "count", + "extra_requests", + "started_at", + "ended_at", + "overlap_count", + "possible_retry", + "request_ids", + "operation_ids", + "refs_truncated" ], + "type": "object" + }, + "DebugDurationStats": { "properties": { "max": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "mean": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "min": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "p50": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "p95": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "total": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" } - } - }, - "DebugEndpoint": { - "type": "object", + }, "required": [ - "cached", - "controlled", - "count", - "endpoint", - "failed", - "http_errors", - "id", - "interrupted", - "method", - "pending", - "refs_truncated", - "replayed", - "request_ids", - "service_worker", - "slow", - "statuses", - "timing_samples", - "transfer_bytes", - "transfer_samples" + "min", + "mean", + "p50", + "p95", + "max", + "total" ], + "type": "object" + }, + "DebugEndpoint": { "properties": { "cached": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "controlled": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "count": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "duration_ms": { "anyOf": [ @@ -607,132 +381,148 @@ "type": "string" }, "failed": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "http_errors": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "id": { "type": "string" }, "interrupted": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "method": { "type": "string" }, "pending": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "refs_truncated": { "type": "boolean" }, "replayed": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "request_ids": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "service_worker": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "slow": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "statuses": { - "type": "object", "additionalProperties": { - "type": "integer", "format": "uint64", - "minimum": 0.0 - } + "minimum": 0, + "type": "integer" + }, + "type": "object" }, "timing_samples": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "transfer_bytes": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "transfer_samples": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } - }, - "DebugEvidence": { - "type": "object", + }, "required": [ - "changes", - "fields", - "gaps", - "links", - "observations", - "payloads" + "id", + "method", + "endpoint", + "count", + "failed", + "http_errors", + "pending", + "interrupted", + "statuses", + "slow", + "timing_samples", + "transfer_bytes", + "transfer_samples", + "cached", + "service_worker", + "controlled", + "replayed", + "request_ids", + "refs_truncated" ], + "type": "object" + }, + "DebugEvidence": { "properties": { "changes": { "$ref": "#/definitions/DebugTextChanges" }, "fields": { - "type": "array", "items": { "$ref": "#/definitions/DebugFieldTrace" - } + }, + "type": "array" }, "gaps": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "links": { - "type": "array", "items": { "$ref": "#/definitions/DebugRequestLink" - } + }, + "type": "array" }, "observations": { - "type": "array", "items": { "$ref": "#/definitions/DebugPage" - } + }, + "type": "array" }, "payloads": { - "type": "array", "items": { "$ref": "#/definitions/DebugPayload" - } + }, + "type": "array" } - } - }, - "DebugField": { - "type": "object", + }, "required": [ - "key", - "label", - "state" + "fields", + "payloads", + "links", + "gaps", + "changes", + "observations" ], + "type": "object" + }, + "DebugField": { "properties": { "key": { "type": "string" @@ -755,19 +545,15 @@ "null" ] } - } - }, - "DebugFieldTrace": { - "type": "object", + }, "required": [ - "before", - "input", "key", "label", - "later", - "response", - "submitted" + "state" ], + "type": "object" + }, + "DebugFieldTrace": { "properties": { "before": { "$ref": "#/definitions/DebugValue" @@ -785,35 +571,39 @@ "$ref": "#/definitions/DebugValue" }, "response": { - "type": "array", "items": { "$ref": "#/definitions/DebugValue" - } + }, + "type": "array" }, "submitted": { - "type": "array", "items": { "$ref": "#/definitions/DebugValue" - } + }, + "type": "array" } - } - }, - "DebugIntervention": { - "type": "object", + }, "required": [ - "rule_id", - "state", - "type" + "key", + "label", + "before", + "input", + "submitted", + "response", + "later" ], + "type": "object" + }, + "DebugIntervention": { "properties": { "changes": { + "items": { + "type": "string" + }, "type": [ "array", "null" - ], - "items": { - "type": "string" - } + ] }, "error": { "type": [ @@ -828,96 +618,98 @@ "type": "string" }, "type": { - "type": "string" + "$ref": "#/definitions/DebugInterventionKind" } - } + }, + "required": [ + "rule_id", + "type", + "state" + ], + "type": "object" + }, + "DebugInterventionKind": { + "enum": [ + "block", + "modify", + "mock" + ], + "type": "string" }, "DebugJsonEdit": { - "type": "object", + "additionalProperties": false, "properties": { "remove": { + "items": { + "type": "string" + }, "type": [ "array", "null" - ], - "items": { - "type": "string" - } + ] }, "rename": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "set": { + "additionalProperties": true, "type": [ "object", "null" - ], - "additionalProperties": true + ] } }, - "additionalProperties": false + "type": "object" }, "DebugLongTask": { - "type": "object", - "required": [ - "at", - "duration_ms" - ], "properties": { "at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "duration_ms": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" } - } - }, - "DebugMetric": { - "type": "object", + }, "required": [ - "reasons", - "state" + "at", + "duration_ms" ], + "type": "object" + }, + "DebugMetric": { "properties": { "reasons": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "state": { "type": "string" }, "value": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] } - } - }, - "DebugOperation": { - "type": "object", + }, "required": [ - "console_ids", - "id", - "method", - "request_ids", - "run_id", - "sequence", - "started_at", "state", - "truncated" + "reasons" ], + "type": "object" + }, + "DebugOperation": { "properties": { "after": { "anyOf": [ @@ -940,10 +732,10 @@ ] }, "console_ids": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "error": { "type": [ @@ -952,11 +744,11 @@ ] }, "finished_at": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "id": { "type": "string" @@ -965,11 +757,11 @@ "type": "string" }, "observation_end": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "observation_limited": { "type": [ @@ -978,27 +770,27 @@ ] }, "observations": { + "items": { + "$ref": "#/definitions/DebugPage" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/DebugPage" - } + ] }, "request_ids": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "run_id": { "type": "string" }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "source": { "type": [ @@ -1007,11 +799,11 @@ ] }, "started_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "state": { - "type": "string" + "$ref": "#/definitions/DebugOperationState" }, "target": { "type": [ @@ -1023,33 +815,74 @@ "type": "boolean" }, "window_end": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] } - } + }, + "required": [ + "id", + "run_id", + "sequence", + "method", + "started_at", + "state", + "request_ids", + "console_ids", + "truncated" + ], + "type": "object" }, - "DebugPage": { - "type": "object", + "DebugOperationState": { + "enum": [ + "running", + "completed", + "error", + "interrupted" + ], + "type": "string" + }, + "DebugOutput": { + "description": "Reports how the requested output budget affected a debug response.", + "properties": { + "budget": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "omitted": { + "items": { + "type": "string" + }, + "type": "array" + }, + "truncated": { + "type": "boolean" + } + }, "required": [ - "at", - "state" + "budget", + "truncated", + "omitted" ], + "type": "object" + }, + "DebugPage": { "properties": { "at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "fields": { + "items": { + "$ref": "#/definitions/DebugField" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/DebugField" - } + ] }, "fields_partial": { "type": [ @@ -1090,16 +923,14 @@ "null" ] } - } + }, + "required": [ + "at", + "state" + ], + "type": "object" }, "DebugPayload": { - "type": "object", - "required": [ - "part", - "path", - "request_id", - "value" - ], "properties": { "part": { "type": "string" @@ -1119,35 +950,22 @@ "value": { "type": "string" } - } - }, - "DebugPerformance": { - "type": "object", + }, "required": [ - "coverage", - "document_key", - "early", - "id", - "long_tasks", - "long_tasks_truncated", - "metrics", - "navigation", - "observed_at", - "scope", - "sequence", - "started_at", - "state", - "time_origin", - "url", - "visibility", - "visibility_truncated" + "request_id", + "part", + "path", + "value" ], + "type": "object" + }, + "DebugPerformance": { "properties": { "coverage": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "document_key": { "type": "string" @@ -1159,145 +977,158 @@ "type": "string" }, "long_tasks": { - "type": "array", "items": { "$ref": "#/definitions/DebugLongTask" - } + }, + "type": "array" }, "long_tasks_truncated": { "type": "boolean" }, "metrics": { - "type": "object", "additionalProperties": { "$ref": "#/definitions/DebugMetric" - } + }, + "type": "object" }, "navigation": { "type": "string" }, "observed_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "scope": { "type": "string" }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "started_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "state": { "type": "string" }, "time_origin": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "url": { "type": "string" }, "visibility": { - "type": "array", "items": { "$ref": "#/definitions/DebugVisibility" - } + }, + "type": "array" }, "visibility_truncated": { "type": "boolean" } - } - }, - "DebugRecording": { - "type": "object", + }, "required": [ - "console", - "operations", - "pages", - "requests", - "run", - "saved_at", - "version" + "id", + "document_key", + "sequence", + "time_origin", + "started_at", + "observed_at", + "url", + "navigation", + "state", + "early", + "scope", + "visibility", + "visibility_truncated", + "metrics", + "long_tasks", + "long_tasks_truncated", + "coverage" ], + "type": "object" + }, + "DebugRecording": { "properties": { "console": { - "type": "array", "items": { "$ref": "#/definitions/DebugConsole" - } + }, + "type": "array" }, "operations": { - "type": "array", "items": { "$ref": "#/definitions/DebugOperation" - } + }, + "type": "array" }, "pages": { - "type": "array", "items": { "$ref": "#/definitions/DebugPage" - } + }, + "type": "array" }, "performance": { + "items": { + "$ref": "#/definitions/DebugPerformance" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/DebugPerformance" - } + ] }, "replays": { + "items": { + "$ref": "#/definitions/DebugReplay" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/DebugReplay" - } + ] }, "requests": { - "type": "array", "items": { "$ref": "#/definitions/DebugRequest" - } + }, + "type": "array" }, "rules": { + "items": { + "$ref": "#/definitions/DebugRule" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/DebugRule" - } + ] }, "run": { "$ref": "#/definitions/DebugRun" }, "saved_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "version": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } - }, - "DebugReplay": { - "type": "object", + }, "required": [ - "id", - "key", - "source_request_id", - "state" + "version", + "saved_at", + "run", + "requests", + "operations", + "console", + "pages" ], + "type": "object" + }, + "DebugReplay": { "properties": { "error": { "type": [ @@ -1323,35 +1154,30 @@ "state": { "type": "string" } - } - }, - "DebugRequest": { - "type": "object", + }, "required": [ "id", - "method", - "request_body", - "response_body", - "run_id", - "sequence", - "started_at", - "state", - "url" + "key", + "source_request_id", + "state" ], + "type": "object" + }, + "DebugRequest": { "properties": { "decoded_bytes": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "duration_ms": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "error": { "type": [ @@ -1360,11 +1186,11 @@ ] }, "finished_at": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "frame_id": { "type": [ @@ -1456,13 +1282,13 @@ "$ref": "#/definitions/DebugBody" }, "request_headers": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "resource_type": { "type": [ @@ -1474,53 +1300,53 @@ "$ref": "#/definitions/DebugBody" }, "response_headers": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "run_id": { "type": "string" }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "started_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "state": { "type": "string" }, "status": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "timing": { + "additionalProperties": { + "format": "double", + "type": "number" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "number", - "format": "double" - } + ] }, "transfer_bytes": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "truncated": { "type": [ @@ -1531,14 +1357,21 @@ "url": { "type": "string" } - } - }, - "DebugRequestIntegrity": { - "type": "object", + }, "required": [ - "metadata", - "url" + "id", + "run_id", + "sequence", + "started_at", + "method", + "url", + "state", + "request_body", + "response_body" ], + "type": "object" + }, + "DebugRequestIntegrity": { "properties": { "metadata": { "description": "Request metadata needed for replay; excludes response headers.", @@ -1553,14 +1386,14 @@ "url": { "type": "string" } - } - }, - "DebugRequestLink": { - "type": "object", + }, "required": [ - "relation", - "request_id" + "url", + "metadata" ], + "type": "object" + }, + "DebugRequestLink": { "properties": { "relation": { "type": "string" @@ -1568,36 +1401,31 @@ "request_id": { "type": "string" } - } - }, - "DebugRule": { - "type": "object", + }, "required": [ - "created_at", - "effect", - "failures", - "hits", - "id", - "match", - "state" + "request_id", + "relation" ], + "type": "object" + }, + "DebugRule": { "properties": { "created_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "effect": { "$ref": "#/definitions/DebugRuleEffect" }, "failures": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "hits": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "id": { "type": "string" @@ -1618,40 +1446,45 @@ ] }, "state": { - "type": "string" + "$ref": "#/definitions/DebugRuleState" }, "times": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "required": [ + "match", + "effect", + "id", + "state", + "hits", + "failures", + "created_at" + ], + "type": "object" }, "DebugRuleEffect": { "oneOf": [ { - "type": "object", - "required": [ - "type" - ], + "additionalProperties": false, "properties": { "type": { - "type": "string", - "enum": [ - "block" - ] + "const": "block", + "type": "string" } }, - "additionalProperties": false - }, - { - "type": "object", "required": [ "type" ], + "type": "object" + }, + { + "additionalProperties": false, "properties": { "body": { "type": [ @@ -1660,16 +1493,16 @@ ] }, "headers": { - "type": [ - "object", - "null" - ], "additionalProperties": { "type": [ "string", "null" ] - } + }, + "type": [ + "object", + "null" + ] }, "json": { "anyOf": [ @@ -1688,10 +1521,8 @@ ] }, "type": { - "type": "string", - "enum": [ - "modify" - ] + "const": "modify", + "type": "string" }, "url": { "type": [ @@ -1700,57 +1531,56 @@ ] } }, - "additionalProperties": false - }, - { - "type": "object", "required": [ - "body", - "status", "type" ], + "type": "object" + }, + { + "additionalProperties": false, "properties": { "body": { "type": "string" }, "delay_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "headers": { + "additionalProperties": { + "type": "string" + }, "type": [ "object", "null" - ], - "additionalProperties": { - "type": "string" - } + ] }, "status": { - "type": "integer", "format": "uint16", - "minimum": 0.0 + "maximum": 65535, + "minimum": 0, + "type": "integer" }, "type": { - "type": "string", - "enum": [ - "mock" - ] + "const": "mock", + "type": "string" } }, - "additionalProperties": false + "required": [ + "type", + "status", + "body" + ], + "type": "object" } ] }, "DebugRuleMatch": { - "type": "object", - "required": [ - "url" - ], + "additionalProperties": false, "properties": { "method": { "type": [ @@ -1768,70 +1598,65 @@ "type": "string" } }, - "additionalProperties": false - }, - "DebugRun": { - "type": "object", "required": [ - "coverage", - "dropped_console", - "dropped_operations", - "dropped_requests", - "errors", - "id", - "name", - "next_since", - "operations", - "requests", - "session_id", - "started_at", - "state", - "tab_id", "url" ], + "type": "object" + }, + "DebugRuleState": { + "enum": [ + "enabled", + "disabled", + "exhausted", + "removed", + "stopped" + ], + "type": "string" + }, + "DebugRun": { "properties": { "active_rules": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "coverage": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "dropped_console": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "dropped_operations": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "dropped_requests": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "environment": { - "type": [ - "object", - "null" - ], "additionalProperties": { "type": "string" - } + }, + "type": [ + "object", + "null" + ] }, "errors": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "id": { "type": "string" @@ -1840,36 +1665,36 @@ "type": "string" }, "next_since": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "operations": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "requests": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "saved_at": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "session_id": { "type": "string" }, "started_at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "state": { - "type": "string" + "$ref": "#/definitions/DebugRunState" }, "stop_reason": { "type": [ @@ -1878,13 +1703,22 @@ ] }, "stopped_at": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] + }, + "storage": { + "anyOf": [ + { + "$ref": "#/definitions/DebugStorage" + }, + { + "type": "null" + } + ] }, - "storage": true, "storage_error": { "type": [ "string", @@ -1892,51 +1726,104 @@ ] }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "url": { "type": "string" } - } + }, + "required": [ + "id", + "session_id", + "tab_id", + "name", + "url", + "started_at", + "state", + "requests", + "operations", + "errors", + "dropped_requests", + "dropped_operations", + "dropped_console", + "coverage", + "next_since" + ], + "type": "object" }, - "DebugTextChanges": { - "type": "object", + "DebugRunState": { + "enum": [ + "capturing", + "stopped" + ], + "type": "string" + }, + "DebugStorage": { + "description": "Bounded local retention statistics included in debug run metadata.", + "properties": { + "bytes": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "dropped": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "pins": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "requests": { + "format": "uint64", + "minimum": 0, + "type": "integer" + } + }, "required": [ - "added", - "removed", - "truncated" + "requests", + "bytes", + "dropped", + "pins" ], + "type": "object" + }, + "DebugTextChanges": { "properties": { "added": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "removed": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "truncated": { "type": "boolean" } - } - }, - "DebugValue": { - "type": "object", + }, "required": [ - "state" + "added", + "removed", + "truncated" ], + "type": "object" + }, + "DebugValue": { "properties": { "at": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "source": { "type": [ @@ -1953,23 +1840,240 @@ "null" ] } - } - }, - "DebugVisibility": { - "type": "object", + }, "required": [ - "at", "state" ], + "type": "object" + }, + "DebugVisibility": { "properties": { "at": { - "type": "number", - "format": "double" + "format": "double", + "type": "number" }, "state": { "type": "string" } - } + }, + "required": [ + "at", + "state" + ], + "type": "object" + } + }, + "properties": { + "activity": { + "anyOf": [ + { + "$ref": "#/definitions/DebugActivity" + }, + { + "type": "null" + } + ] + }, + "aggregates": { + "items": { + "$ref": "#/definitions/DebugEndpoint" + }, + "type": [ + "array", + "null" + ] + }, + "analysis": { + "anyOf": [ + { + "$ref": "#/definitions/DebugAnalysis" + }, + { + "type": "null" + } + ] + }, + "capabilities": true, + "console": { + "items": { + "$ref": "#/definitions/DebugConsole" + }, + "type": [ + "array", + "null" + ] + }, + "duplicates": { + "items": { + "$ref": "#/definitions/DebugDuplicate" + }, + "type": [ + "array", + "null" + ] + }, + "evidence": { + "anyOf": [ + { + "$ref": "#/definitions/DebugEvidence" + }, + { + "type": "null" + } + ] + }, + "next_offset": { + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "next_since": { + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "operation": { + "anyOf": [ + { + "$ref": "#/definitions/DebugOperation" + }, + { + "type": "null" + } + ] + }, + "operations": { + "items": { + "$ref": "#/definitions/DebugOperation" + }, + "type": [ + "array", + "null" + ] + }, + "output": { + "anyOf": [ + { + "$ref": "#/definitions/DebugOutput" + }, + { + "type": "null" + } + ] + }, + "pages": { + "items": { + "$ref": "#/definitions/DebugPage" + }, + "type": [ + "array", + "null" + ] + }, + "performance": { + "items": { + "$ref": "#/definitions/DebugPerformance" + }, + "type": [ + "array", + "null" + ] + }, + "recording": { + "anyOf": [ + { + "$ref": "#/definitions/DebugRecording" + }, + { + "type": "null" + } + ] + }, + "replay": { + "anyOf": [ + { + "$ref": "#/definitions/DebugReplay" + }, + { + "type": "null" + } + ] + }, + "replays": { + "items": { + "$ref": "#/definitions/DebugReplay" + }, + "type": [ + "array", + "null" + ] + }, + "request": { + "anyOf": [ + { + "$ref": "#/definitions/DebugRequest" + }, + { + "type": "null" + } + ] + }, + "requests": { + "items": { + "$ref": "#/definitions/DebugRequest" + }, + "type": [ + "array", + "null" + ] + }, + "rules": { + "items": { + "$ref": "#/definitions/DebugRule" + }, + "type": [ + "array", + "null" + ] + }, + "run": { + "anyOf": [ + { + "$ref": "#/definitions/DebugRun" + }, + { + "type": "null" + } + ] + }, + "runs": { + "items": { + "$ref": "#/definitions/DebugRun" + }, + "type": [ + "array", + "null" + ] + }, + "session_id": { + "type": "string" + }, + "truncated": { + "type": [ + "boolean", + "null" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "DebugResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_download_params.json b/crates/bsk-protocol/schema/tool_download_params.json index 3bfbba7f6..520607643 100644 --- a/crates/bsk-protocol/schema/tool_download_params.json +++ b/crates/bsk-protocol/schema/tool_download_params.json @@ -1,10 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DownloadParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "browser_relative_dir": { "description": "Daemon-injected relative directory beneath Chrome's Downloads root.", @@ -14,13 +9,13 @@ ] }, "max_byte_size": { - "description": "Daemon-injected authoritative transfer size limit. The extension uses it only for early cancellation; daemon import remains the final check.", + "description": "Daemon-injected authoritative transfer size limit. The extension uses\nit only for early cancellation; daemon import remains the final check.", + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "ref": { "type": [ @@ -38,19 +33,24 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "DownloadParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_download_result.json b/crates/bsk-protocol/schema/tool_download_result.json index 726ca50f1..4441963d3 100644 --- a/crates/bsk-protocol/schema/tool_download_result.json +++ b/crates/bsk-protocol/schema/tool_download_result.json @@ -1,12 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DownloadResult", - "type": "object", - "required": [ - "byte_size", - "suggested_filename", - "tab_id" - ], "properties": { "browser_path": { "description": "Extension-internal completed Chrome download path, stripped by the daemon.", @@ -16,9 +9,9 @@ ] }, "byte_size": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "danger": { "type": [ @@ -36,8 +29,8 @@ "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "transfer_id": { "description": "Opaque id returned by the daemon to the CLI.", @@ -58,5 +51,12 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "suggested_filename", + "byte_size" + ], + "title": "DownloadResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_emulate_overrides.json b/crates/bsk-protocol/schema/tool_emulate_overrides.json index d765a7088..1a0100278 100644 --- a/crates/bsk-protocol/schema/tool_emulate_overrides.json +++ b/crates/bsk-protocol/schema/tool_emulate_overrides.json @@ -1,8 +1,75 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EmulateOverrides", - "description": "Concrete emulation overrides for one tab. Field presence drives the extension: only the overrides whose fields are set are touched, so a call may change just the UA, just the viewport, or any combination.", - "type": "object", + "definitions": { + "UserAgentBrandVersion": { + "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", + "properties": { + "brand": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "brand", + "version" + ], + "type": "object" + }, + "UserAgentMetadata": { + "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional\nand only sent when present.", + "properties": { + "architecture": { + "type": [ + "string", + "null" + ] + }, + "brands": { + "items": { + "$ref": "#/definitions/UserAgentBrandVersion" + }, + "type": [ + "array", + "null" + ] + }, + "full_version": { + "type": [ + "string", + "null" + ] + }, + "mobile": { + "type": [ + "boolean", + "null" + ] + }, + "model": { + "type": [ + "string", + "null" + ] + }, + "platform": { + "type": [ + "string", + "null" + ] + }, + "platform_version": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + } + }, + "description": "Concrete emulation overrides for one tab. Field presence drives the\nextension: only the overrides whose fields are set are touched, so a\ncall may change just the UA, just the viewport, or any combination.", "properties": { "accept_language": { "description": "`Accept-Language` header override. Requires `user_agent`.", @@ -12,40 +79,40 @@ ] }, "device_scale_factor": { - "description": "Device scale factor (device pixel ratio). Only meaningful with `width`/`height`; the extension maps `None` to CDP's `0` (\"use the display's native factor\").", + "description": "Device scale factor (device pixel ratio). Only meaningful with\n`width`/`height`; the extension maps `None` to CDP's `0`\n(\"use the display's native factor\").", + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "height": { "description": "Viewport height in CSS pixels. Requires `width`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "max_touch_points": { - "description": "Touch points reported while touch emulation is on (CDP defaults to 1 when omitted).", + "description": "Touch points reported while touch emulation is on (CDP defaults\nto 1 when omitted).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "mobile": { - "description": "Emulate a mobile viewport (meta-viewport handling, overlay scrollbars). Only meaningful with `width`/`height`.", + "description": "Emulate a mobile viewport (meta-viewport handling, overlay\nscrollbars). Only meaningful with `width`/`height`.", "type": [ "boolean", "null" ] }, "touch": { - "description": "Enable/disable touch emulation (`Emulation.setTouchEmulationEnabled`). When omitted while `max_touch_points` is set, touch is enabled.", + "description": "Enable/disable touch emulation\n(`Emulation.setTouchEmulationEnabled`). When omitted while\n`max_touch_points` is set, touch is enabled.", "type": [ "boolean", "null" @@ -59,7 +126,6 @@ ] }, "user_agent_metadata": { - "description": "UA client-hints metadata. Requires `user_agent`.", "anyOf": [ { "$ref": "#/definitions/UserAgentMetadata" @@ -67,85 +133,19 @@ { "type": "null" } - ] + ], + "description": "UA client-hints metadata. Requires `user_agent`." }, "width": { "description": "Viewport width in CSS pixels. Requires `height`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } }, - "definitions": { - "UserAgentBrandVersion": { - "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", - "type": "object", - "required": [ - "brand", - "version" - ], - "properties": { - "brand": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "UserAgentMetadata": { - "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional and only sent when present.", - "type": "object", - "properties": { - "architecture": { - "type": [ - "string", - "null" - ] - }, - "brands": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/UserAgentBrandVersion" - } - }, - "full_version": { - "type": [ - "string", - "null" - ] - }, - "mobile": { - "type": [ - "boolean", - "null" - ] - }, - "model": { - "type": [ - "string", - "null" - ] - }, - "platform": { - "type": [ - "string", - "null" - ] - }, - "platform_version": { - "type": [ - "string", - "null" - ] - } - } - } - } + "title": "EmulateOverrides", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_emulate_params.json b/crates/bsk-protocol/schema/tool_emulate_params.json index 4e313fee0..317c857cc 100644 --- a/crates/bsk-protocol/schema/tool_emulate_params.json +++ b/crates/bsk-protocol/schema/tool_emulate_params.json @@ -1,45 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EmulateParams", - "type": "object", - "required": [ - "session_id" - ], - "properties": { - "off": { - "description": "Clear every emulation override on the tab and restore its real environment. Mutually exclusive with `overrides`.", - "type": [ - "boolean", - "null" - ] - }, - "overrides": { - "description": "Overrides to apply. Required unless `off` is set.", - "anyOf": [ - { - "$ref": "#/definitions/EmulateOverrides" - }, - { - "type": "null" - } - ] - }, - "session_id": { - "type": "string" - }, - "tab_id": { - "description": "Target tab. Defaults to the Agent Window's active tab.", - "type": [ - "integer", - "null" - ], - "format": "int64" - } - }, "definitions": { "EmulateOverrides": { - "description": "Concrete emulation overrides for one tab. Field presence drives the extension: only the overrides whose fields are set are touched, so a call may change just the UA, just the viewport, or any combination.", - "type": "object", + "description": "Concrete emulation overrides for one tab. Field presence drives the\nextension: only the overrides whose fields are set are touched, so a\ncall may change just the UA, just the viewport, or any combination.", "properties": { "accept_language": { "description": "`Accept-Language` header override. Requires `user_agent`.", @@ -49,40 +12,40 @@ ] }, "device_scale_factor": { - "description": "Device scale factor (device pixel ratio). Only meaningful with `width`/`height`; the extension maps `None` to CDP's `0` (\"use the display's native factor\").", + "description": "Device scale factor (device pixel ratio). Only meaningful with\n`width`/`height`; the extension maps `None` to CDP's `0`\n(\"use the display's native factor\").", + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "height": { "description": "Viewport height in CSS pixels. Requires `width`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "max_touch_points": { - "description": "Touch points reported while touch emulation is on (CDP defaults to 1 when omitted).", + "description": "Touch points reported while touch emulation is on (CDP defaults\nto 1 when omitted).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "mobile": { - "description": "Emulate a mobile viewport (meta-viewport handling, overlay scrollbars). Only meaningful with `width`/`height`.", + "description": "Emulate a mobile viewport (meta-viewport handling, overlay\nscrollbars). Only meaningful with `width`/`height`.", "type": [ "boolean", "null" ] }, "touch": { - "description": "Enable/disable touch emulation (`Emulation.setTouchEmulationEnabled`). When omitted while `max_touch_points` is set, touch is enabled.", + "description": "Enable/disable touch emulation\n(`Emulation.setTouchEmulationEnabled`). When omitted while\n`max_touch_points` is set, touch is enabled.", "type": [ "boolean", "null" @@ -96,7 +59,6 @@ ] }, "user_agent_metadata": { - "description": "UA client-hints metadata. Requires `user_agent`.", "anyOf": [ { "$ref": "#/definitions/UserAgentMetadata" @@ -104,26 +66,23 @@ { "type": "null" } - ] + ], + "description": "UA client-hints metadata. Requires `user_agent`." }, "width": { "description": "Viewport width in CSS pixels. Requires `height`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "type": "object" }, "UserAgentBrandVersion": { "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", - "type": "object", - "required": [ - "brand", - "version" - ], "properties": { "brand": { "type": "string" @@ -131,11 +90,15 @@ "version": { "type": "string" } - } + }, + "required": [ + "brand", + "version" + ], + "type": "object" }, "UserAgentMetadata": { - "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional and only sent when present.", - "type": "object", + "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional\nand only sent when present.", "properties": { "architecture": { "type": [ @@ -144,13 +107,13 @@ ] }, "brands": { + "items": { + "$ref": "#/definitions/UserAgentBrandVersion" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/UserAgentBrandVersion" - } + ] }, "full_version": { "type": [ @@ -182,7 +145,44 @@ "null" ] } - } + }, + "type": "object" } - } + }, + "properties": { + "off": { + "description": "Clear every emulation override on the tab and restore its real\nenvironment. Mutually exclusive with `overrides`.", + "type": [ + "boolean", + "null" + ] + }, + "overrides": { + "anyOf": [ + { + "$ref": "#/definitions/EmulateOverrides" + }, + { + "type": "null" + } + ], + "description": "Overrides to apply. Required unless `off` is set." + }, + "session_id": { + "type": "string" + }, + "tab_id": { + "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "session_id" + ], + "title": "EmulateParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_emulate_result.json b/crates/bsk-protocol/schema/tool_emulate_result.json index cb6124a41..3a7818f3d 100644 --- a/crates/bsk-protocol/schema/tool_emulate_result.json +++ b/crates/bsk-protocol/schema/tool_emulate_result.json @@ -1,43 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EmulateResult", - "type": "object", - "required": [ - "cleared", - "tab_id" - ], - "properties": { - "applied": { - "description": "Echo of the overrides that were applied. Absent when cleared.", - "anyOf": [ - { - "$ref": "#/definitions/EmulateOverrides" - }, - { - "type": "null" - } - ] - }, - "cleared": { - "description": "True when overrides were cleared (`off`); false when applied.", - "type": "boolean" - }, - "note": { - "description": "Scope note: emulation overrides are per-tab (CDP target) and are not inherited by new tabs.", - "type": [ - "string", - "null" - ] - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "EmulateOverrides": { - "description": "Concrete emulation overrides for one tab. Field presence drives the extension: only the overrides whose fields are set are touched, so a call may change just the UA, just the viewport, or any combination.", - "type": "object", + "description": "Concrete emulation overrides for one tab. Field presence drives the\nextension: only the overrides whose fields are set are touched, so a\ncall may change just the UA, just the viewport, or any combination.", "properties": { "accept_language": { "description": "`Accept-Language` header override. Requires `user_agent`.", @@ -47,40 +12,40 @@ ] }, "device_scale_factor": { - "description": "Device scale factor (device pixel ratio). Only meaningful with `width`/`height`; the extension maps `None` to CDP's `0` (\"use the display's native factor\").", + "description": "Device scale factor (device pixel ratio). Only meaningful with\n`width`/`height`; the extension maps `None` to CDP's `0`\n(\"use the display's native factor\").", + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "height": { "description": "Viewport height in CSS pixels. Requires `width`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "max_touch_points": { - "description": "Touch points reported while touch emulation is on (CDP defaults to 1 when omitted).", + "description": "Touch points reported while touch emulation is on (CDP defaults\nto 1 when omitted).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "mobile": { - "description": "Emulate a mobile viewport (meta-viewport handling, overlay scrollbars). Only meaningful with `width`/`height`.", + "description": "Emulate a mobile viewport (meta-viewport handling, overlay\nscrollbars). Only meaningful with `width`/`height`.", "type": [ "boolean", "null" ] }, "touch": { - "description": "Enable/disable touch emulation (`Emulation.setTouchEmulationEnabled`). When omitted while `max_touch_points` is set, touch is enabled.", + "description": "Enable/disable touch emulation\n(`Emulation.setTouchEmulationEnabled`). When omitted while\n`max_touch_points` is set, touch is enabled.", "type": [ "boolean", "null" @@ -94,7 +59,6 @@ ] }, "user_agent_metadata": { - "description": "UA client-hints metadata. Requires `user_agent`.", "anyOf": [ { "$ref": "#/definitions/UserAgentMetadata" @@ -102,26 +66,23 @@ { "type": "null" } - ] + ], + "description": "UA client-hints metadata. Requires `user_agent`." }, "width": { "description": "Viewport width in CSS pixels. Requires `height`.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "type": "object" }, "UserAgentBrandVersion": { "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", - "type": "object", - "required": [ - "brand", - "version" - ], "properties": { "brand": { "type": "string" @@ -129,11 +90,15 @@ "version": { "type": "string" } - } + }, + "required": [ + "brand", + "version" + ], + "type": "object" }, "UserAgentMetadata": { - "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional and only sent when present.", - "type": "object", + "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional\nand only sent when present.", "properties": { "architecture": { "type": [ @@ -142,13 +107,13 @@ ] }, "brands": { + "items": { + "$ref": "#/definitions/UserAgentBrandVersion" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/UserAgentBrandVersion" - } + ] }, "full_version": { "type": [ @@ -180,7 +145,42 @@ "null" ] } - } + }, + "type": "object" + } + }, + "properties": { + "applied": { + "anyOf": [ + { + "$ref": "#/definitions/EmulateOverrides" + }, + { + "type": "null" + } + ], + "description": "Echo of the overrides that were applied. Absent when cleared." + }, + "cleared": { + "description": "True when overrides were cleared (`off`); false when applied.", + "type": "boolean" + }, + "note": { + "description": "Scope note: emulation overrides are per-tab (CDP target) and are\nnot inherited by new tabs.", + "type": [ + "string", + "null" + ] + }, + "tab_id": { + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "cleared" + ], + "title": "EmulateResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_emulate_user_agent_metadata.json b/crates/bsk-protocol/schema/tool_emulate_user_agent_metadata.json index d8d173c51..0dcc1ed42 100644 --- a/crates/bsk-protocol/schema/tool_emulate_user_agent_metadata.json +++ b/crates/bsk-protocol/schema/tool_emulate_user_agent_metadata.json @@ -1,8 +1,24 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "UserAgentMetadata", - "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional and only sent when present.", - "type": "object", + "definitions": { + "UserAgentBrandVersion": { + "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", + "properties": { + "brand": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "brand", + "version" + ], + "type": "object" + } + }, + "description": "Mirror of CDP `Emulation.UserAgentMetadata`; every field is optional\nand only sent when present.", "properties": { "architecture": { "type": [ @@ -11,13 +27,13 @@ ] }, "brands": { + "items": { + "$ref": "#/definitions/UserAgentBrandVersion" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/UserAgentBrandVersion" - } + ] }, "full_version": { "type": [ @@ -50,22 +66,6 @@ ] } }, - "definitions": { - "UserAgentBrandVersion": { - "description": "One entry of CDP `Emulation.UserAgentBrandVersion` (UA client hints).", - "type": "object", - "required": [ - "brand", - "version" - ], - "properties": { - "brand": { - "type": "string" - }, - "version": { - "type": "string" - } - } - } - } + "title": "UserAgentMetadata", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_evaluate_error.json b/crates/bsk-protocol/schema/tool_evaluate_error.json index 117137e66..2578d67c1 100644 --- a/crates/bsk-protocol/schema/tool_evaluate_error.json +++ b/crates/bsk-protocol/schema/tool_evaluate_error.json @@ -1,27 +1,27 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EvaluateError", - "type": "object", - "required": [ - "text" - ], "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "text": { "type": "string" } - } + }, + "required": [ + "text" + ], + "title": "EvaluateError", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_evaluate_params.json b/crates/bsk-protocol/schema/tool_evaluate_params.json index 45cf5bcce..dc8d4568c 100644 --- a/crates/bsk-protocol/schema/tool_evaluate_params.json +++ b/crates/bsk-protocol/schema/tool_evaluate_params.json @@ -1,14 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EvaluateParams", - "type": "object", - "required": [ - "expression", - "session_id" - ], "properties": { "await_promise": { - "description": "Await the expression when it resolves to a Promise (CDP `Runtime.evaluate(awaitPromise=...)`). Defaults to `true`.", + "description": "Await the expression when it resolves to a Promise (CDP\n`Runtime.evaluate(awaitPromise=...)`). Defaults to `true`.", "type": [ "boolean", "null" @@ -18,7 +12,7 @@ "type": "string" }, "return_by_value": { - "description": "Ask CDP to serialise the result by value (vs. returning a `RemoteObject` id we cannot use). Defaults to `true`.", + "description": "Ask CDP to serialise the result by value (vs. returning a\n`RemoteObject` id we cannot use). Defaults to `true`.", "type": [ "boolean", "null" @@ -29,20 +23,26 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's currently active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { "description": "Hard upper bound on the evaluation. Defaults to 30s.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] } - } + }, + "required": [ + "session_id", + "expression" + ], + "title": "EvaluateParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_evaluate_result.json b/crates/bsk-protocol/schema/tool_evaluate_result.json index f37c14a78..e1c069977 100644 --- a/crates/bsk-protocol/schema/tool_evaluate_result.json +++ b/crates/bsk-protocol/schema/tool_evaluate_result.json @@ -1,83 +1,41 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "EvaluateResult", - "description": "Outcome of an `evaluate` call.\n\n* `ok: true` → expression evaluated successfully; `value` holds the JSON-serialised return value (`null` is meaningful and distinct from \"missing\"). * `ok: false` → the expression threw; `error.text` holds the stringified `exceptionDetails.text` / `exception.description`. The RPC itself still succeeds — the daemon does NOT map JS throws to top-level RPC errors so agents can act on the throw text.", - "type": "object", - "required": [ - "ok", - "tab_id" - ], - "properties": { - "dialogs": { - "description": "Native JS dialogs observed and auto-handled during this call.", - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error": { - "anyOf": [ - { - "$ref": "#/definitions/EvaluateError" - }, - { - "type": "null" - } - ] - }, - "ok": { - "type": "boolean" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "value": true - }, "definitions": { "EvaluateError": { - "type": "object", - "required": [ - "text" - ], "properties": { "column": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "line": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "text": { "type": "string" } - } + }, + "required": [ + "text" + ], + "type": "object" }, "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -99,13 +57,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -116,17 +74,59 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" } - } + }, + "description": "Outcome of an `evaluate` call.\n\n* `ok: true` → expression evaluated successfully; `value` holds the\n JSON-serialised return value (`null` is meaningful and distinct\n from \"missing\").\n* `ok: false` → the expression threw; `error.text` holds the\n stringified `exceptionDetails.text` / `exception.description`.\n The RPC itself still succeeds — the daemon does NOT map JS throws\n to top-level RPC errors so agents can act on the throw text.", + "properties": { + "dialogs": { + "description": "Native JS dialogs observed and auto-handled during this call.", + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error": { + "anyOf": [ + { + "$ref": "#/definitions/EvaluateError" + }, + { + "type": "null" + } + ] + }, + "ok": { + "type": "boolean" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "value": true + }, + "required": [ + "ok", + "tab_id" + ], + "title": "EvaluateResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_fill_params.json b/crates/bsk-protocol/schema/tool_fill_params.json index 8f8f480ce..a42d65fa2 100644 --- a/crates/bsk-protocol/schema/tool_fill_params.json +++ b/crates/bsk-protocol/schema/tool_fill_params.json @@ -1,14 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "FillParams", - "type": "object", - "required": [ - "session_id", - "value" - ], "properties": { "clear_before": { - "description": "Clear the field before typing. Defaults to `true`; pass `false` to append instead of replacing.", + "description": "Clear the field before typing. Defaults to `true`; pass `false`\nto append instead of replacing.", "type": [ "boolean", "null" @@ -30,22 +24,28 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "value": { "type": "string" } - } + }, + "required": [ + "session_id", + "value" + ], + "title": "FillParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_fill_result.json b/crates/bsk-protocol/schema/tool_fill_result.json index 5d18aea04..4074711ae 100644 --- a/crates/bsk-protocol/schema/tool_fill_result.json +++ b/crates/bsk-protocol/schema/tool_fill_result.json @@ -1,60 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "FillResult", - "type": "object", - "required": [ - "tab_id", - "value_length" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "value_length": { - "description": "UTF-16 code-unit length of the value that was finally typed (matches what `input.value.length` would report in the page).", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -76,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -93,17 +49,61 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" ] + }, + "used_selector": { + "type": [ + "string", + "null" + ] + }, + "value_length": { + "description": "UTF-16 code-unit length of the value that was finally typed\n(matches what `input.value.length` would report in the page).", + "format": "uint32", + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "tab_id", + "value_length" + ], + "title": "FillResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_focus_params.json b/crates/bsk-protocol/schema/tool_focus_params.json index 9009bec20..e260a154d 100644 --- a/crates/bsk-protocol/schema/tool_focus_params.json +++ b/crates/bsk-protocol/schema/tool_focus_params.json @@ -1,13 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "FocusParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "ref": { - "description": "Optional `@e` ref allocated by the last observation. Mutually exclusive with `selector`.", + "description": "Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.", "type": [ "string", "null" @@ -24,19 +19,24 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "FocusParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_focus_result.json b/crates/bsk-protocol/schema/tool_focus_result.json index 196501dae..1a4c40235 100644 --- a/crates/bsk-protocol/schema/tool_focus_result.json +++ b/crates/bsk-protocol/schema/tool_focus_result.json @@ -1,58 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "FocusResult", - "type": "object", - "required": [ - "focused", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "focused": { - "description": "Whether the target holds DOM focus in its document or shadow root after the call.", - "type": "boolean" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -74,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -91,17 +49,59 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "focused": { + "description": "Whether the target holds DOM focus in its document or shadow root after the call.", + "type": "boolean" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" + ] + }, + "used_selector": { + "type": [ + "string", + "null" ] } - } + }, + "required": [ + "tab_id", + "focused" + ], + "title": "FocusResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_get_html_params.json b/crates/bsk-protocol/schema/tool_get_html_params.json index f775e9a0a..c27d0006b 100644 --- a/crates/bsk-protocol/schema/tool_get_html_params.json +++ b/crates/bsk-protocol/schema/tool_get_html_params.json @@ -1,23 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetHtmlParams", - "description": "Parameters for `tool.get_html`. Either give a tab and (optionally) a snapshot ref to scope the dump to one subtree, or leave both empty to fall back to the Agent Window's active tab and the document root.\n\nThe wire field is `\"ref\"` (a Rust keyword); the Rust binding lives in [`Self::ref_`] and uses serde rename / alias so JSON stays clean.", - "type": "object", - "required": [ - "session_id" - ], + "description": "Parameters for `tool.get_html`. Either give a tab and (optionally) a\nsnapshot ref to scope the dump to one subtree, or leave both empty\nto fall back to the Agent Window's active tab and the document\nroot.\n\nThe wire field is `\"ref\"` (a Rust keyword); the Rust binding lives\nin [`Self::ref_`] and uses serde rename / alias so JSON stays clean.", "properties": { "max_bytes": { - "description": "Truncate the HTML to at most this many bytes. Optional; extension applies a sensible default (`524288` = 512 KiB) when omitted.", + "description": "Truncate the HTML to at most this many bytes. Optional;\nextension applies a sensible default (`524288` = 512 KiB) when\nomitted.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "ref": { - "description": "Optional `@e` ref allocated by the last `tool.snapshot`. Accepts both `\"e3\"` and `\"@e3\"`. When given the extension calls `DOM.getOuterHTML({ backendNodeId })` for the matching node; otherwise it fetches the document element.", + "description": "Optional `@e` ref allocated by the last `tool.snapshot`.\nAccepts both `\"e3\"` and `\"@e3\"`. When given the extension calls\n`DOM.getOuterHTML({ backendNodeId })` for the matching node;\notherwise it fetches the document element.", "type": [ "string", "null" @@ -27,11 +22,16 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "GetHtmlParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_get_html_result.json b/crates/bsk-protocol/schema/tool_get_html_result.json index 130d1a428..7287fa2c5 100644 --- a/crates/bsk-protocol/schema/tool_get_html_result.json +++ b/crates/bsk-protocol/schema/tool_get_html_result.json @@ -1,57 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetHtmlResult", - "type": "object", - "required": [ - "byte_size", - "html", - "tab_id" - ], - "properties": { - "byte_size": { - "description": "Total byte length of the original (un-truncated) HTML payload.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "html": { - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "truncated": { - "description": "True when `html` was truncated to honour `max_bytes`. Agents should treat the missing tail as elided.", - "default": false, - "type": "boolean" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -73,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -90,17 +49,58 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" + } + }, + "properties": { + "byte_size": { + "description": "Total byte length of the original (un-truncated) HTML payload.", + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "html": { + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "truncated": { + "default": false, + "description": "True when `html` was truncated to honour `max_bytes`. Agents\nshould treat the missing tail as elided.", + "type": "boolean" } - } + }, + "required": [ + "html", + "byte_size", + "tab_id" + ], + "title": "GetHtmlResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_hover_params.json b/crates/bsk-protocol/schema/tool_hover_params.json index 56a700322..eaa93010b 100644 --- a/crates/bsk-protocol/schema/tool_hover_params.json +++ b/crates/bsk-protocol/schema/tool_hover_params.json @@ -1,22 +1,29 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "HoverParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + } + }, "properties": { "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "ref": { - "description": "Optional `@e` ref allocated by the last observation. Mutually exclusive with `selector`.", + "description": "Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.", "type": [ "string", "null" @@ -33,40 +40,33 @@ }, "settle_ms": { "description": "Wait after the mouse move so hover-triggered UI can settle.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 - } - }, - "definitions": { - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" ] } - } + }, + "required": [ + "session_id" + ], + "title": "HoverParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_hover_result.json b/crates/bsk-protocol/schema/tool_hover_result.json index d8fab36ca..a1b5ba727 100644 --- a/crates/bsk-protocol/schema/tool_hover_result.json +++ b/crates/bsk-protocol/schema/tool_hover_result.json @@ -1,64 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "HoverResult", - "type": "object", - "required": [ - "tab_id", - "x", - "y" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "x": { - "description": "Viewport-relative hover coordinates (CSS pixels).", - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -80,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -97,17 +49,65 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" ] + }, + "used_selector": { + "type": [ + "string", + "null" + ] + }, + "x": { + "description": "Viewport-relative hover coordinates (CSS pixels).", + "format": "double", + "type": "number" + }, + "y": { + "format": "double", + "type": "number" } - } + }, + "required": [ + "tab_id", + "x", + "y" + ], + "title": "HoverResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_back_params.json b/crates/bsk-protocol/schema/tool_navigate_back_params.json index c7c685c61..0f5de057d 100644 --- a/crates/bsk-protocol/schema/tool_navigate_back_params.json +++ b/crates/bsk-protocol/schema/tool_navigate_back_params.json @@ -1,28 +1,35 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateBackParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "WaitUntil": { + "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` → `load`\n* `DomContentLoaded` → `DOMContentLoaded`\n* `NetworkIdle` → `networkIdle`\n* `Commit` → `commit` (earliest event after the navigation actually\n commits to a new document)", + "enum": [ + "load", + "domcontentloaded", + "networkidle", + "commit" + ], + "type": "string" + } + }, "properties": { "session_id": { "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "wait_until": { "anyOf": [ @@ -35,16 +42,9 @@ ] } }, - "definitions": { - "WaitUntil": { - "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names: * `Load` → `load` * `DomContentLoaded` → `DOMContentLoaded` * `NetworkIdle` → `networkIdle` * `Commit` → `commit` (earliest event after the navigation actually commits to a new document)", - "type": "string", - "enum": [ - "load", - "domcontentloaded", - "networkidle", - "commit" - ] - } - } + "required": [ + "session_id" + ], + "title": "NavigateBackParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_back_result.json b/crates/bsk-protocol/schema/tool_navigate_back_result.json index cc2827cba..7ef7a18ce 100644 --- a/crates/bsk-protocol/schema/tool_navigate_back_result.json +++ b/crates/bsk-protocol/schema/tool_navigate_back_result.json @@ -1,63 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateBackResult", - "type": "object", - "required": [ - "reached", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error_text": { - "type": [ - "string", - "null" - ] - }, - "final_url": { - "type": [ - "string", - "null" - ] - }, - "previous_url": { - "type": [ - "string", - "null" - ] - }, - "reached": { - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -79,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -96,17 +49,64 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error_text": { + "type": [ + "string", + "null" ] + }, + "final_url": { + "type": [ + "string", + "null" + ] + }, + "previous_url": { + "type": [ + "string", + "null" + ] + }, + "reached": { + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "reached" + ], + "title": "NavigateBackResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_forward_params.json b/crates/bsk-protocol/schema/tool_navigate_forward_params.json index 822e2ad64..e10ffaeb9 100644 --- a/crates/bsk-protocol/schema/tool_navigate_forward_params.json +++ b/crates/bsk-protocol/schema/tool_navigate_forward_params.json @@ -1,28 +1,35 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateForwardParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "WaitUntil": { + "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` → `load`\n* `DomContentLoaded` → `DOMContentLoaded`\n* `NetworkIdle` → `networkIdle`\n* `Commit` → `commit` (earliest event after the navigation actually\n commits to a new document)", + "enum": [ + "load", + "domcontentloaded", + "networkidle", + "commit" + ], + "type": "string" + } + }, "properties": { "session_id": { "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "wait_until": { "anyOf": [ @@ -35,16 +42,9 @@ ] } }, - "definitions": { - "WaitUntil": { - "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names: * `Load` → `load` * `DomContentLoaded` → `DOMContentLoaded` * `NetworkIdle` → `networkIdle` * `Commit` → `commit` (earliest event after the navigation actually commits to a new document)", - "type": "string", - "enum": [ - "load", - "domcontentloaded", - "networkidle", - "commit" - ] - } - } + "required": [ + "session_id" + ], + "title": "NavigateForwardParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_forward_result.json b/crates/bsk-protocol/schema/tool_navigate_forward_result.json index 5771ae6d2..2a700c83a 100644 --- a/crates/bsk-protocol/schema/tool_navigate_forward_result.json +++ b/crates/bsk-protocol/schema/tool_navigate_forward_result.json @@ -1,63 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateForwardResult", - "type": "object", - "required": [ - "reached", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error_text": { - "type": [ - "string", - "null" - ] - }, - "final_url": { - "type": [ - "string", - "null" - ] - }, - "previous_url": { - "type": [ - "string", - "null" - ] - }, - "reached": { - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -79,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -96,17 +49,64 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error_text": { + "type": [ + "string", + "null" ] + }, + "final_url": { + "type": [ + "string", + "null" + ] + }, + "previous_url": { + "type": [ + "string", + "null" + ] + }, + "reached": { + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "reached" + ], + "title": "NavigateForwardResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_params.json b/crates/bsk-protocol/schema/tool_navigate_params.json index a49d9fcaa..e78a7bf7d 100644 --- a/crates/bsk-protocol/schema/tool_navigate_params.json +++ b/crates/bsk-protocol/schema/tool_navigate_params.json @@ -1,37 +1,42 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateParams", - "type": "object", - "required": [ - "session_id", - "url" - ], + "definitions": { + "WaitUntil": { + "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` → `load`\n* `DomContentLoaded` → `DOMContentLoaded`\n* `NetworkIdle` → `networkIdle`\n* `Commit` → `commit` (earliest event after the navigation actually\n commits to a new document)", + "enum": [ + "load", + "domcontentloaded", + "networkidle", + "commit" + ], + "type": "string" + } + }, "properties": { "session_id": { "type": "string" }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's currently active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { - "description": "Hard upper bound on the wait; the extension also enforces its own AbortController hookup (M7 stops listening for further lifecycle events once exceeded). Defaults to 30s if omitted.", + "description": "Hard upper bound on the wait; the extension also enforces its\nown AbortController hookup (M7 stops listening for further\nlifecycle events once exceeded). Defaults to 30s if omitted.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "url": { "type": "string" }, "wait_until": { - "description": "Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`].", "anyOf": [ { "$ref": "#/definitions/WaitUntil" @@ -39,19 +44,14 @@ { "type": "null" } - ] + ], + "description": "Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]." } }, - "definitions": { - "WaitUntil": { - "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names: * `Load` → `load` * `DomContentLoaded` → `DOMContentLoaded` * `NetworkIdle` → `networkIdle` * `Commit` → `commit` (earliest event after the navigation actually commits to a new document)", - "type": "string", - "enum": [ - "load", - "domcontentloaded", - "networkidle", - "commit" - ] - } - } + "required": [ + "session_id", + "url" + ], + "title": "NavigateParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_navigate_result.json b/crates/bsk-protocol/schema/tool_navigate_result.json index 865351162..0b965de93 100644 --- a/crates/bsk-protocol/schema/tool_navigate_result.json +++ b/crates/bsk-protocol/schema/tool_navigate_result.json @@ -1,63 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NavigateResult", - "description": "Outcome of a navigation. `reached` is the lifecycle name the extension actually observed before returning — either the requested `wait_until` value, or `\"timeout\"` when the wait expired before that event fired.", - "type": "object", - "required": [ - "reached", - "tab_id", - "url" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error_text": { - "type": [ - "string", - "null" - ] - }, - "final_url": { - "description": "Tab URL after the navigation settles. May differ from `url` if the server redirected (e.g. http → https) or `wait_until=commit` raced.", - "type": [ - "string", - "null" - ] - }, - "reached": { - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "url": { - "type": "string" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -79,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -96,17 +49,64 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "description": "Outcome of a navigation. `reached` is the lifecycle name the\nextension actually observed before returning — either the requested\n`wait_until` value, or `\"timeout\"` when the wait expired before\nthat event fired.", + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error_text": { + "type": [ + "string", + "null" ] + }, + "final_url": { + "description": "Tab URL after the navigation settles. May differ from `url` if\nthe server redirected (e.g. http → https) or `wait_until=commit`\nraced.", + "type": [ + "string", + "null" + ] + }, + "reached": { + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "url": { + "type": "string" } - } + }, + "required": [ + "tab_id", + "url", + "reached" + ], + "title": "NavigateResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_network_entry.json b/crates/bsk-protocol/schema/tool_network_entry.json index 295d092a9..ab99bf859 100644 --- a/crates/bsk-protocol/schema/tool_network_entry.json +++ b/crates/bsk-protocol/schema/tool_network_entry.json @@ -1,11 +1,21 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NetworkEntry", - "type": "object", - "required": [ - "kind", - "sequence" - ], + "definitions": { + "NetworkEntryKind": { + "oneOf": [ + { + "const": "response", + "description": "A response was received (`Network.responseReceived`).", + "type": "string" + }, + { + "const": "failure", + "description": "The request failed before completing (`Network.loadingFailed`).", + "type": "string" + } + ] + } + }, "properties": { "error_text": { "description": "CDP failure reason (`failure` entries only).", @@ -36,18 +46,18 @@ ] }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "status": { "description": "HTTP status code (`response` entries only).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "status_text": { "type": [ @@ -56,11 +66,11 @@ ] }, "timestamp": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "truncated": { "default": false, @@ -73,24 +83,10 @@ ] } }, - "definitions": { - "NetworkEntryKind": { - "oneOf": [ - { - "description": "A response was received (`Network.responseReceived`).", - "type": "string", - "enum": [ - "response" - ] - }, - { - "description": "The request failed before completing (`Network.loadingFailed`).", - "type": "string", - "enum": [ - "failure" - ] - } - ] - } - } + "required": [ + "sequence", + "kind" + ], + "title": "NetworkEntry", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_network_params.json b/crates/bsk-protocol/schema/tool_network_params.json index 2b9fa7145..4279b9645 100644 --- a/crates/bsk-protocol/schema/tool_network_params.json +++ b/crates/bsk-protocol/schema/tool_network_params.json @@ -1,48 +1,48 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NetworkParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "limit": { "description": "Maximum number of entries to return. Extension applies safe defaults and caps.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "max_text_chars": { "description": "Maximum characters returned per URL / error text. Extension applies safe defaults and caps.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "session_id": { "type": "string" }, "since": { "description": "Return entries with sequence strictly greater than this cursor.", + "format": "uint64", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint64", - "minimum": 0.0 + ] }, "tab_id": { "description": "Optional target tab. Defaults to the Agent Window's currently active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "NetworkParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_network_result.json b/crates/bsk-protocol/schema/tool_network_result.json index 324ca09c4..4a5cc6378 100644 --- a/crates/bsk-protocol/schema/tool_network_result.json +++ b/crates/bsk-protocol/schema/tool_network_result.json @@ -1,39 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NetworkResult", - "type": "object", - "required": [ - "next_since", - "tab_id" - ], - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/NetworkEntry" - } - }, - "next_since": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "truncated": { - "default": false, - "type": "boolean" - } - }, "definitions": { "NetworkEntry": { - "type": "object", - "required": [ - "kind", - "sequence" - ], "properties": { "error_text": { "description": "CDP failure reason (`failure` entries only).", @@ -64,18 +32,18 @@ ] }, "sequence": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "status": { "description": "HTTP status code (`response` entries only).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "status_text": { "type": [ @@ -84,11 +52,11 @@ ] }, "timestamp": { + "format": "double", "type": [ "number", "null" - ], - "format": "double" + ] }, "truncated": { "default": false, @@ -100,25 +68,54 @@ "null" ] } - } + }, + "required": [ + "sequence", + "kind" + ], + "type": "object" }, "NetworkEntryKind": { "oneOf": [ { + "const": "response", "description": "A response was received (`Network.responseReceived`).", - "type": "string", - "enum": [ - "response" - ] + "type": "string" }, { + "const": "failure", "description": "The request failed before completing (`Network.loadingFailed`).", - "type": "string", - "enum": [ - "failure" - ] + "type": "string" } ] } - } + }, + "properties": { + "entries": { + "default": [], + "items": { + "$ref": "#/definitions/NetworkEntry" + }, + "type": "array" + }, + "next_since": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "truncated": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "tab_id", + "next_since" + ], + "title": "NetworkResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_observe_params.json b/crates/bsk-protocol/schema/tool_observe_params.json index 28994bf1f..c4e83ee3d 100644 --- a/crates/bsk-protocol/schema/tool_observe_params.json +++ b/crates/bsk-protocol/schema/tool_observe_params.json @@ -1,11 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ObserveParams", - "description": "Parameters for `tool.observe` — produce a semantic VOM observation for one tab plus a fresh `@e` ref-store on the extension side.\n\nUnlike `tool.snapshot`, this path may run bounded perception probes such as hover-surface discovery, but only when `probe_hover` asks for them. It must not submit input, click, navigate, or otherwise commit page state.", - "type": "object", - "required": [ - "session_id" - ], + "description": "Parameters for `tool.observe` — produce a semantic VOM observation\nfor one tab plus a fresh `@e` ref-store on the extension side.\n\nUnlike `tool.snapshot`, this path may run bounded perception probes\nsuch as hover-surface discovery, but only when `probe_hover` asks for\nthem. It must not submit input, click, navigate, or otherwise commit\npage state.", "properties": { "cursor": { "description": "Continue a retained observation; does not recapture the page.", @@ -15,43 +10,48 @@ ] }, "debug_surfaces": { - "description": "Include implementation diagnostics for conditional surface probes.", "default": false, + "description": "Include implementation diagnostics for conditional surface probes.", "type": "boolean" }, "max_depth": { "description": "Cap the depth of the rendered VOM tree.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "max_tokens": { - "description": "Soft cap on rendered tokens (approximate; extension uses a best-effort heuristic based on character count).", + "description": "Soft cap on rendered tokens (approximate; extension uses a\nbest-effort heuristic based on character count).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "probe_hover": { - "description": "Opt in to active hover probing: the extension moves the real cursor over a bounded set of controls to discover hover-only menus and tooltips.\n\nOff by default. Probing costs seconds of wall clock, mutates the live page, and pays off only on pages whose content is genuinely hidden behind hover. Request it when a static observation looks like it is missing hover-revealed structure.", "default": false, + "description": "Opt in to active hover probing: the extension moves the real cursor\nover a bounded set of controls to discover hover-only menus and\ntooltips.\n\nOff by default. Probing costs seconds of wall clock, mutates the live\npage, and pays off only on pages whose content is genuinely hidden\nbehind hover. Request it when a static observation looks like it is\nmissing hover-revealed structure.", "type": "boolean" }, "session_id": { "type": "string" }, "tab_id": { - "description": "Optional target tab. Defaults to the Agent Window's currently active tab.", + "description": "Optional target tab. Defaults to the Agent Window's currently\nactive tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "ObserveParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_observe_result.json b/crates/bsk-protocol/schema/tool_observe_result.json index 890e5fab7..5a50e6b20 100644 --- a/crates/bsk-protocol/schema/tool_observe_result.json +++ b/crates/bsk-protocol/schema/tool_observe_result.json @@ -1,105 +1,34 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ObserveResult", - "type": "object", - "required": [ - "ref_count", - "tab_id", - "text" - ], - "properties": { - "debug": { - "anyOf": [ - { - "$ref": "#/definitions/ObserveDebug" - }, - { - "type": "null" - } - ] - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "hover_probe": { - "description": "Present only when `probe_hover` was requested and probing actually ran.", - "anyOf": [ - { - "$ref": "#/definitions/HoverProbeReport" - }, - { - "type": "null" - } - ] - }, - "next_cursor": { - "description": "Continue omitted content from this same observation.", - "type": [ - "string", - "null" - ] - }, - "ref_count": { - "description": "Number of `@e` refs registered for this session by this observation. Equivalent to the size of the new ref-store map.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "tab_id": { - "description": "Tab the observation was computed for.", - "type": "integer", - "format": "int64" - }, - "text": { - "description": "Semantic VOM observation text. Refs are rendered as `@e` so the agent can copy them into subsequent interaction tools.", - "type": "string" - }, - "truncated": { - "description": "Whether the rendered tree was truncated because of `max_depth` / `max_tokens`. Agents may re-run with looser caps.", - "default": false, - "type": "boolean" - } - }, "definitions": { "HoverProbeReport": { - "description": "Reports what active hover probing did during an observation, so the agent can judge how far the live page may have drifted from the returned text.", - "type": "object", - "required": [ - "performed", - "revealed_content" - ], + "description": "Reports what active hover probing did during an observation, so the agent\ncan judge how far the live page may have drifted from the returned text.", "properties": { "performed": { "description": "The real cursor was moved over page content during this observation.", "type": "boolean" }, "revealed_content": { - "description": "Hovering surfaced content the static tree does not contain, so the page reacts to the cursor and may not have fully reverted.", + "description": "Hovering surfaced content the static tree does not contain, so the page\nreacts to the cursor and may not have fully reverted.", "type": "boolean" } - } + }, + "required": [ + "performed", + "revealed_content" + ], + "type": "object" }, "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -121,13 +50,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -138,36 +67,38 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" }, "ObserveDebug": { - "type": "object", "properties": { "surface_probes": { - "type": "array", "items": { "$ref": "#/definitions/SurfaceProbeDebug" - } + }, + "type": "array" } - } + }, + "type": "object" }, "SurfaceProbeDebug": { - "type": "object", - "required": [ - "sub_items", - "trigger_action", - "trigger_backend_node_id" - ], "properties": { "confidence": { "type": [ @@ -176,17 +107,17 @@ ] }, "sub_items": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "trigger_action": { "type": "string" }, "trigger_backend_node_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "trigger_point": { "anyOf": [ @@ -198,24 +129,93 @@ } ] } - } + }, + "required": [ + "trigger_backend_node_id", + "trigger_action", + "sub_items" + ], + "type": "object" }, "SurfaceProbePoint": { - "type": "object", + "properties": { + "x": { + "format": "double", + "type": "number" + }, + "y": { + "format": "double", + "type": "number" + } + }, "required": [ "x", "y" ], - "properties": { - "x": { - "type": "number", - "format": "double" + "type": "object" + } + }, + "properties": { + "debug": { + "anyOf": [ + { + "$ref": "#/definitions/ObserveDebug" }, - "y": { - "type": "number", - "format": "double" + { + "type": "null" + } + ] + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "hover_probe": { + "anyOf": [ + { + "$ref": "#/definitions/HoverProbeReport" + }, + { + "type": "null" } - } + ], + "description": "Present only when `probe_hover` was requested and probing actually ran." + }, + "next_cursor": { + "description": "Continue omitted content from this same observation.", + "type": [ + "string", + "null" + ] + }, + "ref_count": { + "description": "Number of `@e` refs registered for this session by this\nobservation. Equivalent to the size of the new ref-store map.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "tab_id": { + "description": "Tab the observation was computed for.", + "format": "int64", + "type": "integer" + }, + "text": { + "description": "Semantic VOM observation text. Refs are rendered as `@e` so\nthe agent can copy them into subsequent interaction tools.", + "type": "string" + }, + "truncated": { + "default": false, + "description": "Whether the rendered tree was truncated because of `max_depth` /\n`max_tokens`. Agents may re-run with looser caps.", + "type": "boolean" } - } + }, + "required": [ + "text", + "ref_count", + "tab_id" + ], + "title": "ObserveResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_press_params.json b/crates/bsk-protocol/schema/tool_press_params.json index 7b0b1cd71..e1df31cb9 100644 --- a/crates/bsk-protocol/schema/tool_press_params.json +++ b/crates/bsk-protocol/schema/tool_press_params.json @@ -1,33 +1,39 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PressParams", - "type": "object", - "required": [ - "key", - "session_id" - ], + "definitions": { + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + } + }, "properties": { "hold_ms": { - "description": "Hold the key down for this many milliseconds between `keyDown` and `keyUp`. Useful for testing long-press handlers.", + "description": "Hold the key down for this many milliseconds between `keyDown`\nand `keyUp`. Useful for testing long-press handlers.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "key": { - "description": "Logical key name. Accepts CDP `key` strings (`Enter`, `Escape`, `ArrowDown`, single characters like `a`), or a compound expression such as `Ctrl+A` / `Meta+Shift+P`. Modifiers in the compound form combine with anything supplied via `modifiers`.", + "description": "Logical key name. Accepts CDP `key` strings (`Enter`, `Escape`,\n`ArrowDown`, single characters like `a`), or a compound\nexpression such as `Ctrl+A` / `Meta+Shift+P`. Modifiers in the\ncompound form combine with anything supplied via `modifiers`.", "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "ref": { "description": "Optional target to focus before dispatching the key.", @@ -46,31 +52,25 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 - } - }, - "definitions": { - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" ] } - } + }, + "required": [ + "session_id", + "key" + ], + "title": "PressParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_press_result.json b/crates/bsk-protocol/schema/tool_press_result.json index cc937c237..867c1977e 100644 --- a/crates/bsk-protocol/schema/tool_press_result.json +++ b/crates/bsk-protocol/schema/tool_press_result.json @@ -1,56 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PressResult", - "type": "object", - "required": [ - "code", - "key", - "tab_id" - ], - "properties": { - "code": { - "type": "string" - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "key": { - "type": "string" - }, - "modifiers": { - "default": [], - "type": "array", - "items": { - "$ref": "#/definitions/KeyModifier" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -72,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -89,27 +49,67 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" } - } + }, + "properties": { + "code": { + "type": "string" + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "key": { + "type": "string" + }, + "modifiers": { + "default": [], + "items": { + "$ref": "#/definitions/KeyModifier" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "tab_id", + "key", + "code" + ], + "title": "PressResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_await_params.json b/crates/bsk-protocol/schema/tool_record_await_params.json index 7a8350ae1..9b723c848 100644 --- a/crates/bsk-protocol/schema/tool_record_await_params.json +++ b/crates/bsk-protocol/schema/tool_record_await_params.json @@ -1,21 +1,21 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordAwaitParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "session_id": { "type": "string" }, "timeout_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "RecordAwaitParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_await_result.json b/crates/bsk-protocol/schema/tool_record_await_result.json index 26b6ea8c8..4e986a9f3 100644 --- a/crates/bsk-protocol/schema/tool_record_await_result.json +++ b/crates/bsk-protocol/schema/tool_record_await_result.json @@ -1,36 +1,25 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordAwaitResult", - "type": "object", - "required": [ - "trace" - ], - "properties": { - "trace": { - "$ref": "#/definitions/RecordedTrace" - } - }, "definitions": { "FillCommit": { - "type": "string", "enum": [ "enter", "suggestion", "blur" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "NavigationCause": { - "type": "string", "enum": [ "user_typed", "link", @@ -39,15 +28,11 @@ "history", "script", "browser" - ] + ], + "type": "string" }, "PageRefV2": { "description": "Page context dictionary entry — referenced by steps via `page` id.", - "type": "object", - "required": [ - "id", - "url" - ], "properties": { "id": { "type": "string" @@ -61,49 +46,50 @@ "url": { "type": "string" } - } + }, + "required": [ + "id", + "url" + ], + "type": "object" }, "RecordedTrace": { + "else": { + "$ref": "#/definitions/TraceV2" + }, "if": { - "required": [ - "version" - ], "properties": { "version": { "type": "integer" } - } + }, + "required": [ + "version" + ] }, "then": { "$ref": "#/definitions/TraceV3" - }, - "else": { - "$ref": "#/definitions/TraceV2" } }, "RecorderInfo": { - "type": "object", - "required": [ - "bsk", - "vom" - ], "properties": { "bsk": { "type": "string" }, "vom": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "bsk", + "vom" + ], + "type": "object" }, "SelectedOptionV2": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -114,14 +100,14 @@ "value": { "type": "string" } - } - }, - "SelectedOptionV3": { - "description": "One selected option (`select` op).", - "type": "object", + }, "required": [ "value" ], + "type": "object" + }, + "SelectedOptionV3": { + "description": "One selected option (`select` op).", "properties": { "label": { "type": [ @@ -132,44 +118,41 @@ "value": { "type": "string" } - } + }, + "required": [ + "value" + ], + "type": "object" }, "StepEffectV2": { "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], "properties": { "navigated_to": { "description": "Reference into `pages[]` for the destination page.", "type": "string" } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "navigated_to" ], + "type": "object" + }, + "StepResultV3": { "properties": { "state": { "type": "string" } - } + }, + "required": [ + "state" + ], + "type": "object" }, "StepV2": { "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -182,15 +165,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -199,17 +180,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -222,15 +203,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -239,17 +218,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -262,15 +241,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -279,18 +256,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -303,15 +279,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -329,18 +303,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -353,40 +327,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -399,27 +372,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -435,7 +406,14 @@ } ] } - } + }, + "required": [ + "op", + "id", + "page", + "key" + ], + "type": "object" } ] }, @@ -444,29 +422,18 @@ "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -478,28 +445,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -508,29 +475,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -542,29 +506,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -576,34 +538,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -621,38 +579,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -661,41 +619,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -714,28 +670,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -744,23 +699,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } + }, + "required": [ + "op", + "id", + "state", + "result" + ], + "type": "object" } ] }, "StopReason": { - "type": "string", "enum": [ "user_finish", "cli_stop" - ] + ], + "type": "string" }, "TargetDescriptorV2": { "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" - ], "properties": { "name": { "type": [ @@ -795,11 +753,14 @@ "tag": { "type": "string" } - } + }, + "required": [ + "tag" + ], + "type": "object" }, "TargetDescriptorV3": { "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", "properties": { "ctx": { "type": [ @@ -828,27 +789,22 @@ "unmatched": { "type": "boolean" } - } + }, + "type": "object" }, "TraceEntry": { - "type": "object", - "required": [ - "start_url" - ], "properties": { "start_url": { "type": "string" } - } + }, + "required": [ + "start_url" + ], + "type": "object" }, "TraceStateV3": { "description": "Page observation dictionary entry — referenced by steps via `state` / `result.state`.", - "type": "object", - "required": [ - "body", - "id", - "url" - ], "properties": { "body": { "description": "Full page observation (front matter + VOM body + annotations).", @@ -869,27 +825,25 @@ "url": { "type": "string" } - } - }, - "TraceV2": { - "title": "TraceV2", - "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable. `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` classification.", - "type": "object", + }, "required": [ - "entry", - "pages", - "recorded_at", - "steps" + "id", + "url", + "body" ], + "type": "object" + }, + "TraceV2": { + "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable.\n`states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace`\nclassification — serde still ignores them, but the JSON Schema rejects them.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" }, "pages": { - "type": "array", "items": { "$ref": "#/definitions/PageRefV2" - } + }, + "type": "array" }, "purpose": { "type": [ @@ -909,10 +863,10 @@ }, "states": false, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV2" - } + }, + "type": "array" }, "version": { "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", @@ -920,20 +874,18 @@ "type": "integer" } } - } - }, - "TraceV3": { - "description": "Wire trace returned by `tool.record_stop` / `await`.", - "type": "object", + }, "required": [ - "entry", "recorded_at", - "recorder", - "states", - "steps", - "stopped_by", - "version" + "entry", + "pages", + "steps" ], + "type": "object" + }, + "TraceV3": { + "additionalProperties": false, + "description": "Wire trace returned by `tool.record_stop` / `await`.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" @@ -957,26 +909,45 @@ ] }, "states": { - "type": "array", "items": { "$ref": "#/definitions/TraceStateV3" - } + }, + "type": "array" }, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV3" - } + }, + "type": "array" }, "stopped_by": { "$ref": "#/definitions/StopReason" }, "version": { - "type": "integer", - "const": 3 + "const": 3, + "type": "integer" } }, - "additionalProperties": false + "required": [ + "version", + "recorded_at", + "stopped_by", + "entry", + "recorder", + "states", + "steps" + ], + "type": "object" } - } + }, + "properties": { + "trace": { + "$ref": "#/definitions/RecordedTrace" + } + }, + "required": [ + "trace" + ], + "title": "RecordAwaitResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_start_params.json b/crates/bsk-protocol/schema/tool_record_start_params.json index 4120938bb..253c6f533 100644 --- a/crates/bsk-protocol/schema/tool_record_start_params.json +++ b/crates/bsk-protocol/schema/tool_record_start_params.json @@ -1,18 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordStartParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "max_page_tokens": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "purpose": { "type": [ @@ -37,20 +32,20 @@ ] }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "trace_version": { "description": "Desired trace export format. Omitted means v2; `3` requests v3.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "url": { "type": [ @@ -58,5 +53,10 @@ "null" ] } - } + }, + "required": [ + "session_id" + ], + "title": "RecordStartParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_start_result.json b/crates/bsk-protocol/schema/tool_record_start_result.json index 5c04ceb07..ffacdaad2 100644 --- a/crates/bsk-protocol/schema/tool_record_start_result.json +++ b/crates/bsk-protocol/schema/tool_record_start_result.json @@ -1,18 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordStartResult", - "type": "object", - "required": [ - "recording", - "tab_id" - ], "properties": { "recording": { "type": "boolean" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "recording" + ], + "title": "RecordStartResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_stop_params.json b/crates/bsk-protocol/schema/tool_record_stop_params.json index 2132963cb..d62b2b4af 100644 --- a/crates/bsk-protocol/schema/tool_record_stop_params.json +++ b/crates/bsk-protocol/schema/tool_record_stop_params.json @@ -1,13 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordStopParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "session_id": { "type": "string" } - } + }, + "required": [ + "session_id" + ], + "title": "RecordStopParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_record_stop_result.json b/crates/bsk-protocol/schema/tool_record_stop_result.json index 3973df41f..fd93f901d 100644 --- a/crates/bsk-protocol/schema/tool_record_stop_result.json +++ b/crates/bsk-protocol/schema/tool_record_stop_result.json @@ -1,36 +1,25 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordStopResult", - "type": "object", - "required": [ - "trace" - ], - "properties": { - "trace": { - "$ref": "#/definitions/RecordedTrace" - } - }, "definitions": { "FillCommit": { - "type": "string", "enum": [ "enter", "suggestion", "blur" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "NavigationCause": { - "type": "string", "enum": [ "user_typed", "link", @@ -39,15 +28,11 @@ "history", "script", "browser" - ] + ], + "type": "string" }, "PageRefV2": { "description": "Page context dictionary entry — referenced by steps via `page` id.", - "type": "object", - "required": [ - "id", - "url" - ], "properties": { "id": { "type": "string" @@ -61,49 +46,50 @@ "url": { "type": "string" } - } + }, + "required": [ + "id", + "url" + ], + "type": "object" }, "RecordedTrace": { + "else": { + "$ref": "#/definitions/TraceV2" + }, "if": { - "required": [ - "version" - ], "properties": { "version": { "type": "integer" } - } + }, + "required": [ + "version" + ] }, "then": { "$ref": "#/definitions/TraceV3" - }, - "else": { - "$ref": "#/definitions/TraceV2" } }, "RecorderInfo": { - "type": "object", - "required": [ - "bsk", - "vom" - ], "properties": { "bsk": { "type": "string" }, "vom": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "bsk", + "vom" + ], + "type": "object" }, "SelectedOptionV2": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -114,14 +100,14 @@ "value": { "type": "string" } - } - }, - "SelectedOptionV3": { - "description": "One selected option (`select` op).", - "type": "object", + }, "required": [ "value" ], + "type": "object" + }, + "SelectedOptionV3": { + "description": "One selected option (`select` op).", "properties": { "label": { "type": [ @@ -132,44 +118,41 @@ "value": { "type": "string" } - } + }, + "required": [ + "value" + ], + "type": "object" }, "StepEffectV2": { "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], "properties": { "navigated_to": { "description": "Reference into `pages[]` for the destination page.", "type": "string" } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "navigated_to" ], + "type": "object" + }, + "StepResultV3": { "properties": { "state": { "type": "string" } - } + }, + "required": [ + "state" + ], + "type": "object" }, "StepV2": { "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -182,15 +165,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -199,17 +180,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -222,15 +203,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -239,17 +218,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -262,15 +241,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -279,18 +256,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -303,15 +279,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -329,18 +303,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -353,40 +327,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -399,27 +372,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -435,7 +406,14 @@ } ] } - } + }, + "required": [ + "op", + "id", + "page", + "key" + ], + "type": "object" } ] }, @@ -444,29 +422,18 @@ "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -478,28 +445,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -508,29 +475,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -542,29 +506,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -576,34 +538,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -621,38 +579,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -661,41 +619,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -714,28 +670,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -744,23 +699,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } + }, + "required": [ + "op", + "id", + "state", + "result" + ], + "type": "object" } ] }, "StopReason": { - "type": "string", "enum": [ "user_finish", "cli_stop" - ] + ], + "type": "string" }, "TargetDescriptorV2": { "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" - ], "properties": { "name": { "type": [ @@ -795,11 +753,14 @@ "tag": { "type": "string" } - } + }, + "required": [ + "tag" + ], + "type": "object" }, "TargetDescriptorV3": { "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", "properties": { "ctx": { "type": [ @@ -828,27 +789,22 @@ "unmatched": { "type": "boolean" } - } + }, + "type": "object" }, "TraceEntry": { - "type": "object", - "required": [ - "start_url" - ], "properties": { "start_url": { "type": "string" } - } + }, + "required": [ + "start_url" + ], + "type": "object" }, "TraceStateV3": { "description": "Page observation dictionary entry — referenced by steps via `state` / `result.state`.", - "type": "object", - "required": [ - "body", - "id", - "url" - ], "properties": { "body": { "description": "Full page observation (front matter + VOM body + annotations).", @@ -869,27 +825,25 @@ "url": { "type": "string" } - } - }, - "TraceV2": { - "title": "TraceV2", - "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable. `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` classification.", - "type": "object", + }, "required": [ - "entry", - "pages", - "recorded_at", - "steps" + "id", + "url", + "body" ], + "type": "object" + }, + "TraceV2": { + "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable.\n`states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace`\nclassification — serde still ignores them, but the JSON Schema rejects them.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" }, "pages": { - "type": "array", "items": { "$ref": "#/definitions/PageRefV2" - } + }, + "type": "array" }, "purpose": { "type": [ @@ -909,10 +863,10 @@ }, "states": false, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV2" - } + }, + "type": "array" }, "version": { "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", @@ -920,20 +874,18 @@ "type": "integer" } } - } - }, - "TraceV3": { - "description": "Wire trace returned by `tool.record_stop` / `await`.", - "type": "object", + }, "required": [ - "entry", "recorded_at", - "recorder", - "states", - "steps", - "stopped_by", - "version" + "entry", + "pages", + "steps" ], + "type": "object" + }, + "TraceV3": { + "additionalProperties": false, + "description": "Wire trace returned by `tool.record_stop` / `await`.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" @@ -957,26 +909,45 @@ ] }, "states": { - "type": "array", "items": { "$ref": "#/definitions/TraceStateV3" - } + }, + "type": "array" }, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV3" - } + }, + "type": "array" }, "stopped_by": { "$ref": "#/definitions/StopReason" }, "version": { - "type": "integer", - "const": 3 + "const": 3, + "type": "integer" } }, - "additionalProperties": false + "required": [ + "version", + "recorded_at", + "stopped_by", + "entry", + "recorder", + "states", + "steps" + ], + "type": "object" } - } + }, + "properties": { + "trace": { + "$ref": "#/definitions/RecordedTrace" + } + }, + "required": [ + "trace" + ], + "title": "RecordStopResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_reload_params.json b/crates/bsk-protocol/schema/tool_reload_params.json index fac11d6e4..5d7cee11b 100644 --- a/crates/bsk-protocol/schema/tool_reload_params.json +++ b/crates/bsk-protocol/schema/tool_reload_params.json @@ -1,10 +1,17 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ReloadParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "WaitUntil": { + "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` → `load`\n* `DomContentLoaded` → `DOMContentLoaded`\n* `NetworkIdle` → `networkIdle`\n* `Commit` → `commit` (earliest event after the navigation actually\n commits to a new document)", + "enum": [ + "load", + "domcontentloaded", + "networkidle", + "commit" + ], + "type": "string" + } + }, "properties": { "hard": { "description": "When `true`, bypass the HTTP cache (CDP `Page.reload(ignoreCache=true)`).", @@ -17,19 +24,19 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "wait_until": { "anyOf": [ @@ -42,16 +49,9 @@ ] } }, - "definitions": { - "WaitUntil": { - "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names: * `Load` → `load` * `DomContentLoaded` → `DOMContentLoaded` * `NetworkIdle` → `networkIdle` * `Commit` → `commit` (earliest event after the navigation actually commits to a new document)", - "type": "string", - "enum": [ - "load", - "domcontentloaded", - "networkidle", - "commit" - ] - } - } + "required": [ + "session_id" + ], + "title": "ReloadParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_reload_result.json b/crates/bsk-protocol/schema/tool_reload_result.json index cddfc6111..2a6ef4005 100644 --- a/crates/bsk-protocol/schema/tool_reload_result.json +++ b/crates/bsk-protocol/schema/tool_reload_result.json @@ -1,63 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ReloadResult", - "type": "object", - "required": [ - "reached", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error_text": { - "type": [ - "string", - "null" - ] - }, - "final_url": { - "type": [ - "string", - "null" - ] - }, - "previous_url": { - "type": [ - "string", - "null" - ] - }, - "reached": { - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -79,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -96,17 +49,64 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error_text": { + "type": [ + "string", + "null" ] + }, + "final_url": { + "type": [ + "string", + "null" + ] + }, + "previous_url": { + "type": [ + "string", + "null" + ] + }, + "reached": { + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "reached" + ], + "title": "ReloadResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_request_help_params.json b/crates/bsk-protocol/schema/tool_request_help_params.json index dd6db311c..c4619526b 100644 --- a/crates/bsk-protocol/schema/tool_request_help_params.json +++ b/crates/bsk-protocol/schema/tool_request_help_params.json @@ -1,68 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RequestHelpParams", - "type": "object", - "required": [ - "prompt", - "session_id" - ], - "properties": { - "completion_criteria": { - "description": "Optional explicit success detector. Navigation by itself is not a completion signal; these criteria must match before the tool can auto-complete without the user clicking Done.", - "anyOf": [ - { - "$ref": "#/definitions/HelpCompletionCriteria" - }, - { - "type": "null" - } - ] - }, - "prompt": { - "description": "Message shown to the user explaining what to do.", - "type": "string" - }, - "session_id": { - "type": "string" - }, - "tab_id": { - "description": "Target tab. Defaults to the Agent Window's active tab.", - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "targets": { - "description": "Optional components to scroll to + flash-highlight.", - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/HelpTarget" - } - }, - "timeout_ms": { - "description": "Hard upper bound on the wait. Defaults to 300000 (5 min), enforced daemon-side via the generic tool timeout.", - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 1.0 - }, - "title": { - "description": "Optional custom title for the help overlay. Falls back to the extension's default localized title when omitted.", - "type": [ - "string", - "null" - ] - } - }, "definitions": { "HelpCompletionCondition": { - "type": "object", "properties": { "selector_exists": { "type": [ @@ -96,50 +35,50 @@ }, "url_matches": { "description": "RE2-compatible URL regex (maximum 128 characters). Backtracking-only syntax is rejected.", + "maxLength": 128, "type": [ "string", "null" - ], - "maxLength": 128 + ] } - } + }, + "type": "object" }, "HelpCompletionCriteria": { - "type": "object", "properties": { "all": { - "type": [ - "array", - "null" - ], "items": { "$ref": "#/definitions/HelpCompletionCondition" }, - "maxItems": 8 - }, - "any": { + "maxItems": 8, "type": [ "array", "null" - ], + ] + }, + "any": { "items": { "$ref": "#/definitions/HelpCompletionCondition" }, - "maxItems": 8 + "maxItems": 8, + "type": [ + "array", + "null" + ] }, "stable_for_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "type": "object" }, "HelpTarget": { - "description": "One component the user is asked to look at / interact with. Exactly one of `ref` / `selector` should be supplied (mirrors the click/fill convention). When neither matches a live element the overlay still shows the prompt and reports the miss via [`ResolvedTarget`].", - "type": "object", + "description": "One component the user is asked to look at / interact with. Exactly\none of `ref` / `selector` should be supplied (mirrors the\nclick/fill convention). When neither matches a live element the\noverlay still shows the prompt and reports the miss via\n[`ResolvedTarget`].", "properties": { "ref": { "type": [ @@ -153,7 +92,68 @@ "null" ] } - } + }, + "type": "object" } - } + }, + "properties": { + "completion_criteria": { + "anyOf": [ + { + "$ref": "#/definitions/HelpCompletionCriteria" + }, + { + "type": "null" + } + ], + "description": "Optional explicit success detector. Navigation by itself is not a\ncompletion signal; these criteria must match before the tool can\nauto-complete without the user clicking Done." + }, + "prompt": { + "description": "Message shown to the user explaining what to do.", + "type": "string" + }, + "session_id": { + "type": "string" + }, + "tab_id": { + "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "targets": { + "description": "Optional components to scroll to + flash-highlight.", + "items": { + "$ref": "#/definitions/HelpTarget" + }, + "type": [ + "array", + "null" + ] + }, + "timeout_ms": { + "description": "Hard upper bound on the wait. Defaults to 300000 (5 min),\nenforced daemon-side via the generic tool timeout.", + "format": "uint32", + "minimum": 1, + "type": [ + "integer", + "null" + ] + }, + "title": { + "description": "Optional custom title for the help overlay. Falls back to the\nextension's default localized title when omitted.", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "session_id", + "prompt" + ], + "title": "RequestHelpParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_request_help_result.json b/crates/bsk-protocol/schema/tool_request_help_result.json index d7b7dc775..560508091 100644 --- a/crates/bsk-protocol/schema/tool_request_help_result.json +++ b/crates/bsk-protocol/schema/tool_request_help_result.json @@ -1,104 +1,48 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RequestHelpResult", - "type": "object", - "required": [ - "outcome", - "tab_id" - ], - "properties": { - "completed_by": { - "anyOf": [ - { - "$ref": "#/definitions/HelpCompletedBy" - }, - { - "type": "null" - } - ] - }, - "note": { - "type": [ - "string", - "null" - ] - }, - "outcome": { - "$ref": "#/definitions/HelpOutcome" - }, - "resolved_targets": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/ResolvedTarget" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "HelpCompletedBy": { - "type": "string", "enum": [ "system" - ] + ], + "type": "string" }, "HelpOutcome": { "oneOf": [ { + "const": "continued", "description": "User completed the step and clicked Done / return control.", - "type": "string", - "enum": [ - "continued" - ] + "type": "string" }, { + "const": "cancelled", "description": "User declined / aborted via the overlay's Cancel button.", - "type": "string", - "enum": [ - "cancelled" - ] + "type": "string" }, { + "const": "timed_out", "description": "The wait expired before the user acted.", - "type": "string", - "enum": [ - "timed_out" - ] + "type": "string" }, { + "const": "completed", "description": "Explicit success criteria matched while the user had control.", - "type": "string", - "enum": [ - "completed" - ] + "type": "string" }, { - "description": "The page navigated while waiting (full reload or SPA URL change). Deprecated: navigation alone should not end a help request.", - "type": "string", - "enum": [ - "navigated" - ] + "const": "navigated", + "description": "The page navigated while waiting (full reload or SPA URL change).\nDeprecated: navigation alone should not end a help request.", + "type": "string" }, { - "description": "request-help is disabled by configuration (`BSK_REQUEST_HELP=off`): the call returns immediately without ever showing the overlay.", - "type": "string", - "enum": [ - "disabled" - ] + "const": "disabled", + "description": "request-help is disabled by configuration (`BSK_REQUEST_HELP=off`):\nthe call returns immediately without ever showing the overlay.", + "type": "string" } ] }, "ResolvedTarget": { - "description": "Per-target resolution status echoed back so the agent can tell which `ref` / `selector` actually matched a live element.", - "type": "object", - "required": [ - "matched" - ], + "description": "Per-target resolution status echoed back so the agent can tell which\n`ref` / `selector` actually matched a live element.", "properties": { "matched": { "type": "boolean" @@ -115,7 +59,51 @@ "null" ] } - } + }, + "required": [ + "matched" + ], + "type": "object" } - } + }, + "properties": { + "completed_by": { + "anyOf": [ + { + "$ref": "#/definitions/HelpCompletedBy" + }, + { + "type": "null" + } + ] + }, + "note": { + "type": [ + "string", + "null" + ] + }, + "outcome": { + "$ref": "#/definitions/HelpOutcome" + }, + "resolved_targets": { + "items": { + "$ref": "#/definitions/ResolvedTarget" + }, + "type": [ + "array", + "null" + ] + }, + "tab_id": { + "format": "int64", + "type": "integer" + } + }, + "required": [ + "outcome", + "tab_id" + ], + "title": "RequestHelpResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_full_page_params.json b/crates/bsk-protocol/schema/tool_screenshot_full_page_params.json index 8cf657a36..8b727794a 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_full_page_params.json +++ b/crates/bsk-protocol/schema/tool_screenshot_full_page_params.json @@ -1,14 +1,17 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotFullPageParams", - "description": "Scroll the session's active web page from top to bottom. PNG bytes are exported in bounded chunks through `tool.screenshot_read`, then released.", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "ScreenshotScope": { + "enum": [ + "follow", + "current" + ], + "type": "string" + } + }, + "description": "Scroll the session's active web page from top to bottom. PNG bytes are\nexported in bounded chunks through `tool.screenshot_read`, then released.", "properties": { "scope": { - "description": "Follow appended content (default), or capture the initial document height.", "anyOf": [ { "$ref": "#/definitions/ScreenshotScope" @@ -16,35 +19,32 @@ { "type": "null" } - ] + ], + "description": "Follow appended content (default), or capture the initial document height." }, "session_id": { "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { "description": "Capture and PNG encoding deadline; defaults to 120000 milliseconds.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "definitions": { - "ScreenshotScope": { - "type": "string", - "enum": [ - "follow", - "current" ] } - } + }, + "required": [ + "session_id" + ], + "title": "ScreenshotFullPageParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_full_page_result.json b/crates/bsk-protocol/schema/tool_screenshot_full_page_result.json index bf15abda4..d112600c5 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_full_page_result.json +++ b/crates/bsk-protocol/schema/tool_screenshot_full_page_result.json @@ -1,78 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotFullPageResult", - "type": "object", - "required": [ - "byte_size", - "capture_id", - "format", - "height", - "tab_id", - "width" - ], - "properties": { - "byte_size": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "capture_id": { - "description": "Opaque, session-scoped export capability. Never an agent filesystem path.", - "type": "string" - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "format": { - "type": "string" - }, - "height": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "scope": { - "anyOf": [ - { - "$ref": "#/definitions/ScreenshotScope" - }, - { - "type": "null" - } - ] - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "width": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -94,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -111,24 +49,86 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" }, "ScreenshotScope": { - "type": "string", "enum": [ "follow", "current" + ], + "type": "string" + } + }, + "properties": { + "byte_size": { + "format": "uint64", + "minimum": 0, + "type": "integer" + }, + "capture_id": { + "description": "Opaque, session-scoped export capability. Never an agent filesystem path.", + "type": "string" + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "format": { + "type": "string" + }, + "height": { + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "scope": { + "anyOf": [ + { + "$ref": "#/definitions/ScreenshotScope" + }, + { + "type": "null" + } ] + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "width": { + "format": "uint32", + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "capture_id", + "width", + "height", + "format", + "tab_id", + "byte_size" + ], + "title": "ScreenshotFullPageResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_params.json b/crates/bsk-protocol/schema/tool_screenshot_params.json index e63c55f70..debcee655 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_params.json +++ b/crates/bsk-protocol/schema/tool_screenshot_params.json @@ -1,14 +1,9 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotParams", - "description": "Parameters for `tool.screenshot`. Omit `ref` to capture the visible tab; pass an `@e` ref from the last `tool.snapshot` to crop to that element.", - "type": "object", - "required": [ - "session_id" - ], + "description": "Parameters for `tool.screenshot`. Omit `ref` to capture the visible\ntab; pass an `@e` ref from the last `tool.snapshot` to crop to\nthat element.", "properties": { "ref": { - "description": "Optional `@e` ref allocated by the last `tool.snapshot`. Accepts both `\"e3\"` and `\"@e3\"`.", + "description": "Optional `@e` ref allocated by the last `tool.snapshot`.\nAccepts both `\"e3\"` and `\"@e3\"`.", "type": [ "string", "null" @@ -18,11 +13,16 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "ScreenshotParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_read_params.json b/crates/bsk-protocol/schema/tool_screenshot_read_params.json index 0d0341dea..7dfb0e4f8 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_read_params.json +++ b/crates/bsk-protocol/schema/tool_screenshot_read_params.json @@ -1,24 +1,24 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotReadParams", - "type": "object", - "required": [ - "capture_id", - "offset", - "session_id" - ], "properties": { "capture_id": { "type": "string" }, "offset": { "description": "Byte offset, allowing an interrupted chunk request to be retried.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "session_id": { "type": "string" } - } + }, + "required": [ + "session_id", + "capture_id", + "offset" + ], + "title": "ScreenshotReadParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_read_result.json b/crates/bsk-protocol/schema/tool_screenshot_read_result.json index 299fb6f12..38cd81ee6 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_read_result.json +++ b/crates/bsk-protocol/schema/tool_screenshot_read_result.json @@ -1,12 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotReadResult", - "type": "object", - "required": [ - "data_base64", - "eof", - "next_offset" - ], "properties": { "data_base64": { "description": "At most 256 KiB of PNG bytes, base64 encoded.", @@ -16,9 +9,16 @@ "type": "boolean" }, "next_offset": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "data_base64", + "next_offset", + "eof" + ], + "title": "ScreenshotReadResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_release_params.json b/crates/bsk-protocol/schema/tool_screenshot_release_params.json index d37bc5637..bf146d548 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_release_params.json +++ b/crates/bsk-protocol/schema/tool_screenshot_release_params.json @@ -1,11 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotReleaseParams", - "type": "object", - "required": [ - "capture_id", - "session_id" - ], "properties": { "capture_id": { "type": "string" @@ -13,5 +7,11 @@ "session_id": { "type": "string" } - } + }, + "required": [ + "session_id", + "capture_id" + ], + "title": "ScreenshotReleaseParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_release_result.json b/crates/bsk-protocol/schema/tool_screenshot_release_result.json index 256c5d256..74be055bb 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_release_result.json +++ b/crates/bsk-protocol/schema/tool_screenshot_release_result.json @@ -1,13 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotReleaseResult", - "type": "object", - "required": [ - "released" - ], "properties": { "released": { "type": "boolean" } - } + }, + "required": [ + "released" + ], + "title": "ScreenshotReleaseResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_screenshot_result.json b/crates/bsk-protocol/schema/tool_screenshot_result.json index f78342d1e..4797e4e0f 100644 --- a/crates/bsk-protocol/schema/tool_screenshot_result.json +++ b/crates/bsk-protocol/schema/tool_screenshot_result.json @@ -1,79 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScreenshotResult", - "type": "object", - "required": [ - "format", - "image_base64", - "tab_id" - ], - "properties": { - "capture_id": { - "description": "Single-use visual point-click capture, in the original PNG coordinate space.", - "type": [ - "string", - "null" - ] - }, - "capture_unavailable": { - "description": "Image remains viewable but cannot authorize a point click.", - "type": [ - "string", - "null" - ] - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "format": { - "description": "Always `\"png\"` in v0.1; reserved for future JPEG / WebP support.", - "type": "string" - }, - "height": { - "description": "Pixel height (see [`Self::width`]).", - "default": 0, - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "image_base64": { - "description": "Base64-encoded PNG payload (no `data:` prefix).", - "type": "string" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "width": { - "description": "Pixel width parsed from the PNG IHDR. May be `0` when parsing fails (extension only logs a warning in that case so the agent still gets the image).", - "default": 0, - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -95,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -112,17 +49,80 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "capture_id": { + "description": "Single-use visual point-click capture, in the original PNG coordinate space.", + "type": [ + "string", + "null" ] + }, + "capture_unavailable": { + "description": "Image remains viewable but cannot authorize a point click.", + "type": [ + "string", + "null" + ] + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "format": { + "description": "Always `\"png\"` in v0.1; reserved for future JPEG / WebP support.", + "type": "string" + }, + "height": { + "default": 0, + "description": "Pixel height (see [`Self::width`]).", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "image_base64": { + "description": "Base64-encoded PNG payload (no `data:` prefix).", + "type": "string" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "width": { + "default": 0, + "description": "Pixel width parsed from the PNG IHDR. May be `0` when parsing\nfails (extension only logs a warning in that case so the agent\nstill gets the image).", + "format": "uint32", + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "image_base64", + "format", + "tab_id" + ], + "title": "ScreenshotResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_scroll_to_params.json b/crates/bsk-protocol/schema/tool_scroll_to_params.json index 77ada1de6..9d93ea419 100644 --- a/crates/bsk-protocol/schema/tool_scroll_to_params.json +++ b/crates/bsk-protocol/schema/tool_scroll_to_params.json @@ -1,13 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScrollToParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "ref": { - "description": "Optional `@e` ref allocated by the last observation. Mutually exclusive with `selector`.", + "description": "Optional `@e` ref allocated by the last observation.\nMutually exclusive with `selector`.", "type": [ "string", "null" @@ -24,19 +19,24 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "ScrollToParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_scroll_to_result.json b/crates/bsk-protocol/schema/tool_scroll_to_result.json index cad271089..34260049a 100644 --- a/crates/bsk-protocol/schema/tool_scroll_to_result.json +++ b/crates/bsk-protocol/schema/tool_scroll_to_result.json @@ -1,74 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ScrollToResult", - "type": "object", - "required": [ - "height", - "tab_id", - "width", - "x", - "y" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "height": { - "type": "number", - "format": "double" - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "width": { - "type": "number", - "format": "double" - }, - "x": { - "description": "Bounding rectangle of the element's visible border-box portion, in top-level viewport CSS pixels, after ancestor and viewport clipping. Partial visibility is sufficient. This is not an occlusion or hit test.", - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -90,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -107,17 +49,75 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "height": { + "format": "double", + "type": "number" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" + ] + }, + "used_selector": { + "type": [ + "string", + "null" ] + }, + "width": { + "format": "double", + "type": "number" + }, + "x": { + "description": "Bounding rectangle of the element's visible border-box portion, in\ntop-level viewport CSS pixels, after ancestor and viewport clipping.\nPartial visibility is sufficient. This is not an occlusion or hit test.", + "format": "double", + "type": "number" + }, + "y": { + "format": "double", + "type": "number" } - } + }, + "required": [ + "tab_id", + "x", + "y", + "width", + "height" + ], + "title": "ScrollToResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_select_params.json b/crates/bsk-protocol/schema/tool_select_params.json index 347b4a996..2af918003 100644 --- a/crates/bsk-protocol/schema/tool_select_params.json +++ b/crates/bsk-protocol/schema/tool_select_params.json @@ -1,21 +1,15 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SelectParams", - "type": "object", - "required": [ - "session_id", - "values" - ], "properties": { "ref": { - "description": "Optional `@e` ref allocated by the last `tool.snapshot`. Mutually exclusive with `selector`. Accepts both `\"e3\"` and `\"@e3\"`.", + "description": "Optional `@e` ref allocated by the last `tool.snapshot`.\nMutually exclusive with `selector`. Accepts both `\"e3\"` and\n`\"@e3\"`.", "type": [ "string", "null" ] }, "selector": { - "description": "CSS selector resolved against the live DOM. Mutually exclusive with `ref_`.", + "description": "CSS selector resolved against the live DOM. Mutually exclusive\nwith `ref_`.", "type": [ "string", "null" @@ -26,27 +20,33 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { "description": "Maximum time the daemon waits for the tool call before timing out.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "values": { - "description": "Option `value` strings to set as the final selection. For a single-select `` the list replaces the current selection (an empty list clears all selections).", - "type": "array", + "description": "Option `value` strings to set as the final selection. For a\nsingle-select `` the list replaces the current selection\n(an empty list clears all selections).", "items": { "type": "string" - } + }, + "type": "array" } - } + }, + "required": [ + "session_id", + "values" + ], + "title": "SelectParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_select_result.json b/crates/bsk-protocol/schema/tool_select_result.json index 77cc9903e..694b0d2b2 100644 --- a/crates/bsk-protocol/schema/tool_select_result.json +++ b/crates/bsk-protocol/schema/tool_select_result.json @@ -1,74 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SelectResult", - "type": "object", - "required": [ - "multiple", - "selected_labels", - "selected_values", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "multiple": { - "description": "Whether the target `` had the `multiple` attribute.", + "type": "boolean" + }, + "selected_labels": { + "description": "Visible labels of the selected options (same order as\n`selected_values`).", + "items": { + "type": "string" + }, + "type": "array" + }, + "selected_values": { + "description": "Final selected option `value` attributes after the call.", + "items": { + "type": "string" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" + ] + }, + "used_selector": { + "type": [ + "string", + "null" ] } - } + }, + "required": [ + "tab_id", + "multiple", + "selected_values", + "selected_labels" + ], + "title": "SelectResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_session_start_params.json b/crates/bsk-protocol/schema/tool_session_start_params.json index 0b8eb212f..dc94f6794 100644 --- a/crates/bsk-protocol/schema/tool_session_start_params.json +++ b/crates/bsk-protocol/schema/tool_session_start_params.json @@ -1,10 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SessionStartParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "browser_instance_id": { "type": [ @@ -13,7 +8,7 @@ ] }, "focused": { - "description": "Whether the new Agent Window should take focus. Omitted means the extension's default (`true`) for compatibility with older clients.", + "description": "Whether the new Agent Window should take focus. Omitted means the\nextension's default (`true`) for compatibility with older clients.", "type": [ "boolean", "null" @@ -21,24 +16,29 @@ }, "height": { "description": "Optional Agent Window outer height in CSS pixels (100..=7680).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "session_id": { "type": "string" }, "width": { "description": "Optional Agent Window outer width in CSS pixels (100..=7680).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] } - } + }, + "required": [ + "session_id" + ], + "title": "SessionStartParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_session_start_result.json b/crates/bsk-protocol/schema/tool_session_start_result.json index 6649f7baf..32e3354ee 100644 --- a/crates/bsk-protocol/schema/tool_session_start_result.json +++ b/crates/bsk-protocol/schema/tool_session_start_result.json @@ -1,40 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SessionStartResult", - "type": "object", - "properties": { - "agent_window_id": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "interaction": { - "anyOf": [ - { - "$ref": "#/definitions/InteractionPolicy" - }, - { - "type": "null" - } - ] - } - }, "definitions": { "BorrowConfirmationPolicy": { - "type": "string", "enum": [ "always", "never" - ] + ], + "type": "string" }, "InteractionPolicy": { - "type": "object", - "required": [ - "borrow_confirmation", - "request_help" - ], "properties": { "borrow_confirmation": { "$ref": "#/definitions/BorrowConfirmationPolicy" @@ -42,14 +16,40 @@ "request_help": { "$ref": "#/definitions/RequestHelpPolicy" } - } + }, + "required": [ + "borrow_confirmation", + "request_help" + ], + "type": "object" }, "RequestHelpPolicy": { - "type": "string", "enum": [ "enabled", "disabled" + ], + "type": "string" + } + }, + "properties": { + "agent_window_id": { + "format": "int64", + "type": [ + "integer", + "null" + ] + }, + "interaction": { + "anyOf": [ + { + "$ref": "#/definitions/InteractionPolicy" + }, + { + "type": "null" + } ] } - } + }, + "title": "SessionStartResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_session_stop_params.json b/crates/bsk-protocol/schema/tool_session_stop_params.json index 4551981c3..9fafe7a87 100644 --- a/crates/bsk-protocol/schema/tool_session_stop_params.json +++ b/crates/bsk-protocol/schema/tool_session_stop_params.json @@ -1,13 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SessionStopParams", - "type": "object", - "required": [ - "session_id" - ], "properties": { "session_id": { "type": "string" } - } + }, + "required": [ + "session_id" + ], + "title": "SessionStopParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_session_stop_result.json b/crates/bsk-protocol/schema/tool_session_stop_result.json index dc7341cc6..9a9552821 100644 --- a/crates/bsk-protocol/schema/tool_session_stop_result.json +++ b/crates/bsk-protocol/schema/tool_session_stop_result.json @@ -1,26 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SessionStopResult", - "type": "object", - "properties": { - "return_failures": { - "type": "array", - "items": { - "$ref": "#/definitions/ReturnFailure" - } - }, - "returned_tab_ids": { - "type": "array", - "items": { - "type": "integer", - "format": "int64" - } - } - }, "definitions": { "ErrorCode": { "description": "Stable daemon/extension error codes (§4.5).", - "type": "string", "enum": [ "unknown_method", "unsupported", @@ -35,15 +17,10 @@ "version_too_old", "multiple_browsers_online", "no_browser_connected" - ] + ], + "type": "string" }, "ReturnFailure": { - "type": "object", - "required": [ - "code", - "message", - "tab_id" - ], "properties": { "code": { "$ref": "#/definitions/ErrorCode" @@ -52,10 +29,40 @@ "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "code", + "message" + ], + "type": "object" + } + }, + "description": "Full extension response, including whether a window was left with the user.", + "properties": { + "return_failures": { + "items": { + "$ref": "#/definitions/ReturnFailure" + }, + "type": "array" + }, + "returned_tab_ids": { + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "window_released": { + "type": [ + "boolean", + "null" + ] } - } + }, + "title": "SessionStopOutcome", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_snapshot_params.json b/crates/bsk-protocol/schema/tool_snapshot_params.json index 862be88df..144ff003b 100644 --- a/crates/bsk-protocol/schema/tool_snapshot_params.json +++ b/crates/bsk-protocol/schema/tool_snapshot_params.json @@ -1,40 +1,40 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SnapshotParams", - "description": "Parameters for `tool.snapshot` — produce an indented accessibility tree for one tab plus a fresh `@e` ref-store on the extension side (design §4 / §7).", - "type": "object", - "required": [ - "session_id" - ], + "description": "Parameters for `tool.snapshot` — produce an indented accessibility\ntree for one tab plus a fresh `@e` ref-store on the extension\nside (design §4 / §7).", "properties": { "max_depth": { - "description": "Cap the depth of the rendered tree (defense against very deep pages). Implementation-defined default; agents typically use `Some(16)` for \"browse and read\" prompts.", + "description": "Cap the depth of the rendered tree (defense against very deep\npages). Implementation-defined default; agents typically use\n`Some(16)` for \"browse and read\" prompts.", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "max_tokens": { - "description": "Soft cap on rendered tokens (approximate; extension uses a best-effort heuristic based on character count).", + "description": "Soft cap on rendered tokens (approximate; extension uses a\nbest-effort heuristic based on character count).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "session_id": { "type": "string" }, "tab_id": { - "description": "Optional target tab. Defaults to the Agent Window's currently active tab.", + "description": "Optional target tab. Defaults to the Agent Window's currently\nactive tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "session_id" + ], + "title": "SnapshotParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_snapshot_result.json b/crates/bsk-protocol/schema/tool_snapshot_result.json index da4ff111c..e335c361c 100644 --- a/crates/bsk-protocol/schema/tool_snapshot_result.json +++ b/crates/bsk-protocol/schema/tool_snapshot_result.json @@ -1,59 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SnapshotResult", - "type": "object", - "required": [ - "ref_count", - "tab_id", - "text" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "ref_count": { - "description": "Number of `@e` refs registered for this session by this snapshot. Equivalent to the size of the new ref-store map.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "tab_id": { - "description": "Tab the snapshot was actually computed for (after resolving the optional `tab_id` default).", - "type": "integer", - "format": "int64" - }, - "text": { - "description": "Indented aria-snapshot text. Refs are rendered as `@e` so the agent can copy them into subsequent `tool.click` / `tool.fill` selectors.", - "type": "string" - }, - "truncated": { - "description": "Whether the rendered tree was truncated because of `max_depth` / `max_tokens`. Agents may re-run with looser caps.", - "default": false, - "type": "boolean" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -75,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -92,17 +49,60 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" } - } + }, + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "ref_count": { + "description": "Number of `@e` refs registered for this session by this\nsnapshot. Equivalent to the size of the new ref-store map.", + "format": "uint32", + "minimum": 0, + "type": "integer" + }, + "tab_id": { + "description": "Tab the snapshot was actually computed for (after resolving the\noptional `tab_id` default).", + "format": "int64", + "type": "integer" + }, + "text": { + "description": "Indented aria-snapshot text. Refs are rendered as `@e` so the\nagent can copy them into subsequent `tool.click` / `tool.fill`\nselectors.", + "type": "string" + }, + "truncated": { + "default": false, + "description": "Whether the rendered tree was truncated because of `max_depth` /\n`max_tokens`. Agents may re-run with looser caps.", + "type": "boolean" + } + }, + "required": [ + "text", + "ref_count", + "tab_id" + ], + "title": "SnapshotResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_borrow_params.json b/crates/bsk-protocol/schema/tool_tab_borrow_params.json index eda7ec3ef..6434dc3f4 100644 --- a/crates/bsk-protocol/schema/tool_tab_borrow_params.json +++ b/crates/bsk-protocol/schema/tool_tab_borrow_params.json @@ -1,12 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabBorrowParams", - "description": "Params for `tool.tab_borrow`. Moves a *user* tab into the requesting session's Agent Window, recording its original window / index so `tab_return` (or session_stop) can put it back.", - "type": "object", - "required": [ - "session_id", - "tab_id" - ], + "description": "Params for `tool.tab_borrow`. Moves a *user* tab into the\nrequesting session's Agent Window, recording its original window /\nindex so `tab_return` (or session_stop) can put it back.", "properties": { "confirm": { "description": "Legacy input, ignored. Browser settings decide whether confirmation is required.", @@ -17,19 +11,25 @@ }, "confirmation_timeout_ms": { "description": "Maximum time to wait for user confirmation (default 60 seconds).", + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 + ] }, "session_id": { "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "session_id" + ], + "title": "TabBorrowParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_borrow_result.json b/crates/bsk-protocol/schema/tool_tab_borrow_result.json index 226385a9a..7bf329842 100644 --- a/crates/bsk-protocol/schema/tool_tab_borrow_result.json +++ b/crates/bsk-protocol/schema/tool_tab_borrow_result.json @@ -1,29 +1,29 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabBorrowResult", - "type": "object", - "required": [ - "agent_window_id", - "original_index", - "original_window_id", - "tab_id" - ], "properties": { "agent_window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "original_index": { - "type": "integer", - "format": "int32" + "format": "int32", + "type": "integer" }, "original_window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "original_window_id", + "original_index", + "agent_window_id" + ], + "title": "TabBorrowResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_close_params.json b/crates/bsk-protocol/schema/tool_tab_close_params.json index 9284d585c..8dd83e73d 100644 --- a/crates/bsk-protocol/schema/tool_tab_close_params.json +++ b/crates/bsk-protocol/schema/tool_tab_close_params.json @@ -1,18 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabCloseParams", - "type": "object", - "required": [ - "session_id", - "tab_id" - ], "properties": { "session_id": { "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "session_id" + ], + "title": "TabCloseParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_close_result.json b/crates/bsk-protocol/schema/tool_tab_close_result.json index 6c5c76e19..607caabba 100644 --- a/crates/bsk-protocol/schema/tool_tab_close_result.json +++ b/crates/bsk-protocol/schema/tool_tab_close_result.json @@ -1,14 +1,14 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabCloseResult", - "type": "object", - "required": [ - "tab_id" - ], "properties": { "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id" + ], + "title": "TabCloseResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_create_params.json b/crates/bsk-protocol/schema/tool_tab_create_params.json index 25a7727af..781d019b0 100644 --- a/crates/bsk-protocol/schema/tool_tab_create_params.json +++ b/crates/bsk-protocol/schema/tool_tab_create_params.json @@ -1,11 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabCreateParams", - "description": "Params for `tool.tab_create`. The new tab is always created inside the requesting session's Agent Window (design §6 sandbox rule — agents never spawn tabs in user windows).", - "type": "object", - "required": [ - "session_id" - ], + "description": "Params for `tool.tab_create`. The new tab is always created inside\nthe requesting session's Agent Window (design §6 sandbox rule —\nagents never spawn tabs in user windows).", "properties": { "active": { "description": "Focus the new tab? Defaults to `true` (matches `chrome.tabs.create`).", @@ -15,12 +10,12 @@ ] }, "index": { - "description": "Insertion index within the Agent Window's tab strip. Omit to append at the end.", + "description": "Insertion index within the Agent Window's tab strip. Omit to\nappend at the end.", + "format": "int32", "type": [ "integer", "null" - ], - "format": "int32" + ] }, "session_id": { "type": "string" @@ -32,5 +27,10 @@ "null" ] } - } + }, + "required": [ + "session_id" + ], + "title": "TabCreateParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_create_result.json b/crates/bsk-protocol/schema/tool_tab_create_result.json index b3eb9880c..7f2549fff 100644 --- a/crates/bsk-protocol/schema/tool_tab_create_result.json +++ b/crates/bsk-protocol/schema/tool_tab_create_result.json @@ -1,24 +1,24 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabCreateResult", - "type": "object", - "required": [ - "tab_id", - "window_id" - ], "properties": { "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "url": { - "description": "Best-effort URL of the newly created tab. May be empty if Chrome has not yet committed the navigation (e.g. pending load).", "default": "", + "description": "Best-effort URL of the newly created tab. May be empty if Chrome\nhas not yet committed the navigation (e.g. pending load).", "type": "string" }, "window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "window_id" + ], + "title": "TabCreateResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_list_params.json b/crates/bsk-protocol/schema/tool_tab_list_params.json index af5e95e6d..df3c66273 100644 --- a/crates/bsk-protocol/schema/tool_tab_list_params.json +++ b/crates/bsk-protocol/schema/tool_tab_list_params.json @@ -1,32 +1,28 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabListParams", - "type": "object", - "required": [ - "session_id" - ], - "properties": { - "scope": { - "default": "all", - "allOf": [ - { - "$ref": "#/definitions/TabScope" - } - ] - }, - "session_id": { - "type": "string" - } - }, "definitions": { "TabScope": { - "description": "View scope for [`TabListParams`] (§6 sandbox table).\n\n* `User` — tabs that live in any window other than an Agent Window. * `Agent` — tabs in the requesting session's Agent Window only. * `All` — both of the above; never reveals other sessions' Agent Windows (cross-session isolation per §6).", - "type": "string", + "description": "View scope for [`TabListParams`] (§6 sandbox table).\n\n* `User` — tabs that live in any window other than an Agent Window.\n* `Agent` — tabs in the requesting session's Agent Window only.\n* `All` — both of the above; never reveals other sessions' Agent\n Windows (cross-session isolation per §6).", "enum": [ "user", "agent", "all" - ] + ], + "type": "string" } - } + }, + "properties": { + "scope": { + "$ref": "#/definitions/TabScope", + "default": "all" + }, + "session_id": { + "type": "string" + } + }, + "required": [ + "session_id" + ], + "title": "TabListParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_list_result.json b/crates/bsk-protocol/schema/tool_tab_list_result.json index dc05e633a..425c1ca19 100644 --- a/crates/bsk-protocol/schema/tool_tab_list_result.json +++ b/crates/bsk-protocol/schema/tool_tab_list_result.json @@ -1,25 +1,8 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabListResult", - "type": "object", - "required": [ - "tabs" - ], - "properties": { - "tabs": { - "type": "array", - "items": { - "$ref": "#/definitions/TabInfo" - } - } - }, "definitions": { "TabInfo": { - "description": "A single tab entry returned by [`TabListResult`].\n\n`scope` reports how the requesting session sees this tab: tabs owned by the session's own Agent Window are tagged `agent`; everything else falls into `user`. (Other sessions' Agent Windows are filtered out before they reach this struct.)", - "type": "object", - "required": [ - "tab_id" - ], + "description": "A single tab entry returned by [`TabListResult`].\n\n`scope` reports how the requesting session sees this tab: tabs owned\nby the session's own Agent Window are tagged `agent`; everything\nelse falls into `user`. (Other sessions' Agent Windows are filtered\nout before they reach this struct.)", "properties": { "active": { "type": [ @@ -28,7 +11,6 @@ ] }, "scope": { - "description": "Where the tab sits relative to the requesting session: `user` or `agent`. `all` is a request-side filter only and never appears on an individual tab entry.", "anyOf": [ { "$ref": "#/definitions/TabScope" @@ -36,11 +18,12 @@ { "type": "null" } - ] + ], + "description": "Where the tab sits relative to the requesting session: `user` or\n`agent`. `all` is a request-side filter only and never appears\non an individual tab entry." }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "title": { "type": [ @@ -55,22 +38,39 @@ ] }, "window_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] } - } + }, + "required": [ + "tab_id" + ], + "type": "object" }, "TabScope": { - "description": "View scope for [`TabListParams`] (§6 sandbox table).\n\n* `User` — tabs that live in any window other than an Agent Window. * `Agent` — tabs in the requesting session's Agent Window only. * `All` — both of the above; never reveals other sessions' Agent Windows (cross-session isolation per §6).", - "type": "string", + "description": "View scope for [`TabListParams`] (§6 sandbox table).\n\n* `User` — tabs that live in any window other than an Agent Window.\n* `Agent` — tabs in the requesting session's Agent Window only.\n* `All` — both of the above; never reveals other sessions' Agent\n Windows (cross-session isolation per §6).", "enum": [ "user", "agent", "all" - ] + ], + "type": "string" + } + }, + "properties": { + "tabs": { + "items": { + "$ref": "#/definitions/TabInfo" + }, + "type": "array" } - } + }, + "required": [ + "tabs" + ], + "title": "TabListResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_return_params.json b/crates/bsk-protocol/schema/tool_tab_return_params.json index f16486735..9f9e3cdaf 100644 --- a/crates/bsk-protocol/schema/tool_tab_return_params.json +++ b/crates/bsk-protocol/schema/tool_tab_return_params.json @@ -1,18 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabReturnParams", - "type": "object", - "required": [ - "session_id", - "tab_id" - ], "properties": { "session_id": { "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "session_id" + ], + "title": "TabReturnParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_return_result.json b/crates/bsk-protocol/schema/tool_tab_return_result.json index c485e2090..80e096510 100644 --- a/crates/bsk-protocol/schema/tool_tab_return_result.json +++ b/crates/bsk-protocol/schema/tool_tab_return_result.json @@ -1,28 +1,28 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabReturnResult", - "type": "object", - "required": [ - "returned_to_index", - "returned_to_window_id", - "tab_id" - ], "properties": { "fallback": { - "description": "True when the original window had been closed and we fell back to either the last focused normal window or a newly-created window. Lets the CLI surface \"tab returned to a different window\" hints.", + "description": "True when the original window had been closed and we fell back\nto either the last focused normal window or a newly-created\nwindow. Lets the CLI surface \"tab returned to a different\nwindow\" hints.", "type": "boolean" }, "returned_to_index": { - "type": "integer", - "format": "int32" + "format": "int32", + "type": "integer" }, "returned_to_window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "returned_to_window_id", + "returned_to_index" + ], + "title": "TabReturnResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_select_params.json b/crates/bsk-protocol/schema/tool_tab_select_params.json index 0dfacaa8d..2a7e50c2f 100644 --- a/crates/bsk-protocol/schema/tool_tab_select_params.json +++ b/crates/bsk-protocol/schema/tool_tab_select_params.json @@ -1,18 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabSelectParams", - "type": "object", - "required": [ - "session_id", - "tab_id" - ], "properties": { "session_id": { "type": "string" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "session_id" + ], + "title": "TabSelectParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_tab_select_result.json b/crates/bsk-protocol/schema/tool_tab_select_result.json index 3f9ac1ef5..02edf7189 100644 --- a/crates/bsk-protocol/schema/tool_tab_select_result.json +++ b/crates/bsk-protocol/schema/tool_tab_select_result.json @@ -1,19 +1,19 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TabSelectResult", - "type": "object", - "required": [ - "tab_id", - "window_id" - ], "properties": { "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "window_id" + ], + "title": "TabSelectResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_upload_params.json b/crates/bsk-protocol/schema/tool_upload_params.json index dd784b997..d258ed391 100644 --- a/crates/bsk-protocol/schema/tool_upload_params.json +++ b/crates/bsk-protocol/schema/tool_upload_params.json @@ -1,17 +1,41 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "UploadParams", - "type": "object", - "required": [ - "files", - "session_id" - ], + "definitions": { + "UploadFile": { + "properties": { + "name": { + "type": "string" + }, + "staged_path": { + "type": [ + "string", + "null" + ] + }, + "transfer_id": { + "type": "string" + } + }, + "required": [ + "transfer_id", + "name" + ], + "type": "object" + }, + "UploadMode": { + "enum": [ + "input", + "drop" + ], + "type": "string" + } + }, "properties": { "files": { - "type": "array", "items": { "$ref": "#/definitions/UploadFile" - } + }, + "type": "array" }, "mode": { "$ref": "#/definitions/UploadMode" @@ -32,49 +56,25 @@ "type": "string" }, "tab_id": { + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 0, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "definitions": { - "UploadFile": { - "type": "object", - "required": [ - "name", - "transfer_id" - ], - "properties": { - "name": { - "type": "string" - }, - "staged_path": { - "type": [ - "string", - "null" - ] - }, - "transfer_id": { - "type": "string" - } - } - }, - "UploadMode": { - "type": "string", - "enum": [ - "input", - "drop" ] } - } + }, + "required": [ + "session_id", + "files" + ], + "title": "UploadParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_upload_result.json b/crates/bsk-protocol/schema/tool_upload_result.json index 192c10dc8..d7054a0d0 100644 --- a/crates/bsk-protocol/schema/tool_upload_result.json +++ b/crates/bsk-protocol/schema/tool_upload_result.json @@ -1,21 +1,15 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "UploadResult", - "type": "object", - "required": [ - "file_names", - "tab_id" - ], "properties": { "file_names": { - "type": "array", "items": { "type": "string" - } + }, + "type": "array" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "used_ref": { "type": [ @@ -29,5 +23,11 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "file_names" + ], + "title": "UploadResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wait_for_navigation_params.json b/crates/bsk-protocol/schema/tool_wait_for_navigation_params.json index 72d92fb81..9b5b7af36 100644 --- a/crates/bsk-protocol/schema/tool_wait_for_navigation_params.json +++ b/crates/bsk-protocol/schema/tool_wait_for_navigation_params.json @@ -1,33 +1,39 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WaitForNavigationParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "WaitUntil": { + "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names:\n* `Load` → `load`\n* `DomContentLoaded` → `DOMContentLoaded`\n* `NetworkIdle` → `networkIdle`\n* `Commit` → `commit` (earliest event after the navigation actually\n commits to a new document)", + "enum": [ + "load", + "domcontentloaded", + "networkidle", + "commit" + ], + "type": "string" + } + }, "properties": { "session_id": { "type": "string" }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's currently active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { "description": "Hard upper bound on the wait. Defaults to 30s.", + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 + ] }, "wait_until": { - "description": "Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`].", "anyOf": [ { "$ref": "#/definitions/WaitUntil" @@ -35,19 +41,13 @@ { "type": "null" } - ] + ], + "description": "Lifecycle phase to wait on. Defaults to [`WaitUntil::Load`]." } }, - "definitions": { - "WaitUntil": { - "description": "Page-lifecycle checkpoint a navigation should wait on.\n\nMapping to CDP `Page.lifecycleEvent` names: * `Load` → `load` * `DomContentLoaded` → `DOMContentLoaded` * `NetworkIdle` → `networkIdle` * `Commit` → `commit` (earliest event after the navigation actually commits to a new document)", - "type": "string", - "enum": [ - "load", - "domcontentloaded", - "networkidle", - "commit" - ] - } - } + "required": [ + "session_id" + ], + "title": "WaitForNavigationParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wait_for_navigation_result.json b/crates/bsk-protocol/schema/tool_wait_for_navigation_result.json index d38af47d6..e6846b292 100644 --- a/crates/bsk-protocol/schema/tool_wait_for_navigation_result.json +++ b/crates/bsk-protocol/schema/tool_wait_for_navigation_result.json @@ -1,52 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WaitForNavigationResult", - "description": "Outcome of a wait_for_navigation. `reached` is the wire name of the lifecycle phase the extension actually observed before returning — either the requested `wait_until`, or `\"timeout\"` when the wait expired before that event fired.", - "type": "object", - "required": [ - "reached", - "tab_id" - ], - "properties": { - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "error_text": { - "type": [ - "string", - "null" - ] - }, - "reached": { - "$ref": "#/definitions/WaitForNavigationReached" - }, - "tab_id": { - "type": "integer", - "format": "int64" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -68,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -85,27 +49,63 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" - ] + ], + "type": "string" }, "WaitForNavigationReached": { - "type": "string", "enum": [ "load", "domcontentloaded", "networkidle", "commit", "timeout" + ], + "type": "string" + } + }, + "description": "Outcome of a wait_for_navigation. `reached` is the wire name of the\nlifecycle phase the extension actually observed before returning —\neither the requested `wait_until`, or `\"timeout\"` when the wait\nexpired before that event fired.", + "properties": { + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "error_text": { + "type": [ + "string", + "null" ] + }, + "reached": { + "$ref": "#/definitions/WaitForNavigationReached" + }, + "tab_id": { + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "tab_id", + "reached" + ], + "title": "WaitForNavigationResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wait_ms_params.json b/crates/bsk-protocol/schema/tool_wait_ms_params.json index 1a7a53c8c..f99536660 100644 --- a/crates/bsk-protocol/schema/tool_wait_ms_params.json +++ b/crates/bsk-protocol/schema/tool_wait_ms_params.json @@ -1,15 +1,15 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WaitMsParams", - "type": "object", - "required": [ - "duration_ms" - ], "properties": { "duration_ms": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "duration_ms" + ], + "title": "WaitMsParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wait_ms_result.json b/crates/bsk-protocol/schema/tool_wait_ms_result.json index 448dd4d24..e25ac0f6a 100644 --- a/crates/bsk-protocol/schema/tool_wait_ms_result.json +++ b/crates/bsk-protocol/schema/tool_wait_ms_result.json @@ -1,15 +1,15 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WaitMsResult", - "type": "object", - "required": [ - "waited_ms" - ], "properties": { "waited_ms": { - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "waited_ms" + ], + "title": "WaitMsResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wheel_params.json b/crates/bsk-protocol/schema/tool_wheel_params.json index c5b404036..89f48016c 100644 --- a/crates/bsk-protocol/schema/tool_wheel_params.json +++ b/crates/bsk-protocol/schema/tool_wheel_params.json @@ -1,34 +1,41 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WheelParams", - "type": "object", - "required": [ - "session_id" - ], + "definitions": { + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + } + }, "properties": { "delta_x": { - "description": "Native CDP wheel input in CSS pixels. Positive X means right. Not measured displacement.", "default": 0.0, - "type": "number", - "format": "double" + "description": "Native CDP wheel input in CSS pixels. Positive X means right. Not measured displacement.", + "format": "double", + "type": "number" }, "delta_y": { - "description": "Native CDP wheel input in CSS pixels. Positive Y means down. Defaults to zero.", "default": 0.0, - "type": "number", - "format": "double" + "description": "Native CDP wheel input in CSS pixels. Positive Y means down. Defaults to zero.", + "format": "double", + "type": "number" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "ref": { - "description": "Optional `@e` ref used as the wheel event's hit-test point. Mutually exclusive with `selector`. When neither is supplied, the event is dispatched at the viewport centre.", + "description": "Optional `@e` ref used as the wheel event's hit-test point.\nMutually exclusive with `selector`. When neither is supplied,\nthe event is dispatched at the viewport centre.", "type": [ "string", "null" @@ -45,31 +52,24 @@ }, "tab_id": { "description": "Target tab. Defaults to the Agent Window's active tab.", + "format": "int64", "type": [ "integer", "null" - ], - "format": "int64" + ] }, "timeout_ms": { + "format": "uint32", + "minimum": 1, "type": [ "integer", "null" - ], - "format": "uint32", - "minimum": 1.0 - } - }, - "definitions": { - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" ] } - } + }, + "required": [ + "session_id" + ], + "title": "WheelParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_wheel_result.json b/crates/bsk-protocol/schema/tool_wheel_result.json index e81785bfd..91ee71e8e 100644 --- a/crates/bsk-protocol/schema/tool_wheel_result.json +++ b/crates/bsk-protocol/schema/tool_wheel_result.json @@ -1,75 +1,16 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WheelResult", - "type": "object", - "required": [ - "delta_x", - "delta_y", - "tab_id", - "x", - "y" - ], - "properties": { - "delta_x": { - "description": "Requested deltas, not measured scroll distance or completion.", - "type": "number", - "format": "double" - }, - "delta_y": { - "type": "number", - "format": "double" - }, - "dialogs": { - "type": "array", - "items": { - "$ref": "#/definitions/JavaScriptDialogInfo" - } - }, - "tab_id": { - "type": "integer", - "format": "int64" - }, - "used_ref": { - "type": [ - "string", - "null" - ] - }, - "used_selector": { - "type": [ - "string", - "null" - ] - }, - "x": { - "description": "Top-level viewport coordinates where the real wheel event was dispatched.", - "type": "number", - "format": "double" - }, - "y": { - "type": "number", - "format": "double" - } - }, "definitions": { "JavaScriptDialogHandledAction": { "description": "How the extension resolved the dialog so CDP could continue.", - "type": "string", "enum": [ "accepted", "dismissed" - ] + ], + "type": "string" }, "JavaScriptDialogInfo": { "description": "One observed + handled JavaScript dialog during a tool call.", - "type": "object", - "required": [ - "handled", - "message", - "sequence", - "tab_id", - "type" - ], "properties": { "default_prompt": { "type": [ @@ -91,13 +32,13 @@ }, "sequence": { "description": "Monotonic per-tab sequence for ordering within a session.", - "type": "integer", "format": "uint64", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "tab_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" }, "type": { "$ref": "#/definitions/JavaScriptDialogType" @@ -108,17 +49,76 @@ "null" ] } - } + }, + "required": [ + "tab_id", + "type", + "message", + "handled", + "sequence" + ], + "type": "object" }, "JavaScriptDialogType": { "description": "Native JS dialog kind reported by CDP.", - "type": "string", "enum": [ "alert", "confirm", "prompt", "beforeunload" + ], + "type": "string" + } + }, + "properties": { + "delta_x": { + "description": "Requested deltas, not measured scroll distance or completion.", + "format": "double", + "type": "number" + }, + "delta_y": { + "format": "double", + "type": "number" + }, + "dialogs": { + "items": { + "$ref": "#/definitions/JavaScriptDialogInfo" + }, + "type": "array" + }, + "tab_id": { + "format": "int64", + "type": "integer" + }, + "used_ref": { + "type": [ + "string", + "null" ] + }, + "used_selector": { + "type": [ + "string", + "null" + ] + }, + "x": { + "description": "Top-level viewport coordinates where the real wheel event was dispatched.", + "format": "double", + "type": "number" + }, + "y": { + "format": "double", + "type": "number" } - } + }, + "required": [ + "tab_id", + "x", + "y", + "delta_x", + "delta_y" + ], + "title": "WheelResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_window_resize_params.json b/crates/bsk-protocol/schema/tool_window_resize_params.json index f6faffc4d..a1f1a92f8 100644 --- a/crates/bsk-protocol/schema/tool_window_resize_params.json +++ b/crates/bsk-protocol/schema/tool_window_resize_params.json @@ -1,27 +1,27 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WindowResizeParams", - "type": "object", - "required": [ - "height", - "session_id", - "width" - ], "properties": { "height": { "description": "New Agent Window outer height in CSS pixels (100..=7680).", - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "session_id": { "type": "string" }, "width": { "description": "New Agent Window outer width in CSS pixels (100..=7680).", - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "session_id", + "width", + "height" + ], + "title": "WindowResizeParams", + "type": "object" } diff --git a/crates/bsk-protocol/schema/tool_window_resize_result.json b/crates/bsk-protocol/schema/tool_window_resize_result.json index f4cc6467b..8c0e94925 100644 --- a/crates/bsk-protocol/schema/tool_window_resize_result.json +++ b/crates/bsk-protocol/schema/tool_window_resize_result.json @@ -1,26 +1,26 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "WindowResizeResult", - "type": "object", - "required": [ - "height", - "width", - "window_id" - ], "properties": { "height": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "width": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "window_id": { - "type": "integer", - "format": "int64" + "format": "int64", + "type": "integer" } - } + }, + "required": [ + "window_id", + "width", + "height" + ], + "title": "WindowResizeResult", + "type": "object" } diff --git a/crates/bsk-protocol/schema/trace.json b/crates/bsk-protocol/schema/trace.json index 95dfb1576..0db7e9ff5 100644 --- a/crates/bsk-protocol/schema/trace.json +++ b/crates/bsk-protocol/schema/trace.json @@ -1,43 +1,25 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordedTrace", - "if": { - "required": [ - "version" - ], - "properties": { - "version": { - "type": "integer" - } - } - }, - "then": { - "$ref": "#/definitions/TraceV3" - }, - "else": { - "$ref": "#/definitions/TraceV2" - }, "definitions": { "FillCommit": { - "type": "string", "enum": [ "enter", "suggestion", "blur" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "NavigationCause": { - "type": "string", "enum": [ "user_typed", "link", @@ -46,15 +28,11 @@ "history", "script", "browser" - ] + ], + "type": "string" }, "PageRefV2": { "description": "Page context dictionary entry — referenced by steps via `page` id.", - "type": "object", - "required": [ - "id", - "url" - ], "properties": { "id": { "type": "string" @@ -68,31 +46,32 @@ "url": { "type": "string" } - } - }, - "RecorderInfo": { - "type": "object", + }, "required": [ - "bsk", - "vom" + "id", + "url" ], + "type": "object" + }, + "RecorderInfo": { "properties": { "bsk": { "type": "string" }, "vom": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "bsk", + "vom" + ], + "type": "object" }, "SelectedOptionV2": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -103,14 +82,14 @@ "value": { "type": "string" } - } - }, - "SelectedOptionV3": { - "description": "One selected option (`select` op).", - "type": "object", + }, "required": [ "value" ], + "type": "object" + }, + "SelectedOptionV3": { + "description": "One selected option (`select` op).", "properties": { "label": { "type": [ @@ -121,44 +100,41 @@ "value": { "type": "string" } - } + }, + "required": [ + "value" + ], + "type": "object" }, "StepEffectV2": { "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], "properties": { "navigated_to": { "description": "Reference into `pages[]` for the destination page.", "type": "string" } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "navigated_to" ], + "type": "object" + }, + "StepResultV3": { "properties": { "state": { "type": "string" } - } + }, + "required": [ + "state" + ], + "type": "object" }, "StepV2": { "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -171,15 +147,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -188,17 +162,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -211,15 +185,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -228,17 +200,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -251,15 +223,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -268,18 +238,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -292,15 +261,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -318,18 +285,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -342,40 +309,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -388,27 +354,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -424,7 +388,14 @@ } ] } - } + }, + "required": [ + "op", + "id", + "page", + "key" + ], + "type": "object" } ] }, @@ -433,29 +404,18 @@ "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -467,28 +427,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -497,29 +457,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -531,29 +488,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -565,34 +520,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -610,38 +561,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -650,41 +601,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -703,28 +652,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -733,23 +681,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } + }, + "required": [ + "op", + "id", + "state", + "result" + ], + "type": "object" } ] }, "StopReason": { - "type": "string", "enum": [ "user_finish", "cli_stop" - ] + ], + "type": "string" }, "TargetDescriptorV2": { "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" - ], "properties": { "name": { "type": [ @@ -784,11 +735,14 @@ "tag": { "type": "string" } - } + }, + "required": [ + "tag" + ], + "type": "object" }, "TargetDescriptorV3": { "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", "properties": { "ctx": { "type": [ @@ -817,27 +771,22 @@ "unmatched": { "type": "boolean" } - } + }, + "type": "object" }, "TraceEntry": { - "type": "object", - "required": [ - "start_url" - ], "properties": { "start_url": { "type": "string" } - } + }, + "required": [ + "start_url" + ], + "type": "object" }, "TraceStateV3": { "description": "Page observation dictionary entry — referenced by steps via `state` / `result.state`.", - "type": "object", - "required": [ - "body", - "id", - "url" - ], "properties": { "body": { "description": "Full page observation (front matter + VOM body + annotations).", @@ -858,27 +807,25 @@ "url": { "type": "string" } - } - }, - "TraceV2": { - "title": "TraceV2", - "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable. `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` classification.", - "type": "object", + }, "required": [ - "entry", - "pages", - "recorded_at", - "steps" + "id", + "url", + "body" ], + "type": "object" + }, + "TraceV2": { + "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable.\n`states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace`\nclassification — serde still ignores them, but the JSON Schema rejects them.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" }, "pages": { - "type": "array", "items": { "$ref": "#/definitions/PageRefV2" - } + }, + "type": "array" }, "purpose": { "type": [ @@ -898,10 +845,10 @@ }, "states": false, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV2" - } + }, + "type": "array" }, "version": { "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", @@ -909,20 +856,18 @@ "type": "integer" } } - } - }, - "TraceV3": { - "description": "Wire trace returned by `tool.record_stop` / `await`.", - "type": "object", + }, "required": [ - "entry", "recorded_at", - "recorder", - "states", - "steps", - "stopped_by", - "version" + "entry", + "pages", + "steps" ], + "type": "object" + }, + "TraceV3": { + "additionalProperties": false, + "description": "Wire trace returned by `tool.record_stop` / `await`.", "properties": { "entry": { "$ref": "#/definitions/TraceEntry" @@ -946,26 +891,52 @@ ] }, "states": { - "type": "array", "items": { "$ref": "#/definitions/TraceStateV3" - } + }, + "type": "array" }, "steps": { - "type": "array", "items": { "$ref": "#/definitions/StepV3" - } + }, + "type": "array" }, "stopped_by": { "$ref": "#/definitions/StopReason" }, "version": { - "type": "integer", - "const": 3 + "const": 3, + "type": "integer" } }, - "additionalProperties": false + "required": [ + "version", + "recorded_at", + "stopped_by", + "entry", + "recorder", + "states", + "steps" + ], + "type": "object" } - } + }, + "else": { + "$ref": "#/definitions/TraceV2" + }, + "if": { + "properties": { + "version": { + "type": "integer" + } + }, + "required": [ + "version" + ] + }, + "then": { + "$ref": "#/definitions/TraceV3" + }, + "title": "RecordedTrace" } diff --git a/crates/bsk-protocol/schema/trace_step.json b/crates/bsk-protocol/schema/trace_step.json index b13ef8930..f540aabdf 100644 --- a/crates/bsk-protocol/schema/trace_step.json +++ b/crates/bsk-protocol/schema/trace_step.json @@ -1,44 +1,25 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "RecordedStep", - "not": { - "required": [ - "page", - "state" - ] - }, - "if": { - "required": [ - "state" - ] - }, - "then": { - "$ref": "#/definitions/StepV3" - }, - "else": { - "$ref": "#/definitions/StepV2" - }, "definitions": { "FillCommit": { - "type": "string", "enum": [ "enter", "suggestion", "blur" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "NavigationCause": { - "type": "string", "enum": [ "user_typed", "link", @@ -47,14 +28,11 @@ "history", "script", "browser" - ] + ], + "type": "string" }, "SelectedOptionV2": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -65,14 +43,14 @@ "value": { "type": "string" } - } - }, - "SelectedOptionV3": { - "description": "One selected option (`select` op).", - "type": "object", + }, "required": [ "value" ], + "type": "object" + }, + "SelectedOptionV3": { + "description": "One selected option (`select` op).", "properties": { "label": { "type": [ @@ -83,44 +61,41 @@ "value": { "type": "string" } - } + }, + "required": [ + "value" + ], + "type": "object" }, "StepEffectV2": { "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], "properties": { "navigated_to": { "description": "Reference into `pages[]` for the destination page.", "type": "string" } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "navigated_to" ], + "type": "object" + }, + "StepResultV3": { "properties": { "state": { "type": "string" } - } + }, + "required": [ + "state" + ], + "type": "object" }, "StepV2": { "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -133,15 +108,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -150,17 +123,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -173,15 +146,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -190,17 +161,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -213,15 +184,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -230,18 +199,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -254,15 +222,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -280,18 +246,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -304,40 +270,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -350,27 +315,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -386,7 +349,14 @@ } ] } - } + }, + "required": [ + "op", + "id", + "page", + "key" + ], + "type": "object" } ] }, @@ -395,29 +365,18 @@ "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -429,28 +388,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -459,29 +418,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -493,29 +449,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -527,34 +481,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -572,38 +522,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -612,41 +562,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -665,28 +613,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -695,16 +642,19 @@ "description": "Observation id immediately before this action.", "type": "string" } - } + }, + "required": [ + "op", + "id", + "state", + "result" + ], + "type": "object" } ] }, "TargetDescriptorV2": { "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" - ], "properties": { "name": { "type": [ @@ -739,11 +689,14 @@ "tag": { "type": "string" } - } + }, + "required": [ + "tag" + ], + "type": "object" }, "TargetDescriptorV3": { "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", "properties": { "ctx": { "type": [ @@ -772,7 +725,26 @@ "unmatched": { "type": "boolean" } - } + }, + "type": "object" } - } + }, + "else": { + "$ref": "#/definitions/StepV2" + }, + "if": { + "required": [ + "state" + ] + }, + "not": { + "required": [ + "page", + "state" + ] + }, + "then": { + "$ref": "#/definitions/StepV3" + }, + "title": "RecordedStep" } diff --git a/crates/bsk-protocol/schema/trace_step_v2.json b/crates/bsk-protocol/schema/trace_step_v2.json index 2d11f9809..e2d0a4d69 100644 --- a/crates/bsk-protocol/schema/trace_step_v2.json +++ b/crates/bsk-protocol/schema/trace_step_v2.json @@ -1,17 +1,94 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StepV2", + "definitions": { + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + }, + "SelectedOptionV2": { + "description": "One selected option (`select` op).", + "properties": { + "label": { + "type": [ + "string", + "null" + ] + }, + "value": { + "type": "string" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "StepEffectV2": { + "description": "Observed navigation after a step (objective fact only).", + "properties": { + "navigated_to": { + "description": "Reference into `pages[]` for the destination page.", + "type": "string" + } + }, + "required": [ + "navigated_to" + ], + "type": "object" + }, + "TargetDescriptorV2": { + "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", + "properties": { + "name": { + "type": [ + "string", + "null" + ] + }, + "name_attr": { + "type": [ + "string", + "null" + ] + }, + "nearby_label": { + "type": [ + "string", + "null" + ] + }, + "placeholder": { + "type": [ + "string", + "null" + ] + }, + "role": { + "type": [ + "string", + "null" + ] + }, + "tag": { + "type": "string" + } + }, + "required": [ + "tag" + ], + "type": "object" + } + }, "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -24,15 +101,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -41,17 +116,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -64,15 +139,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -81,17 +154,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -104,15 +177,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -121,18 +192,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -145,15 +215,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -171,18 +239,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -195,40 +263,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -241,27 +308,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -277,92 +342,15 @@ } ] } - } - } - ], - "definitions": { - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" - ] - }, - "SelectedOptionV2": { - "description": "One selected option (`select` op).", - "type": "object", + }, "required": [ - "value" - ], - "properties": { - "label": { - "type": [ - "string", - "null" - ] - }, - "value": { - "type": "string" - } - } - }, - "StepEffectV2": { - "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], - "properties": { - "navigated_to": { - "description": "Reference into `pages[]` for the destination page.", - "type": "string" - } - } - }, - "TargetDescriptorV2": { - "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" + "op", + "id", + "page", + "key" ], - "properties": { - "name": { - "type": [ - "string", - "null" - ] - }, - "name_attr": { - "type": [ - "string", - "null" - ] - }, - "nearby_label": { - "type": [ - "string", - "null" - ] - }, - "placeholder": { - "type": [ - "string", - "null" - ] - }, - "role": { - "type": [ - "string", - "null" - ] - }, - "tag": { - "type": "string" - } - } + "type": "object" } - } + ], + "title": "StepV2" } diff --git a/crates/bsk-protocol/schema/trace_step_v3.json b/crates/bsk-protocol/schema/trace_step_v3.json index 49f74eece..5f179e6b9 100644 --- a/crates/bsk-protocol/schema/trace_step_v3.json +++ b/crates/bsk-protocol/schema/trace_step_v3.json @@ -1,33 +1,115 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StepV3", + "definitions": { + "FillCommit": { + "enum": [ + "enter", + "suggestion", + "blur" + ], + "type": "string" + }, + "KeyModifier": { + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", + "enum": [ + "alt", + "ctrl", + "meta", + "shift" + ], + "type": "string" + }, + "NavigationCause": { + "enum": [ + "user_typed", + "link", + "form_submit", + "reload", + "history", + "script", + "browser" + ], + "type": "string" + }, + "SelectedOptionV3": { + "description": "One selected option (`select` op).", + "properties": { + "label": { + "type": [ + "string", + "null" + ] + }, + "value": { + "type": "string" + } + }, + "required": [ + "value" + ], + "type": "object" + }, + "StepResultV3": { + "properties": { + "state": { + "type": "string" + } + }, + "required": [ + "state" + ], + "type": "object" + }, + "TargetDescriptorV3": { + "description": "Stable semantic handle for an interacted element within a page observation.", + "properties": { + "ctx": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "ref": { + "type": [ + "string", + "null" + ] + }, + "role": { + "type": [ + "string", + "null" + ] + }, + "unmatched": { + "type": "boolean" + } + }, + "type": "object" + } + }, "description": "One recorded user action — discriminated union by `op`.", "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -39,28 +121,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -69,29 +151,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -103,29 +182,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -137,34 +214,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -182,38 +255,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -222,41 +295,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -275,28 +346,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -305,101 +375,15 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - } - ], - "definitions": { - "FillCommit": { - "type": "string", - "enum": [ - "enter", - "suggestion", - "blur" - ] - }, - "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", - "enum": [ - "alt", - "ctrl", - "meta", - "shift" - ] - }, - "NavigationCause": { - "type": "string", - "enum": [ - "user_typed", - "link", - "form_submit", - "reload", - "history", - "script", - "browser" - ] - }, - "SelectedOptionV3": { - "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], - "properties": { - "label": { - "type": [ - "string", - "null" - ] - }, - "value": { - "type": "string" - } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "op", + "id", + "state", + "result" ], - "properties": { - "state": { - "type": "string" - } - } - }, - "TargetDescriptorV3": { - "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", - "properties": { - "ctx": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": [ - "string", - "null" - ] - }, - "ref": { - "type": [ - "string", - "null" - ] - }, - "role": { - "type": [ - "string", - "null" - ] - }, - "unmatched": { - "type": "boolean" - } - } + "type": "object" } - } + ], + "title": "StepV3" } diff --git a/crates/bsk-protocol/schema/trace_v2.json b/crates/bsk-protocol/schema/trace_v2.json index bd1081caf..5fb69cb71 100644 --- a/crates/bsk-protocol/schema/trace_v2.json +++ b/crates/bsk-protocol/schema/trace_v2.json @@ -1,72 +1,18 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TraceV2", - "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable. `states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace` classification.", - "type": "object", - "required": [ - "entry", - "pages", - "recorded_at", - "steps" - ], - "properties": { - "entry": { - "$ref": "#/definitions/TraceEntry" - }, - "pages": { - "type": "array", - "items": { - "$ref": "#/definitions/PageRefV2" - } - }, - "purpose": { - "type": [ - "string", - "null" - ] - }, - "recorded_at": { - "description": "RFC 3339 timestamp when recording stopped.", - "type": "string" - }, - "started_at": { - "type": [ - "string", - "null" - ] - }, - "states": false, - "steps": { - "type": "array", - "items": { - "$ref": "#/definitions/StepV2" - } - }, - "version": { - "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", - "not": { - "type": "integer" - } - } - }, "definitions": { "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "PageRefV2": { "description": "Page context dictionary entry — referenced by steps via `page` id.", - "type": "object", - "required": [ - "id", - "url" - ], "properties": { "id": { "type": "string" @@ -80,14 +26,15 @@ "url": { "type": "string" } - } + }, + "required": [ + "id", + "url" + ], + "type": "object" }, "SelectedOptionV2": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -98,33 +45,30 @@ "value": { "type": "string" } - } + }, + "required": [ + "value" + ], + "type": "object" }, "StepEffectV2": { "description": "Observed navigation after a step (objective fact only).", - "type": "object", - "required": [ - "navigated_to" - ], "properties": { "navigated_to": { "description": "Reference into `pages[]` for the destination page.", "type": "string" } - } + }, + "required": [ + "navigated_to" + ], + "type": "object" }, "StepV2": { "description": "One recorded user action — discriminated union by `op` (v2).", "oneOf": [ { "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", - "required": [ - "id", - "op", - "page", - "to" - ], "properties": { "effect": { "anyOf": [ @@ -137,15 +81,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -154,17 +96,17 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target" + "to" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -177,15 +119,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -194,17 +134,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -217,15 +157,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -234,18 +172,17 @@ "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "target", - "value" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -258,15 +195,13 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -284,18 +219,18 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", "page", - "selection", - "target" + "target", + "value" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -308,40 +243,39 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", "type": "string" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV2" - } + }, + "type": "array" }, "target": { "$ref": "#/definitions/TargetDescriptorV2" } - } - }, - { - "description": "Fields shared by every v2 step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", - "page" + "id", + "page", + "target", + "selection" ], + "type": "object" + }, + { + "description": "Fields shared by every v2 step variant (flattened in JSON).", "properties": { "effect": { "anyOf": [ @@ -354,27 +288,25 @@ ] }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "page": { "description": "Reference into `pages[]`.", @@ -390,16 +322,19 @@ } ] } - } + }, + "required": [ + "op", + "id", + "page", + "key" + ], + "type": "object" } ] }, "TargetDescriptorV2": { "description": "Stable semantic handle for an interacted element (v2).\n\n`name` and `nearby_label` are **untrusted page text**.", - "type": "object", - "required": [ - "tag" - ], "properties": { "name": { "type": [ @@ -434,18 +369,71 @@ "tag": { "type": "string" } - } - }, - "TraceEntry": { - "type": "object", + }, "required": [ - "start_url" + "tag" ], + "type": "object" + }, + "TraceEntry": { "properties": { "start_url": { "type": "string" } + }, + "required": [ + "start_url" + ], + "type": "object" + } + }, + "description": "Persisted user-action trace exported by legacy `tool.record_stop` / `await`.\n\nUnknown extension fields are ignored so older traces remain readable.\n`states[]` and a numeric `version` are reserved for Trace v3 / `RecordedTrace`\nclassification — serde still ignores them, but the JSON Schema rejects them.", + "properties": { + "entry": { + "$ref": "#/definitions/TraceEntry" + }, + "pages": { + "items": { + "$ref": "#/definitions/PageRefV2" + }, + "type": "array" + }, + "purpose": { + "type": [ + "string", + "null" + ] + }, + "recorded_at": { + "description": "RFC 3339 timestamp when recording stopped.", + "type": "string" + }, + "started_at": { + "type": [ + "string", + "null" + ] + }, + "states": false, + "steps": { + "items": { + "$ref": "#/definitions/StepV2" + }, + "type": "array" + }, + "version": { + "description": "Numeric version selects Trace v3. Legacy v2 envelopes omit this field.", + "not": { + "type": "integer" } } - } + }, + "required": [ + "recorded_at", + "entry", + "pages", + "steps" + ], + "title": "TraceV2", + "type": "object" } diff --git a/crates/bsk-protocol/schema/trace_v3.json b/crates/bsk-protocol/schema/trace_v3.json index 3557e8725..abce59a91 100644 --- a/crates/bsk-protocol/schema/trace_v3.json +++ b/crates/bsk-protocol/schema/trace_v3.json @@ -1,81 +1,26 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TraceV3", - "description": "Wire trace returned by `tool.record_stop` / `await`.", - "type": "object", - "required": [ - "entry", - "recorded_at", - "recorder", - "states", - "steps", - "stopped_by", - "version" - ], - "properties": { - "entry": { - "$ref": "#/definitions/TraceEntry" - }, - "purpose": { - "type": [ - "string", - "null" - ] - }, - "recorded_at": { - "type": "string" - }, - "recorder": { - "$ref": "#/definitions/RecorderInfo" - }, - "started_at": { - "type": [ - "string", - "null" - ] - }, - "states": { - "type": "array", - "items": { - "$ref": "#/definitions/TraceStateV3" - } - }, - "steps": { - "type": "array", - "items": { - "$ref": "#/definitions/StepV3" - } - }, - "stopped_by": { - "$ref": "#/definitions/StopReason" - }, - "version": { - "type": "integer", - "const": 3 - } - }, "additionalProperties": false, "definitions": { "FillCommit": { - "type": "string", "enum": [ "enter", "suggestion", "blur" - ] + ], + "type": "string" }, "KeyModifier": { - "description": "Keyboard modifier flags. Multiple flags may be combined; the extension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4, shift=8`).", - "type": "string", + "description": "Keyboard modifier flags. Multiple flags may be combined; the\nextension folds them into CDP's bitfield (`alt=1, ctrl=2, meta=4,\nshift=8`).", "enum": [ "alt", "ctrl", "meta", "shift" - ] + ], + "type": "string" }, "NavigationCause": { - "type": "string", "enum": [ "user_typed", "link", @@ -84,31 +29,28 @@ "history", "script", "browser" - ] + ], + "type": "string" }, "RecorderInfo": { - "type": "object", - "required": [ - "bsk", - "vom" - ], "properties": { "bsk": { "type": "string" }, "vom": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" } - } + }, + "required": [ + "bsk", + "vom" + ], + "type": "object" }, "SelectedOptionV3": { "description": "One selected option (`select` op).", - "type": "object", - "required": [ - "value" - ], "properties": { "label": { "type": [ @@ -119,47 +61,40 @@ "value": { "type": "string" } - } - }, - "StepResultV3": { - "type": "object", + }, "required": [ - "state" + "value" ], + "type": "object" + }, + "StepResultV3": { "properties": { "state": { "type": "string" } - } + }, + "required": [ + "state" + ], + "type": "object" }, "StepV3": { "description": "One recorded user action — discriminated union by `op`.", "oneOf": [ { "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", - "required": [ - "cause", - "id", - "op", - "result", - "state", - "to" - ], "properties": { "cause": { "$ref": "#/definitions/NavigationCause" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "navigate" - ] + "const": "navigate", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -171,28 +106,28 @@ "to": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "to", + "cause" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "switch_tab" - ] + "const": "switch_tab", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -201,29 +136,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "click" - ] + "const": "click", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -235,29 +167,27 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", + "result", "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "hover" - ] + "const": "hover", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -269,34 +199,30 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "commit", - "id", "op", - "result", + "id", "state", - "target", - "value" + "result", + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "commit": { "$ref": "#/definitions/FillCommit" }, "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "fill" - ] + "const": "fill", + "type": "string" }, "redacted": { "type": "boolean" @@ -314,38 +240,38 @@ "value": { "type": "string" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", - "result", + "id", "state", - "target" + "result", + "target", + "value", + "commit" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "select" - ] + "const": "select", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" }, "selection": { - "type": "array", "items": { "$ref": "#/definitions/SelectedOptionV3" - } + }, + "type": "array" }, "state": { "description": "Observation id immediately before this action.", @@ -354,41 +280,39 @@ "target": { "$ref": "#/definitions/TargetDescriptorV3" } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", - "key", "op", + "id", + "state", "result", - "state" + "target" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "key": { "type": "string" }, "modifiers": { + "items": { + "$ref": "#/definitions/KeyModifier" + }, "type": [ "array", "null" - ], - "items": { - "$ref": "#/definitions/KeyModifier" - } + ] }, "op": { - "type": "string", - "enum": [ - "press" - ] + "const": "press", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -407,28 +331,27 @@ } ] } - } - }, - { - "description": "Fields shared by every step variant (flattened in JSON).", - "type": "object", + }, "required": [ - "id", "op", + "id", + "state", "result", - "state" + "key" ], + "type": "object" + }, + { + "description": "Fields shared by every step variant (flattened in JSON).", "properties": { "id": { - "type": "integer", "format": "uint32", - "minimum": 0.0 + "minimum": 0, + "type": "integer" }, "op": { - "type": "string", - "enum": [ - "scroll" - ] + "const": "scroll", + "type": "string" }, "result": { "$ref": "#/definitions/StepResultV3" @@ -437,20 +360,26 @@ "description": "Observation id immediately before this action.", "type": "string" } - } + }, + "required": [ + "op", + "id", + "state", + "result" + ], + "type": "object" } ] }, "StopReason": { - "type": "string", "enum": [ "user_finish", "cli_stop" - ] + ], + "type": "string" }, "TargetDescriptorV3": { "description": "Stable semantic handle for an interacted element within a page observation.", - "type": "object", "properties": { "ctx": { "type": [ @@ -479,27 +408,22 @@ "unmatched": { "type": "boolean" } - } + }, + "type": "object" }, "TraceEntry": { - "type": "object", - "required": [ - "start_url" - ], "properties": { "start_url": { "type": "string" } - } + }, + "required": [ + "start_url" + ], + "type": "object" }, "TraceStateV3": { "description": "Page observation dictionary entry — referenced by steps via `state` / `result.state`.", - "type": "object", - "required": [ - "body", - "id", - "url" - ], "properties": { "body": { "description": "Full page observation (front matter + VOM body + annotations).", @@ -520,7 +444,67 @@ "url": { "type": "string" } - } + }, + "required": [ + "id", + "url", + "body" + ], + "type": "object" } - } + }, + "description": "Wire trace returned by `tool.record_stop` / `await`.", + "properties": { + "entry": { + "$ref": "#/definitions/TraceEntry" + }, + "purpose": { + "type": [ + "string", + "null" + ] + }, + "recorded_at": { + "type": "string" + }, + "recorder": { + "$ref": "#/definitions/RecorderInfo" + }, + "started_at": { + "type": [ + "string", + "null" + ] + }, + "states": { + "items": { + "$ref": "#/definitions/TraceStateV3" + }, + "type": "array" + }, + "steps": { + "items": { + "$ref": "#/definitions/StepV3" + }, + "type": "array" + }, + "stopped_by": { + "$ref": "#/definitions/StopReason" + }, + "version": { + "const": 3, + "type": "integer" + } + }, + "required": [ + "version", + "recorded_at", + "stopped_by", + "entry", + "recorder", + "states", + "steps" + ], + "title": "TraceV3", + "type": "object" } diff --git a/crates/bsk-protocol/src/bin/dump-schema.rs b/crates/bsk-protocol/src/bin/dump-schema.rs index 8400971a2..a8fda0e0a 100644 --- a/crates/bsk-protocol/src/bin/dump-schema.rs +++ b/crates/bsk-protocol/src/bin/dump-schema.rs @@ -34,7 +34,12 @@ fn standalone(catalog: &Value, name: &str) -> Value { let definitions = catalog["schema"]["definitions"] .as_object() .expect("definitions"); - let mut root = definitions[name].clone(); + let mut root = definitions.get(name).expect("root definition").clone(); + // Boolean schemas are valid Draft-07 roots, but cannot carry metadata. + // Wrapping them preserves their meaning while allowing a title and dialect. + if root.is_boolean() { + root = serde_json::json!({ "allOf": [root] }); + } let mut pending = BTreeSet::new(); let mut included = Map::new(); references(&root, &mut pending); @@ -88,7 +93,9 @@ fn main() { for part in ["params", "result"] { let name = method[part].as_str().expect("contract name"); // Daemon-private payloads are intentionally not extension contracts. - if name == "Value" { + if method["owner"] == "daemon" + && catalog["schema"]["definitions"][name] == Value::Bool(true) + { continue; } write_schema(&dir, &format!("{base}_{part}"), standalone(&catalog, name)); diff --git a/scripts/protocol.mjs b/scripts/protocol.mjs index 98d0de978..f679e258d 100644 --- a/scripts/protocol.mjs +++ b/scripts/protocol.mjs @@ -2,7 +2,8 @@ // Generate the extension contract from the Rust method catalog. --check never writes source files. import { spawnSync } from "node:child_process"; import { createHash } from "node:crypto"; -import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs"; +import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; import Ajv from "ajv"; @@ -17,23 +18,41 @@ const args = new Set(process.argv.slice(2)); if ([...args].some((arg) => !["--check", "--json"].includes(arg))) { throw new Error("Usage: node scripts/protocol.mjs [--check] [--json]"); } -const exported = spawnSync( - "cargo", - [ - "run", - "--quiet", - "--locked", - "--target-dir", - join(root, "target/protocol"), - "-p", - "bsk-protocol", - "--bin", - "export-protocol", - ], - { cwd: root, encoding: "utf8", maxBuffer: 32 * 1024 * 1024, timeout: 300_000 }, -); -if (exported.status !== 0) throw new Error(exported.error?.message ?? exported.stderr); -const catalog = JSON.parse(exported.stdout); +function runExporter(binary, extraArgs = []) { + const exported = spawnSync( + "cargo", + [ + "run", + "--quiet", + "--locked", + "--target-dir", + join(root, "target/protocol"), + "-p", + "bsk-protocol", + "--bin", + binary, + ...extraArgs, + ], + { cwd: root, encoding: "utf8", maxBuffer: 32 * 1024 * 1024, timeout: 300_000 }, + ); + if (exported.status !== 0) throw new Error(exported.error?.message ?? exported.stderr); + return exported.stdout; +} +const catalog = JSON.parse(runExporter("export-protocol")); +// Export through the same Rust entry point as cli:build. Even --check writes +// only into this temporary directory before comparing checked-in schemas. +const temporarySchemas = mkdtempSync(join(tmpdir(), "bsk-protocol-")); +let schemas; +try { + runExporter("dump-schema", ["--", "--out-dir", temporarySchemas]); + schemas = new Map( + readdirSync(temporarySchemas) + .sort() + .map((name) => [name, readFileSync(join(temporarySchemas, name), "utf8")]), + ); +} finally { + rmSync(temporarySchemas, { recursive: true, force: true }); +} if (catalog.format_version !== 1 || !catalog.methods.length) throw new Error("Invalid protocol catalog"); const definitions = catalog.schema.definitions; @@ -318,26 +337,40 @@ const outputs = new Map([ ], ]); const changed = []; -for (const [name, source] of outputs) { - let existing; +for (const [directory, files, label] of [ + [destination, outputs, ""], + [join(root, "crates/bsk-protocol/schema"), schemas, "schema/"], +]) { + let unexpected = []; try { - existing = readFileSync(join(destination, name), "utf8"); + unexpected = readdirSync(directory).filter((name) => !files.has(name)); } catch {} - if (existing !== source) changed.push(name); - if (!args.has("--check")) { - mkdirSync(destination, { recursive: true }); - writeFileSync(join(destination, name), source); + if (unexpected.length) + throw new Error( + `Unexpected generated files: ${unexpected.map((name) => label + name).join(", ")}`, + ); + for (const [name, source] of files) { + let existing; + try { + existing = readFileSync(join(directory, name), "utf8"); + } catch {} + if (existing !== source) changed.push(label + name); + if (!args.has("--check")) { + mkdirSync(directory, { recursive: true }); + writeFileSync(join(directory, name), source); + } } } -let unexpected = []; -try { - unexpected = readdirSync(destination).filter((name) => !outputs.has(name)); -} catch {} -if (unexpected.length) throw new Error(`Unexpected generated files: ${unexpected.join(", ")}`); -const report = { methods: methods.length, contracts: names.length, fingerprint, stale: changed }; +const report = { + methods: methods.length, + contracts: names.length, + schemas: schemas.size, + fingerprint, + stale: changed, +}; console.log( args.has("--json") ? JSON.stringify(report, null, 2) - : `${args.has("--check") ? "Checked" : "Generated"} ${methods.length} extension methods and ${names.length} contracts.${args.has("--check") && changed.length ? ` Stale: ${changed.join(", ")}. Run pnpm protocol:generate.` : ""}`, + : `${args.has("--check") ? "Checked" : "Generated"} ${methods.length} extension methods, ${names.length} contracts and ${schemas.size} standalone schemas.${args.has("--check") && changed.length ? ` Stale: ${changed.join(", ")}. Run pnpm protocol:generate.` : ""}`, ); if (args.has("--check") && changed.length) process.exitCode = 1; From fa267c0c2f3ccbcced2d692226346951e80769bd Mon Sep 17 00:00:00 2001 From: NianJiuZst <3235467914@qq.com> Date: Wed, 7 Oct 2026 13:07:35 -0500 Subject: [PATCH 4/5] fix(extension): bundle browser archive test dependencies --- .../src/debug/__tests__/archive.browser.test.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/extension/src/debug/__tests__/archive.browser.test.ts b/apps/extension/src/debug/__tests__/archive.browser.test.ts index 641ed0d46..493131bbe 100644 --- a/apps/extension/src/debug/__tests__/archive.browser.test.ts +++ b/apps/extension/src/debug/__tests__/archive.browser.test.ts @@ -1,9 +1,9 @@ // @vitest-environment node // Native IndexedDB coverage; uses an isolated Chrome profile, never the user's extension. -import { readFileSync } from "node:fs"; import { createServer } from "node:http"; -import ts from "typescript"; +import { fileURLToPath } from "node:url"; +import { buildSync } from "esbuild"; import { describe, expect, it } from "vitest"; describe.skipIf(!process.env.BSK_CLICK_CHROME)("browser-local debug history", () => { @@ -20,9 +20,15 @@ describe.skipIf(!process.env.BSK_CLICK_CHROME)("browser-local debug history", () "json-source", ].map((name) => [ name, - ts.transpileModule(readFileSync(new URL(`../${name}.ts`, import.meta.url), "utf8"), { - compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ES2022 }, - }).outputText, + buildSync({ + entryPoints: [fileURLToPath(new URL(`../${name}.ts`, import.meta.url))], + bundle: true, + write: false, + format: "esm", + platform: "browser", + target: "es2022", + alias: { "@": fileURLToPath(new URL("../../", import.meta.url)) }, + }).outputFiles[0].text, ]), ); const server = createServer((request, response) => { From 16422122e54add499f73158b8f34f492a4cb25de Mon Sep 17 00:00:00 2001 From: NianJiuZst <3235467914@qq.com> Date: Tue, 20 Oct 2026 04:06:42 -0500 Subject: [PATCH 5/5] fix(protocol): preserve video and action recording exclusion --- apps/extension/src/tools/dispatcher.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/extension/src/tools/dispatcher.ts b/apps/extension/src/tools/dispatcher.ts index 7a5efac6a..4dc023d39 100644 --- a/apps/extension/src/tools/dispatcher.ts +++ b/apps/extension/src/tools/dispatcher.ts @@ -847,12 +847,19 @@ export class ToolDispatcher { }); }, "tool.record_start": async (params, signal, onInputSent) => { - return this.recording + const release = this.video?.reserveActionRecording(params.session_id); + if (this.video && !release) + return { + code: "invalid_params", + message: "Stop video recording before starting action recording", + }; + const started = this.recording ? handleRecordStart(this.sessions, params, { ...this.recording, signal, }) - : recordingRuntimeUnavailable(); + : Promise.resolve(recordingRuntimeUnavailable()); + return release ? started.finally(release) : started; }, "tool.record_stop": async (params, signal, onInputSent) => { return this.recording