Initial commit: OpenClaw Skill Collection

6 custom skills (assign-task, dispatch-webhook, daily-briefing,
task-capture, qmd-brain, tts-voice) with technical documentation.
Compatible with Claude Code, OpenClaw, Codex CLI, and OpenCode.
This commit is contained in:
2026-03-13 10:58:30 +08:00
commit 4c966a3ad2
884 changed files with 140761 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
{
"title": "Gateway architecture",
"content": "Last updated: 2026-01-22\n\n* A single longlived **Gateway** owns all messaging surfaces (WhatsApp via\n Baileys, Telegram via grammY, Slack, Discord, Signal, iMessage, WebChat).\n* Control-plane clients (macOS app, CLI, web UI, automations) connect to the\n Gateway over **WebSocket** on the configured bind host (default\n `127.0.0.1:18789`).\n* **Nodes** (macOS/iOS/Android/headless) also connect over **WebSocket**, but\n declare `role: node` with explicit caps/commands.\n* One Gateway per host; it is the only place that opens a WhatsApp session.\n* A **canvas host** (default `18793`) serves agenteditable HTML and A2UI.\n\n## Components and flows\n\n* Maintains provider connections.\n* Exposes a typed WS API (requests, responses, serverpush events).\n* Validates inbound frames against JSON Schema.\n* Emits events like `agent`, `chat`, `presence`, `health`, `heartbeat`, `cron`.\n\n### Clients (mac app / CLI / web admin)\n\n* One WS connection per client.\n* Send requests (`health`, `status`, `send`, `agent`, `system-presence`).\n* Subscribe to events (`tick`, `agent`, `presence`, `shutdown`).\n\n### Nodes (macOS / iOS / Android / headless)\n\n* Connect to the **same WS server** with `role: node`.\n* Provide a device identity in `connect`; pairing is **devicebased** (role `node`) and\n approval lives in the device pairing store.\n* Expose commands like `canvas.*`, `camera.*`, `screen.record`, `location.get`.\n\n* [Gateway protocol](/gateway/protocol)\n\n* Static UI that uses the Gateway WS API for chat history and sends.\n* In remote setups, connects through the same SSH/Tailscale tunnel as other\n clients.\n\n## Connection lifecycle (single client)\n\n## Wire protocol (summary)\n\n* Transport: WebSocket, text frames with JSON payloads.\n* First frame **must** be `connect`.\n* After handshake:\n * Requests: `{type:\"req\", id, method, params}` → `{type:\"res\", id, ok, payload|error}`\n * Events: `{type:\"event\", event, payload, seq?, stateVersion?}`\n* If `OPENCLAW_GATEWAY_TOKEN` (or `--token`) is set, `connect.params.auth.token`\n must match or the socket closes.\n* Idempotency keys are required for sideeffecting methods (`send`, `agent`) to\n safely retry; the server keeps a shortlived dedupe cache.\n* Nodes must include `role: \"node\"` plus caps/commands/permissions in `connect`.\n\n## Pairing + local trust\n\n* All WS clients (operators + nodes) include a **device identity** on `connect`.\n* New device IDs require pairing approval; the Gateway issues a **device token**\n for subsequent connects.\n* **Local** connects (loopback or the gateway hosts own tailnet address) can be\n autoapproved to keep samehost UX smooth.\n* **Nonlocal** connects must sign the `connect.challenge` nonce and require\n explicit approval.\n* Gateway auth (`gateway.auth.*`) still applies to **all** connections, local or\n remote.\n\nDetails: [Gateway protocol](/gateway/protocol), [Pairing](/start/pairing),\n[Security](/gateway/security).\n\n## Protocol typing and codegen\n\n* TypeBox schemas define the protocol.\n* JSON Schema is generated from those schemas.\n* Swift models are generated from the JSON Schema.\n\n* Preferred: Tailscale or VPN.\n* Alternative: SSH tunnel\n \n* The same handshake + auth token apply over the tunnel.\n* TLS + optional pinning can be enabled for WS in remote setups.\n\n## Operations snapshot\n\n* Start: `openclaw gateway` (foreground, logs to stdout).\n* Health: `health` over WS (also included in `hello-ok`).\n* Supervision: launchd/systemd for autorestart.\n\n* Exactly one Gateway controls a single Baileys session per host.\n* Handshake is mandatory; any nonJSON or nonconnect first frame is a hard close.\n* Events are not replayed; clients must refresh on gaps.",
"code_samples": [
{
"code": "Client Gateway\n | |\n |---- req:connect -------->|\n |<------ res (ok) ---------| (or res error + close)\n | (payload=hello-ok carries snapshot: presence + health)\n | |\n |<------ event:presence ---|\n |<------ event:tick -------|\n | |\n |------- req:agent ------->|\n |<------ res:agent --------| (ack: {runId,status:\"accepted\"})\n |<------ event:agent ------| (streaming)\n |<------ res:agent --------| (final: {runId,status,summary})\n | |",
"language": "unknown"
}
],
"headings": [
{
"level": "h2",
"text": "Overview",
"id": "overview"
},
{
"level": "h2",
"text": "Components and flows",
"id": "components-and-flows"
},
{
"level": "h3",
"text": "Gateway (daemon)",
"id": "gateway-(daemon)"
},
{
"level": "h3",
"text": "Clients (mac app / CLI / web admin)",
"id": "clients-(mac-app-/-cli-/-web-admin)"
},
{
"level": "h3",
"text": "Nodes (macOS / iOS / Android / headless)",
"id": "nodes-(macos-/-ios-/-android-/-headless)"
},
{
"level": "h3",
"text": "WebChat",
"id": "webchat"
},
{
"level": "h2",
"text": "Connection lifecycle (single client)",
"id": "connection-lifecycle-(single-client)"
},
{
"level": "h2",
"text": "Wire protocol (summary)",
"id": "wire-protocol-(summary)"
},
{
"level": "h2",
"text": "Pairing + local trust",
"id": "pairing-+-local-trust"
},
{
"level": "h2",
"text": "Protocol typing and codegen",
"id": "protocol-typing-and-codegen"
},
{
"level": "h2",
"text": "Remote access",
"id": "remote-access"
},
{
"level": "h2",
"text": "Operations snapshot",
"id": "operations-snapshot"
},
{
"level": "h2",
"text": "Invariants",
"id": "invariants"
}
],
"url": "llms-txt#gateway-architecture",
"links": []
}