🕸 clawline · v0.2.x · monorepo 已合

Clawline · 给 OpenClaw 装上多端聊天入口

让 Web / 微信小程序 / Chrome 扩展 / 桌面 Tauri app / 自建客户端都能直连 OpenClaw AI Agent 实时聊天。

系统组件
6
SDK · Gateway · Channel · Client Web · WeChat 小程序 · Browser Agent
部署模式
2
直连 (websocket) + 中继 (relay)
架构成熟度
3.8/10
原型可演示 · 尚未生产就绪
01 · 整体拓扑

客户端 → 中继 → OpenClaw Agent

Gateway 在云端替 OpenClaw 挡下所有客户端连接,不用公网暴露本地实例。所有消息走 WebSocket 双向, 兼容 REST 同步/SSE 流式两种回退。

1 · 多端客户端 Client Web (React SPA) Vite · PWA · 端口 4026 同时打包成 Tauri 2 桌面 app Client WeChat 微信原生小程序 .wxml / .wxss / .js Browser Agent Chrome extension native host · 端口 4821 自定义客户端 via @clawlines/sdk Browser / Node.js WebSocket (wss://) / REST (HTTP) 2 · 中继网关 · gateway Relay Gateway (云端) 端口 19180 (dev) / 19080 (prod) WebSocket Relay /client (客户端) · /backend (channel) frame 协议 · 双向广播 REST API /api/chat · /api/messages · /api/media sync JSON · SSE 流式 · 3 种 auth Admin UI (React 19 + shadcn) 频道/用户 CRUD · 连接监控 · QR 配对 Logto SSO / Admin token 双通 限流 · 认证 · 持久化 · 死信重试 100 req/min/IP · WS 30 msg/min · timingSafeEqual 3 · 持久化 Supabase (db.dora) cl_channels / cl_channel_users cl_messages (去重 index) cl_settings / cl_relay_nodes 异步写 → 失败重试 2 次 → jsonl DLQ 本地媒体存储 /api/media/upload → uploads/ multipart / base64 / raw 3 种 MEDIA_MAX_BYTES 上限 ws://127.0.0.1:19180/backend 4 · Channel Plugin · openclaw @restry/clawline OpenClaw channel 插件 ✎ symlink 到 ~/.openclaw/extensions 3 模式: websocket / relay / webhook Zod 验证 · 200 LRU 去重 · 流式转发 OpenClaw Runtime 端口 18789 · GET /health launchctl · ai.openclaw.gateway AI Agent Runtime Anthropic / OpenAI / 自建 图例: 实线 = 主流量 虚线 = channel ↔ gateway 隧道
02 · 部署模式

直连 vs 中继

要不要暴露 OpenClaw 到公网 —— 一句话决定用哪种模式。绝大多数场景是「中继」, OpenClaw 在家里 / 内网, gateway 在云端替它挡子弹。

模式 A · 直连 Direct

websocket

客户端直连 OpenClaw channel 端口。OpenClaw 必须公网可达。

客户端 ─── WebSocket ──→ OpenClaw (Channel Plugin)
                            :8080 (默认)

✓ 简单 · 零中继延迟
✗ OpenClaw 端口暴露公网 · 需要自己搞证书/防火墙

模式 B · 中继 Relay

relay

默认推荐。OpenClaw 主动出站连 gateway, gateway 挡下所有客户端。

客户端 ─── WSS ──→ Gateway (云) ←── WS ── OpenClaw (家)
                    :19180                     :18789

✓ OpenClaw 无需公网 IP · 客户端不感知后端
✓ 消息持久化 · 离线可 sync · 多客户端广播
✗ gateway 是 SPOF

03 · 6 大组件

每个组件干一件事

全部在 clawline/platform pnpm monorepo 里。sdk / docs 独立 repo; wechat 小程序 + browser-agent 各自 repo 只是暂未合入。

core

@clawlines/sdk

WebSocket 客户端库, 给第三方接入用。包含 ClawlineClient (单连接) + ClawlinePool (LRU 连接池, 默认最多 3 并发)。

平台: browser + Node.js
协议: 自动重连 6 次 · 指数退避
能力: 文本 / 媒体 / 引用 / 表情 / 编辑
apps/gateway · @clawlines/relay-gateway

Relay Gateway

Node ESM 中继网关, 云端跑。所有客户端 + channel 都连它, 它做认证 / 限流 / 持久化 / 消息路由。

端口: 19180 (dev) / 19080 (prod)
WS: /client · /backend
REST: /api/chat · /api/messages · /api/media 等 15+
apps/channel · @restry/clawline

Channel Plugin

OpenClaw 插件, symlink 加载 TS 源码直接跑。做消息 pipeline: Zod 验证 → 去重 → 白名单 → 媒体下载/转录 → agent 路由 → 流式回推。

集成: OpenClaw Plugin SDK
模式: websocket / relay / webhook
加载: 改 .ts 需重启 openclaw
apps/client-web · clawline-client-web

Client Web + Tauri

React 19 + Vite SPA。同一份代码同时打包成 Web PWA + Tauri 2 桌面 app。有独立 updater 走 GitHub Releases。

端口 (dev): 4026
桌面版: Tauri 2 · macOS / Win / Linux 三平台
发版: tag desktop-v* 触发 CI
client-wechat

WeChat 小程序

微信原生小程序客户端, .wxml/.wxss/.js。走 WSS 连 gateway, 用 SDK 协议。

Repo: 独立 (未合入 monorepo)
协议: 同 SDK · 兼容 relay 模式
browser-agent

Browser Agent

Chrome 扩展 + native host。让 OpenClaw 通过 HTTP Hook API 反向控制浏览器 (打开 tab / 抓 DOM / 执行 JS)。

Repo: 独立
Native host: 端口 4821
用途: agent 控浏览器
04 · Gateway API

3 种 auth × 15 个 REST × 2 个 WebSocket

Gateway 对外暴露的接口全表。Admin 需要 X-Relay-Admin-Token 或 Logto JWT · User 需要 channel user token · Open 无需认证。

Method Path 说明 Auth
WEBSOCKET
WS/backendOpenClaw channel 上行 · channelId + secret 握手channel
WS/client?channelId=&token=&chatId=&agentId=客户端连接 · token 认证User
聊天 & 消息
POST/api/chat发消息 · sync JSON 或 SSE 流 (Accept 头切换)User
GET/api/messages/sync拉断线期间消息 · after/before 双向分页User
GET/api/messagesAdmin 浏览消息日志Admin
GET/api/messages/stats按小时/模型/频道聚合 · 最近 500 条Admin
媒体 & AI 辅助
POST/api/media/upload3 种 body: multipart / base64 / rawUser
GET/api/media/:filename下载媒体Open
POST/api/suggestionsAI 生成后续建议 / 回复草稿User
POST/api/voice-refineAI 优化 ASR 转录文本User
管理 & Meta
GET/healthz健康检查 · 后端数 / 客户端数 / 频道列表Open
GET/api/meta网关元数据 · 认证状态 · 公开 URLOpen
GET/api/state完整中继状态Admin
POST/api/channels · /api/channels/:id/users频道 / 用户 CRUDAdmin
GET/api/agents列出 agent · online 状态Admin
*/api/settings · /api/ai-settings · /api/relay-nodes通用设置 · AI 配置 · 多节点管理Admin
05 · 架构成熟度 · 3.8/10

原型可演示,尚未生产就绪

按 8 个维度打分,评分标准: 1-3 原型阶段 · 4-6 内测可用 · 7-8 生产就绪 · 9-10 工程卓越。红色 = 阻断上线的硬伤。

文档完整度
7/10
已整理到 76% 覆盖率, PRODUCT_OVERVIEW + ISSUE_ANALYSIS + FEATURE_GAP 三份齐
API 设计
5/10
REST 命名规范, 但 4 种 auth 混用, 无版本化
部署就绪度
5/10
Docker + CI/CD + /healthz, 但单进程 · 无结构化日志 · 无监控
错误处理
4/10
重试机制 + DLQ 有, 但 UI 提示不统一 (toast/banner/console) 空 catch 散布
代码模块化
3/10
Gateway server.js 2131 行单文件, HTTP+WS+auth+media+LLM 全耦合
安全架构
3/10
3 个致命漏洞: CORS 默认全开 · service_role_key 绕 RLS · sync 无频道级授权
SDK 采用率
2/10
Web 端没用 SDK, clawChannel.ts 1465 行独立重实现协议
测试基础设施
1/10
全项目零单元测试 · Web 端 2 个 E2E 引用不存在 IndexedDB 实质失效
综合
3.8/10
加权平均 · 生产阻断项 4 条 · 补齐前不建议对外
06 · 实战踩坑

已固化到 skill 的坑

3 个 skill 沉淀了这些血泪教训: clawline-local-dev / clawline-api-integration / clawline-desktop-release

Tauri v2 updater 返回结构变了
plugin:updater|check 不再返回 { available } · 只有 null 或元数据对象。旧代码 if (!update.available) return 永远静默跳出, updater 表面无症状实际从未触发过。
✓ 用静态 import + Update.downloadAndInstall(); 死锁: 旧 app 装到用户手里永远收不到更新, 修好版必须靠手动覆盖升上来
GitHub Draft release 静默失败
release-desktop.ymlreleaseDraft: true, 打完 tag 生成 draft, 但 /releases/latest/download/latest.json 不解析 draft → updater 拉 404 → tauri.ts console.warn 吞掉错误 → 无症状。
✓ 每次发版必手动 gh release edit --draft=false --latest
window.confirm 在 Tauri webview 静默返回 false
用户报"已取消"哪怕没点取消。window.confirm / alert 全不可靠。
✓ React 自建 modal 走事件; 见 UpdateModal.tsx + clawline:update-available
Progress chunkLength 是增量不是累计
Tauri Update.downloadAndInstall onEvent Progress 事件, chunkLength = 本次 chunk 字节数不是累计。直接当百分比基数会一直显示 0-1% 抖动。
✓ 自己累加 downloaded += e.data.chunkLength
gateway .env vs .env.dev 双端口
.env → 19080 (prod) · .env.dev → 19180 (dev)。channel plugin config 只指一个, 两个同时跑会 sink 到错的。
✓ 启前先 kill 19080 或 19180 一个
/health 假死
relay-gateway 的 /health 返回 {ok:false, error:"not found"} 因为压根没实现。看这个当挂了 → 白重启一次。
✓ 判活: GET / 返 HTML 且 WS /backend 能开就是活的
openclaw plugins list 永挂不返回
openclaw status 同挂 · 已知 CLI bug · timeout 也无用
✓ 用 curl /health 判 gateway · 用 cat openclaw.json 判 plugin
桌面端 Clawline.app 永远不要 kill
主人铁律。改 web 就 pnpm dev 端口 4026 + Chrome 测, 不重启桌面端。桌面端只能靠发新 release 升级。
✗ pkill chrome 类命令也禁 (会杀主人工作窗口)
07 · Repo 结构

2026-05 已合成 pnpm monorepo

主 monorepo clawline/platform 装 3 个 app; sdk / wechat / browser-agent / docs 仍独立 repo。开发分支全走 dev, main 只 track 不动。

# 本地路径: ~/projects/clawline/ clawline/ ├── platform/ # 主 monorepo (pnpm workspaces) │ ├── apps/ │ │ ├── channel/ # @restry/clawline · OpenClaw 插件 │ │ ├── gateway/ # @clawlines/relay-gateway · Node ESM │ │ │ ├── server.js # 2131 行单文件 · P0 待拆分 │ │ │ ├── .env / .env.dev # 双 config → 双端口 (19080/19180) │ │ │ └── admin/ # React 19 + shadcn Admin UI │ │ └── client-web/ # clawline-client-web · Vite + Tauri 2 │ │ ├── src/ # React 19 SPA │ │ └── src-tauri/ # 桌面壳 · updater · release CI │ ├── packages/ # 预留 Phase 2 共享包 │ └── pnpm-workspace.yaml │ ├── sdk/ # @clawlines/sdk · 未合入 (独立 repo) ├── client-wechat/ # 微信原生小程序 · 独立 repo ├── browser-agent/ # Chrome extension + native host · 独立 repo └── docs/ # PRODUCT_OVERVIEW / ARCHITECTURE_ROADMAP / ISSUE_ANALYSIS # OpenClaw 加载方式 (无需 build) ~/.openclaw/extensions/clawline → ~/projects/clawline/platform/apps/channel