# coze-bridge

本机后台 daemon，把云端 Agent Service 与 Claude Code、Codex、OpenClaw、Hermes 等 AI agent 通过扩展 ACP 协议桥接起来。

## 前置依赖

- **Node ≥ 22**
- 仅建立设备连接不需要安装 framework，也不要求已有 Agent 或 Project
- 真正执行本地 Agent 时需要对应运行时：本地 Claude Code、OpenClaw、Hermes 分别依赖可用的 `claude`、`openclaw`、`hermes-acp`；Codex 使用 Bridge 固化的私有运行时

## 用法

以下示例统一使用 `npx -y coze-bridge@latest`，不会假设用户已全局安装 CLI；如果已经全局安装，可自行省略此前缀。

```bash
# 启动 / 复用当前 daemon, 投递 pair（默认不注册 OS 保活服务）
npx -y coze-bridge@latest --pat-token=<sat_xxx> --pair-code=<xxx>

# 已成功 pair 后，使用落盘 PAT 重建生产环境连接（默认不注册 OS 保活服务）
npx -y coze-bridge@latest connect

# 切换并持久化 PPE 环境；daemon 被 supervisor 重启后仍恢复该环境
npx -y coze-bridge@latest connect --env=ppe_coze_drive

# 查 daemon 状态
npx -y coze-bridge@latest status

# 回收所有 agent 子进程；下次 prompt 按最新环境重新拉起
npx -y coze-bridge@latest reload

# 保留连接环境，升级到 npm latest，并保持当前手动 / supervisor 托管形态
npx -y coze-bridge@latest update

# 注销 OS 保活服务并停止 daemon
npx -y coze-bridge@latest stop

# 清理: 停 daemon + 卸自启 + 删 ~/.coze/bridge (保留 ~/.coze/agents 工作区)
npx -y coze-bridge@latest purge

# 显式注册 OS 保活服务并按平台能力接管 / 注销 supervisor 配置
npx -y coze-bridge@latest service install
npx -y coze-bridge@latest service uninstall
```

> 老 flag（`--status` / `--stop` / `--install-service` / `--uninstall`）仍能用，但 stderr 会打印 deprecation warning，后续 major bump 会删除。建议切到新子命令形态。
>
> 注意 `--uninstall` 在 0.1.67 起映射到新 `purge`: 删除范围从 `~/.coze` 收窄到 `~/.coze/bridge`, 不再误删 `~/.coze/agents/<id>/workspace` 里用户写过的 CLAUDE.md / SOUL.md。完全重置仍可手动 `rm -rf ~/.coze`。

> `pair` / `connect` 只启动或复用当前 daemon，不会首次创建 launchd、systemd 或 Task Scheduler 配置。`service install` 是唯一显式注册入口；普通的 `pair`、`connect`、`update` 不会迁移或删除旧版本及此前显式注册的服务。
>
> **显式注册后的平台能力**:
> - **macOS / Linux**: `service install` 会关闭当前手动 daemon，等待单实例锁释放，再由 launchd / systemd 接管；支持开机自启和崩溃拉起（KeepAlive / `Restart=always`）。接管失败会清理本次半成品，并尽量恢复原手动 daemon，但命令仍返回失败。
> - **Windows**: `service install` 只登记 Task Scheduler 的 **登录时自启**（ONLOGON），不会停止或立即启动 daemon，任务从下次登录起生效；不支持崩溃自动重启。
>
> `stop` 会先注销保活服务，再通过 IPC 和进程清理停止 daemon。`service uninstall` 不发送 IPC shutdown，也不扫杀手动 daemon；但 macOS 的 `launchctl unload` 和 Linux 的 `systemctl disable --now` 会停止原本由 supervisor 托管的 daemon。Windows 删除计划任务不会停止当前手动 daemon。

### 配对参数

| Flag | 说明 |
|---|---|
| `--pat-token <sat_xxx>` | coze PAT token, 从 coze 平台拿 |
| `--pair-code <xxx>` | 配对码, 从云端 UI 拿 |
| `--device-id <id>` | 云端 Device / Project / Agent 定向重连命令提供的稳定硬件 ID；Bridge 会校验本机 ID，不应手工修改 |

支持 `--name VALUE` 与 `--name=VALUE` 两种写法。

通用首次配对命令可以在没有 Agent、Project 或 framework 时直接执行。云端已有设备或本地项目需要重连时，平台返回的命令会追加 `--device-id`；Bridge 只把它用于本机身份校验，不会改变 `_agent/pair` 协议。

