<!-- Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net> -->
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
<!-- Copyleft: GNU GPLv3 or later applies to this file. -->

# Hermes Node Protocol
# Copyright (c) 2026 Stefy (nextime) Lanza <stefy@nexlab.net>
# All rights reserved.
# 
# This software is released under the MIT License with a copyleft clause.
# See the LICENSE file for full terms.
# Browser Control Protocol Schema

## Message Format

All browser control messages follow this structure:

```json
{
  "type": "browser_control",
  "id": "unique-command-id",
  "layer": "high_level|playwright|cdp",
  "command": "command_name",
  "page_id": "page_1",
  "params": {
    // Command-specific parameters
  }
}
```

## Response Format

```json
{
  "type": "browser_control_response",
  "id": "unique-command-id",
  "result": "ok|error",
  // Result-specific fields
}
```

---

## Layer 1: High-Level Commands

### Launch Browser

**Command:** `launch`

```json
{
  "type": "browser_control",
  "id": "cmd_1",
  "layer": "high_level",
  "command": "launch",
  "params": {
    "config": {
      "mode": "headless",  // "headless", "headed", "attach"
      "cdp_url": null,     // For attach mode: "http://localhost:9222"
      "viewport": {"width": 1920, "height": 1080},
      "timeout": 30000
    }
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_1",
  "result": "ok",
  "mode": "headless",
  "browser_version": "120.0.6099.109"
}
```

### Create Context

**Command:** `create_context`

```json
{
  "type": "browser_control",
  "id": "cmd_2",
  "layer": "high_level",
  "command": "create_context",
  "params": {
    "config": {
      "name": "my_context",
      "persistent": false,
      "incognito": true,
      "user_data_dir": null,  // For persistent: "/path/to/profile"
      "viewport": {"width": 1920, "height": 1080},
      "user_agent": "Custom User Agent",
      "locale": "en-US",
      "timezone": "America/New_York",
      "geolocation": {"latitude": 40.7128, "longitude": -74.0060},
      "permissions": ["geolocation", "notifications"],
      "extra_http_headers": {"X-Custom": "value"},
      "ignore_https_errors": false,
      "java_script_enabled": true,
      "bypass_csp": false
    }
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_2",
  "result": "ok",
  "context_name": "my_context",
  "persistent": false
}
```

### New Page

**Command:** `new_page`

```json
{
  "type": "browser_control",
  "id": "cmd_3",
  "layer": "high_level",
  "command": "new_page",
  "params": {
    "context_name": "my_context"  // Optional, uses "default" if not specified
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_3",
  "result": "ok",
  "page_id": "page_1",
  "context_name": "my_context"
}
```

### Navigate

**Command:** `navigate`

```json
{
  "type": "browser_control",
  "id": "cmd_4",
  "layer": "high_level",
  "command": "navigate",
  "page_id": "page_1",
  "params": {
    "url": "https://example.com",
    "wait_until": "load"  // "load", "domcontentloaded", "networkidle"
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_4",
  "result": "ok",
  "url": "https://example.com",
  "status": 200,
  "title": "Example Domain"
}
```

### Click

**Command:** `click`

```json
{
  "type": "browser_control",
  "id": "cmd_5",
  "layer": "high_level",
  "command": "click",
  "page_id": "page_1",
  "params": {
    "selector": "#submit-button",
    "button": "left",      // Optional: "left", "right", "middle"
    "click_count": 1,      // Optional: number of clicks
    "delay": 0             // Optional: delay between mousedown and mouseup in ms
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_5",
  "result": "ok"
}
```

### Fill Input

**Command:** `fill`

```json
{
  "type": "browser_control",
  "id": "cmd_6",
  "layer": "high_level",
  "command": "fill",
  "page_id": "page_1",
  "params": {
    "selector": "#username",
    "value": "myusername"
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_6",
  "result": "ok"
}
```

### Type Text

**Command:** `type_text`

```json
{
  "type": "browser_control",
  "id": "cmd_7",
  "layer": "high_level",
  "command": "type_text",
  "page_id": "page_1",
  "params": {
    "selector": "#search",
    "text": "search query",
    "delay": 100  // Optional: delay between keystrokes in ms
  }
}
```

### Wait for Selector

**Command:** `wait_for_selector`

```json
{
  "type": "browser_control",
  "id": "cmd_8",
  "layer": "high_level",
  "command": "wait_for_selector",
  "page_id": "page_1",
  "params": {
    "selector": ".result",
    "state": "visible",  // "attached", "detached", "visible", "hidden"
    "timeout": 30000
  }
}
```

### Screenshot

**Command:** `screenshot`

```json
{
  "type": "browser_control",
  "id": "cmd_9",
  "layer": "high_level",
  "command": "screenshot",
  "page_id": "page_1",
  "params": {
    "full_page": false,
    "path": "/tmp/screenshot.png"  // Optional: save to file
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_9",
  "result": "ok",
  "screenshot": "iVBORw0KGgoAAAANSUhEUgAA...",  // Base64 encoded PNG
  "path": "/tmp/screenshot.png"
}
```

### Execute Script

**Command:** `execute_script`

```json
{
  "type": "browser_control",
  "id": "cmd_10",
  "layer": "high_level",
  "command": "execute_script",
  "page_id": "page_1",
  "params": {
    "script": "document.title"
  }
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_10",
  "result": "ok",
  "result": "Example Domain"
}
```

