{
  "openapi": "3.0.3",
  "info": {
    "title": "DevFlow Agent Protocol",
    "version": "1.0.0",
    "description": "Framework-agnostic protocol for runtime app inspection, interaction, and debugging. Supports any UI framework (MAUI, React Native, Flutter, native Android/iOS, etc.).\n",
    "license": {
      "name": "Ailoha Binary Distribution License",
      "url": "https://ailoha.dev/license.html"
    }
  },
  "servers": [
    {
      "url": "http://localhost:{port}",
      "description": "Agent HTTP server running inside the target application",
      "variables": {
        "port": {
          "default": "9233",
          "description": "Port the agent is listening on"
        }
      }
    }
  ],
  "tags": [
    {
      "name": "agent",
      "description": "Agent discovery and status"
    },
    {
      "name": "ui",
      "description": "UI tree inspection, element queries, screenshots"
    },
    {
      "name": "ui-actions",
      "description": "UI interaction (tap, fill, scroll, gestures, etc.)"
    },
    {
      "name": "webview",
      "description": "WebView inspection and interaction"
    },
    {
      "name": "profiler",
      "description": "Performance profiling"
    },
    {
      "name": "network",
      "description": "Network request monitoring"
    },
    {
      "name": "logs",
      "description": "Application logs"
    },
    {
      "name": "device",
      "description": "Device info, sensors, BLE, jobs, permissions, geolocation"
    },
    {
      "name": "storage",
      "description": "Preferences, secure storage, and sandboxed app files"
    },
    {
      "name": "extensions",
      "description": "Third-party extension routes"
    }
  ],
  "paths": {
    "/api/v1/agent/status": {
      "get": {
        "operationId": "getAgentStatus",
        "tags": [
          "agent"
        ],
        "summary": "Get agent status",
        "description": "Returns the agent's identity, platform, version, and running state.\n",
        "responses": {
          "200": {
            "description": "Agent status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/agent-status"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/agent/capabilities": {
      "get": {
        "operationId": "getAgentCapabilities",
        "tags": [
          "agent"
        ],
        "summary": "Get agent capabilities",
        "description": "Returns the capabilities and extensions supported by this agent.\n",
        "responses": {
          "200": {
            "description": "Agent capabilities",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/agent-capabilities"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/tree": {
      "get": {
        "operationId": "getUiTree",
        "tags": [
          "ui"
        ],
        "summary": "Get visual tree",
        "description": "Returns the full visual tree of the application. Windows are root nodes. Use query parameters to limit depth, select a tree layer, or scope to a subtree.\n",
        "parameters": [
          {
            "name": "depth",
            "in": "query",
            "description": "Maximum depth of the tree to return. Unlimited if omitted.",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          },
          {
            "name": "layer",
            "in": "query",
            "description": "Which tree layer to return.",
            "schema": {
              "type": "string",
              "enum": [
                "framework",
                "native",
                "render"
              ],
              "default": "framework"
            }
          },
          {
            "name": "rootId",
            "in": "query",
            "description": "Element ID to scope the tree to a subtree.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "in": "query",
            "description": "Additional data to include with each element.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "properties"
                ]
              }
            },
            "style": "form",
            "explode": "false"
          }
        ],
        "responses": {
          "200": {
            "description": "Array of root elements (windows) with their children.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/element-info"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/elements/{id}": {
      "get": {
        "operationId": "getElement",
        "tags": [
          "ui"
        ],
        "summary": "Get element by ID",
        "description": "Returns a single element by its globally unique identifier.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ElementIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "The requested element.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/element-info"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/elements": {
      "get": {
        "operationId": "queryElements",
        "tags": [
          "ui"
        ],
        "summary": "Query elements with locator strategies",
        "description": "Searches the visual tree for elements matching the given locator strategy and value.\n",
        "parameters": [
          {
            "name": "strategy",
            "in": "query",
            "required": "true",
            "description": "Locator strategy to use.",
            "schema": {
              "$ref": "#/components/schemas/LocatorStrategy"
            }
          },
          {
            "name": "value",
            "in": "query",
            "required": "true",
            "description": "Locator value.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of results.",
            "schema": {
              "type": "integer",
              "minimum": "1",
              "default": "10"
            }
          },
          {
            "name": "include",
            "in": "query",
            "description": "Additional data to include with each element.",
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "properties",
                  "bounds"
                ]
              }
            },
            "style": "form",
            "explode": "false"
          }
        ],
        "responses": {
          "200": {
            "description": "Matching elements.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/element-info"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidSelector"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/hit-test": {
      "get": {
        "operationId": "hitTest",
        "tags": [
          "ui"
        ],
        "summary": "Find element at coordinates",
        "description": "Returns the elements at the given screen coordinates, ordered deepest first (innermost element first).\n",
        "parameters": [
          {
            "name": "x",
            "in": "query",
            "required": "true",
            "description": "X coordinate.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "y",
            "in": "query",
            "required": "true",
            "description": "Y coordinate.",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Elements at the given coordinates (deepest first).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/element-info"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/screenshot": {
      "get": {
        "operationId": "captureScreenshot",
        "tags": [
          "ui"
        ],
        "summary": "Capture screenshot",
        "description": "Captures a screenshot of the entire screen or a specific element.\n",
        "parameters": [
          {
            "name": "elementId",
            "in": "query",
            "description": "Element to screenshot. If omitted, captures the full screen.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "maxWidth",
            "in": "query",
            "description": "Maximum width in pixels. The image is scaled down if wider.",
            "schema": {
              "type": "integer",
              "minimum": "1"
            }
          },
          {
            "name": "scale",
            "in": "query",
            "description": "Scale mode. `native` returns at device pixel density; `auto` returns a reasonable size for agent consumption.\n",
            "schema": {
              "type": "string",
              "enum": [
                "native",
                "auto"
              ],
              "default": "auto"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "Image format.",
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpeg"
              ],
              "default": "png"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot image.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/tap": {
      "post": {
        "operationId": "tapElement",
        "tags": [
          "ui-actions"
        ],
        "summary": "Tap element or coordinates",
        "description": "Taps on an element (by ID) or at absolute coordinates.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TapRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "400": {
            "$ref": "#/components/responses/ElementNotInteractable"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/fill": {
      "post": {
        "operationId": "fillElement",
        "tags": [
          "ui-actions"
        ],
        "summary": "Fill text into element",
        "description": "Clears any existing text and fills the element with the given text.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FillRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "400": {
            "$ref": "#/components/responses/ElementNotInteractable"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/clear": {
      "post": {
        "operationId": "clearElement",
        "tags": [
          "ui-actions"
        ],
        "summary": "Clear text from element",
        "description": "Clears any text content from the specified element.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClearRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "400": {
            "$ref": "#/components/responses/ElementNotInteractable"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/focus": {
      "post": {
        "operationId": "focusElement",
        "tags": [
          "ui-actions"
        ],
        "summary": "Focus element",
        "description": "Gives keyboard focus to the specified element.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FocusRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "400": {
            "$ref": "#/components/responses/ElementNotInteractable"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/scroll": {
      "post": {
        "operationId": "scrollElement",
        "tags": [
          "ui-actions"
        ],
        "summary": "Scroll element",
        "description": "Scrolls an element by delta, to an item index, or to a named position.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScrollRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "400": {
            "$ref": "#/components/responses/ElementNotInteractable"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/navigate": {
      "post": {
        "operationId": "navigateRoute",
        "tags": [
          "ui-actions"
        ],
        "summary": "Navigate to route",
        "description": "Navigates the application to the specified route or page.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NavigateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/resize": {
      "post": {
        "operationId": "resizeWindow",
        "tags": [
          "ui-actions"
        ],
        "summary": "Resize window",
        "description": "Resizes a window or element to the given dimensions.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResizeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/back": {
      "post": {
        "operationId": "goBack",
        "tags": [
          "ui-actions"
        ],
        "summary": "Go back",
        "description": "Performs a back navigation gesture in the application.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BackRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/key": {
      "post": {
        "operationId": "pressKey",
        "tags": [
          "ui-actions"
        ],
        "summary": "Press key",
        "description": "Sends a key press event to the focused element or the application.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/gesture": {
      "post": {
        "operationId": "performGesture",
        "tags": [
          "ui-actions"
        ],
        "summary": "Perform complex gesture",
        "description": "Executes a sequence of pointer actions (move, down, up, pause) to perform complex gestures like swipe, pinch, or drag.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GestureRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/actions/batch": {
      "post": {
        "operationId": "batchActions",
        "tags": [
          "ui-actions"
        ],
        "summary": "Execute batch actions",
        "description": "Executes multiple actions in sequence. Optionally continues on error.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionSuccess"
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ui/elements/{id}/properties/{name}": {
      "get": {
        "operationId": "getElementProperty",
        "tags": [
          "ui"
        ],
        "summary": "Get element property value",
        "description": "Returns the current value of a named property on an element.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ElementIdPath"
          },
          {
            "name": "name",
            "in": "path",
            "required": "true",
            "description": "Property name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Property value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "value"
                  ],
                  "properties": {
                    "value": {}
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "operationId": "setElementProperty",
        "tags": [
          "ui"
        ],
        "summary": "Set element property value",
        "description": "Sets the value of a named property on an element and returns the new value.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ElementIdPath"
          },
          {
            "name": "name",
            "in": "path",
            "required": "true",
            "description": "Property name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "value"
                ],
                "properties": {
                  "value": {
                    "description": "The value to set."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new property value after setting.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "value"
                  ],
                  "properties": {
                    "value": {}
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/contexts": {
      "get": {
        "operationId": "getWebViewContexts",
        "tags": [
          "webview"
        ],
        "summary": "List WebView instances",
        "description": "Returns all active WebView contexts in the application.\n",
        "responses": {
          "200": {
            "description": "Array of WebView contexts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebViewContext"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/evaluate": {
      "post": {
        "operationId": "evaluateJavaScript",
        "tags": [
          "webview"
        ],
        "summary": "Execute JavaScript in WebView",
        "description": "Evaluates a JavaScript expression inside a WebView context and returns the result.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvaluateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evaluation result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvaluateResponse"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/dom": {
      "get": {
        "operationId": "getWebViewDom",
        "tags": [
          "webview"
        ],
        "summary": "Get DOM snapshot",
        "description": "Returns a simplified snapshot of the DOM tree in the WebView.\n",
        "parameters": [
          {
            "name": "contextId",
            "in": "query",
            "description": "WebView context ID. Uses the default context if omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Simplified DOM tree.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Simplified DOM tree representation."
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/dom/query": {
      "post": {
        "operationId": "queryWebViewDom",
        "tags": [
          "webview"
        ],
        "summary": "CSS query in DOM",
        "description": "Executes a CSS selector query against the WebView DOM and returns matching nodes.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DomQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Matching DOM nodes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "description": "Simplified DOM node."
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidSelector"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/source": {
      "get": {
        "operationId": "getWebViewSource",
        "tags": [
          "webview"
        ],
        "summary": "Get page source",
        "description": "Returns the HTML source of the WebView page.\n",
        "parameters": [
          {
            "name": "contextId",
            "in": "query",
            "description": "WebView context ID. Uses the default context if omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Page HTML source.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/navigate": {
      "post": {
        "operationId": "navigateWebView",
        "tags": [
          "webview"
        ],
        "summary": "Navigate WebView",
        "description": "Navigates the WebView to the specified URL.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebViewNavigateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Navigation initiated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/input/click": {
      "post": {
        "operationId": "clickInWebView",
        "tags": [
          "webview"
        ],
        "summary": "Click element in WebView",
        "description": "Clicks a DOM element matching the given CSS selector inside the WebView.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebViewInputClickRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Click performed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidSelector"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/input/fill": {
      "post": {
        "operationId": "fillInWebView",
        "tags": [
          "webview"
        ],
        "summary": "Fill field in WebView",
        "description": "Clears and fills a DOM input element matching the given CSS selector.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebViewInputFillRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Fill performed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidSelector"
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/input/text": {
      "post": {
        "operationId": "insertTextInWebView",
        "tags": [
          "webview"
        ],
        "summary": "Insert text in WebView",
        "description": "Inserts text into the currently focused element in the WebView without clearing existing content.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebViewInputTextRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Text inserted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/webview/screenshot": {
      "get": {
        "operationId": "captureWebViewScreenshot",
        "tags": [
          "webview"
        ],
        "summary": "Capture WebView screenshot",
        "description": "Captures a screenshot of the WebView content.\n",
        "parameters": [
          {
            "name": "contextId",
            "in": "query",
            "description": "WebView context ID. Uses the default context if omitted.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot image.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ElementNotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/capabilities": {
      "get": {
        "operationId": "getProfilerCapabilities",
        "tags": [
          "profiler"
        ],
        "summary": "Get profiling capabilities",
        "description": "Returns which profiling features are supported on the current platform.\n",
        "responses": {
          "200": {
            "description": "Profiler capabilities.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfilerCapabilities"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/sessions": {
      "post": {
        "operationId": "startProfilerSession",
        "tags": [
          "profiler"
        ],
        "summary": "Start profiler session",
        "description": "Starts a new profiling session with the given sample interval.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sampleIntervalMs": {
                    "type": "integer",
                    "minimum": "1",
                    "description": "Sampling interval in milliseconds."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfilerSessionInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/sessions/{id}": {
      "delete": {
        "operationId": "stopProfilerSession",
        "tags": [
          "profiler"
        ],
        "summary": "Stop profiler session",
        "description": "Stops an active profiling session.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": "true",
            "description": "Profiler session ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session stopped.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfilerSessionInfo"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/sessions/{id}/samples": {
      "get": {
        "operationId": "getProfilerSamples",
        "tags": [
          "profiler"
        ],
        "summary": "Get profiler samples",
        "description": "Returns profiling samples, markers, and spans collected since the given cursors. Use cursor values from the previous response to poll for new data.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": "true",
            "description": "Profiler session ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sampleCursor",
            "in": "query",
            "description": "Cursor for samples. Start at 0.",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          },
          {
            "name": "markerCursor",
            "in": "query",
            "description": "Cursor for markers. Start at 0.",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          },
          {
            "name": "spanCursor",
            "in": "query",
            "description": "Cursor for spans. Start at 0.",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of items to return per category.",
            "schema": {
              "type": "integer",
              "minimum": "1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Profiler batch of samples, markers, and spans.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfilerBatch"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/markers": {
      "post": {
        "operationId": "publishProfilerMarker",
        "tags": [
          "profiler"
        ],
        "summary": "Publish profiler marker",
        "description": "Publishes a timestamped marker event into the active profiling session.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfilerMarker"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Marker published.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/spans": {
      "post": {
        "operationId": "publishProfilerSpan",
        "tags": [
          "profiler"
        ],
        "summary": "Publish profiler span",
        "description": "Publishes a completed span into the active profiling session.\n",
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProfilerSpan"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Span published.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/profiler/hotspots": {
      "get": {
        "operationId": "getProfilerHotspots",
        "tags": [
          "profiler"
        ],
        "summary": "Get performance hotspots",
        "description": "Returns aggregated performance hotspots from the profiling session.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of hotspots to return.",
            "schema": {
              "type": "integer",
              "minimum": "1"
            }
          },
          {
            "name": "minDurationMs",
            "in": "query",
            "description": "Minimum average duration in milliseconds.",
            "schema": {
              "type": "number",
              "minimum": "0"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "description": "Filter by hotspot kind.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of hotspots.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProfilerHotspot"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/network/requests": {
      "get": {
        "operationId": "getNetworkRequests",
        "tags": [
          "network"
        ],
        "summary": "List captured network requests",
        "description": "Returns captured HTTP requests, optionally filtered by host, method, or status code.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of requests to return.",
            "schema": {
              "type": "integer",
              "minimum": "1"
            }
          },
          {
            "name": "host",
            "in": "query",
            "description": "Filter by host name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "method",
            "in": "query",
            "description": "Filter by HTTP method.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "statusCode",
            "in": "query",
            "description": "Filter by status code.",
            "schema": {
              "type": "integer",
              "minimum": "100",
              "maximum": "599"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of network request summaries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/NetworkRequestSummary"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "clearNetworkRequests",
        "tags": [
          "network"
        ],
        "summary": "Clear captured requests",
        "description": "Clears all captured network requests from the buffer.\n",
        "responses": {
          "204": {
            "description": "Requests cleared."
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/network/requests/{id}": {
      "get": {
        "operationId": "getNetworkRequestDetail",
        "tags": [
          "network"
        ],
        "summary": "Get network request detail",
        "description": "Returns full details for a captured network request, including headers and body content.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": "true",
            "description": "Network request ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Full network request detail.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkRequestDetail"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/logs": {
      "get": {
        "operationId": "getLogs",
        "tags": [
          "logs"
        ],
        "summary": "Query application logs",
        "description": "Returns application log entries, optionally filtered by source and level.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of log entries.",
            "schema": {
              "type": "integer",
              "minimum": "1"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "description": "Number of entries to skip (for pagination).",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          },
          {
            "name": "source",
            "in": "query",
            "description": "Filter by log source.",
            "schema": {
              "type": "string",
              "enum": [
                "native",
                "webview",
                "framework"
              ]
            }
          },
          {
            "name": "level",
            "in": "query",
            "description": "Minimum log level.",
            "schema": {
              "type": "string",
              "enum": [
                "trace",
                "debug",
                "info",
                "warning",
                "error",
                "critical"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of log entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LogEntry"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/info": {
      "get": {
        "operationId": "getDeviceInfo",
        "tags": [
          "device"
        ],
        "summary": "Get device info",
        "description": "Returns hardware and OS information about the device.\n",
        "responses": {
          "200": {
            "description": "Device information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeviceInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/display": {
      "get": {
        "operationId": "getDisplayInfo",
        "tags": [
          "device"
        ],
        "summary": "Get display info",
        "description": "Returns display dimensions, density, and orientation.\n",
        "responses": {
          "200": {
            "description": "Display information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DisplayInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/battery": {
      "get": {
        "operationId": "getBatteryInfo",
        "tags": [
          "device"
        ],
        "summary": "Get battery info",
        "description": "Returns battery level, state, and power source.\n",
        "responses": {
          "200": {
            "description": "Battery information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatteryInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/connectivity": {
      "get": {
        "operationId": "getConnectivityInfo",
        "tags": [
          "device"
        ],
        "summary": "Get connectivity info",
        "description": "Returns network connectivity status and connection profiles.\n",
        "responses": {
          "200": {
            "description": "Connectivity information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectivityInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/app": {
      "get": {
        "operationId": "getAppInfo",
        "tags": [
          "device"
        ],
        "summary": "Get app info",
        "description": "Returns application name, version, build number, and package ID.\n",
        "responses": {
          "200": {
            "description": "Application information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppInfo"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/sensors": {
      "get": {
        "operationId": "listSensors",
        "tags": [
          "device"
        ],
        "summary": "List available sensors",
        "description": "Returns the list of sensors and their availability/active status.\n",
        "responses": {
          "200": {
            "description": "Array of sensor info.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SensorInfo"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/sensors/{name}/start": {
      "post": {
        "operationId": "startSensor",
        "tags": [
          "device"
        ],
        "summary": "Start sensor",
        "description": "Starts collecting data from the named sensor. Readings are delivered via the WebSocket sensor channel.\n",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": "true",
            "description": "Sensor name (e.g. accelerometer, gyroscope, compass).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "speed",
            "in": "query",
            "description": "Sensor update speed. Framework-dependent (e.g. \"fastest\", \"game\", \"ui\", \"default\").\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sensor started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SensorInfo"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "501": {
            "$ref": "#/components/responses/UnsupportedCapability"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/sensors/{name}/stop": {
      "post": {
        "operationId": "stopSensor",
        "tags": [
          "device"
        ],
        "summary": "Stop sensor",
        "description": "Stops collecting data from the named sensor.\n",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": "true",
            "description": "Sensor name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sensor stopped.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SensorInfo"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/permissions": {
      "get": {
        "operationId": "listPermissions",
        "tags": [
          "device"
        ],
        "summary": "List permissions",
        "description": "Returns the status of all known permissions.\n",
        "responses": {
          "200": {
            "description": "Array of permission info.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PermissionInfo"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/permissions/{name}": {
      "get": {
        "operationId": "checkPermission",
        "tags": [
          "device"
        ],
        "summary": "Check permission status",
        "description": "Returns the current status of a specific permission.\n",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": "true",
            "description": "Permission name (e.g. camera, location, microphone).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Permission status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PermissionInfo"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/geolocation": {
      "get": {
        "operationId": "getGeolocation",
        "tags": [
          "device"
        ],
        "summary": "Get current location",
        "description": "Returns the device's current geographic location.\n",
        "parameters": [
          {
            "name": "accuracy",
            "in": "query",
            "description": "Desired accuracy level.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeout",
            "in": "query",
            "description": "Timeout in milliseconds for the location request.",
            "schema": {
              "type": "integer",
              "minimum": "0"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current location.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeolocationResult"
                }
              }
            }
          },
          "408": {
            "$ref": "#/components/responses/Timeout"
          },
          "501": {
            "$ref": "#/components/responses/UnsupportedCapability"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/jobs": {
      "get": {
        "operationId": "listDeviceJobs",
        "tags": [
          "device"
        ],
        "summary": "List platform background jobs",
        "description": "Returns platform background jobs known to the agent. Android reports WorkManager identifiers, tags, states, and run attempts. iOS and Mac Catalyst report pending BGTaskScheduler requests.\n",
        "responses": {
          "200": {
            "description": "Platform job list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobListResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/jobs/{identifier}/run": {
      "post": {
        "operationId": "runDeviceJob",
        "tags": [
          "device"
        ],
        "summary": "Trigger a platform background job",
        "description": "Attempts to trigger the named platform background job. iOS and Mac Catalyst submit a BGTaskRequest for the identifier; pass `type` when the task is known to be an app refresh task. Android may report `success=false` when worker types and request inputs cannot be reconstructed safely from the listed identifier or tags.\n",
        "parameters": [
          {
            "name": "identifier",
            "in": "path",
            "required": "true",
            "description": "Platform job identifier returned by the list endpoint.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "false",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobRunRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job trigger result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunResponse"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/UnsupportedCapability"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/ble": {
      "get": {
        "operationId": "getBleStatus",
        "tags": [
          "device"
        ],
        "summary": "Get BLE monitor status",
        "description": "Returns Bluetooth Low Energy monitor status, including whether scanning is active, the number of buffered events, active stream subscribers, and whether native scanning is supported.\n",
        "responses": {
          "200": {
            "description": "BLE monitor status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BleStatus"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/ble/events": {
      "get": {
        "operationId": "getBleEvents",
        "tags": [
          "device"
        ],
        "summary": "List BLE events",
        "description": "Returns recent BLE events recorded by the agent, optionally filtered by event type.\n",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Maximum number of events to return.",
            "schema": {
              "type": "integer",
              "minimum": "0",
              "default": "100"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Optional BLE event type filter.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Buffered BLE events.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BleEventsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid BLE event query.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "clearBleEvents",
        "tags": [
          "device"
        ],
        "summary": "Clear BLE events",
        "description": "Clears all buffered BLE events.",
        "responses": {
          "200": {
            "description": "BLE events cleared.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/ble/scan/start": {
      "post": {
        "operationId": "startBleScan",
        "tags": [
          "device"
        ],
        "summary": "Start BLE scan",
        "description": "Starts native BLE scanning when supported by the current platform. Discovered advertisements are buffered as BLE events and streamed to BLE WebSocket subscribers.\n",
        "responses": {
          "200": {
            "description": "BLE scan started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionResponse"
                }
              }
            }
          },
          "501": {
            "$ref": "#/components/responses/UnsupportedCapability"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/device/ble/scan/stop": {
      "post": {
        "operationId": "stopBleScan",
        "tags": [
          "device"
        ],
        "summary": "Stop BLE scan",
        "description": "Stops an active BLE scan.",
        "responses": {
          "200": {
            "description": "BLE scan stopped.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActionResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/roots": {
      "get": {
        "operationId": "listStorageRoots",
        "tags": [
          "storage"
        ],
        "summary": "List file storage roots",
        "description": "Lists logical file storage roots advertised by the agent. Absolute on-device paths are not returned. The shared implementation advertises `appData` when an app data directory is available.\n",
        "responses": {
          "200": {
            "description": "Storage roots.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorageRootsResponse"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/files": {
      "get": {
        "operationId": "listFiles",
        "tags": [
          "storage"
        ],
        "summary": "List storage files",
        "description": "Lists files and directories under an advertised storage root. The optional path is always relative to the selected root; rooted paths, `..` traversal segments, and symlink/reparse-point traversal are rejected. Absolute on-device paths are not returned. Omit `root` to use the default `appData` root.\n",
        "parameters": [
          {
            "name": "root",
            "in": "query",
            "description": "Storage root id. Defaults to `appData`. Use `/api/v1/storage/roots` to discover supported roots.",
            "schema": {
              "type": "string",
              "default": "appData"
            }
          },
          {
            "name": "path",
            "in": "query",
            "description": "Relative subdirectory path. Omit or pass an empty string for the selected root.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Directory listing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidPath"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/files/{path}": {
      "get": {
        "operationId": "downloadFile",
        "tags": [
          "storage"
        ],
        "summary": "Download a storage file",
        "description": "Downloads a file under an advertised storage root and returns base64-encoded content. The path parameter is a single URI-encoded relative path; path separators inside it must be percent-encoded. Omit `root` to use the default `appData` root.\n",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "URI-encoded relative file path under the selected storage root.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "root",
            "in": "query",
            "description": "Storage root id. Defaults to `appData`. Use `/api/v1/storage/roots` to discover supported roots.",
            "schema": {
              "type": "string",
              "default": "appData"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File content and metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDownloadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidPath"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "operationId": "uploadFile",
        "tags": [
          "storage"
        ],
        "summary": "Upload a storage file",
        "description": "Creates or overwrites a file under an advertised storage root. Parent directories are created automatically after path sandbox validation. Omit `root` to use the default `appData` root.\n",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "URI-encoded relative file path under the selected storage root.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "root",
            "in": "query",
            "description": "Storage root id. Defaults to `appData`. Use `/api/v1/storage/roots` to discover supported roots.",
            "schema": {
              "type": "string",
              "default": "appData"
            }
          }
        ],
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileUploadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded file metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileUploadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidPath"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "deleteFile",
        "tags": [
          "storage"
        ],
        "summary": "Delete a storage file",
        "description": "Deletes a file under an advertised storage root. Omit `root` to use the default `appData` root.",
        "parameters": [
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "URI-encoded relative file path under the selected storage root.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "root",
            "in": "query",
            "description": "Storage root id. Defaults to `appData`. Use `/api/v1/storage/roots` to discover supported roots.",
            "schema": {
              "type": "string",
              "default": "appData"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted file metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDeleteResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidPath"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/preferences": {
      "get": {
        "operationId": "listPreferences",
        "tags": [
          "storage"
        ],
        "summary": "List preferences",
        "description": "Returns all preference entries, optionally scoped to a shared container.\n",
        "parameters": [
          {
            "name": "sharedName",
            "in": "query",
            "description": "Shared preference container name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of preference entries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PreferenceEntry"
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "clearPreferences",
        "tags": [
          "storage"
        ],
        "summary": "Clear all preferences",
        "description": "Deletes all preferences, optionally scoped to a shared container.\n",
        "parameters": [
          {
            "name": "sharedName",
            "in": "query",
            "description": "Shared preference container name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Preferences cleared."
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/preferences/{key}": {
      "get": {
        "operationId": "getPreference",
        "tags": [
          "storage"
        ],
        "summary": "Get preference value",
        "description": "Returns the value of a specific preference key.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Preference key.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Expected value type for deserialization.",
            "schema": {
              "$ref": "#/components/schemas/PreferenceValueType"
            }
          },
          {
            "name": "sharedName",
            "in": "query",
            "description": "Shared preference container name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Preference entry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreferenceEntry"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "operationId": "setPreference",
        "tags": [
          "storage"
        ],
        "summary": "Set preference value",
        "description": "Creates or updates a preference entry.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Preference key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreferenceSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preference set.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreferenceEntry"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "deletePreference",
        "tags": [
          "storage"
        ],
        "summary": "Delete preference",
        "description": "Deletes a specific preference by key.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Preference key.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sharedName",
            "in": "query",
            "description": "Shared preference container name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Preference deleted."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/secure": {
      "delete": {
        "operationId": "clearSecureStorage",
        "tags": [
          "storage"
        ],
        "summary": "Clear all secure storage",
        "description": "Deletes all values from secure storage.\n",
        "responses": {
          "204": {
            "description": "Secure storage cleared."
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/storage/secure/{key}": {
      "get": {
        "operationId": "getSecureValue",
        "tags": [
          "storage"
        ],
        "summary": "Get secure storage value",
        "description": "Returns the value stored under the given key in secure storage.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Secure storage key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secure value.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "value"
                  ],
                  "properties": {
                    "value": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "operationId": "setSecureValue",
        "tags": [
          "storage"
        ],
        "summary": "Set secure storage value",
        "description": "Stores a value in secure storage under the given key.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Secure storage key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "true",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SecureStorageSetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Value stored.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "deleteSecureValue",
        "tags": [
          "storage"
        ],
        "summary": "Delete secure storage value",
        "description": "Deletes a specific value from secure storage.\n",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": "true",
            "description": "Secure storage key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Value deleted."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/ext/{namespace}/{path}": {
      "get": {
        "operationId": "callExtensionGet",
        "tags": [
          "extensions"
        ],
        "summary": "Call extension endpoint (GET)",
        "description": "Proxy route for third-party extension GET endpoints. The namespace uses reverse-domain notation (e.g. `com.example.analytics`). Available extensions and their self-describing tools are discoverable via `GET /api/v1/agent/capabilities`. The `path` segment represents the extension-defined relative path; agents may accept nested sub-paths.\n",
        "parameters": [
          {
            "name": "namespace",
            "in": "path",
            "required": "true",
            "description": "Extension namespace in reverse-domain notation.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9]*\\.[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "Extension-defined sub-path.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Extension-defined response.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "operationId": "callExtensionPost",
        "tags": [
          "extensions"
        ],
        "summary": "Call extension endpoint (POST)",
        "description": "Proxy route for third-party extension POST endpoints. Request and response schemas are extension-defined and advertised by the tool descriptor in the capabilities response.\n",
        "parameters": [
          {
            "name": "namespace",
            "in": "path",
            "required": "true",
            "description": "Extension namespace in reverse-domain notation.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9]*\\.[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "Extension-defined sub-path.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "false",
          "content": {
            "application/json": {
              "schema": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extension-defined response.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "put": {
        "operationId": "callExtensionPut",
        "tags": [
          "extensions"
        ],
        "summary": "Call extension endpoint (PUT)",
        "description": "Proxy route for third-party extension PUT endpoints. Request and response schemas are extension-defined and advertised by the tool descriptor in the capabilities response.\n",
        "parameters": [
          {
            "name": "namespace",
            "in": "path",
            "required": "true",
            "description": "Extension namespace in reverse-domain notation.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9]*\\.[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "Extension-defined sub-path.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": "false",
          "content": {
            "application/json": {
              "schema": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extension-defined response.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "callExtensionDelete",
        "tags": [
          "extensions"
        ],
        "summary": "Call extension endpoint (DELETE)",
        "description": "Proxy route for third-party extension DELETE endpoints. Available extension tools and behavior annotations are discoverable from `GET /api/v1/agent/capabilities`.\n",
        "parameters": [
          {
            "name": "namespace",
            "in": "path",
            "required": "true",
            "description": "Extension namespace in reverse-domain notation.",
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9]*\\.[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
            }
          },
          {
            "name": "path",
            "in": "path",
            "required": "true",
            "description": "Extension-defined sub-path.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Extension-defined response.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "ElementIdPath": {
        "name": "id",
        "in": "path",
        "required": "true",
        "description": "Globally unique element identifier.",
        "schema": {
          "type": "string",
          "description": "Globally unique element identifier within the visual tree."
        }
      }
    },
    "responses": {
      "ActionSuccess": {
        "description": "Action completed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ActionResponse"
            }
          }
        }
      },
      "ElementNotFound": {
        "description": "Element not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:element-not-found",
              "title": "Element not found",
              "status": "404",
              "errorCode": "element-not-found"
            }
          }
        }
      },
      "ElementNotInteractable": {
        "description": "Element is not interactable.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:element-not-interactable",
              "title": "Element not interactable",
              "status": "400",
              "errorCode": "element-not-interactable"
            }
          }
        }
      },
      "InvalidSelector": {
        "description": "Invalid selector or locator.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:invalid-selector",
              "title": "Invalid selector",
              "status": "400",
              "errorCode": "invalid-selector"
            }
          }
        }
      },
      "Timeout": {
        "description": "Operation timed out.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:timeout",
              "title": "Timeout",
              "status": "408",
              "errorCode": "timeout"
            }
          }
        }
      },
      "UnsupportedCapability": {
        "description": "Capability not supported on this platform.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:unsupported-capability",
              "title": "Unsupported capability",
              "status": "501",
              "errorCode": "unsupported-capability"
            }
          }
        }
      },
      "InvalidPath": {
        "description": "Invalid or unsafe storage path or unavailable storage root.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:invalid-path",
              "title": "Invalid storage path",
              "status": "400",
              "errorCode": "invalid-path"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:element-not-found",
              "title": "Not found",
              "status": "404"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ProblemDetails"
            },
            "example": {
              "type": "urn:devflow:error:internal-error",
              "title": "Internal error",
              "status": "500",
              "errorCode": "internal-error"
            }
          }
        }
      }
    },
    "schemas": {
      "agent-status": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "agent-status.json",
        "title": "AgentStatus",
        "description": "Agent status response providing runtime information about the agent, device, and application.",
        "type": "object",
        "required": [
          "agent",
          "platform",
          "device",
          "app",
          "running",
          "uptime"
        ],
        "properties": {
          "agent": {
            "type": "object",
            "description": "Information about the DevFlow agent itself.",
            "required": [
              "name",
              "version",
              "framework",
              "frameworkVersion"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the DevFlow agent implementation."
              },
              "version": {
                "type": "string",
                "description": "Semantic version of the agent."
              },
              "sessionId": {
                "type": "string",
                "description": "Optional metadata-only identifier for the build/session that produced this agent. It is used to distinguish agents from different worktrees or environments without changing the application package or bundle identity."
              },
              "framework": {
                "type": "string",
                "description": "The UI framework the agent is instrumented for (e.g. 'maui', 'react-native')."
              },
              "frameworkVersion": {
                "type": "string",
                "description": "Version of the UI framework."
              }
            }
          },
          "platform": {
            "type": "string",
            "enum": [
              "ios",
              "android",
              "maccatalyst",
              "windows",
              "linux",
              "macos"
            ],
            "description": "The target platform the agent is running on."
          },
          "device": {
            "type": "object",
            "description": "Information about the device or emulator/simulator.",
            "required": [
              "model",
              "manufacturer",
              "osVersion",
              "idiom"
            ],
            "properties": {
              "model": {
                "type": "string",
                "description": "Device model name (e.g. 'iPhone 15 Pro', 'Pixel 8')."
              },
              "manufacturer": {
                "type": "string",
                "description": "Device manufacturer (e.g. 'Apple', 'Google')."
              },
              "osVersion": {
                "type": "string",
                "description": "Operating system version string."
              },
              "idiom": {
                "type": "string",
                "enum": [
                  "phone",
                  "tablet",
                  "desktop",
                  "tv",
                  "watch"
                ],
                "description": "Device form factor idiom."
              }
            }
          },
          "app": {
            "type": "object",
            "description": "Information about the instrumented application.",
            "required": [
              "name",
              "version",
              "packageId"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "Display name of the application."
              },
              "version": {
                "type": "string",
                "description": "Application version string."
              },
              "packageId": {
                "type": "string",
                "description": "Application package identifier (e.g. 'com.example.myapp')."
              }
            }
          },
          "running": {
            "type": "boolean",
            "description": "Whether the application is currently running and responsive."
          },
          "capabilities": {
            "type": "object",
            "description": "Boolean status summary for agent capabilities.",
            "properties": {
              "ui": {
                "type": "boolean"
              },
              "screenshots": {
                "type": "boolean"
              },
              "webview": {
                "type": "boolean"
              },
              "network": {
                "type": "boolean"
              },
              "logs": {
                "type": "boolean"
              },
              "sensors": {
                "type": "boolean"
              },
              "storage": {
                "type": "boolean"
              },
              "profiler": {
                "type": "boolean"
              },
              "jobs": {
                "type": "boolean",
                "description": "Whether platform background jobs are supported by this agent."
              },
              "ble": {
                "type": "boolean",
                "description": "Whether Bluetooth Low Energy monitoring is supported by this agent."
              }
            },
            "additionalProperties": true
          },
          "uptime": {
            "type": "string",
            "description": "Agent uptime as an ISO 8601 duration (e.g. 'PT1H30M15S').",
            "pattern": "^P"
          },
          "extensions": {
            "type": "object",
            "description": "Lightweight marker indicating registered extensions. Allows clients to skip the heavier capabilities fetch when no extensions are present or when cached extension descriptors are still current.",
            "properties": {
              "count": {
                "type": "integer",
                "description": "Number of registered extensions. When 0, clients can skip the capabilities call for extension discovery.",
                "minimum": 0
              },
              "hash": {
                "type": "string",
                "description": "SHA-256 hash of the serialized extensions map from the capabilities response. Clients cache extension metadata keyed by this hash and only re-fetch capabilities when it changes.",
                "pattern": "^[a-f0-9]{64}$"
              }
            },
            "required": [
              "count",
              "hash"
            ]
          }
        }
      },
      "agent-capabilities": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "agent-capabilities.json",
        "title": "AgentCapabilities",
        "description": "Capability discovery response describing what the agent supports.",
        "type": "object",
        "required": [
          "agent",
          "capabilities"
        ],
        "properties": {
          "agent": {
            "type": "object",
            "description": "Information about the DevFlow agent itself.",
            "required": [
              "name",
              "version",
              "framework",
              "frameworkVersion"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "Name of the DevFlow agent implementation."
              },
              "version": {
                "type": "string",
                "description": "Semantic version of the agent."
              },
              "framework": {
                "type": "string",
                "description": "The UI framework the agent is instrumented for."
              },
              "frameworkVersion": {
                "type": "string",
                "description": "Version of the UI framework."
              }
            }
          },
          "capabilities": {
            "type": "object",
            "description": "Map of capability namespaces to their details. Keys are dot-separated namespaces.",
            "additionalProperties": {
              "type": "object",
              "required": [
                "version",
                "features"
              ],
              "properties": {
                "version": {
                  "type": "integer",
                  "description": "Capability version number.",
                  "minimum": 1
                },
                "features": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "List of supported features within this capability namespace."
                }
              },
              "additionalProperties": true,
              "description": "Capability details including version, features, and optional extra fields."
            },
            "examples": [
              {
                "ui.tree": {
                  "version": 1,
                  "features": [
                    "find",
                    "query",
                    "snapshot"
                  ]
                },
                "ui.actions": {
                  "version": 1,
                  "features": [
                    "tap",
                    "fill",
                    "scroll",
                    "gesture"
                  ]
                },
                "ui.screenshot": {
                  "version": 1,
                  "features": [
                    "fullPage",
                    "element"
                  ]
                },
                "webview": {
                  "version": 1,
                  "features": [
                    "evaluate",
                    "dom",
                    "navigate"
                  ]
                },
                "profiler": {
                  "version": 1,
                  "features": [
                    "samples",
                    "spans",
                    "markers"
                  ]
                },
                "network": {
                  "version": 1,
                  "features": [
                    "capture",
                    "detail"
                  ]
                },
                "logs": {
                  "version": 1,
                  "features": [
                    "stream",
                    "query"
                  ]
                },
                "device.info": {
                  "version": 1,
                  "features": [
                    "display",
                    "battery",
                    "connectivity"
                  ]
                },
                "device.sensors": {
                  "version": 1,
                  "features": [
                    "accelerometer",
                    "gyroscope",
                    "compass"
                  ]
                },
                "device.jobs": {
                  "version": 1,
                  "features": [
                    "list",
                    "run"
                  ],
                  "supported": true
                },
                "device.ble": {
                  "version": 1,
                  "features": [
                    "status",
                    "events",
                    "scan",
                    "websocket"
                  ],
                  "supported": true
                },
                "storage.preferences": {
                  "version": 1,
                  "features": [
                    "get",
                    "set",
                    "delete"
                  ]
                },
                "storage.files": {
                  "version": 1,
                  "features": [
                    "roots",
                    "list",
                    "download",
                    "upload",
                    "delete"
                  ]
                },
                "storage.secure": {
                  "version": 1,
                  "features": [
                    "get",
                    "set",
                    "delete"
                  ]
                }
              }
            ]
          },
          "extensions": {
            "type": "object",
            "description": "Map of extension namespaces (reverse-domain notation) to their self-describing tool registrations. Each extension is discoverable and invocable by CLI and MCP clients without hardcoded extension-specific code.",
            "additionalProperties": {
              "$ref": "#/components/schemas/ExtensionDescriptor"
            }
          }
        },
        "$defs": {
          "ExtensionDescriptor": {
            "type": "object",
            "required": [
              "version",
              "description",
              "tools"
            ],
            "properties": {
              "version": {
                "type": "string",
                "description": "Semantic version of this extension. Changes to this value signal clients to refresh cached tool definitions.",
                "pattern": "^\\d+\\.\\d+\\.\\d+"
              },
              "description": {
                "type": "string",
                "description": "Human-readable description of what this extension provides."
              },
              "tools": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ExtensionTool"
                },
                "description": "Self-describing tools exposed by this extension. Each tool maps to an HTTP endpoint under /api/v1/ext/{namespace}/."
              }
            },
            "description": "Extension descriptor with version, description, and self-describing tools."
          },
          "ExtensionTool": {
            "type": "object",
            "required": [
              "name",
              "description",
              "method",
              "path"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "Machine-readable tool name, unique within the extension (e.g. 'list_errors', 'capture_message').",
                "pattern": "^[a-z][a-z0-9_]*$"
              },
              "description": {
                "type": "string",
                "description": "Human-readable description of what this tool does. Used by CLI help text and MCP tool metadata."
              },
              "method": {
                "type": "string",
                "enum": [
                  "GET",
                  "POST",
                  "PUT",
                  "DELETE"
                ],
                "description": "HTTP method for this tool's endpoint."
              },
              "path": {
                "type": "string",
                "description": "Full URL path for this tool (e.g. '/api/v1/ext/com.example.analytics/events')."
              },
              "parameters": {
                "type": "object",
                "description": "JSON Schema describing the tool's input parameters. For GET requests, parameters are query strings. For POST and PUT, parameters are the JSON request body.",
                "additionalProperties": true
              },
              "returns": {
                "type": "object",
                "description": "JSON Schema describing the tool's response body.",
                "additionalProperties": true
              },
              "annotations": {
                "$ref": "#/components/schemas/ExtensionToolAnnotations"
              }
            }
          },
          "ExtensionToolAnnotations": {
            "type": "object",
            "description": "Hints about the tool's behavior, modeled after MCP tool annotations.",
            "properties": {
              "readOnly": {
                "type": "boolean",
                "description": "True if the tool only reads data and has no side effects.",
                "default": false
              },
              "idempotent": {
                "type": "boolean",
                "description": "True if calling the tool multiple times with the same input has the same effect as calling it once.",
                "default": false
              },
              "destructive": {
                "type": "boolean",
                "description": "True if the tool may delete data or cause irreversible changes.",
                "default": false
              },
              "category": {
                "type": "string",
                "description": "Optional grouping category (e.g. 'diagnostics', 'analytics', 'testing')."
              }
            }
          }
        }
      },
      "ExtensionDescriptor": {
        "type": "object",
        "required": [
          "version",
          "description",
          "tools"
        ],
        "properties": {
          "version": {
            "type": "string",
            "description": "Semantic version of this extension. Changes to this value signal clients to refresh cached tool definitions.",
            "pattern": "^\\d+\\.\\d+\\.\\d+"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of what this extension provides."
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExtensionTool"
            },
            "description": "Self-describing tools exposed by this extension. Each tool maps to an HTTP endpoint under /api/v1/ext/{namespace}/."
          }
        },
        "description": "Extension descriptor with version, description, and self-describing tools."
      },
      "ExtensionTool": {
        "type": "object",
        "required": [
          "name",
          "description",
          "method",
          "path"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Machine-readable tool name, unique within the extension (e.g. 'list_errors', 'capture_message').",
            "pattern": "^[a-z][a-z0-9_]*$"
          },
          "description": {
            "type": "string",
            "description": "Human-readable description of what this tool does. Used by CLI help text and MCP tool metadata."
          },
          "method": {
            "type": "string",
            "enum": [
              "GET",
              "POST",
              "PUT",
              "DELETE"
            ],
            "description": "HTTP method for this tool's endpoint."
          },
          "path": {
            "type": "string",
            "description": "Full URL path for this tool (e.g. '/api/v1/ext/com.example.analytics/events')."
          },
          "parameters": {
            "type": "object",
            "description": "JSON Schema describing the tool's input parameters. For GET requests, parameters are query strings. For POST and PUT, parameters are the JSON request body.",
            "additionalProperties": true
          },
          "returns": {
            "type": "object",
            "description": "JSON Schema describing the tool's response body.",
            "additionalProperties": true
          },
          "annotations": {
            "$ref": "#/components/schemas/ExtensionToolAnnotations"
          }
        }
      },
      "ExtensionToolAnnotations": {
        "type": "object",
        "description": "Hints about the tool's behavior, modeled after MCP tool annotations.",
        "properties": {
          "readOnly": {
            "type": "boolean",
            "description": "True if the tool only reads data and has no side effects.",
            "default": false
          },
          "idempotent": {
            "type": "boolean",
            "description": "True if calling the tool multiple times with the same input has the same effect as calling it once.",
            "default": false
          },
          "destructive": {
            "type": "boolean",
            "description": "True if the tool may delete data or cause irreversible changes.",
            "default": false
          },
          "category": {
            "type": "string",
            "description": "Optional grouping category (e.g. 'diagnostics', 'analytics', 'testing')."
          }
        }
      },
      "element-info": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "element-info.json",
        "title": "ElementInfo",
        "description": "Core visual tree element model representing a single node in the UI hierarchy.",
        "type": "object",
        "required": [
          "id",
          "type",
          "fullType",
          "framework",
          "state",
          "bounds"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Globally unique element identifier within the visual tree."
          },
          "parentId": {
            "oneOf": [
              {
                "type": "string",
                "description": "Globally unique element identifier within the visual tree."
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifier of the parent element, or null for root elements."
          },
          "type": {
            "type": "string",
            "description": "Short type name of the element (e.g. 'Button')."
          },
          "fullType": {
            "type": "string",
            "description": "Fully qualified type name (e.g. 'Microsoft.Maui.Controls.Button')."
          },
          "framework": {
            "type": "string",
            "description": "The UI framework that owns this element.",
            "examples": [
              "maui",
              "react-native",
              "flutter",
              "android",
              "ios"
            ]
          },
          "automationId": {
            "type": "string",
            "description": "Automation identifier set by the developer for testing purposes.",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "Visible text content of the element.",
            "nullable": true
          },
          "value": {
            "type": "string",
            "description": "Current value for input elements (e.g. text field content, slider value).",
            "nullable": true
          },
          "role": {
            "type": "string",
            "description": "Semantic role of the element for accessibility and interaction purposes.",
            "examples": [
              "button",
              "textbox",
              "checkbox",
              "image",
              "list",
              "listitem",
              "link",
              "heading",
              "window"
            ]
          },
          "traits": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Semantic traits describing the element's capabilities and behavior.",
            "examples": [
              [
                "interactive",
                "focusable",
                "scrollable",
                "adjustable",
                "header",
                "summary"
              ]
            ]
          },
          "state": {
            "type": "object",
            "description": "Current interactive and visual state of the element.",
            "required": [
              "displayed",
              "enabled",
              "selected",
              "focused",
              "opacity"
            ],
            "properties": {
              "displayed": {
                "type": "boolean",
                "description": "Whether the element is currently visible on screen."
              },
              "enabled": {
                "type": "boolean",
                "description": "Whether the element is enabled for user interaction."
              },
              "selected": {
                "type": "boolean",
                "description": "Whether the element is currently selected."
              },
              "focused": {
                "type": "boolean",
                "description": "Whether the element currently has input focus."
              },
              "opacity": {
                "type": "number",
                "description": "Opacity of the element from fully transparent (0) to fully opaque (1).",
                "minimum": 0,
                "maximum": 1
              }
            }
          },
          "bounds": {
            "$ref": "#/components/schemas/bounds-info",
            "description": "Bounding rectangle of the element."
          },
          "gestures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Gesture types recognized by this element.",
            "examples": [
              [
                "tap",
                "doubleTap",
                "longPress",
                "swipe",
                "pinch"
              ]
            ]
          },
          "style": {
            "type": "object",
            "description": "Style information for the element.",
            "properties": {
              "classes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "CSS or style classes applied to this element."
              }
            }
          },
          "nativeView": {
            "type": "object",
            "description": "Information about the underlying native platform view.",
            "properties": {
              "type": {
                "type": "string",
                "description": "Native platform type name (e.g. 'UIButton', 'android.widget.Button').",
                "nullable": true
              },
              "properties": {
                "type": "object",
                "additionalProperties": true,
                "description": "Key-value pairs of native view properties.",
                "nullable": true
              }
            },
            "nullable": true
          },
          "frameworkProperties": {
            "type": "object",
            "additionalProperties": true,
            "description": "Framework-specific key-value pairs not captured by standard fields.",
            "nullable": true
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/element-info",
              "description": "Child element in the visual tree."
            },
            "description": "Child elements forming the subtree under this element."
          }
        }
      },
      "bounds-info": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "$id": "bounds-info.json",
        "title": "BoundsInfo",
        "description": "Bounding rectangle for a visual element.",
        "type": "object",
        "required": [
          "x",
          "y",
          "width",
          "height"
        ],
        "properties": {
          "x": {
            "type": "number",
            "description": "The x-coordinate of the top-left corner."
          },
          "y": {
            "type": "number",
            "description": "The y-coordinate of the top-left corner."
          },
          "width": {
            "type": "number",
            "description": "The width of the bounding rectangle.",
            "minimum": 0
          },
          "height": {
            "type": "number",
            "description": "The height of the bounding rectangle.",
            "minimum": 0
          },
          "coordinate": {
            "$ref": "#/components/schemas/CoordinateSystem",
            "description": "The coordinate system for this bounding rectangle.",
            "default": "window"
          }
        }
      },
      "CoordinateSystem": {
        "type": "string",
        "enum": [
          "window",
          "screen"
        ],
        "description": "Coordinate system for bounding rectangles and points."
      },
      "LocatorStrategy": {
        "type": "string",
        "enum": [
          "AccessibilityId",
          "CssSelector",
          "type",
          "text",
          "xpath"
        ],
        "description": "Strategy used to locate an element in the visual tree."
      },
      "TapRequest": {
        "type": "object",
        "description": "Request to perform a tap/click action on an element or at coordinates.",
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target element identifier. Either elementId or coordinates must be provided.",
            "nullable": true
          },
          "x": {
            "type": "number",
            "description": "X coordinate for the tap. Used when tapping by position rather than element.",
            "nullable": true
          },
          "y": {
            "type": "number",
            "description": "Y coordinate for the tap. Used when tapping by position rather than element.",
            "nullable": true
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "FillRequest": {
        "type": "object",
        "description": "Request to fill text into an input element.",
        "required": [
          "elementId",
          "text"
        ],
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target input element identifier."
          },
          "text": {
            "type": "string",
            "description": "Text content to fill into the element."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "ClearRequest": {
        "type": "object",
        "description": "Request to clear the content of an input element.",
        "required": [
          "elementId"
        ],
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target input element identifier."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "FocusRequest": {
        "type": "object",
        "description": "Request to move input focus to an element.",
        "required": [
          "elementId"
        ],
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target element identifier to receive focus."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "ScrollRequest": {
        "type": "object",
        "description": "Request to perform a scroll action on a scrollable element.",
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target scrollable element identifier. If null, scrolls the primary scrollable view.",
            "nullable": true
          },
          "deltaX": {
            "type": "number",
            "description": "Horizontal scroll delta in device-independent pixels."
          },
          "deltaY": {
            "type": "number",
            "description": "Vertical scroll delta in device-independent pixels."
          },
          "animated": {
            "type": "boolean",
            "description": "Whether the scroll should be animated.",
            "default": true
          },
          "itemIndex": {
            "type": "integer",
            "description": "Index of the item to scroll to in a list or collection view.",
            "minimum": 0,
            "nullable": true
          },
          "groupIndex": {
            "type": "integer",
            "description": "Index of the group containing the target item.",
            "minimum": 0,
            "nullable": true
          },
          "scrollToPosition": {
            "type": "string",
            "enum": [
              "makeVisible",
              "start",
              "center",
              "end",
              null
            ],
            "description": "Alignment of the target item within the viewport after scrolling.",
            "nullable": true
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "NavigateRequest": {
        "type": "object",
        "description": "Request to navigate to a named route or URI within the application.",
        "required": [
          "route"
        ],
        "properties": {
          "route": {
            "type": "string",
            "description": "Route or URI to navigate to."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "ResizeRequest": {
        "type": "object",
        "description": "Request to resize a window or element.",
        "required": [
          "width",
          "height"
        ],
        "properties": {
          "elementId": {
            "type": "string",
            "description": "Target window element identifier. If null, resizes the main application window.",
            "nullable": true
          },
          "width": {
            "type": "integer",
            "description": "Target width in device-independent pixels.",
            "minimum": 1
          },
          "height": {
            "type": "integer",
            "description": "Target height in device-independent pixels.",
            "minimum": 1
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "BackRequest": {
        "type": "object",
        "description": "Request to perform a back navigation action.",
        "properties": {
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "KeyRequest": {
        "type": "object",
        "description": "Request to send a key press event.",
        "required": [
          "key"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Key identifier to press (e.g. 'Enter', 'Escape', 'Tab', 'a', 'F1')."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "GestureRequest": {
        "type": "object",
        "description": "Request to perform a complex gesture as a sequence of pointer actions.",
        "required": [
          "actions"
        ],
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GestureAction"
            },
            "description": "Ordered sequence of gesture actions to perform."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          }
        }
      },
      "GestureAction": {
        "type": "object",
        "description": "A single action within a gesture sequence.",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "pointerMove",
              "pointerDown",
              "pointerUp",
              "pause"
            ],
            "description": "The type of gesture action to perform."
          },
          "x": {
            "type": "number",
            "description": "X coordinate for the action.",
            "nullable": true
          },
          "y": {
            "type": "number",
            "description": "Y coordinate for the action.",
            "nullable": true
          },
          "duration": {
            "type": "integer",
            "description": "Duration of this action in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "button": {
            "type": "integer",
            "description": "Pointer button index (0 = primary, 1 = middle, 2 = secondary).",
            "default": 0,
            "minimum": 0,
            "nullable": true
          }
        }
      },
      "BatchRequest": {
        "type": "object",
        "description": "Request to perform multiple actions in sequence as a single batch operation.",
        "required": [
          "actions"
        ],
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchAction"
            },
            "description": "Ordered list of actions to perform."
          },
          "include": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "screenshot",
                "tree"
              ]
            },
            "description": "Optional data to include in the action response."
          },
          "continueOnError": {
            "type": "boolean",
            "description": "Whether to continue executing remaining actions if one fails.",
            "default": false
          }
        }
      },
      "BatchAction": {
        "type": "object",
        "description": "A single action within a batch, combining the action type with its parameters.",
        "required": [
          "action"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "tap",
              "fill",
              "clear",
              "focus",
              "scroll",
              "navigate",
              "resize",
              "back",
              "key",
              "gesture"
            ],
            "description": "The type of action to perform."
          },
          "elementId": {
            "type": "string",
            "description": "Target element identifier.",
            "nullable": true
          },
          "x": {
            "type": "number",
            "description": "X coordinate (for tap and gesture actions).",
            "nullable": true
          },
          "y": {
            "type": "number",
            "description": "Y coordinate (for tap and gesture actions).",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "Text content (for fill action).",
            "nullable": true
          },
          "deltaX": {
            "type": "number",
            "description": "Horizontal scroll delta (for scroll action).",
            "nullable": true
          },
          "deltaY": {
            "type": "number",
            "description": "Vertical scroll delta (for scroll action).",
            "nullable": true
          },
          "animated": {
            "type": "boolean",
            "description": "Whether scroll should be animated (for scroll action).",
            "nullable": true
          },
          "itemIndex": {
            "type": "integer",
            "description": "Item index to scroll to (for scroll action).",
            "minimum": 0,
            "nullable": true
          },
          "groupIndex": {
            "type": "integer",
            "description": "Group index for scroll target (for scroll action).",
            "minimum": 0,
            "nullable": true
          },
          "scrollToPosition": {
            "type": "string",
            "enum": [
              "makeVisible",
              "start",
              "center",
              "end",
              null
            ],
            "description": "Scroll alignment (for scroll action).",
            "nullable": true
          },
          "route": {
            "type": "string",
            "description": "Route to navigate to (for navigate action).",
            "nullable": true
          },
          "width": {
            "type": "integer",
            "description": "Target width (for resize action).",
            "minimum": 1,
            "nullable": true
          },
          "height": {
            "type": "integer",
            "description": "Target height (for resize action).",
            "minimum": 1,
            "nullable": true
          },
          "key": {
            "type": "string",
            "description": "Key to press (for key action).",
            "nullable": true
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GestureAction"
            },
            "description": "Gesture action sequence (for gesture action).",
            "nullable": true
          }
        }
      },
      "WebViewContext": {
        "type": "object",
        "description": "Represents a discovered WebView context within the application.",
        "required": [
          "id",
          "url",
          "ready"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this WebView context."
          },
          "elementId": {
            "type": "string",
            "description": "Identifier linking this WebView to its corresponding element in the native UI tree.",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "Current URL loaded in the WebView."
          },
          "title": {
            "type": "string",
            "description": "Page title of the WebView content.",
            "nullable": true
          },
          "ready": {
            "type": "boolean",
            "description": "Whether the WebView is ready for interaction (page loaded and DOM available)."
          }
        }
      },
      "EvaluateRequest": {
        "type": "object",
        "description": "Request to evaluate a JavaScript expression in a WebView context.",
        "required": [
          "expression"
        ],
        "properties": {
          "expression": {
            "type": "string",
            "description": "JavaScript expression to evaluate."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier. If null, uses the default or only available context.",
            "nullable": true
          },
          "returnByValue": {
            "type": "boolean",
            "description": "Whether to return the result by value (serialized) rather than by reference.",
            "default": true
          }
        }
      },
      "EvaluateResponse": {
        "type": "object",
        "description": "Response from evaluating a JavaScript expression.",
        "properties": {
          "result": {
            "description": "The result of the JavaScript evaluation as a JSON value."
          },
          "exceptionDetails": {
            "type": "object",
            "description": "Exception details if the evaluation threw an error.",
            "properties": {
              "text": {
                "type": "string",
                "description": "Exception message text."
              },
              "lineNumber": {
                "type": "integer",
                "description": "Line number where the exception occurred.",
                "minimum": 0,
                "nullable": true
              },
              "columnNumber": {
                "type": "integer",
                "description": "Column number where the exception occurred.",
                "minimum": 0,
                "nullable": true
              }
            },
            "nullable": true
          }
        }
      },
      "DomQueryRequest": {
        "type": "object",
        "description": "Request to query the DOM using a CSS selector.",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "type": "string",
            "description": "CSS selector to query the DOM."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier.",
            "nullable": true
          }
        }
      },
      "WebViewNavigateRequest": {
        "type": "object",
        "description": "Request to navigate a WebView to a URL.",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "description": "URL to navigate the WebView to."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier.",
            "nullable": true
          }
        }
      },
      "WebViewInputClickRequest": {
        "type": "object",
        "description": "Request to click an element within a WebView using a CSS selector.",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "type": "string",
            "description": "CSS selector of the element to click."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier.",
            "nullable": true
          }
        }
      },
      "WebViewInputFillRequest": {
        "type": "object",
        "description": "Request to fill text into a WebView input element identified by a CSS selector.",
        "required": [
          "selector",
          "text"
        ],
        "properties": {
          "selector": {
            "type": "string",
            "description": "CSS selector of the input element to fill."
          },
          "text": {
            "type": "string",
            "description": "Text content to fill into the input element."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier.",
            "nullable": true
          }
        }
      },
      "WebViewInputTextRequest": {
        "type": "object",
        "description": "Request to type text into the currently focused element within a WebView.",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "description": "Text to type into the focused element."
          },
          "contextId": {
            "type": "string",
            "description": "Target WebView context identifier.",
            "nullable": true
          }
        }
      },
      "ProfilerCapabilities": {
        "type": "object",
        "description": "Describes the profiler capabilities available on the current platform and agent.",
        "required": [
          "platform",
          "managedMemorySupported",
          "nativeMemorySupported",
          "gcSupported",
          "cpuPercentSupported",
          "fpsSupported",
          "frameTimingsEstimated",
          "nativeFrameTimingsSupported",
          "jankEventsSupported",
          "uiThreadStallSupported",
          "threadCountSupported"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "description": "Platform identifier (e.g. 'ios', 'android', 'maccatalyst')."
          },
          "managedMemorySupported": {
            "type": "boolean",
            "description": "Whether managed heap memory measurement is supported."
          },
          "nativeMemorySupported": {
            "type": "boolean",
            "description": "Whether native memory measurement is supported."
          },
          "gcSupported": {
            "type": "boolean",
            "description": "Whether garbage collection counter reporting is supported."
          },
          "cpuPercentSupported": {
            "type": "boolean",
            "description": "Whether CPU percentage measurement is supported."
          },
          "fpsSupported": {
            "type": "boolean",
            "description": "Whether frames-per-second measurement is supported."
          },
          "frameTimingsEstimated": {
            "type": "boolean",
            "description": "Whether frame timings are estimated rather than measured directly."
          },
          "nativeFrameTimingsSupported": {
            "type": "boolean",
            "description": "Whether native frame timing measurement is supported."
          },
          "jankEventsSupported": {
            "type": "boolean",
            "description": "Whether jank frame detection events are supported."
          },
          "uiThreadStallSupported": {
            "type": "boolean",
            "description": "Whether UI thread stall detection is supported."
          },
          "threadCountSupported": {
            "type": "boolean",
            "description": "Whether thread count reporting is supported."
          }
        }
      },
      "ProfilerSessionInfo": {
        "type": "object",
        "description": "Information about an active or completed profiler session.",
        "required": [
          "sessionId",
          "startedAtUtc",
          "sampleIntervalMs",
          "isActive"
        ],
        "properties": {
          "sessionId": {
            "type": "string",
            "description": "Unique identifier for this profiler session."
          },
          "startedAtUtc": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "sampleIntervalMs": {
            "type": "integer",
            "description": "Interval between profiler samples in milliseconds.",
            "minimum": 1
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the profiler session is currently active."
          }
        }
      },
      "ProfilerBatch": {
        "type": "object",
        "description": "A batch of profiler data including samples, markers, and spans with cursor positions for pagination.",
        "required": [
          "sessionId",
          "samples",
          "markers",
          "spans",
          "sampleCursor",
          "markerCursor",
          "spanCursor",
          "isActive"
        ],
        "properties": {
          "sessionId": {
            "type": "string",
            "description": "Identifier of the profiler session this batch belongs to."
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfilerSample"
            },
            "description": "Array of profiler samples in this batch."
          },
          "markers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfilerMarker"
            },
            "description": "Array of profiler markers in this batch."
          },
          "spans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProfilerSpan"
            },
            "description": "Array of profiler spans in this batch."
          },
          "sampleCursor": {
            "type": "integer",
            "description": "Cursor position for the next page of samples.",
            "minimum": 0
          },
          "markerCursor": {
            "type": "integer",
            "description": "Cursor position for the next page of markers.",
            "minimum": 0
          },
          "spanCursor": {
            "type": "integer",
            "description": "Cursor position for the next page of spans.",
            "minimum": 0
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the profiler session is still actively collecting data."
          }
        }
      },
      "ProfilerSample": {
        "type": "object",
        "description": "A single profiler sample capturing a point-in-time snapshot of performance metrics.",
        "required": [
          "tsUtc"
        ],
        "properties": {
          "tsUtc": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "fps": {
            "type": "number",
            "description": "Frames per second at the time of sampling.",
            "minimum": 0,
            "nullable": true
          },
          "frameTimeMsP50": {
            "type": "number",
            "description": "Median (P50) frame time in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "frameTimeMsP95": {
            "type": "number",
            "description": "95th percentile (P95) frame time in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "worstFrameTimeMs": {
            "type": "number",
            "description": "Worst (maximum) frame time in milliseconds during the sample interval.",
            "minimum": 0,
            "nullable": true
          },
          "managedBytes": {
            "type": "integer",
            "description": "Managed heap memory usage in bytes.",
            "minimum": 0,
            "nullable": true
          },
          "gc0": {
            "type": "integer",
            "description": "Number of generation 0 garbage collections since last sample.",
            "minimum": 0,
            "nullable": true
          },
          "gc1": {
            "type": "integer",
            "description": "Number of generation 1 garbage collections since last sample.",
            "minimum": 0,
            "nullable": true
          },
          "gc2": {
            "type": "integer",
            "description": "Number of generation 2 garbage collections since last sample.",
            "minimum": 0,
            "nullable": true
          },
          "nativeMemoryBytes": {
            "type": "integer",
            "description": "Native (unmanaged) memory usage in bytes.",
            "minimum": 0,
            "nullable": true
          },
          "nativeMemoryKind": {
            "type": "string",
            "description": "Kind of native memory measurement (e.g. 'resident', 'virtual', 'private').",
            "nullable": true
          },
          "cpuPercent": {
            "type": "number",
            "description": "CPU usage percentage at the time of sampling.",
            "minimum": 0,
            "maximum": 100,
            "nullable": true
          },
          "threadCount": {
            "type": "integer",
            "description": "Total number of threads in the process.",
            "minimum": 0,
            "nullable": true
          },
          "jankFrameCount": {
            "type": "integer",
            "description": "Number of janky (dropped/slow) frames since last sample.",
            "minimum": 0,
            "nullable": true
          },
          "uiThreadStallCount": {
            "type": "integer",
            "description": "Number of UI thread stalls since last sample.",
            "minimum": 0,
            "nullable": true
          },
          "frameSource": {
            "type": "string",
            "description": "Source of frame timing data (e.g. 'choreographer', 'displayLink', 'estimated').",
            "nullable": true
          },
          "frameQuality": {
            "type": "string",
            "description": "Qualitative assessment of frame quality (e.g. 'smooth', 'mild-jank', 'severe-jank').",
            "nullable": true
          }
        }
      },
      "ProfilerMarker": {
        "type": "object",
        "description": "A discrete profiler marker event representing a notable occurrence.",
        "required": [
          "tsUtc",
          "type",
          "name"
        ],
        "properties": {
          "tsUtc": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "type": {
            "type": "string",
            "description": "Marker type category (e.g. 'gc', 'layout', 'navigation', 'user')."
          },
          "name": {
            "type": "string",
            "description": "Human-readable name of the marker event."
          },
          "payloadJson": {
            "type": "string",
            "description": "Optional JSON-encoded payload with additional marker data.",
            "nullable": true
          }
        }
      },
      "ProfilerSpan": {
        "type": "object",
        "description": "A profiler span representing a timed operation, compatible with OpenTelemetry span semantics.",
        "required": [
          "spanId",
          "startTsUtc",
          "durationMs",
          "kind",
          "name"
        ],
        "properties": {
          "spanId": {
            "type": "string",
            "description": "Unique identifier for this span."
          },
          "parentSpanId": {
            "type": "string",
            "description": "Identifier of the parent span, or null for root spans.",
            "nullable": true
          },
          "traceId": {
            "type": "string",
            "description": "Trace identifier grouping related spans.",
            "nullable": true
          },
          "startTsUtc": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "endTsUtc": {
            "oneOf": [
              {
                "type": "string",
                "format": "date-time",
                "description": "ISO 8601 date-time timestamp."
              },
              {
                "type": "null"
              }
            ],
            "description": "UTC timestamp when this span ended, or null if still in progress."
          },
          "durationMs": {
            "type": "number",
            "description": "Duration of the span in milliseconds.",
            "minimum": 0
          },
          "kind": {
            "type": "string",
            "description": "Kind of span (e.g. 'layout', 'render', 'navigation', 'network', 'user')."
          },
          "name": {
            "type": "string",
            "description": "Human-readable name describing the operation."
          },
          "status": {
            "type": "string",
            "description": "Span status (e.g. 'ok', 'error', 'cancelled').",
            "nullable": true
          },
          "threadId": {
            "type": "string",
            "description": "Identifier of the thread this span executed on.",
            "nullable": true
          },
          "screen": {
            "type": "string",
            "description": "Screen or page name where this span occurred.",
            "nullable": true
          },
          "elementPath": {
            "type": "string",
            "description": "Path to the element in the visual tree associated with this span.",
            "nullable": true
          },
          "tagsJson": {
            "type": "string",
            "description": "Optional JSON-encoded tags with additional span metadata.",
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "Error message if the span ended with an error.",
            "nullable": true
          }
        }
      },
      "ProfilerHotspot": {
        "type": "object",
        "description": "A profiler hotspot identifying a frequently occurring or slow operation.",
        "required": [
          "kind",
          "name",
          "count",
          "avgDurationMs"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "Kind of hotspot (e.g. 'layout', 'render', 'navigation', 'network')."
          },
          "name": {
            "type": "string",
            "description": "Name of the operation that is a hotspot."
          },
          "screen": {
            "type": "string",
            "description": "Screen or page where this hotspot occurs.",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "description": "Number of times this operation was observed.",
            "minimum": 0
          },
          "errorCount": {
            "type": "integer",
            "description": "Number of times this operation resulted in an error.",
            "minimum": 0,
            "nullable": true
          },
          "avgDurationMs": {
            "type": "number",
            "description": "Average duration of this operation in milliseconds.",
            "minimum": 0
          },
          "p95DurationMs": {
            "type": "number",
            "description": "95th percentile duration in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "maxDurationMs": {
            "type": "number",
            "description": "Maximum observed duration in milliseconds.",
            "minimum": 0,
            "nullable": true
          }
        }
      },
      "NetworkRequestSummary": {
        "type": "object",
        "description": "Summary of a captured network request with key metadata and timing.",
        "required": [
          "id",
          "timestamp",
          "method",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this network request."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "method": {
            "type": "string",
            "description": "HTTP method (e.g. 'GET', 'POST', 'PUT', 'DELETE')."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Full URL of the request."
          },
          "host": {
            "type": "string",
            "description": "Hostname portion of the URL.",
            "nullable": true
          },
          "path": {
            "type": "string",
            "description": "Path portion of the URL.",
            "nullable": true
          },
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code of the response, or null if the request has not completed.",
            "minimum": 100,
            "maximum": 599,
            "nullable": true
          },
          "statusText": {
            "type": "string",
            "description": "HTTP status text of the response (e.g. 'OK', 'Not Found').",
            "nullable": true
          },
          "durationMs": {
            "type": "number",
            "description": "Total request/response duration in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "Error message if the request failed.",
            "nullable": true
          },
          "requestContentType": {
            "type": "string",
            "description": "Content-Type header of the request.",
            "nullable": true
          },
          "responseContentType": {
            "type": "string",
            "description": "Content-Type header of the response.",
            "nullable": true
          },
          "requestSize": {
            "type": "integer",
            "description": "Size of the request body in bytes.",
            "minimum": 0,
            "nullable": true
          },
          "responseSize": {
            "type": "integer",
            "description": "Size of the response body in bytes.",
            "minimum": 0,
            "nullable": true
          }
        }
      },
      "NetworkRequestDetail": {
        "description": "Detailed view of a captured network request including headers and body content.",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for this network request."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "method": {
            "type": "string",
            "description": "HTTP method (e.g. 'GET', 'POST', 'PUT', 'DELETE')."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Full URL of the request."
          },
          "host": {
            "type": "string",
            "description": "Hostname portion of the URL.",
            "nullable": true
          },
          "path": {
            "type": "string",
            "description": "Path portion of the URL.",
            "nullable": true
          },
          "statusCode": {
            "type": "integer",
            "description": "HTTP status code of the response, or null if the request has not completed.",
            "minimum": 100,
            "maximum": 599,
            "nullable": true
          },
          "statusText": {
            "type": "string",
            "description": "HTTP status text of the response (e.g. 'OK', 'Not Found').",
            "nullable": true
          },
          "durationMs": {
            "type": "number",
            "description": "Total request/response duration in milliseconds.",
            "minimum": 0,
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "Error message if the request failed.",
            "nullable": true
          },
          "requestContentType": {
            "type": "string",
            "description": "Content-Type header of the request.",
            "nullable": true
          },
          "responseContentType": {
            "type": "string",
            "description": "Content-Type header of the response.",
            "nullable": true
          },
          "requestSize": {
            "type": "integer",
            "description": "Size of the request body in bytes.",
            "minimum": 0,
            "nullable": true
          },
          "responseSize": {
            "type": "integer",
            "description": "Size of the response body in bytes.",
            "minimum": 0,
            "nullable": true
          },
          "requestHeaders": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Request headers as key-value pairs. Agents should redact sensitive values such as Authorization, Cookie, Set-Cookie, and Proxy-Authorization by default.",
            "nullable": true
          },
          "responseHeaders": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Response headers as key-value pairs. Agents should redact sensitive values such as Authorization, Cookie, Set-Cookie, and Proxy-Authorization by default.",
            "nullable": true
          },
          "requestBody": {
            "type": "string",
            "description": "Request body content as a string.",
            "nullable": true
          },
          "responseBody": {
            "type": "string",
            "description": "Response body content as a string.",
            "nullable": true
          },
          "requestBodyEncoding": {
            "type": "string",
            "description": "Encoding of the request body (e.g. 'utf-8', 'base64').",
            "nullable": true
          },
          "responseBodyEncoding": {
            "type": "string",
            "description": "Encoding of the response body (e.g. 'utf-8', 'base64').",
            "nullable": true
          },
          "requestBodyTruncated": {
            "type": "boolean",
            "description": "Whether the request body was truncated due to size limits.",
            "nullable": true
          },
          "responseBodyTruncated": {
            "type": "boolean",
            "description": "Whether the response body was truncated due to size limits.",
            "nullable": true
          }
        },
        "required": [
          "id",
          "method",
          "timestamp",
          "url"
        ]
      },
      "LogEntry": {
        "type": "object",
        "description": "A single log entry from the application.",
        "required": [
          "timestamp",
          "level",
          "category",
          "message",
          "source"
        ],
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "level": {
            "type": "string",
            "enum": [
              "trace",
              "debug",
              "info",
              "warning",
              "error",
              "critical"
            ],
            "description": "Severity level of the log entry."
          },
          "category": {
            "type": "string",
            "description": "Log category or logger name (e.g. 'Microsoft.Maui.Controls', 'HttpClient', 'App')."
          },
          "message": {
            "type": "string",
            "description": "The log message text."
          },
          "exception": {
            "type": "string",
            "description": "Exception details if the log entry is associated with an error.",
            "nullable": true
          },
          "source": {
            "type": "string",
            "enum": [
              "native",
              "webview",
              "framework"
            ],
            "description": "Origin of the log entry."
          }
        }
      },
      "DeviceInfo": {
        "type": "object",
        "description": "Hardware and platform information about the device.",
        "required": [
          "model",
          "manufacturer",
          "osVersion",
          "platform",
          "idiom",
          "architecture"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Device model name (e.g. 'iPhone 15 Pro', 'Pixel 8')."
          },
          "manufacturer": {
            "type": "string",
            "description": "Device manufacturer (e.g. 'Apple', 'Google', 'Samsung')."
          },
          "osVersion": {
            "type": "string",
            "description": "Operating system version string."
          },
          "platform": {
            "type": "string",
            "description": "Platform identifier (e.g. 'ios', 'android', 'maccatalyst', 'windows')."
          },
          "idiom": {
            "type": "string",
            "description": "Device form factor (e.g. 'phone', 'tablet', 'desktop', 'tv', 'watch')."
          },
          "architecture": {
            "type": "string",
            "description": "CPU architecture (e.g. 'arm64', 'x64', 'x86')."
          }
        }
      },
      "DisplayInfo": {
        "type": "object",
        "description": "Display characteristics of the device screen.",
        "required": [
          "width",
          "height",
          "density",
          "orientation"
        ],
        "properties": {
          "width": {
            "type": "number",
            "description": "Display width in device-independent pixels.",
            "minimum": 0
          },
          "height": {
            "type": "number",
            "description": "Display height in device-independent pixels.",
            "minimum": 0
          },
          "density": {
            "type": "number",
            "description": "Display pixel density (ratio of physical to logical pixels).",
            "exclusiveMinimum": true,
            "minimum": 0
          },
          "orientation": {
            "type": "string",
            "enum": [
              "portrait",
              "landscape"
            ],
            "description": "Current display orientation."
          },
          "refreshRate": {
            "type": "number",
            "description": "Display refresh rate in Hz, or null if unavailable.",
            "exclusiveMinimum": true,
            "nullable": true,
            "minimum": 0
          }
        }
      },
      "BatteryInfo": {
        "type": "object",
        "description": "Battery status information.",
        "required": [
          "level",
          "state",
          "powerSource"
        ],
        "properties": {
          "level": {
            "type": "number",
            "description": "Battery charge level from empty (0) to full (1).",
            "minimum": 0,
            "maximum": 1
          },
          "state": {
            "type": "string",
            "enum": [
              "unknown",
              "charging",
              "discharging",
              "full",
              "notCharging"
            ],
            "description": "Current battery charging state."
          },
          "powerSource": {
            "type": "string",
            "enum": [
              "unknown",
              "battery",
              "ac",
              "usb",
              "wireless"
            ],
            "description": "Current power source."
          }
        }
      },
      "ConnectivityInfo": {
        "type": "object",
        "description": "Network connectivity status.",
        "required": [
          "networkAccess",
          "connectionProfiles"
        ],
        "properties": {
          "networkAccess": {
            "type": "string",
            "enum": [
              "none",
              "local",
              "internet",
              "constrainedInternet"
            ],
            "description": "Level of network access available."
          },
          "connectionProfiles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Active connection profiles (e.g. 'wifi', 'cellular', 'ethernet', 'bluetooth')."
          }
        }
      },
      "AppInfo": {
        "type": "object",
        "description": "Application metadata.",
        "required": [
          "name",
          "version",
          "buildNumber",
          "packageId"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the application."
          },
          "version": {
            "type": "string",
            "description": "Application version string."
          },
          "buildNumber": {
            "type": "string",
            "description": "Application build number."
          },
          "packageId": {
            "type": "string",
            "description": "Application package identifier (e.g. 'com.example.myapp')."
          },
          "theme": {
            "type": "string",
            "description": "Current application theme (e.g. 'light', 'dark', 'system').",
            "nullable": true
          }
        }
      },
      "SensorInfo": {
        "type": "object",
        "description": "Information about a device sensor.",
        "required": [
          "name",
          "available",
          "active"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the sensor (e.g. 'accelerometer', 'gyroscope', 'magnetometer', 'barometer', 'compass')."
          },
          "available": {
            "type": "boolean",
            "description": "Whether this sensor is available on the device."
          },
          "active": {
            "type": "boolean",
            "description": "Whether this sensor is currently active and streaming data."
          }
        }
      },
      "PermissionInfo": {
        "type": "object",
        "description": "Status of a device permission.",
        "required": [
          "name",
          "status"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Name of the permission (e.g. 'camera', 'location', 'microphone', 'photos', 'contacts')."
          },
          "status": {
            "type": "string",
            "enum": [
              "unknown",
              "denied",
              "granted",
              "restricted",
              "limited"
            ],
            "description": "Current status of this permission."
          }
        }
      },
      "GeolocationResult": {
        "type": "object",
        "description": "A geolocation reading.",
        "required": [
          "latitude",
          "longitude",
          "accuracy",
          "timestamp"
        ],
        "properties": {
          "latitude": {
            "type": "number",
            "description": "Latitude in decimal degrees.",
            "minimum": -90,
            "maximum": 90
          },
          "longitude": {
            "type": "number",
            "description": "Longitude in decimal degrees.",
            "minimum": -180,
            "maximum": 180
          },
          "altitude": {
            "type": "number",
            "description": "Altitude in meters above sea level, or null if unavailable.",
            "nullable": true
          },
          "accuracy": {
            "type": "number",
            "description": "Horizontal accuracy in meters.",
            "minimum": 0
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          }
        }
      },
      "JobListResponse": {
        "type": "object",
        "description": "Response returned when listing platform background jobs.",
        "required": [
          "platform",
          "supported",
          "jobs"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "description": "Platform name reported by the agent."
          },
          "type": {
            "type": "string",
            "description": "Platform scheduler implementation, such as WorkManager or BGTaskScheduler."
          },
          "supported": {
            "type": "boolean",
            "description": "Whether the current platform supports listing jobs."
          },
          "runSupported": {
            "type": "boolean",
            "description": "Whether listed jobs can be triggered by this agent."
          },
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlatformJob"
            },
            "description": "Background jobs reported by the platform."
          },
          "error": {
            "type": "string",
            "description": "Platform-specific error message if listing failed."
          }
        },
        "additionalProperties": true
      },
      "PlatformJob": {
        "type": "object",
        "description": "A platform background job. Android jobs expose WorkManager fields; iOS and Mac Catalyst jobs expose BGTaskScheduler fields.",
        "required": [
          "identifier"
        ],
        "properties": {
          "identifier": {
            "type": "string",
            "description": "Platform job identifier. Android maps this to the WorkManager UUID; iOS and Mac Catalyst map this to the BGTask identifier."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Android WorkManager tags associated with the work."
          },
          "state": {
            "type": "string",
            "description": "Android WorkManager state, such as ENQUEUED, RUNNING, SUCCEEDED, FAILED, BLOCKED, or CANCELLED."
          },
          "runAttemptCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Android WorkManager run attempt count."
          },
          "type": {
            "type": "string",
            "enum": [
              "processing",
              "refresh"
            ],
            "description": "iOS or Mac Catalyst BGTask request type."
          },
          "earliestBeginDate": {
            "type": "string",
            "description": "Earliest begin date reported by BGTaskScheduler, if present."
          }
        },
        "additionalProperties": true
      },
      "JobRunRequest": {
        "type": "object",
        "description": "Optional request body used when triggering a platform background job.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "processing",
              "refresh"
            ],
            "description": "iOS or Mac Catalyst BGTask request type. If omitted, the agent resolves it from pending requests when possible and otherwise defaults to processing."
          }
        },
        "additionalProperties": false
      },
      "JobRunResponse": {
        "type": "object",
        "description": "Response returned after attempting to trigger a platform background job.",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the job trigger request was submitted successfully."
          },
          "supported": {
            "type": "boolean",
            "description": "Whether triggering this job is supported on the current platform."
          },
          "identifier": {
            "type": "string",
            "description": "Requested platform job identifier."
          },
          "type": {
            "type": "string",
            "enum": [
              "processing",
              "refresh"
            ],
            "description": "BGTask request type used on iOS or Mac Catalyst."
          },
          "message": {
            "type": "string",
            "description": "Human-readable success message."
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        },
        "additionalProperties": true
      },
      "BleStatus": {
        "type": "object",
        "description": "Bluetooth Low Energy monitor status.",
        "required": [
          "isScanning",
          "eventCount",
          "subscriberCount",
          "scanSupported"
        ],
        "properties": {
          "isScanning": {
            "type": "boolean",
            "description": "Whether a native BLE scan is currently active."
          },
          "eventCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of BLE events currently buffered."
          },
          "subscriberCount": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of active BLE event stream subscribers."
          },
          "scanSupported": {
            "type": "boolean",
            "description": "Whether this agent implementation supports native BLE scanning."
          },
          "error": {
            "type": "string",
            "description": "Last platform-specific BLE error, if any."
          }
        },
        "additionalProperties": true
      },
      "BleEventsResponse": {
        "type": "object",
        "description": "Response returned when listing buffered BLE events.",
        "required": [
          "events"
        ],
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BleEvent"
            },
            "description": "Buffered BLE events."
          }
        }
      },
      "BleEvent": {
        "type": "object",
        "description": "A Bluetooth Low Energy event recorded by the monitor.",
        "required": [
          "type",
          "timestamp"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "BLE event type recorded by the monitor. Agents may also record custom app-defined event types.",
            "examples": [
              "scan_result",
              "connected",
              "disconnected",
              "read",
              "write",
              "notification",
              "scan_error"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 date-time timestamp."
          },
          "deviceId": {
            "type": "string",
            "description": "Platform device identifier, such as a Bluetooth address or UUID."
          },
          "deviceName": {
            "type": "string",
            "description": "Device display name, if available."
          },
          "rssi": {
            "type": "integer",
            "description": "Received signal strength in dBm, when available."
          },
          "serviceUuids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Advertised service UUIDs, when available."
          },
          "characteristicUuid": {
            "type": "string",
            "description": "Characteristic UUID for read, write, or notification events."
          },
          "valueBase64": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "Characteristic value encoded as base64, when present."
          },
          "message": {
            "type": "string",
            "description": "Human-readable event message."
          },
          "error": {
            "type": "string",
            "description": "Human-readable error message for error events."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Platform-specific BLE event metadata."
          }
        },
        "additionalProperties": true
      },
      "ProblemDetails": {
        "type": "object",
        "description": "RFC 7807 Problem Details error response.",
        "required": [
          "type",
          "title",
          "status"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference that identifies the problem type."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code for this occurrence of the problem.",
            "minimum": 100,
            "maximum": 599
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "instance": {
            "type": "string",
            "format": "uri",
            "description": "A URI reference that identifies the specific occurrence of the problem."
          },
          "errorCode": {
            "type": "string",
            "enum": [
              "ElementNotFound",
              "StaleElementReference",
              "ElementNotInteractable",
              "InvalidSelector",
              "timeout",
              "UnknownCommand",
              "UnsupportedCapability",
              "InvalidPath",
              "InternalError"
            ],
            "description": "Machine-readable error code identifying the category of failure."
          }
        }
      },
      "ActionResponse": {
        "type": "object",
        "description": "Response returned after executing an action, optionally including a screenshot and/or visual tree.",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Whether the action completed successfully."
          },
          "error": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ProblemDetails"
              },
              {
                "type": "null"
              }
            ],
            "description": "Error details if the action failed."
          },
          "screenshot": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "Base64-encoded screenshot taken after the action, if requested via include.",
            "nullable": true
          },
          "tree": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/element-info"
            },
            "description": "Visual tree snapshot taken after the action, if requested via include.",
            "nullable": true
          }
        }
      },
      "StorageRootsResponse": {
        "type": "object",
        "description": "Logical file storage roots advertised by the agent.",
        "required": [
          "roots"
        ],
        "properties": {
          "roots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StorageRoot"
            }
          }
        }
      },
      "StorageRoot": {
        "type": "object",
        "description": "A logical app storage root advertised by the agent. Absolute device paths are intentionally not exposed.",
        "required": [
          "id",
          "displayName",
          "kind",
          "isWritable",
          "isReadOnly",
          "isPersistent",
          "isBackedUp",
          "mayBeClearedBySystem",
          "isUserVisible",
          "supportedOperations"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable root id to pass as the root query parameter."
          },
          "displayName": {
            "type": "string",
            "description": "Human-readable root name."
          },
          "kind": {
            "type": "string",
            "description": "Portable root kind, such as appData."
          },
          "isWritable": {
            "type": "boolean",
            "description": "Whether files can be uploaded or deleted in this root."
          },
          "isReadOnly": {
            "type": "boolean",
            "description": "Whether this root is read-only."
          },
          "isPersistent": {
            "type": "boolean",
            "description": "Whether data is expected to persist across app restarts."
          },
          "isBackedUp": {
            "type": "boolean",
            "description": "Whether the platform typically backs up this root."
          },
          "mayBeClearedBySystem": {
            "type": "boolean",
            "description": "Whether the operating system may purge files in this root."
          },
          "isUserVisible": {
            "type": "boolean",
            "description": "Whether the root is normally visible to users outside the app."
          },
          "supportedOperations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "list",
                "download",
                "upload",
                "delete"
              ]
            },
            "description": "File operations supported by this root."
          }
        }
      },
      "FileListResponse": {
        "type": "object",
        "description": "Directory listing under a logical storage root. Absolute device paths are never returned.",
        "required": [
          "root",
          "path",
          "entries"
        ],
        "properties": {
          "root": {
            "type": "string",
            "description": "Logical storage root id used for the listing."
          },
          "path": {
            "type": "string",
            "description": "Normalized relative directory path. Empty string represents the selected storage root."
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileEntry"
            }
          }
        }
      },
      "FileEntry": {
        "type": "object",
        "description": "A file or directory under a storage root.",
        "required": [
          "name",
          "type",
          "lastModified"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Entry name, not including parent directories."
          },
          "type": {
            "type": "string",
            "enum": [
              "file",
              "directory"
            ],
            "description": "Entry kind."
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "description": "File size in bytes. Present only for file entries."
          },
          "lastModified": {
            "type": "string",
            "format": "date-time",
            "description": "UTC timestamp when the entry was last modified."
          }
        }
      },
      "FileDownloadResponse": {
        "type": "object",
        "description": "Downloaded file content and metadata.",
        "required": [
          "root",
          "path",
          "size",
          "lastModified",
          "contentBase64"
        ],
        "properties": {
          "root": {
            "type": "string",
            "description": "Logical storage root id used for the download."
          },
          "path": {
            "type": "string",
            "description": "Normalized relative file path."
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "description": "File size in bytes."
          },
          "lastModified": {
            "type": "string",
            "format": "date-time",
            "description": "UTC timestamp when the file was last modified."
          },
          "contentBase64": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "File content encoded as base64."
          }
        }
      },
      "FileUploadRequest": {
        "type": "object",
        "description": "Request to upload file content under a storage root.",
        "required": [
          "contentBase64"
        ],
        "properties": {
          "contentBase64": {
            "type": "string",
            "contentEncoding": "base64",
            "description": "File content encoded as base64."
          }
        }
      },
      "FileUploadResponse": {
        "type": "object",
        "description": "Uploaded file metadata.",
        "required": [
          "success",
          "root",
          "path",
          "size",
          "lastModified"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "root": {
            "type": "string",
            "description": "Logical storage root id used for the upload."
          },
          "path": {
            "type": "string",
            "description": "Normalized relative file path."
          },
          "size": {
            "type": "integer",
            "minimum": 0,
            "description": "File size in bytes."
          },
          "lastModified": {
            "type": "string",
            "format": "date-time",
            "description": "UTC timestamp when the file was last modified."
          }
        }
      },
      "FileDeleteResponse": {
        "type": "object",
        "description": "Deleted file metadata.",
        "required": [
          "success",
          "root",
          "path"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "root": {
            "type": "string",
            "description": "Logical storage root id used for the delete."
          },
          "path": {
            "type": "string",
            "description": "Normalized relative file path."
          },
          "message": {
            "type": "string",
            "description": "Human-readable delete confirmation."
          }
        }
      },
      "PreferenceEntry": {
        "type": "object",
        "description": "A single preference key-value entry.",
        "required": [
          "key",
          "value",
          "type"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "Preference key name."
          },
          "value": {
            "description": "Preference value. The actual JSON type depends on the type field."
          },
          "type": {
            "$ref": "#/components/schemas/PreferenceValueType",
            "description": "Data type of the preference value."
          }
        }
      },
      "PreferenceValueType": {
        "type": "string",
        "enum": [
          "String",
          "Int",
          "Bool",
          "Double",
          "Float",
          "Long",
          "datetime"
        ],
        "description": "Data type of a preference value."
      },
      "PreferenceSetRequest": {
        "type": "object",
        "description": "Request to set a preference value.",
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "description": "The value to set for the preference."
          },
          "type": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/PreferenceValueType"
              },
              {
                "type": "null"
              }
            ],
            "description": "Data type of the value. If null, the type is auto-detected from the JSON value."
          },
          "sharedName": {
            "type": "string",
            "description": "Shared preference container name. If null, uses the default container.",
            "nullable": true
          }
        }
      },
      "SecureStorageSetRequest": {
        "type": "object",
        "description": "Request to set a value in secure (encrypted) storage.",
        "required": [
          "value"
        ],
        "properties": {
          "value": {
            "type": "string",
            "description": "The string value to store securely."
          }
        }
      }
    }
  }
}