{
  "version": "0.1.0",
  "contractVersion": "2.1.0",
  "multiPortDiscovery": true,
  "protocol": "tool_request/result",
  "tools": [
    {
      "name": "ping",
      "summary": "Liveness check; returns { ok, version }.",
      "category": "meta",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "capabilities",
      "summary": "Return this self-describing capability manifest (tools + features + versions).",
      "category": "meta",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "reload",
      "summary": "Reload the extension (re-reads dist/ from disk).",
      "category": "meta",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "debug_exec",
      "summary": "Diagnostic: probe in-page bridge availability.",
      "category": "meta",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "detach",
      "summary": "Detach the debugger from the target tab.",
      "category": "meta",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "set_bridge_port",
      "summary": "Set the WebSocket bridge port (persists across reload; enables multi-session on different ports).",
      "category": "meta",
      "params": {
        "type": "object",
        "required": [
          "port"
        ],
        "properties": {
          "port": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "navigate",
      "summary": "Navigate the console tab to a scoped https URL.",
      "category": "navigation",
      "params": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "scroll_to",
      "summary": "Scroll an AX-ref element into view.",
      "category": "navigation",
      "params": {
        "type": "object",
        "required": [
          "ref"
        ],
        "properties": {
          "ref": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "resize_window",
      "summary": "Resize the browser window.",
      "category": "navigation",
      "params": {
        "type": "object",
        "required": [
          "width",
          "height"
        ],
        "properties": {
          "width": {
            "type": "number"
          },
          "height": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "tabs_list",
      "summary": "List scoped console tabs.",
      "category": "navigation",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {}
    },
    {
      "name": "tabs_create",
      "summary": "Open a new tab at a scoped URL.",
      "category": "navigation",
      "params": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "tabs_close",
      "summary": "Close a tab by id.",
      "category": "navigation",
      "params": {
        "type": "object",
        "required": [
          "tabId"
        ],
        "properties": {
          "tabId": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "click",
      "summary": "Deterministic click of an AX-ref element (layout-engine coords + hit-test).",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "ref"
        ],
        "properties": {
          "ref": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "click_element",
      "summary": "Click the element returned by a JS expression (polls; occlusion-safe).",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "js"
        ],
        "properties": {
          "js": {
            "type": "string"
          },
          "wait_ms": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "click_xy",
      "summary": "Trusted click at explicit viewport coordinates.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "x",
          "y"
        ],
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "type_text",
      "summary": "Type text into the focused element (trusted input).",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "form_input",
      "summary": "Set a form field value by AX ref.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "ref",
          "value"
        ],
        "properties": {
          "ref": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "key_press",
      "summary": "Dispatch a key press.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "key"
        ],
        "properties": {
          "key": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "select_option",
      "summary": "Select an option in a native <select> by AX ref.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "ref",
          "value"
        ],
        "properties": {
          "ref": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "label_select",
      "summary": "Type into a CDK-portal typeahead and click the matching option.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "selector",
          "value"
        ],
        "properties": {
          "selector": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "label_value": {
            "type": "string"
          },
          "wait_ms": {
            "type": "number"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "file_upload",
      "summary": "Upload files (base64 data URIs) to a file input by AX ref.",
      "category": "interaction",
      "params": {
        "type": "object",
        "required": [
          "ref",
          "files"
        ],
        "properties": {
          "ref": {
            "type": "string"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "read_ax",
      "summary": "Read the accessibility tree of the page.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "get_page_text",
      "summary": "Return the page text.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "query_dom",
      "summary": "Direct DOM.querySelector at wire speed — bypasses Runtime.evaluate for simple CSS selectors.",
      "category": "read",
      "params": {
        "type": "object",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "type": "string"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "find",
      "summary": "Find AX nodes matching a locator.",
      "category": "read",
      "params": {
        "type": "object",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "type": "string"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "wait_for",
      "summary": "Wait for an AX node matching a locator to appear.",
      "category": "read",
      "params": {
        "type": "object",
        "required": [
          "selector"
        ],
        "properties": {
          "selector": {
            "type": "string"
          },
          "context": {
            "type": "string"
          },
          "timeoutMs": {
            "type": "number"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "assert_text",
      "summary": "Assert an element contains expected text.",
      "category": "read",
      "params": {
        "type": "object",
        "required": [
          "selector",
          "expected"
        ],
        "properties": {
          "selector": {
            "type": "string"
          },
          "expected": {
            "type": "string"
          },
          "context": {
            "type": "string"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "screenshot",
      "summary": "Capture a screenshot (base64 PNG).",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "read_console",
      "summary": "Read buffered console messages, optionally filtered by pattern.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {
          "pattern": {
            "type": "string"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "read_network",
      "summary": "Read buffered network events, optionally filtered by pattern.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {
          "pattern": {
            "type": "string"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "diag_suspension",
      "summary": "Diagnostic: SW-lifecycle event buffer + suspension summary (Phase 0a).",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {}
    },
    {
      "name": "diag_bridges",
      "summary": "List discovered xcsh bridge health without tenant, environment, or session identifiers.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {}
    },
    {
      "name": "diag_activation",
      "summary": "Diagnostic: per-gate tab-activation readiness timings (bridge/worker/page), cold/warm.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {}
    },
    {
      "name": "diag_ttft",
      "summary": "Diagnostic: init→first-token timeline (per-stage ms, total, dominant, cold/warm).",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {}
    },
    {
      "name": "wait_for_api_response",
      "summary": "Wait for a network response whose URL matches a pattern.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {
          "pattern": {
            "type": "string"
          },
          "timeout_ms": {
            "type": "number"
          }
        }
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "get_page_context",
      "summary": "Return a snapshot of the active console page (url, AX tree, captured XC API body) for chat grounding.",
      "category": "read",
      "params": {
        "type": "object",
        "properties": {}
      },
      "flags": {
        "readOnly": true
      }
    },
    {
      "name": "javascript_tool",
      "summary": "Evaluate arbitrary JS in the page (length-capped).",
      "category": "script",
      "params": {
        "type": "object",
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string"
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "browser_batch",
      "summary": "Run a batch of { tool, params } actions in sequence.",
      "category": "script",
      "params": {
        "type": "object",
        "required": [
          "actions"
        ],
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "tool"
              ],
              "properties": {
                "tool": {
                  "type": "string"
                },
                "params": {}
              }
            }
          }
        }
      },
      "flags": {
        "mutates": true
      }
    },
    {
      "name": "set_explain_mode",
      "summary": "Enter/leave explain mode — the gate for all on-page annotation overlays.",
      "category": "annotation",
      "params": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "flags": {}
    },
    {
      "name": "annotate",
      "summary": "Draw an overlay annotation (fingerprint/highlight). No-op unless explain mode is on.",
      "category": "annotation",
      "params": {
        "type": "object",
        "required": [
          "kind"
        ],
        "properties": {
          "kind": {
            "type": "string"
          },
          "ref": {
            "type": "string"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "w": {
            "type": "number"
          },
          "h": {
            "type": "number"
          }
        }
      },
      "flags": {
        "requiresExplainMode": true
      }
    }
  ],
  "features": {
    "explainMode": {
      "tool": "set_explain_mode",
      "default": false,
      "description": "A deliberate, human-paced walkthrough mode. While on, on-page annotation overlays are shown; off by default (fast automation shows nothing)."
    },
    "overlays": {
      "tool": "annotate",
      "requiresExplainMode": true,
      "autoFingerprintOnClick": true,
      "kinds": [
        "fingerprint",
        "highlight"
      ],
      "description": "Transient annotation overlays. In explain mode, clicks auto-draw a fingerprint; `annotate` draws a named overlay by ref or coordinates."
    },
    "capture": {
      "tool": "screenshot",
      "description": "Capture a screenshot (base64 PNG) — for headless annotated-capture flows."
    },
    "viewport": {
      "tool": "resize_window",
      "description": "Control the browser window size."
    },
    "chat": {
      "contextTool": "get_page_context",
      "transport": "websocket-bridge",
      "modes": [
        "educational",
        "presentation",
        "configuration",
        "screenshot",
        "annotation"
      ],
      "messages": [
        "chat_request",
        "chat_delta",
        "chat_done",
        "chat_error",
        "chat_stop",
        "chat_tool_notice",
        "set_host_tools",
        "set_host_tools_ack",
        "set_host_tools_error",
        "host_tool_call",
        "host_tool_update",
        "host_tool_result",
        "host_tool_cancel",
        "chat_media",
        "media_asset_read",
        "media_asset_chunk",
        "media_asset_error"
      ],
      "description": "User ↔ xcsh chat over the bridge. The extension side panel sends chat_request (with mode and page-context snapshot); xcsh streams chat_delta tokens then a terminal chat_done (with reference links) or chat_error. Chat ids are prefixed \"c-\". Tool calls during a turn use the normal tool_request flow. chat_stop halts a streaming response. chat_tool_notice is emitted by the EXTENSION (the service worker) to the panel as a best-effort UI signal when a tool runs during a turn — it is NOT sent by xcsh; xcsh must not produce it to avoid double-rendering in the panel. Rich media uses chat_media descriptors and bounded media_asset_read/media_asset_chunk exchanges; media_asset_error reports unavailable assets.",
      "promptHints": {
        "role": "You are xcsh, the AI assistant embedded in the F5 Distributed Cloud (XC) console side panel. The user is viewing a live console page; help them drive automation and understand settings and their purpose.",
        "grounding": "Every user message carries a page-context snapshot: url/path, title, a trimmed accessibility tree, and — when available — the live XC API resource JSON the page loaded (context.api.body). Treat context.api.body as the authoritative current state of the resource and ground answers in it instead of guessing; respect the truncated flags.",
        "referenceLinks": "Emit every citation as a markdown link [title](url): F5 XC docs (docs.cloud.f5.com) as doc references and the tenant console host as console deep-links. These populate the panel References drawer, so always format references this way rather than as bare URLs.",
        "toolUse": "Drive the console with the extension tools via the normal tool_request flow (navigate, click, annotate, screenshot, get_page_context, and so on). The extension surfaces tool activity to the panel itself (chat_tool_notice) — never emit chat_tool_notice yourself. Each turn ends with exactly one terminal frame, which the transport handles.",
        "modes": {
          "educational": "Explain concepts and answer questions about settings and their purpose.",
          "presentation": "Guided, human-paced walkthrough/demo of the console.",
          "configuration": "Help build and fill F5 XC resource configuration.",
          "screenshot": "Capture annotated screenshots for documentation.",
          "annotation": "Annotate the page for documentation and teaching."
        }
      }
    }
  }
}
