Tairitsu Debug Agent Skill

Protocol version: 0.1.0 | Base URL: http://localhost:<debug-port> (default: dev-port + 1)

Overview

When tairitsu dev is launched with --debug, the packager exposes a Debug API server on a dedicated port (default: 3001 when dev server is on 3000). Agents connect via HTTP to perform browser automation — screenshots, DOM inspection, click/input simulation, JS evaluation — without needing a separate Playwright or Puppeteer process.

Startup

# Start dev server with debug API enabled
just dev --daemon --debug

# Custom debug port
just dev --daemon --debug --debug-port 9223

The debug server starts alongside the dev server. Check readiness:

curl -s http://localhost:3001/health | jq .

Expected response:

{
  "ok": true,
  "data": {
    "status": "ok",
    "version": "0.1.0",
    "api_version": "0.1.0",
    "uptime_secs": 42
  }
}

Endpoints

All endpoints return {"ok": bool, "data"?: ..., "error"?: string}. All POST bodies are JSON. All responses are JSON.

GET /health

Liveness check. Always returns 200 if the debug server is running.

GET /info

Server metadata: version, ports, dist dir, package name, PID, uptime, browser status.

POST /navigate

Navigate the managed browser context to a URL.

{
  "url": "/button"
}

Relative URLs are resolved against the dev server base (http://localhost:<dev_port>).

Response: { "url": "...", "title": "..." }

POST /screenshot

Capture a screenshot of the current page (or an element).

{
  "selector": "#hikari-app",
  "full_page": false,
  "format": "png"
}
FieldTypeDefaultDescription
selectorstring?nullCSS selector to screenshot. null = full viewport
full_pagebool?falseCapture full scrollable page
formatstring?"png"Image format (png, jpeg)

Response: { "data": "<base64-encoded image>", "mime_type": "image/png", "width": 1920, "height": 1080 }

POST /click

Click an element matching a CSS selector.

{
  "selector": "#my-button",
  "button": "left",
  "modifiers": []
}
FieldTypeDefaultDescription
selectorstring(required)CSS selector
buttonstring?"left"Mouse button
modifiersstring[]?[]Key modifiers (Shift, Control, Alt)

Response: { "ok": true } or error if element not found.

POST /type

Type text into an input element.

{
  "selector": "input[name='search']",
  "text": "hello world",
  "clear_first": true,
  "submit": false
}
FieldTypeDefaultDescription
selectorstring(required)CSS selector for input/textarea
textstring(required)Text to type
clear_firstbool?trueClear existing value before typing
submitbool?falsePress Enter after typing

Response: { "ok": true }

POST /evaluate

Execute JavaScript in the page context and return the result.

{
  "expression": "document.title",
  "await_promise": false
}
FieldTypeDefaultDescription
expressionstring(required)JS expression to evaluate
await_promisebool?falseIf true, awaits the result as a Promise

Response: { "result": <serialized JS value>, "type": "string|number|boolean|null|object" }

Security note: Evaluation runs in the page context. The debug server binds to 127.0.0.1 only and should never be exposed to networks.

GET /console

Retrieve recent console log entries from the managed browser.

Response: { "entries": [{ "level": "log|warn|error", "text": "...", "timestamp": "ISO-8601" }] }

GET /dom?selector=...&attribute=...

Query DOM elements by CSS selector.

Query ParamTypeDescription
selectorstring(required) CSS selector
attributestring?If set, return only this attribute's value

Response:

{
  "ok": true,
  "data": {
    "tag": "div",
    "text": "Hello World",
    "html": "<div id=\"app\">...</div>",
    "attributes": { "id": "app", "class": "container" },
    "visible": true,
    "count": 1
  }
}

Agent Workflow Example

A typical agent session for visual debugging:

graph TD
    S1["1. GET /health"] --> S2["2. POST /navigate {url: /}"]
    S2 --> S3["3. POST /screenshot {}"]
    S3 --> S4["4. POST /evaluate<br/>(check WASM state)"]
    S4 --> S5["5. POST /click {selector: .btn-primary}"]
    S5 --> S6["6. POST /creenshot {selector: #dialog}"]
    S6 --> S7["7. GET /console"]
    S7 --> S8["8. POST /navigate {url: /switch}"]
    S8 --> S9["9. POST /screenshot {full_page: true}"]

Error Handling

Status CodeMeaning
200Success
400Invalid request body or missing parameters
404Unknown endpoint
503Browser not connected (headless chromium unavailable)

When ok: false, the error field contains a human-readable description.

Integration Notes