### Evaluate Expression

**Command:** `evaluate`

```json
{
  "type": "browser_control",
  "id": "cmd_11",
  "layer": "high_level",
  "command": "evaluate",
  "page_id": "page_1",
  "params": {
    "expression": "() => document.querySelectorAll('a').length",
    "arg": null  // Optional: argument to pass to function
  }
}
```

### Get Content

**Command:** `get_content`

```json
{
  "type": "browser_control",
  "id": "cmd_12",
  "layer": "high_level",
  "command": "get_content",
  "page_id": "page_1",
  "params": {}
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_12",
  "result": "ok",
  "content": "<!DOCTYPE html><html>..."
}
```

### Get Title

**Command:** `get_title`

```json
{
  "type": "browser_control",
  "id": "cmd_13",
  "layer": "high_level",
  "command": "get_title",
  "page_id": "page_1",
  "params": {}
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_13",
  "result": "ok",
  "title": "Example Domain"
}
```

### List Pages

**Command:** `list_pages`

```json
{
  "type": "browser_control",
  "id": "cmd_14",
  "layer": "high_level",
  "command": "list_pages",
  "params": {}
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_14",
  "result": "ok",
  "pages": [
    {
      "page_id": "page_1",
      "url": "https://example.com",
      "title": "Example Domain"
    }
  ]
}
```

### List Contexts

**Command:** `list_contexts`

```json
{
  "type": "browser_control",
  "id": "cmd_15",
  "layer": "high_level",
  "command": "list_contexts",
  "params": {}
}
```

**Response:**
```json
{
  "type": "browser_control_response",
  "id": "cmd_15",
  "result": "ok",
  "contexts": [
    {
      "name": "default",
      "page_count": 2
    }
  ]
}
```

### Close Page

**Command:** `close_page`

```json
{
  "type": "browser_control",
  "id": "cmd_16",
  "layer": "high_level",
  "command": "close_page",
  "page_id": "page_1",
  "params": {}
}
```

### Close Context

**Command:** `close_context`

```json
{
  "type": "browser_control",
  "id": "cmd_17",
  "layer": "high_level",
  "command": "close_context",
  "params": {
    "context_name": "my_context"
  }
}
```

### Close Browser

**Command:** `close`

```json
{
  "type": "browser_control",
  "id": "cmd_18",
  "layer": "high_level",
  "command": "close",
  "params": {}
}
```

---

## Layer 2: Playwright API Commands

Direct access to Playwright Page API methods.

**Command:** `playwright`

```json
{
  "type": "browser_control",
  "id": "cmd_19",
  "layer": "playwright",
  "command": "locator",
  "page_id": "page_1",
  "params": {
    "args": [".my-class"],
    "kwargs": {}
  }
}
```

**Examples:**
- `locator(selector)` - Get locator
- `get_by_text(text)` - Get element by text
- `get_by_role(role)` - Get element by ARIA role
- `get_by_test_id(test_id)` - Get element by test ID
- `query_selector(selector)` - Query selector
- `query_selector_all(selector)` - Query all selectors

---

## Layer 3: CDP (Chrome DevTools Protocol) Commands

Direct access to Chrome DevTools Protocol.

**Command:** `cdp`

```json
{
  "type": "browser_control",
  "id": "cmd_20",
  "layer": "cdp",
  "command": "Network.enable",
  "page_id": "page_1",
  "params": {}
}
```

**Common CDP Commands:**
- `Network.enable` - Enable network tracking
- `Network.getResponseBody` - Get response body
- `Performance.getMetrics` - Get performance metrics
- `Runtime.evaluate` - Evaluate JavaScript
- `Page.captureScreenshot` - Capture screenshot
- `DOM.getDocument` - Get DOM document

**Example with parameters:**
```json
{
  "type": "browser_control",
  "id": "cmd_21",
  "layer": "cdp",
  "command": "Runtime.evaluate",
  "page_id": "page_1",
  "params": {
    "expression": "window.location.href",
    "returnByValue": true
  }
}
```

---

## Error Responses

```json
{
  "type": "browser_control_response",
  "id": "cmd_x",
  "result": "error",
  "error": "Error message describing what went wrong"
}
```

---

## Launch Modes

### 1. Headless Mode (default)
Browser runs without UI, ideal for automation and servers.

```json
{"mode": "headless"}
```

### 2. Headed Mode
Browser runs with visible UI, useful for debugging.

```json
{"mode": "headed"}
```

### 3. Attach Mode
Attach to existing browser instance via CDP.

```json
{
  "mode": "attach",
  "cdp_url": "http://localhost:9222"
}
```

To launch Chrome with remote debugging:
```bash
google-chrome --remote-debugging-port=9222
```

---

## Context Types

### 1. Incognito Context (default)
Isolated context with no persistent state.

```json
{
  "name": "incognito_ctx",
  "incognito": true,
  "persistent": false
}
```

### 2. Persistent Context
Context with saved cookies, localStorage, etc.

```json
{
  "name": "persistent_ctx",
  "persistent": true,
  "user_data_dir": "/path/to/profile"
}
```

### 3. Named Context
Multiple isolated contexts in same browser.

```json
{
  "name": "user1_context",
  "incognito": true
}
```
