# WxAgent Control Plane Go 1.23 控制面与 React 管理端。节点只主动出站连接,控制面不暴露节点端口。 ## 本地启动 ```bash cd control-plane npm --prefix web ci --no-audit --no-fund npm --prefix web run build go run ./cmd/wxagent-control-plane ``` 启动前设置(单节点兼容写法): ```bash export WXAGENT_NODE_ID=local-node export WXAGENT_NODE_TOKEN='local-node-token' export WXAGENT_WEB_USER=admin export WXAGENT_WEB_PASSWORD='change-me' ``` 多节点/多用户使用 JSON map: ```bash export WXAGENT_NODE_TOKENS='{"node-a":"token-a","node-b":"token-b"}' export WXAGENT_WEB_USERS='{"admin":"change-me","auditor":"read-only-password"}' ``` 可选:`WXAGENT_CONTROL_PLANE_ADDR`(默认 `127.0.0.1:8090`)、`WXAGENT_CONTROL_PLANE_DATA`(默认 `control-plane-data.json`)。Token 只从环境变量读取,不写入控制面数据文件和日志。节点 `service.json` 可设置 `remoteConfigurationFile` 指向 CLI 管理的 `remote.json`;修改上报配置会在下一轮生效,修改远程地址/Token 后需重启 Agent。 浏览器访问 `http://127.0.0.1:8090/`,登录后管理节点、任务、白名单事件和审计记录。生产部署必须使用 HTTPS 和外部密钥管理;本地 HTTP 仅用于 loopback 集成测试。 远程只读查询使用同一持久化任务队列,返回 `task_id` 后通过 `GET /v1/tasks/{task_id}` 取结果: ```text POST /v1/reads/sessions { node_id, account_id, idempotency_key, limit?, offset? } POST /v1/reads/contacts { node_id, account_id, idempotency_key, groups_only, contains?, limit?, offset? } POST /v1/reads/messages { node_id, account_id, idempotency_key, chat_id, include_content?, limit?, offset? } ``` 节点只返回本地已启用且 `identityVerified` 的白名单会话;未授权范围在节点读取前拒绝。`chat_id` 必须使用会话列表返回的稳定会话标识,消息结果是当前微信 UI 可见历史,不是数据库全量历史。联系人查询中的 `chat_id` 使用联系人数据库稳定 ID;所有响应仍受任务结果大小和分页上限约束。 ## 验证 ```bash cd control-plane go test ./... go vet ./... cd ../control-plane/web npm run build cd ../.. ./scripts/remote-control-smoke.sh ``` `remote-control-smoke.sh` 会启动一次临时控制面,运行 .NET 节点协议客户端,验证注册、心跳、任务租约、幂等、结果回传和白名单拒绝;不会操作真实微信联系人。 ## Windows 手工验收 1. 在已登录且未锁定的微信桌面会话中运行 `WxAgent.Host doctor` 和 `WxAgent.Host inspect-ui --output artifacts/ui-tree.json`,确认账号绑定使用稳定 `accountId`,会话使用稳定 `AutomationId`,不使用昵称/PID/窗口句柄猜测。 2. 为节点配置 `remote.json`,例如先执行: ```powershell WxAgent.Host remote auth set --config remote.json --address https://control.example --token $env:WXAGENT_NODE_TOKEN --node node-a --active-account <已确认的accountId> WxAgent.Host remote reporting enable --config remote.json WxAgent.Host remote reporting account-add --config remote.json --account <已确认的accountId> WxAgent.Host remote reporting account-enable --config remote.json --account <已确认的accountId> WxAgent.Host remote reporting allow --config remote.json --account <已确认的accountId> --type group --chat-id <已确认的稳定chatId> --identity-verified WxAgent.Host remote probe run --config remote.json ``` 3. 在节点 `service.json` 设置 `"remoteConfigurationFile": ""` 后启动 `serve`。控制面应显示节点 `Online`、已验证账号和心跳版本。 4. 仅使用文件传输助手、`Hao 豪`、`吉祥三宝`、`消息测试专用群组`做发送/接收验证:先验证允许的群聊事件能到达控制面,再执行 `reporting deny`,确认后续正文不再上传;创建 `send-text` 前确认目标账号、稳定 chat ID 和文本。 5. 在控制面取消任务并验证节点不执行;断开网络后恢复,确认未完成副作用任务显示 `ResultUnconfirmed`,不会自动重放。 未解锁的 Session 0、昵称、PID、窗口句柄和未确认的运行时身份都应视为验收失败;手工验收不得改写微信数据库或绕过安全机制。 ## 容器镜像 `.gitea/workflows/build-web-image.yml` 会构建并推送 `git.ipao.vip//` 镜像:主分支额外更新 `latest`,`v*` 标签额外更新对应版本标签。请在 Gitea 账号级 Secrets 配置 `REGISTRY_TOKEN`;登录用户名使用仓库所有者。