### 自动 connect 某个 agent(可选)

| Flag | 说明 |
|---|---|
| `--agent-id <id>` | pair 成功后自动 connect 该 agent：本地已有配置时 reconnect/revive，否则通过 `_agent/detail` 拉取云端详情并在本机注册 |

```bash
npx -y coze-bridge@latest --pat-token=sat_xxx --pair-code=xxx --agent-id=<your-agent-id>
```

### 环境路由(可选, 联调时用)

| Flag | 说明 |
|---|---|
| `--env <value>` | `ppe_*` 走 `x-use-ppe: 1` + `x-tt-env`; `boe_*` 仅 `x-tt-env` |
| `--handshake-url <url>` | 覆盖 HTTP base, 默认 `https://www.coze.cn`；仅当前 daemon 进程生效 |
| `--frontier-url <url>` | 覆盖 Frontier WS URL, 默认 `wss://frontier.coze.cn`；仅当前 daemon 进程生效 |

```bash
npx -y coze-bridge@latest --pat-token=sat_xxx --pair-code=xxx --env=ppe_xxx
```

成功 pair/connect 后，Bridge 会将 PAT 和 `--env` 写入 `~/.coze/bridge/connection.json`。daemon 被 supervisor 重启时会自动恢复该环境；不带 `--env` 的 pair/connect 明确切回 production，并清除已保存的 PPE/BOE 环境。`--handshake-url`、`--frontier-url` 和 `--mock-scenario` 不持久化。

默认 HTTP/Frontier URL 只表示接入地址，不代表最终一定路由到生产环境；PPE/BOE 由 `x-tt-env`（PPE 同时使用 `x-use-ppe: 1`）决定。

## 行为说明

- **daemon 启动恢复 agent 路由**: `~/.coze/agents/` 中未被 disconnect / delete 的 agent 会重新注册到内存；ACP 子进程按需启动，直到收到下一条 prompt 才 lazy spawn，不需要逐个 reconnect
- **device 级 10s 批量心跳**: pair 成功后每 10s 上行 1 帧 `_agent/health`；没有 eligible agent 时仍发送 `agents:[]` 维持设备在线，新 Agent 注册后自动切换为正常列表
- **两类 device ID 分开管理**: handshake 返回的连接 `deviceId` 只保存在当前 daemon 内存中，切环境或重启后重新获取；本机稳定硬件 ID 由 Bridge 与桌面端共享在 `~/.coze/desktop/device.json`，`--device-id` 校验的是这份硬件 ID
- **cloud deploy 仍是本机执行**: `_meta.cozeDeployType=cloud` 表示模型凭证和网关配置由云端下发，不代表 Agent 进程运行在云端；Bridge 仍会在收到 prompt 时 lazy spawn 对应 ACP 进程。cloud Claude Code / Codex 可使用 Bridge 固化的 wrapper，OpenClaw / Hermes 仍需要本机对应运行时

## 工作目录

```
~/.coze/
├── desktop/
│   └── device.json         # Bridge 与桌面端共享的稳定硬件设备 ID
├── bridge/                 # daemon 文件
│   ├── lib/index.js        # 固化的 dist (npx 首次执行复制过来)
│   ├── bin/                # 注入 Agent 子进程 PATH 的同版本 coze-bridge shim
│   ├── bridge.pid          # PID
│   ├── bridge.port         # IPC HTTP 端口
│   ├── bridge.token        # IPC token (mode 0600)
│   ├── connection.json     # 最近成功连接的 PAT + env (mode 0600)
│   ├── pat-token           # 旧版 PAT 文件，仅用于兼容 fallback
│   ├── agent-env.json      # pair/connect 捕获的 shell 环境快照 (mode 0600)
│   ├── config.json         # framework 探测缓存 + libVersion；不存 handshake deviceId
│   ├── model-cache.json    # per-framework 模型列表缓存
│   ├── bridge.log          # dated 日志迁移提示；legacy/supervisor 裸输出兜底
│   └── logs/
│       ├── bridge-YYYY-MM-DD.log
│       └── daemon-stdio.log
└── agents/<agentId>/       # 每个 agent 一个目录, daemon 重启自动复活
    ├── config.json         # mode 0600 (含 cozeIdentity / model / modelToken / sessions / ...)
    ├── workspace/          # 子进程 cwd, CLAUDE.md / AGENTS.md / SOUL.md 在这
    └── logs/
```

## License

MIT
