{"repo": "chenhg5/cc-connect", "files": {"docs/usage.zh-CN.md": {"f2e4ed83c6953297a92d66d49114196fc4402206": {"t": 1785746421.2026405, "n": 24486, "h": "bfdda70b54476bcf", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [Shell 配置](#shell-配置)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息;单条长度受 `[display].history_max_len` 控制,默认 1000 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n- 每个附件默认上限 **50 MiB**。可在 config.toml 用 `max_attachment_size_mb`(单位 MiB)调整,或用环境变量 `CC_MAX_ATTACHMENT_SIZE_MB` 覆盖该值(同样单位 MiB,设置后优先级更高),例如 `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 目标平台在投递时还会校验自己的文件大小/类型上限;实际生效的是它与 `max_attachment_size_mb` 中**更小**的那个(通过了 cc-connect 的文件仍可能在投递时被平台拒绝)。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## Shell 配置\n\n默认情况下,cc-connect 在 Unix 上使用 `sh`,Windows 上使用 `powershell.exe` 来执行所有 shell 命令(`/shell`、cron exec、hooks 和 webhook exec)。你可以配置使用其他 shell。\n\n### 支持的 Shell\n\n| Shell | 配置值 | 参数标志 |\n|-------|--------|---------|\n| sh(Unix 默认) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd(Windows) | `cmd` | `/C` |\n| PowerShell(Windows 默认) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\n参数标志会根据 shell 名称自动检测,无需手动配置。\n\n### 全局配置\n\n在 `config.toml` 顶层设置 `shell`,更改所有项目的默认 shell:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### 项目级覆盖\n\n为特定项目覆盖 shell:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\n使用 `shell_profile` 在每条 shell 命令前添加初始化脚本。适用于加载 shell profile,使自定义函数、别名和环境变量可用:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nshell profile 和用户命令会用换行符拼接后作为一个整体脚本传给 shell,避免引号转义问题。例如 `/shell echo $MY_VAR` 实际执行的是:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` 同样支持项目级覆盖:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### 影响范围\n\nShell 配置适用于 cc-connect 中所有命令执行路径:\n\n- **`/shell` 命令** — 聊天中的交互式 shell 命令\n- **Cron exec 任务** — `[[cron]]` 中 `exec` 字段的定时任务\n- **Hooks** — `[[hooks]]` 中 `type = \"command\"` 的钩子\n- **Webhook exec** — webhook 请求中 `exec` 字段的命令\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n\n---\n\n## 常见问题(FAQ)\n\n下面这些是 issue 区里反复出现、维护者已经回答过的问题。每条都附上了\n原始 issue / PR 链接,方便继续深入。\n\n### cc-connect 是否支持 OpenClaw?(issue #501)\n\n支持。OpenClaw 通过 [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents) 接入。\ncc-connect 内置了 `acp` agent 类型,可以和任何 ACP 兼容的 CLI 通信,\n包括 OpenClaw 的 `openclaw acp` 子命令。\n\n最小配置示例(完整版见 `config.example.toml` 中 `# --- Example:\nOpenClaw (Gateway-backed ACP bridge) ---` 段):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**远端 Gateway 必须先完成配对授权。** 如果你把 cc-connect 指向\n远程 OpenClaw Gateway(`args = [\"acp\", \"--url\", \"wss://...\"]`),\n必须先配对,否则所有回复都会是空消息:\n\n1. 启动 Gateway:`openclaw acp --url wss://your-gateway:18789`\n2. 另开终端执行:`openclaw pair`\n3. 在 OpenClaw UI 里同意配对请求\n4. 完成后 cc-connect 才能与已授权的 Gateway 通信\n\nOpenClaw 回复空消息几乎都是漏掉了配对步骤(issue #432)。在排查其他\n原因之前,先重跑 `openclaw pair` 并在 UI 中重新授权一次。\n参考:\n\n### 个人微信群聊 — 如何获取正确的 `chat_id`(issue #805)\n\n个人微信(`weixin` 平台)支持群聊。要把机器人绑定到某个群,需要把\n`[[projects.platforms.options]]` 里的 `chat_id` 设置为**群聊 ID**,\n而不是个人用户 ID。群聊 ID 一定以 `@chatroom` 结尾,例如:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # 群聊 ID 以 @chatroom 结尾\n```\n\n**获取群聊 ID 的方法:**\n\n1. 启动 cc-connect,并让机器人加入目标群。\n2. 让群里任意已知允许的用户在群里发一条消息。\n3. 查看 cc-connect 日志,消息到达时会打印带 `@chatroom` 后缀的\n `chat_id`。把那个值原样填到 `chat_id` 即可。\n\n把 `chat_id` 留空(或不写这个键)就表示响应机器人所在的所有聊天。\n填具体值则只响应那个群/个人。\n\n常见坑:\n\n- **「怎么把机器人加进群?」** 个人微信机器人没有\"邀请机器人入群\"\n 的 API;只能由已经扫码绑定 ilink 的微信号,在群里发起\"添加\"或把\n 机器人的二维码发到群里、让群里的人扫码添加。和把普通好友拉进群\n 一样。\n- **群里发消息机器人不响应** — 检查是否把 `chat_id` 绑到了别的用户/\n 群,或 `allow_from` 限制了别的用户,把当前用户也加入。\n- **私聊能回、群聊不回(或反之)** — 复制一份 `[[projects.platforms]]`\n 块,一份 `chat_id` 填群 ID、另一份留空,就能同时覆盖私聊和群聊。\n\n更多关于 `weixin` 平台的内容见 [docs/weixin.md](./weixin.md)。\n\n### Telegram 代理 / 出站限制 (issue #245)\n\nTelegram 平台在 `[projects.platforms.options]` 里直接支持 HTTP 和\nSOCKS5 正向代理。不需要配系统级代理或 sidecar,per Telegram 实例\n设置即可。\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # 或 socks5://127.0.0.1:1080\nproxy_username = \"\" # 代理无鉴权时留空\nproxy_password = \"\"\n```\n\n`proxy` 同时接受 `http://` 和 `socks5://` 两种 URL,鉴权可选。\n代理只作用于该 Telegram 实例的 Bot API 请求,不会影响其他平台或\n管理后台的出站。\n\n完整说明见 [docs/telegram.md](./telegram.md#21-optional-use-a-proxy)(英文原文,\n`docs/telegram.md` 目前只有英文版)。该配置由 PR #389 引入。\n"}, "fa86932f29dcb12cae6ff857b4f6de643539d0aa": {"t": 1785763836.6483977, "n": 24486, "h": "bfdda70b54476bcf", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [Shell 配置](#shell-配置)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息;单条长度受 `[display].history_max_len` 控制,默认 1000 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n- 每个附件默认上限 **50 MiB**。可在 config.toml 用 `max_attachment_size_mb`(单位 MiB)调整,或用环境变量 `CC_MAX_ATTACHMENT_SIZE_MB` 覆盖该值(同样单位 MiB,设置后优先级更高),例如 `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 目标平台在投递时还会校验自己的文件大小/类型上限;实际生效的是它与 `max_attachment_size_mb` 中**更小**的那个(通过了 cc-connect 的文件仍可能在投递时被平台拒绝)。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## Shell 配置\n\n默认情况下,cc-connect 在 Unix 上使用 `sh`,Windows 上使用 `powershell.exe` 来执行所有 shell 命令(`/shell`、cron exec、hooks 和 webhook exec)。你可以配置使用其他 shell。\n\n### 支持的 Shell\n\n| Shell | 配置值 | 参数标志 |\n|-------|--------|---------|\n| sh(Unix 默认) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd(Windows) | `cmd` | `/C` |\n| PowerShell(Windows 默认) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\n参数标志会根据 shell 名称自动检测,无需手动配置。\n\n### 全局配置\n\n在 `config.toml` 顶层设置 `shell`,更改所有项目的默认 shell:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### 项目级覆盖\n\n为特定项目覆盖 shell:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\n使用 `shell_profile` 在每条 shell 命令前添加初始化脚本。适用于加载 shell profile,使自定义函数、别名和环境变量可用:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nshell profile 和用户命令会用换行符拼接后作为一个整体脚本传给 shell,避免引号转义问题。例如 `/shell echo $MY_VAR` 实际执行的是:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` 同样支持项目级覆盖:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### 影响范围\n\nShell 配置适用于 cc-connect 中所有命令执行路径:\n\n- **`/shell` 命令** — 聊天中的交互式 shell 命令\n- **Cron exec 任务** — `[[cron]]` 中 `exec` 字段的定时任务\n- **Hooks** — `[[hooks]]` 中 `type = \"command\"` 的钩子\n- **Webhook exec** — webhook 请求中 `exec` 字段的命令\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n\n---\n\n## 常见问题(FAQ)\n\n下面这些是 issue 区里反复出现、维护者已经回答过的问题。每条都附上了\n原始 issue / PR 链接,方便继续深入。\n\n### cc-connect 是否支持 OpenClaw?(issue #501)\n\n支持。OpenClaw 通过 [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents) 接入。\ncc-connect 内置了 `acp` agent 类型,可以和任何 ACP 兼容的 CLI 通信,\n包括 OpenClaw 的 `openclaw acp` 子命令。\n\n最小配置示例(完整版见 `config.example.toml` 中 `# --- Example:\nOpenClaw (Gateway-backed ACP bridge) ---` 段):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**远端 Gateway 必须先完成配对授权。** 如果你把 cc-connect 指向\n远程 OpenClaw Gateway(`args = [\"acp\", \"--url\", \"wss://...\"]`),\n必须先配对,否则所有回复都会是空消息:\n\n1. 启动 Gateway:`openclaw acp --url wss://your-gateway:18789`\n2. 另开终端执行:`openclaw pair`\n3. 在 OpenClaw UI 里同意配对请求\n4. 完成后 cc-connect 才能与已授权的 Gateway 通信\n\nOpenClaw 回复空消息几乎都是漏掉了配对步骤(issue #432)。在排查其他\n原因之前,先重跑 `openclaw pair` 并在 UI 中重新授权一次。\n参考:\n\n### 个人微信群聊 — 如何获取正确的 `chat_id`(issue #805)\n\n个人微信(`weixin` 平台)支持群聊。要把机器人绑定到某个群,需要把\n`[[projects.platforms.options]]` 里的 `chat_id` 设置为**群聊 ID**,\n而不是个人用户 ID。群聊 ID 一定以 `@chatroom` 结尾,例如:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # 群聊 ID 以 @chatroom 结尾\n```\n\n**获取群聊 ID 的方法:**\n\n1. 启动 cc-connect,并让机器人加入目标群。\n2. 让群里任意已知允许的用户在群里发一条消息。\n3. 查看 cc-connect 日志,消息到达时会打印带 `@chatroom` 后缀的\n `chat_id`。把那个值原样填到 `chat_id` 即可。\n\n把 `chat_id` 留空(或不写这个键)就表示响应机器人所在的所有聊天。\n填具体值则只响应那个群/个人。\n\n常见坑:\n\n- **「怎么把机器人加进群?」** 个人微信机器人没有\"邀请机器人入群\"\n 的 API;只能由已经扫码绑定 ilink 的微信号,在群里发起\"添加\"或把\n 机器人的二维码发到群里、让群里的人扫码添加。和把普通好友拉进群\n 一样。\n- **群里发消息机器人不响应** — 检查是否把 `chat_id` 绑到了别的用户/\n 群,或 `allow_from` 限制了别的用户,把当前用户也加入。\n- **私聊能回、群聊不回(或反之)** — 复制一份 `[[projects.platforms]]`\n 块,一份 `chat_id` 填群 ID、另一份留空,就能同时覆盖私聊和群聊。\n\n更多关于 `weixin` 平台的内容见 [docs/weixin.md](./weixin.md)。\n\n### Telegram 代理 / 出站限制 (issue #245)\n\nTelegram 平台在 `[projects.platforms.options]` 里直接支持 HTTP 和\nSOCKS5 正向代理。不需要配系统级代理或 sidecar,per Telegram 实例\n设置即可。\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # 或 socks5://127.0.0.1:1080\nproxy_username = \"\" # 代理无鉴权时留空\nproxy_password = \"\"\n```\n\n`proxy` 同时接受 `http://` 和 `socks5://` 两种 URL,鉴权可选。\n代理只作用于该 Telegram 实例的 Bot API 请求,不会影响其他平台或\n管理后台的出站。\n\n完整说明见 [docs/telegram.md](./telegram.md#21-optional-use-a-proxy)(英文原文,\n`docs/telegram.md` 目前只有英文版)。该配置由 PR #389 引入。\n"}, "8343c310b6881596c416e11e39b02c9c0c2fb402": {"t": 1785763839.644277, "n": 24441, "h": "30277a467b6ac978", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [Shell 配置](#shell-配置)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n- 每个附件默认上限 **50 MiB**。可在 config.toml 用 `max_attachment_size_mb`(单位 MiB)调整,或用环境变量 `CC_MAX_ATTACHMENT_SIZE_MB` 覆盖该值(同样单位 MiB,设置后优先级更高),例如 `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 目标平台在投递时还会校验自己的文件大小/类型上限;实际生效的是它与 `max_attachment_size_mb` 中**更小**的那个(通过了 cc-connect 的文件仍可能在投递时被平台拒绝)。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## Shell 配置\n\n默认情况下,cc-connect 在 Unix 上使用 `sh`,Windows 上使用 `powershell.exe` 来执行所有 shell 命令(`/shell`、cron exec、hooks 和 webhook exec)。你可以配置使用其他 shell。\n\n### 支持的 Shell\n\n| Shell | 配置值 | 参数标志 |\n|-------|--------|---------|\n| sh(Unix 默认) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd(Windows) | `cmd` | `/C` |\n| PowerShell(Windows 默认) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\n参数标志会根据 shell 名称自动检测,无需手动配置。\n\n### 全局配置\n\n在 `config.toml` 顶层设置 `shell`,更改所有项目的默认 shell:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### 项目级覆盖\n\n为特定项目覆盖 shell:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\n使用 `shell_profile` 在每条 shell 命令前添加初始化脚本。适用于加载 shell profile,使自定义函数、别名和环境变量可用:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nshell profile 和用户命令会用换行符拼接后作为一个整体脚本传给 shell,避免引号转义问题。例如 `/shell echo $MY_VAR` 实际执行的是:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` 同样支持项目级覆盖:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### 影响范围\n\nShell 配置适用于 cc-connect 中所有命令执行路径:\n\n- **`/shell` 命令** — 聊天中的交互式 shell 命令\n- **Cron exec 任务** — `[[cron]]` 中 `exec` 字段的定时任务\n- **Hooks** — `[[hooks]]` 中 `type = \"command\"` 的钩子\n- **Webhook exec** — webhook 请求中 `exec` 字段的命令\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n\n---\n\n## 常见问题(FAQ)\n\n下面这些是 issue 区里反复出现、维护者已经回答过的问题。每条都附上了\n原始 issue / PR 链接,方便继续深入。\n\n### cc-connect 是否支持 OpenClaw?(issue #501)\n\n支持。OpenClaw 通过 [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents) 接入。\ncc-connect 内置了 `acp` agent 类型,可以和任何 ACP 兼容的 CLI 通信,\n包括 OpenClaw 的 `openclaw acp` 子命令。\n\n最小配置示例(完整版见 `config.example.toml` 中 `# --- Example:\nOpenClaw (Gateway-backed ACP bridge) ---` 段):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**远端 Gateway 必须先完成配对授权。** 如果你把 cc-connect 指向\n远程 OpenClaw Gateway(`args = [\"acp\", \"--url\", \"wss://...\"]`),\n必须先配对,否则所有回复都会是空消息:\n\n1. 启动 Gateway:`openclaw acp --url wss://your-gateway:18789`\n2. 另开终端执行:`openclaw pair`\n3. 在 OpenClaw UI 里同意配对请求\n4. 完成后 cc-connect 才能与已授权的 Gateway 通信\n\nOpenClaw 回复空消息几乎都是漏掉了配对步骤(issue #432)。在排查其他\n原因之前,先重跑 `openclaw pair` 并在 UI 中重新授权一次。\n参考:\n\n### 个人微信群聊 — 如何获取正确的 `chat_id`(issue #805)\n\n个人微信(`weixin` 平台)支持群聊。要把机器人绑定到某个群,需要把\n`[[projects.platforms.options]]` 里的 `chat_id` 设置为**群聊 ID**,\n而不是个人用户 ID。群聊 ID 一定以 `@chatroom` 结尾,例如:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # 群聊 ID 以 @chatroom 结尾\n```\n\n**获取群聊 ID 的方法:**\n\n1. 启动 cc-connect,并让机器人加入目标群。\n2. 让群里任意已知允许的用户在群里发一条消息。\n3. 查看 cc-connect 日志,消息到达时会打印带 `@chatroom` 后缀的\n `chat_id`。把那个值原样填到 `chat_id` 即可。\n\n把 `chat_id` 留空(或不写这个键)就表示响应机器人所在的所有聊天。\n填具体值则只响应那个群/个人。\n\n常见坑:\n\n- **「怎么把机器人加进群?」** 个人微信机器人没有\"邀请机器人入群\"\n 的 API;只能由已经扫码绑定 ilink 的微信号,在群里发起\"添加\"或把\n 机器人的二维码发到群里、让群里的人扫码添加。和把普通好友拉进群\n 一样。\n- **群里发消息机器人不响应** — 检查是否把 `chat_id` 绑到了别的用户/\n 群,或 `allow_from` 限制了别的用户,把当前用户也加入。\n- **私聊能回、群聊不回(或反之)** — 复制一份 `[[projects.platforms]]`\n 块,一份 `chat_id` 填群 ID、另一份留空,就能同时覆盖私聊和群聊。\n\n更多关于 `weixin` 平台的内容见 [docs/weixin.md](./weixin.md)。\n\n### Telegram 代理 / 出站限制 (issue #245)\n\nTelegram 平台在 `[projects.platforms.options]` 里直接支持 HTTP 和\nSOCKS5 正向代理。不需要配系统级代理或 sidecar,per Telegram 实例\n设置即可。\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # 或 socks5://127.0.0.1:1080\nproxy_username = \"\" # 代理无鉴权时留空\nproxy_password = \"\"\n```\n\n`proxy` 同时接受 `http://` 和 `socks5://` 两种 URL,鉴权可选。\n代理只作用于该 Telegram 实例的 Bot API 请求,不会影响其他平台或\n管理后台的出站。\n\n完整说明见 [docs/telegram.md](./telegram.md#21-optional-use-a-proxy)(英文原文,\n`docs/telegram.md` 目前只有英文版)。该配置由 PR #389 引入。\n"}, "ae8913c9b4bf0889e001cda8550936bd8c24410c": {"t": 1785763843.2766087, "n": 24159, "h": "cd9ea2c18d89959c", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [Shell 配置](#shell-配置)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## Shell 配置\n\n默认情况下,cc-connect 在 Unix 上使用 `sh`,Windows 上使用 `powershell.exe` 来执行所有 shell 命令(`/shell`、cron exec、hooks 和 webhook exec)。你可以配置使用其他 shell。\n\n### 支持的 Shell\n\n| Shell | 配置值 | 参数标志 |\n|-------|--------|---------|\n| sh(Unix 默认) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd(Windows) | `cmd` | `/C` |\n| PowerShell(Windows 默认) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\n参数标志会根据 shell 名称自动检测,无需手动配置。\n\n### 全局配置\n\n在 `config.toml` 顶层设置 `shell`,更改所有项目的默认 shell:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### 项目级覆盖\n\n为特定项目覆盖 shell:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\n使用 `shell_profile` 在每条 shell 命令前添加初始化脚本。适用于加载 shell profile,使自定义函数、别名和环境变量可用:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nshell profile 和用户命令会用换行符拼接后作为一个整体脚本传给 shell,避免引号转义问题。例如 `/shell echo $MY_VAR` 实际执行的是:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` 同样支持项目级覆盖:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### 影响范围\n\nShell 配置适用于 cc-connect 中所有命令执行路径:\n\n- **`/shell` 命令** — 聊天中的交互式 shell 命令\n- **Cron exec 任务** — `[[cron]]` 中 `exec` 字段的定时任务\n- **Hooks** — `[[hooks]]` 中 `type = \"command\"` 的钩子\n- **Webhook exec** — webhook 请求中 `exec` 字段的命令\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n\n---\n\n## 常见问题(FAQ)\n\n下面这些是 issue 区里反复出现、维护者已经回答过的问题。每条都附上了\n原始 issue / PR 链接,方便继续深入。\n\n### cc-connect 是否支持 OpenClaw?(issue #501)\n\n支持。OpenClaw 通过 [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents) 接入。\ncc-connect 内置了 `acp` agent 类型,可以和任何 ACP 兼容的 CLI 通信,\n包括 OpenClaw 的 `openclaw acp` 子命令。\n\n最小配置示例(完整版见 `config.example.toml` 中 `# --- Example:\nOpenClaw (Gateway-backed ACP bridge) ---` 段):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**远端 Gateway 必须先完成配对授权。** 如果你把 cc-connect 指向\n远程 OpenClaw Gateway(`args = [\"acp\", \"--url\", \"wss://...\"]`),\n必须先配对,否则所有回复都会是空消息:\n\n1. 启动 Gateway:`openclaw acp --url wss://your-gateway:18789`\n2. 另开终端执行:`openclaw pair`\n3. 在 OpenClaw UI 里同意配对请求\n4. 完成后 cc-connect 才能与已授权的 Gateway 通信\n\nOpenClaw 回复空消息几乎都是漏掉了配对步骤(issue #432)。在排查其他\n原因之前,先重跑 `openclaw pair` 并在 UI 中重新授权一次。\n参考:\n\n### 个人微信群聊 — 如何获取正确的 `chat_id`(issue #805)\n\n个人微信(`weixin` 平台)支持群聊。要把机器人绑定到某个群,需要把\n`[[projects.platforms.options]]` 里的 `chat_id` 设置为**群聊 ID**,\n而不是个人用户 ID。群聊 ID 一定以 `@chatroom` 结尾,例如:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # 群聊 ID 以 @chatroom 结尾\n```\n\n**获取群聊 ID 的方法:**\n\n1. 启动 cc-connect,并让机器人加入目标群。\n2. 让群里任意已知允许的用户在群里发一条消息。\n3. 查看 cc-connect 日志,消息到达时会打印带 `@chatroom` 后缀的\n `chat_id`。把那个值原样填到 `chat_id` 即可。\n\n把 `chat_id` 留空(或不写这个键)就表示响应机器人所在的所有聊天。\n填具体值则只响应那个群/个人。\n\n常见坑:\n\n- **「怎么把机器人加进群?」** 个人微信机器人没有\"邀请机器人入群\"\n 的 API;只能由已经扫码绑定 ilink 的微信号,在群里发起\"添加\"或把\n 机器人的二维码发到群里、让群里的人扫码添加。和把普通好友拉进群\n 一样。\n- **群里发消息机器人不响应** — 检查是否把 `chat_id` 绑到了别的用户/\n 群,或 `allow_from` 限制了别的用户,把当前用户也加入。\n- **私聊能回、群聊不回(或反之)** — 复制一份 `[[projects.platforms]]`\n 块,一份 `chat_id` 填群 ID、另一份留空,就能同时覆盖私聊和群聊。\n\n更多关于 `weixin` 平台的内容见 [docs/weixin.md](./weixin.md)。\n\n### Telegram 代理 / 出站限制 (issue #245)\n\nTelegram 平台在 `[projects.platforms.options]` 里直接支持 HTTP 和\nSOCKS5 正向代理。不需要配系统级代理或 sidecar,per Telegram 实例\n设置即可。\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # 或 socks5://127.0.0.1:1080\nproxy_username = \"\" # 代理无鉴权时留空\nproxy_password = \"\"\n```\n\n`proxy` 同时接受 `http://` 和 `socks5://` 两种 URL,鉴权可选。\n代理只作用于该 Telegram 实例的 Bot API 请求,不会影响其他平台或\n管理后台的出站。\n\n完整说明见 [docs/telegram.md](./telegram.md#21-optional-use-a-proxy)(英文原文,\n`docs/telegram.md` 目前只有英文版)。该配置由 PR #389 引入。\n"}, "6feaf90f2f8cccec2203169b4d0edc3edd538837": {"t": 1785763845.017427, "n": 21586, "h": "4527f51b309f4273", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [Shell 配置](#shell-配置)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## Shell 配置\n\n默认情况下,cc-connect 在 Unix 上使用 `sh`,Windows 上使用 `powershell.exe` 来执行所有 shell 命令(`/shell`、cron exec、hooks 和 webhook exec)。你可以配置使用其他 shell。\n\n### 支持的 Shell\n\n| Shell | 配置值 | 参数标志 |\n|-------|--------|---------|\n| sh(Unix 默认) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd(Windows) | `cmd` | `/C` |\n| PowerShell(Windows 默认) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\n参数标志会根据 shell 名称自动检测,无需手动配置。\n\n### 全局配置\n\n在 `config.toml` 顶层设置 `shell`,更改所有项目的默认 shell:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### 项目级覆盖\n\n为特定项目覆盖 shell:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\n使用 `shell_profile` 在每条 shell 命令前添加初始化脚本。适用于加载 shell profile,使自定义函数、别名和环境变量可用:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nshell profile 和用户命令会用换行符拼接后作为一个整体脚本传给 shell,避免引号转义问题。例如 `/shell echo $MY_VAR` 实际执行的是:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` 同样支持项目级覆盖:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### 影响范围\n\nShell 配置适用于 cc-connect 中所有命令执行路径:\n\n- **`/shell` 命令** — 聊天中的交互式 shell 命令\n- **Cron exec 任务** — `[[cron]]` 中 `exec` 字段的定时任务\n- **Hooks** — `[[hooks]]` 中 `type = \"command\"` 的钩子\n- **Webhook exec** — webhook 请求中 `exec` 字段的命令\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "1bd0d9529497121deae0070f1cb5daa4f36364b5": {"t": 1785763847.504085, "n": 20210, "h": "3797062f9ae207d2", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口的 Agent provider,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# 中国区账号可使用 https://api.minimaxi.com/v1\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 实现音频发送的平台,例如飞书/Lark、钉钉、Telegram、Max、微信。\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # 有效范围取决于 provider;MiniMax 通常支持 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.minimax]\napi_key = \"\" # 可留空,自动回退读取 data_dir/config/minimax.json\nbase_url = \"\" # 可留空,默认 https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片、文件与语音回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。用户明确要求“发语音”时,Agent 也可以用同一个 CLI 走 TTS 合成并发送语音。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n- 用户要求语音时用 `cc-connect send --tts` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。TTS 语音回传走 `[tts]` provider 配置,由 TTS 是否可用决定。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"你好\"\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--tts` 会合成文本并通过当前 TTS provider 发送语音。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n4. 用户自然说“发句 xx 的语音”,不想手输 slash 命令。\n\n### 注意事项\n\n- 这个命令是给“附件和语音回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "527220d924b5a60cfa9d020f3bc96516f9ba5bf7": {"t": 1785763848.9629605, "n": 19454, "h": "09cd6ca37cdc57fa", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\n如果你在 Claude Code 的 `settings.json` 中配置了 [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks),cc-connect 会读取并执行它们——匹配的 hook 可以在请求到达消息平台之前自动批准或拒绝。\n\n### 为什么 hook 会被执行两次\n\ncc-connect 使用 `--permission-prompt-tool stdio` 模式启动 Claude Code,这意味着 Claude Code 自身执行 hook 的输出会被丢弃(stdout 被协议占用)。为了让你的 hook 真正生效,cc-connect 会从 `settings.json` 中读取 hook 定义,然后**独立重新执行一次**。\n\n也就是说,每次权限请求你的 hook 命令会被执行**两次**:\n\n1. Claude Code 执行一次(结果丢弃)\n2. cc-connect 执行一次(结果生效)\n\n### LLM 类 hook 如何避免重复消耗\n\n如果你的 hook 是规则类的(例如\"拒绝 `rm -rf`\"),执行两次无所谓。但如果你的 hook 调用了 LLM(如 [ccgate](https://github.com/tak848/ccgate)),第一次执行就是在白白浪费 token。在 hook 开头加上这个判断:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect 会在不含此变量的环境下重新执行我们\nfi\n# ... 你的 hook 逻辑 ...\n```\n\ncc-connect 启动 Claude Code 子进程时会在环境中设置 `CC_CONNECT_PERMISSION_HOOK_SKIP=1`。当你的 hook 检测到这个变量时,说明它运行在 Claude Code 内部(结果会被丢弃)——跳过昂贵的逻辑即可。cc-connect 在自己执行 hook 时会剥离这个变量,所以第二次执行会正常运行。\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "1322565cb66d620c8cd8690a2f313ed72e77a007": {"t": 1785763850.8757012, "n": 18375, "h": "afdb4ddae982e2a2", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- `/dir` 属于特权命令,使用前需要在 `config.toml` 的 `[[projects]]` 下设置 `admin_from`。\n- 不要把 `admin_from` 写到 `[projects.platforms.options]` 里,否则会被忽略。\n- 可先发送 `/whoami` 或 `/status` 获取当前 `User ID`,再把这个 ID 填到 `admin_from`。\n- 如果是个人单人使用,也可以设置 `admin_from = \"*\"`,但这会让所有已允许用户都拥有特权命令权限。\n- 修改 `config.toml` 后,需要重启 `cc-connect`。\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n配置示例:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "c580b68716a7cdc6a0e6702e5782c17d074a7978": {"t": 1785763852.3351803, "n": 17997, "h": "19b02b2e96d8617b", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron exec \ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "9cf496b973f1e814b071c5a43745217b0a0385ab": {"t": 1785763853.8961573, "n": 17967, "h": "af946674e73246f1", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "57bd7be93986ca77d0b29932e5a978c0db95feeb": {"t": 1785763855.490758, "n": 17955, "h": "e451986bf18beab2", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron edit # 可改 cron_expr / prompt / enabled / mute / timeout_mins 等\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "12a6ffd11e6cccae8172b5a3f0556859f376b5a4": {"t": 1785763857.0286098, "n": 17849, "h": "89cdd94dfc4ddf1d", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n### 切换模型时保留历史\n\n`/model` 切换模型时保留当前会话——agent 会在新模型下继续对话(不额外消耗 token)。注意模型切换作用于共享的 agent 实例——如果多个平台使用同一个 project,模型变更会影响所有平台。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "6e0a2e116e4c02490fb7f4636b020a9f6c384480": {"t": 1785763858.7579288, "n": 17725, "h": "9a0c047dbacf091a", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n- 执行 Shell 命令支持 `!` 快捷前缀:`!ls -la` 等同于 `/shell ls -la`,`! --timeout 300 npm install` 可指定超时时间\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "bfb6d69780e27baaceda88560dce4f5a84c5d945": {"t": 1785763861.7848306, "n": 17632, "h": "58b395f185478942", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [引用查看(`/show`)](#引用查看show)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/show <引用>` | 按引用查看文件、目录或代码片段 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 本地引用展示配置(`[projects.references]`)\n\n可选启用对 Agent 输出中的本地文件 / 目录 / 代码位置引用进行标准化与重渲染,提升在 IM 平台中的可读性。\n\n这是一个 **opt-in** 功能:\n\n- 未配置 `[projects.references]` 时,现有行为保持不变\n- 只有命中 `normalize_agents` 和 `render_platforms` 时,才会启用\n\n### 推荐配置\n\n```toml\n[projects.references]\nnormalize_agents = [\"all\"]\nrender_platforms = [\"all\"]\ndisplay_path = \"relative\"\nmarker_style = \"emoji\"\nenclosure_style = \"code\"\n```\n\n### 字段说明\n\n- `normalize_agents`\n - 控制哪些 Agent 输出参与这套引用处理\n - 当前初始支持:`codex`、`claudecode`、`all`\n\n- `render_platforms`\n - 控制在哪些平台发送前应用展示重写\n - 当前初始支持:`feishu`、`weixin`、`all`\n\n- `display_path`\n - 控制路径主体的显示层级\n - 可选值:`absolute`、`relative`、`basename`、`dirname_basename`、`smart`\n\n- `marker_style`\n - 控制前缀标记样式\n - 可选值:`none`、`ascii`、`emoji`\n\n- `enclosure_style`\n - 控制路径主体的包裹样式\n - 可选值:`none`、`bracket`、`angle`、`fullwidth`、`code`\n\n### 支持的引用输入\n\n当前初始支持识别这些常见形式:\n\n- 绝对路径\n- 相对路径\n- 文件 / 目录引用\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接\n- Claude 风格的反引号绝对路径引用\n\n### 行为说明\n\n- 只处理 Agent 输出:\n - thinking\n - final response\n - stream preview\n - progress / card 中的 Agent 文本\n\n- 不处理:\n - 系统消息\n - `/workspace`、`/dir`、`/status` 等命令回复\n - raw tool result\n\n- 网页链接会保持原样,不会被本地引用重写逻辑污染\n\n### 推荐默认值说明\n\n当前最推荐的组合是:\n\n- `display_path = \"relative\"`\n- `marker_style = \"emoji\"`\n- `enclosure_style = \"code\"`\n\n这样通常会得到类似:\n\n- `📄 ui/recovery_contact_form.tsx:11`\n- `📁 docs/spec.v1/`\n\n如果不希望使用 emoji,更推荐:\n\n- `display_path = \"dirname_basename\"`\n- `marker_style = \"ascii\"`\n- `enclosure_style = \"code\"`\n\n---\n\n## 引用查看(`/show`)\n\n可直接基于一个文件 / 目录 / 代码位置引用查看内容,而不必手写 `/shell sed ...`。\n\n### 聊天命令\n\n```text\n/show <路径> 查看文件前 80 行\n/show <路径:行号> 查看该行附近上下文\n/show <路径:起止行> 查看指定 range\n/show <目录路径/> 查看一级目录列表\n```\n\n支持的输入形式包括:\n\n- 绝对路径\n- 相对路径(相对当前 Agent 工作目录)\n- `path:line`\n- `path:line:col`\n- `path:start-end`\n- `path#L42`\n- Markdown 本地文件链接,如:\n - `[file.ts](/abs/path/file.ts#L42)`\n\n### 行为说明\n\n- 文件,无位置:\n - 默认显示文件前 80 行\n- `path:line` / `path#L42`:\n - 默认显示该位置附近上下文\n- `path:start-end`:\n - 默认显示该 range\n- 目录:\n - 默认显示一级目录内容\n\n说明:\n\n- `/show` 只解析“纯引用文本”,不解析前端展示层包装后的 `📄 ...` / `[FILE] ...` 这类样式\n- `/show` 属于本地文件系统查看命令,与 `/shell`、`/dir` 类似,默认受 `admin_from` 权限控制\n\n示例:\n\n```text\n/show ui/recovery_contact_form.tsx\n/show svc/recovery_session_reconciler.go:12\n/show svc/recovery_session_reconciler_test.go:8-17\n/show docs/spec.v1/\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "a0a7cc50f7e6137e893ce0a08d5b3654c423096e": {"t": 1785763863.3127832, "n": 15219, "h": "936eae5eb8246b57", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "d76639360cb4d67483dd9dee525aa4dd2240fa8e": {"t": 1785763865.1353016, "n": 15246, "h": "665323cd599c15e2", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n也可以为项目开启“空闲后自动切换新会话”:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\n开启后,如果用户长时间未发消息,下一条普通消息会自动进入一个新的会话;旧会话仍会保留在 `/list` 中,不会被删除。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "59098aaa2755d9b4780fe746c3de37a78fd7e8a5": {"t": 1785763867.1092026, "n": 15097, "h": "d4709250fcf59cdc", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n- 运行时平台配置还支持可选 `domain` 覆盖 Feishu/Lark API 域名;这不会改变 `setup/new/bind` 的引导地址。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "5a9cf6ef2a7620a4945c5cdc9f94c5fdbfb69f8d": {"t": 1785763868.652892, "n": 15021, "h": "3084533597adadf3", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [Web 管理后台(Beta)](#web-管理后台beta)\n- [Bridge — 外部适配器接入(Beta)](#bridge--外部适配器接入beta)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## Web 管理后台(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,UI 和 API 在后续版本中可能调整。\n\n内嵌在二进制中的全功能管理界面,支持项目管理、会话管理、定时任务编辑、全局设置、聊天界面、多语言等。\n\n### 快速启用(聊天命令)\n\n最简单的方式,在聊天中发送:\n\n```\n/web setup\n```\n\n该命令会自动在 `config.toml` 中启用 **Management API** 和 **Bridge**,生成 token,并返回访问地址。首次启用后需要执行 `/restart` 使配置生效。\n\n启用后,打开返回的地址(默认 `http://localhost:9820`),用显示的 token 登录即可。\n\n### 查看状态\n\n```\n/web # 或 /web status — 查看 Web 管理后台的地址和启用状态\n```\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[management]\nenabled = true\nport = 9820 # 管理后台监听端口\ntoken = \"your-secret-token\" # 登录 token;/web setup 会自动生成\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS 头\n```\n\n然后重启 cc-connect。\n\n### 构建选项\n\nWeb 前端资源默认编译进二进制。如果想排除(减小约 1MB):\n\n```bash\nmake build-noweb\n# 或\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\n使用 `no_web` 构建时,`/web` 命令会提示 Web 管理后台不可用。\n\n### Management API\n\nAPI 与 Web UI 共用同一端口。基础 URL:`http://:/api/v1`\n\n所有 API 请求需要 `Authorization: Bearer ` 请求头。\n\n主要接口:\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/api/v1/status` | 系统状态(版本、运行时间、已连接平台) |\n| `POST` | `/api/v1/restart` | 重启 cc-connect |\n| `POST` | `/api/v1/reload` | 重新加载配置 |\n| `GET` | `/api/v1/projects` | 项目列表 |\n| `GET` | `/api/v1/sessions?project=` | 查询项目的会话列表 |\n| `GET` | `/api/v1/cron` | 定时任务列表 |\n| `GET` | `/api/v1/settings` | 获取全局设置 |\n| `PATCH` | `/api/v1/settings` | 更新全局设置 |\n\n完整 API 参考:[management-api.md](./management-api.md)([中文版](./management-api.zh-CN.md))\n\n---\n\n## Bridge — 外部适配器接入(Beta)\n\n> **状态:Beta。** 此功能自 v1.2.2-beta.5 起可用,协议在后续版本中可能调整。\n\nBridge 提供 WebSocket + REST 服务,让外部适配器(自定义 UI、机器人、脚本等)可以接入 cc-connect —— 发送消息、接收 Agent 事件、管理会话。\n\n### 通过聊天启用\n\n`/web setup` 命令会同时启用 Bridge 和管理后台,无需额外操作。\n\n### 手动配置\n\n在 `config.toml` 中添加:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge 监听端口(与管理后台分开)\ntoken = \"your-bridge-secret\" # WebSocket 和 REST 的认证 token\npath = \"/bridge/ws\" # WebSocket 端点路径\ncors_origins = [\"*\"] # 允许的 CORS 来源;留空则不设置 CORS\n```\n\n然后重启 cc-connect。\n\n### 认证方式\n\n所有 Bridge 连接需要 token 认证,支持三种方式:\n\n- URL 参数:`?token=`\n- 请求头:`Authorization: Bearer `\n- 请求头:`X-Bridge-Token: `\n\n### WebSocket 接入\n\n连接地址:\n\n```\nws://:/bridge/ws?token=\n```\n\nWebSocket 支持双向通信 —— 向 Agent 发送消息,并实时接收 Agent 的文本回复、工具调用、权限请求等事件。\n\n### REST API\n\n与 WebSocket 共用同一端口。\n\n| 方法 | 路径 | 说明 |\n|------|------|------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | 查询会话列表 |\n| `POST` | `/bridge/sessions` | 创建新会话 |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | 获取会话详情及历史 |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | 删除会话 |\n| `POST` | `/bridge/sessions/switch` | 切换当前活跃会话 |\n\n完整协议参考:[bridge-protocol.md](./bridge-protocol.md)([中文版](./bridge-protocol.zh-CN.md))\n\n### 端口汇总\n\n| 服务 | 默认端口 | 配置块 |\n|------|---------|--------|\n| 管理后台(Web UI + API) | 9820 | `[management]` |\n| Bridge(WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "1225b7ee187e3ff58d35e501318b4fae36a3cbe3": {"t": 1785763869.8981123, "n": 11999, "h": "9a336f801ac44501", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 自动模式 | `auto` | 由 Claude 自动判断何时需要确认 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO 模式\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "fa9280b54350673de2e15ddd91337b74f97fb562": {"t": 1785763871.2611675, "n": 11956, "h": "586fb38f2588a77b", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [工作目录切换(`/dir`、`/cd`)](#工作目录切换dircd)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/dir [路径]` | 查看或切换 Agent 工作目录 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 工作目录切换(`/dir`、`/cd`)\n\n可直接在聊天中切换 Agent 下一次会话的工作目录。\n\n### 聊天命令\n\n```\n/dir 查看当前工作目录和最近历史\n/dir <路径> 切换到指定路径(相对或绝对)\n/dir <序号> 按历史序号切换目录\n/dir - 返回上一个目录\n/dir help 查看命令用法\n/cd <路径> `/dir <路径>` 的兼容别名\n```\n\n### 行为说明\n\n- 目录切换会作用于当前项目的下一次会话。\n- 相对路径基于当前 Agent 工作目录解析。\n- 目录历史按项目隔离,可通过序号快速切换。\n- `/cd` 为兼容保留,建议优先使用 `/dir`。\n\n示例:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "00b719d21520ae6b1e0f2d3ed0a49c69b474b7f6": {"t": 1785763872.682568, "n": 11431, "h": "4d4ade1325f74806", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [飞书配置 CLI](#飞书配置-cli)\n- [微信个人号配置 CLI](#微信个人号配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## 微信个人号配置 CLI\n\n个人微信走 **ilink 机器人网关**(HTTP 长轮询,与 OpenClaw `openclaw-weixin` 同类)。可直接用 CLI 扫码登录或绑定已有 Token,并写回 `config.toml`。\n\n**完整图文流程与配置项说明见:[docs/weixin.md](./weixin.md)。**\n\n```bash\n# 推荐:终端展示二维码 + URL,微信扫码确认后自动写配置\ncc-connect weixin setup --project my-project\n\n# 已有 Bearer Token(例如从 OpenClaw 导出)\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin setup --project my-project --token ''\n\n# 强制只走扫码(不接受 --token)\ncc-connect weixin new --project my-project\n```\n\n区别说明:\n\n- `setup`:未传 `--token` 时走扫码;传了 `--token` 时等同绑定并可选校验。\n- `new`:强制扫码。\n- `bind`:强制绑定,必须 `--token`。\n\n行为说明:\n\n- `--project` 不存在时会自动创建项目;项目里没有 `weixin` 平台时会自动追加一块 `[[projects.platforms]]`。\n- 扫码成功后会写入 `token`,以及网关返回的 `base_url`(若有)、`ilink_bot_id` → `account_id` 等。\n- 默认 `--set-allow-from-empty=true`:若 `allow_from` 为空,会用扫码用户的 ilink ID 预填,便于收紧权限。\n- 绑定时默认调用 `getUpdates` 校验 Token;可用 `--skip-verify` 跳过。\n- 首次使用后请在微信里 **先发一条消息**,以便缓存 `context_token`,否则可能无法回复。\n\n常用参数:`--api-url`、`--cdn-url`、`--timeout`、`--qr-image`、`--route-tag`、`--bot-type`、`--debug`(详见 `cc-connect weixin help` 或 [weixin.md](./weixin.md))。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "253a7a73e8c3089f00dd2d69b2bfcedd0461dd02": {"t": 1785763874.1358242, "n": 10292, "h": "d178c21ffdb7cd35", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n可选:`--session-mode new-per-run` 每次触发使用新的 agent 会话(默认 `reuse` 与旧行为一致)。`--timeout-mins N` 设置单次调度最长等待分钟数(`0` 表示不限制;省略为 30 分钟)。\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "9df8d494ddd43a7e836fc8cea6b634b542875d5e": {"t": 1785763875.8245616, "n": 10167, "h": "b9b5b7b670a78561", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [switch ]` | 列出可用模型或按别名切换 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model switch 按别名切换模型\n/model switch 按完整名称切换模型\n/model 兼容旧写法,仍然可用\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "50e22d44be1b50da3ac72a823648600036d82ea4": {"t": 1785763878.1935582, "n": 10106, "h": "8a2019ecbd729de5", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [alias]` | 列出可用模型或按别名切换 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,1M 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model 按别名切换模型\n/model 按完整名称切换模型\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "80ce4a5632941082471401cabe50a62e0523ab1a": {"t": 1785763881.5363245, "n": 10108, "h": "41f7a4dd5fccf35b", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [模型选择](#模型选择)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/model [alias]` | 列出可用模型或按别名切换 |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — 兼容 OpenAI 接口,204K 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 模型选择\n\n通过 `[[providers.models]]` 为每个 Provider 预配置可选模型列表。每个条目包含 `model`(模型标识符)和可选的 `alias`(别名,显示在 `/model` 中)。\n\n### 配置模型\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### 聊天命令\n\n```\n/model 列出可用模型(格式:alias - model)\n/model 按别名切换模型\n/model 按完整名称切换模型\n```\n\n配置了 `models` 时,`/model` 直接显示该列表,不发起 API 请求。未配置时,自动从 Provider API 获取或使用内置备选列表。\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "db8f5f4c00b6e3d2686972d1dcd6b5b049c64f64": {"t": 1785763882.7953148, "n": 9158, "h": "6a3dd5db4033d872", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [图片与文件回传](#图片与文件回传)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — 兼容 OpenAI 接口,204K 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 图片与文件回传\n\n当 Agent 在本地生成了图片、PDF、日志包、报表等文件,需要把结果直接发回当前聊天时,可以使用 `cc-connect send` 的附件模式。\n\n**当前支持平台:**\n- 飞书\n- Telegram\n\n### 什么时候需要先执行 setup\n\n如果当前 Agent 不是“原生 system prompt 注入”类型,升级到包含该功能的版本后,建议先在聊天里执行一次:\n\n```text\n/bind setup\n```\n\n或者:\n\n```text\n/cron setup\n```\n\n这两个命令写入的是同一份 cc-connect 指令。执行任意一个即可。这样 Agent 才会知道:\n- 普通文本回复直接正常输出\n- 生成附件后用 `cc-connect send --image/--file` 回传\n\n如果你以前已经执行过 setup,也建议升级后重新执行一次,以刷新到最新指令。\n\n### 配置开关\n\n如果你想禁用 agent 主动回传附件,可以在 `config.toml` 里加入:\n\n```toml\nattachment_send = \"off\"\n```\n\n默认值是 `on`。这个开关与 agent 的 `/mode` 独立,只影响 `cc-connect send --image/--file` 这条图片/文件回传路径。\n\n### CLI 用法\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\n说明:\n- `--image` 用于图片附件。\n- `--file` 用于任意文件附件。\n- `--message` 可选,用于先发一段说明文字,再发附件。\n- `--image` 和 `--file` 都可以重复多次。\n- 建议使用绝对路径,避免 Agent 当前工作目录变化导致找不到文件。\n- 如果设置了 `attachment_send = \"off\"`,图片/文件回传会被拒绝,但普通文本回复仍然正常。\n\n### 典型场景\n\n1. Agent 生成了截图或图表,需要直接发给用户。\n2. Agent 生成了 PDF、Markdown 导出、日志包或补丁文件,需要作为附件交付。\n3. Agent 想告诉用户“结果已生成”,同时附上一个或多个文件。\n\n### 注意事项\n\n- 这个命令是给“附件回传”用的,不要拿它代替普通文本回复。\n- 只能发送本机上 Agent 可访问到的文件。\n- 必须存在活跃会话;如果当前项目没有活动聊天上下文,命令会失败。\n- 平台本身仍可能有文件大小或文件类型限制。\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。对依赖记忆文件的其他 Agent,先执行一次 `/cron setup` 或 `/bind setup`,效果相同。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "2f01442f75e37b74db7f61ae3332fd8134d3edec": {"t": 1785763885.3241694, "n": 7814, "h": "9bd5c8baba5ea7f7", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [飞书配置 CLI](#飞书配置-cli)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — 兼容 OpenAI 接口,204K 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## 飞书配置 CLI\n\n可以直接通过 CLI 完成飞书/Lark 机器人创建或关联,并自动写回 `config.toml`:\n\n```bash\n# 推荐:统一入口\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# 强制模式(一般不需要)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\n区别说明:\n- `setup`:统一入口。没传凭证时等价 `new`,传了 `--app` 时等价 `bind`。\n- `new`:强制二维码新建,不接受 `--app`。\n- `bind`:强制关联已有机器人,必须提供凭证。\n\n行为说明(通用):\n- `setup` 默认走二维码新建;传入 `--app` 时自动切换到关联已有机器人。\n- `--project` 不存在会自动创建。\n- 项目存在但没有 `feishu/lark` 平台时会自动补一个平台配置。\n- 命令会回填凭证(`app_id` / `app_secret`);扫码新建场景下飞书通常会预配权限和事件订阅。\n- 建议在飞书开放平台再核验一次发布状态与可用范围。\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "8817e58f81b2c0559bef19d479da05f0a093019c": {"t": 1785763886.5147471, "n": 7142, "h": "4bd4e7c681938e17", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — 兼容 OpenAI 接口,204K 超长上下文\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}, "334c58bbfbd510ef48ef674e7d9a081b6f05c1e9": {"t": 1785763887.937531, "n": 6964, "h": "09b3d4c0b0aebe31", "c": "# 使用指南\n\ncc-connect 完整功能使用指南。\n\n## 目录\n\n- [会话管理](#会话管理)\n- [权限模式](#权限模式)\n- [API Provider 管理](#api-provider-管理)\n- [Claude Code Router 集成](#claude-code-router-集成)\n- [语音消息(语音转文字)](#语音消息语音转文字)\n- [语音回复(文字转语音)](#语音回复文字转语音)\n- [定时任务 (Cron)](#定时任务-cron)\n- [多机器人中继](#多机器人中继)\n- [守护进程模式](#守护进程模式)\n- [多工作区模式](#多工作区模式)\n- [配置参考](#配置参考)\n\n---\n\n## 会话管理\n\n每个用户拥有独立的会话和完整的对话上下文。通过斜杠命令管理:\n\n| 命令 | 说明 |\n|------|------|\n| `/new [名称]` | 创建新会话 |\n| `/list` | 列出当前项目的会话 |\n| `/switch ` | 切换到指定会话 |\n| `/current` | 查看当前会话 |\n| `/history [n]` | 查看最近 n 条消息 |\n| `/usage` | 查看账号/模型限额使用情况 |\n| `/provider [...]` | 管理 API Provider |\n| `/allow <工具名>` | 预授权工具 |\n| `/reasoning [等级]` | 查看或切换推理强度(Codex)|\n| `/mode [名称]` | 查看或切换权限模式 |\n| `/quiet` | 开关思考/工具进度消息 |\n| `/stop` | 停止当前执行 |\n| `/help` | 显示可用命令 |\n\n会话中 Agent 请求工具权限时,回复 **允许** / **拒绝** / **允许所有**。\n\n---\n\n## 权限模式\n\n所有 Agent 支持运行时切换权限模式,通过 `/mode` 命令。\n\n### Claude Code 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次工具调用需确认 |\n| 接受编辑 | `acceptEdits` / `edit` | 文件编辑自动通过 |\n| 计划模式 | `plan` | 只规划不执行 |\n| YOLO | `bypassPermissions` / `yolo` | 全部自动通过 |\n\n### Codex 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 建议 | `suggest` | 仅受信命令自动执行 |\n| 自动编辑 | `auto-edit` | 模型自行决定 |\n| 全自动 | `full-auto` | 自动通过 + 沙箱保护 |\n| YOLO | `yolo` | 跳过所有审批 |\n\n### Cursor Agent 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 工具调用前询问 |\n| 强制执行 | `force` / `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读分析 |\n| 问答模式 | `ask` | 问答风格,只读 |\n\n### Gemini CLI 模式\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 每次需确认 |\n| 自动编辑 | `auto_edit` / `edit` | 编辑自动通过 |\n| 全自动 | `yolo` | 自动批准所有 |\n| 规划模式 | `plan` | 只读规划 |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| 模式 | 配置值 | 行为 |\n|------|--------|------|\n| 默认 | `default` | 标准权限 |\n| YOLO | `yolo` | 跳过所有检查 |\n\n### 配置示例\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\n运行时切换:\n```\n/mode # 查看当前和可用模式\n/mode yolo # 切换到 YOLO\n/mode default # 切回默认\n```\n\n---\n\n## API Provider 管理\n\n运行时切换 API Provider,无需重启。\n\n### 配置 Provider\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\"\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# Bedrock、Vertex 等\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI 命令\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # 从 cc-switch 导入\n```\n\n### 聊天命令\n\n```\n/provider 查看当前 Provider\n/provider list 列出所有\n/provider add <名称> [url] [model]\n/provider remove <名称>\n/provider switch <名称>\n/provider <名称> 切换快捷方式\n```\n\n### 环境变量映射\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | 使用 `env` 字段 |\n| OpenCode | `ANTHROPIC_API_KEY` | 使用 `env` 字段 |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Claude Code Router 集成\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) 可将请求路由到不同模型提供商。\n\n### 安装配置\n\n1. 安装:`npm install -g @musistudio/claude-code-router`\n\n2. 配置 `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. 启动:`ccr start`\n\n4. 配置 cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\"\n```\n\n---\n\n## 语音消息(语音转文字)\n\n发送语音消息,自动转文字。\n\n**支持平台:** 飞书、企业微信、Telegram、LINE、Discord、Slack\n\n**前置条件:** OpenAI/Groq API Key,`ffmpeg`\n\n### 配置\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # 或 \"groq\"\nlanguage = \"\" # \"zh\"、\"en\" 或留空自动检测\n\n[speech.openai]\napi_key = \"sk-xxx\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### 安装 ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## 语音回复(文字转语音)\n\n将 AI 回复合成语音发送。\n\n**支持平台:** 飞书\n\n### 配置\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # 或 \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n```\n\n### TTS 模式\n\n| 模式 | 行为 |\n|------|------|\n| `voice_only` | 仅当用户发语音时才语音回复 |\n| `always` | 始终语音回复 |\n\n切换:`/tts always` 或 `/tts voice_only`\n\n---\n\n## 定时任务 (Cron)\n\n创建自动执行的定时任务。\n\n### 聊天命令\n\n```\n/cron 列出所有任务\n/cron add <分> <时> <日> <月> <周> <任务描述> 创建任务\n/cron del 删除任务\n/cron enable 启用\n/cron disable 禁用\n```\n\n示例:\n```\n/cron add 0 6 * * * 帮我收集 GitHub trending 并总结\n```\n\n### CLI 命令\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"总结 GitHub trending\" --desc \"每日趋势\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### 自然语言(Claude Code)\n\n> \"每天早上6点帮我总结 GitHub trending\"\n\nClaude Code 会自动创建定时任务。\n\n---\n\n## 多机器人中继\n\n跨平台机器人通信,群聊多机器人协作。\n\n### 群聊绑定\n\n```\n/bind 查看绑定\n/bind claudecode 添加 claudecode 项目\n/bind gemini 添加 gemini 项目\n/bind -claudecode 移除 claudecode\n```\n\n### 机器人间通信\n\n```bash\ncc-connect relay send --to gemini \"你觉得这个架构怎么样?\"\n```\n\n---\n\n## 守护进程模式\n\n后台服务运行。\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## 多工作区模式\n\n一个 bot 服务多个工作区,每个频道一个独立工作目录。\n\n### 配置\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### 命令\n\n```\n/workspace 查看当前绑定\n/workspace bind <名称> 绑定本地文件夹\n/workspace init 克隆仓库并绑定\n/workspace unbind 解除绑定\n/workspace list 列出所有绑定\n```\n\n### 工作原理\n\n- 频道名 `#project-a` → 自动绑定 `base_dir/project-a/`\n- 每个频道有独立的会话和 Agent 状态\n\n---\n\n## 配置参考\n\n完整配置示例见 [config.example.toml](../config.example.toml)。\n\n### 项目结构\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # 或 codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # 或 dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# 平台特定配置\n```\n"}}, "docs/usage.md": {"f2e4ed83c6953297a92d66d49114196fc4402206": {"t": 1785746545.9439104, "n": 42534, "h": "74db63096f771f61", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Shell Configuration](#shell-configuration)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10; each entry follows `[display].history_max_len`, default 1000) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n- Each attachment is capped at **50 MiB** by default. Configure it with `max_attachment_size_mb` (MiB) in config.toml, or override that value with the `CC_MAX_ATTACHMENT_SIZE_MB` env var (same MiB unit; takes precedence when set), e.g. `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- The target platform also enforces its own file-size/type limit at delivery; the effective per-attachment ceiling is the smaller of that limit and `max_attachment_size_mb` (a file that passes cc-connect may still be rejected by the platform).\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Shell Configuration\n\nBy default, cc-connect uses `sh` on Unix and `powershell.exe` on Windows for all shell execution (`/shell` commands, cron exec jobs, hooks, and webhook exec). You can override this to use a different shell.\n\n### Supported Shells\n\n| Shell | Config value | Flag |\n|-------|-------------|------|\n| sh (default on Unix) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd (Windows) | `cmd` | `/C` |\n| PowerShell (default on Windows) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\nThe flag is auto-detected from the shell name — no manual configuration needed.\n\n### Global Configuration\n\nSet `shell` at the top level of `config.toml` to change the default for all projects:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### Per-Project Override\n\nOverride the shell for a specific project:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\nUse `shell_profile` to prepend a setup script to every shell command. This is useful for sourcing your shell profile so that custom functions, aliases, and environment variables are available:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nThe shell profile and the user's command are joined with a newline and passed as a single script to the shell, avoiding quoting issues. For example, `/shell echo $MY_VAR` becomes:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` also supports per-project override:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### Affected Execution Paths\n\nThe shell configuration applies to all command execution in cc-connect:\n\n- **`/shell` command** — interactive shell commands from chat\n- **Cron exec jobs** — `[[cron]]` entries with `exec` field\n- **Hooks** — `[[hooks]]` entries with `type = \"command\"`\n- **Webhook exec** — webhook requests with `exec` field\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n\n---\n\n## FAQ\n\nQuick answers to questions that came up repeatedly in issues and that the\nmaintainers have resolved. Each entry links back to the originating issue\nor PR so you can dig further if needed.\n\n### Does cc-connect support OpenClaw? (issue #501)\n\nYes. OpenClaw is supported via the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents). cc-connect ships an `acp` agent type that talks to any ACP-compatible CLI, including OpenClaw's `openclaw acp` subcommand.\n\nMinimal config snippet (full version is in `config.example.toml` under\n`# --- Example: OpenClaw (Gateway-backed ACP bridge) ---`):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**Pairing is required for remote gateways.** If you point cc-connect at a\nremote OpenClaw Gateway (`args = [\"acp\", \"--url\", \"wss://...\"]`) you must\npair first or every reply comes back empty:\n\n1. Start the gateway: `openclaw acp --url wss://your-gateway:18789`\n2. In another terminal: `openclaw pair`\n3. Approve the pairing request in the OpenClaw UI\n4. Now cc-connect can talk to the authorized gateway\n\nEmpty responses from OpenClaw are almost always a missing pairing step\n(issue #432). Re-run `openclaw pair` and re-approve before debugging\nanything else. Reference: \n\n### Personal WeChat group chat — finding the right `chat_id` (issue #805)\n\nPersonal WeChat (the `weixin` platform) supports group chats. To bind the\nbot to a specific group, set `chat_id` in `[[projects.platforms.options]]`\nto the **group chat ID**, not an individual user ID. Group chat IDs always\nend with `@chatroom`, for example:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # group chats end with @chatroom\n```\n\n**How to find the group chat ID:**\n\n1. Start cc-connect and let the bot be in the target group.\n2. Send any message in the group from a known allowed account.\n3. Check the cc-connect logs — the incoming `chat_id` (ending in\n `@chatroom`) is logged at the moment the message is received. Copy\n that value into `chat_id`.\n\nLeave `chat_id` empty (or omit the key) to respond to every chat the bot\nis in. Set it to a specific value to restrict the bot to that group or\nuser only.\n\nCommon pitfalls:\n\n- **\"How do I add the bot to a group?\"** Personal WeChat bots are added\n by scanning the QR code *inside* the group with the linked WeChat\n account, or by sharing the QR via the personal chat and then opening\n it inside the target group. There is no API-side \"invite bot to group\"\n call; the bot becomes a group member the same way any other WeChat\n contact does.\n- **Bot never receives group messages** — make sure the group is bound\n to your cc-connect instance. If `allow_from` is set, the first user\n to message in the group is recorded; if the binding is to a\n different user, the bot stays silent.\n- **Bot replies in private but ignores the group (or vice versa)** —\n duplicate the `[[projects.platforms]]` block, one with `chat_id` set\n to the group and one without, to cover both surfaces.\n\nFor more on the `weixin` platform, see [docs/weixin.md](./weixin.md).\n\n### Telegram proxy / outbound restrictions (issue #245)\n\nThe Telegram platform supports HTTP and SOCKS5 forward proxies directly in\n`[projects.platforms.options]`. You do not need a system-wide proxy or a\nsidecar — set the proxy per Telegram instance.\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # or socks5://127.0.0.1:1080\nproxy_username = \"\" # leave empty if no auth\nproxy_password = \"\"\n```\n\n`proxy` accepts both `http://` and `socks5://` URLs. Authentication is\noptional. The proxy only affects the Telegram Bot API calls for that\nplatform instance; other platforms and the management API are not\ntunneled through it.\n\nFull reference: [docs/telegram.md](./telegram.md#21-optional-use-a-proxy).\nThis option was added in PR #389.\n"}, "fa86932f29dcb12cae6ff857b4f6de643539d0aa": {"t": 1785763838.5066733, "n": 42534, "h": "74db63096f771f61", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Shell Configuration](#shell-configuration)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10; each entry follows `[display].history_max_len`, default 1000) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n- Each attachment is capped at **50 MiB** by default. Configure it with `max_attachment_size_mb` (MiB) in config.toml, or override that value with the `CC_MAX_ATTACHMENT_SIZE_MB` env var (same MiB unit; takes precedence when set), e.g. `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- The target platform also enforces its own file-size/type limit at delivery; the effective per-attachment ceiling is the smaller of that limit and `max_attachment_size_mb` (a file that passes cc-connect may still be rejected by the platform).\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Shell Configuration\n\nBy default, cc-connect uses `sh` on Unix and `powershell.exe` on Windows for all shell execution (`/shell` commands, cron exec jobs, hooks, and webhook exec). You can override this to use a different shell.\n\n### Supported Shells\n\n| Shell | Config value | Flag |\n|-------|-------------|------|\n| sh (default on Unix) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd (Windows) | `cmd` | `/C` |\n| PowerShell (default on Windows) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\nThe flag is auto-detected from the shell name — no manual configuration needed.\n\n### Global Configuration\n\nSet `shell` at the top level of `config.toml` to change the default for all projects:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### Per-Project Override\n\nOverride the shell for a specific project:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\nUse `shell_profile` to prepend a setup script to every shell command. This is useful for sourcing your shell profile so that custom functions, aliases, and environment variables are available:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nThe shell profile and the user's command are joined with a newline and passed as a single script to the shell, avoiding quoting issues. For example, `/shell echo $MY_VAR` becomes:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` also supports per-project override:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### Affected Execution Paths\n\nThe shell configuration applies to all command execution in cc-connect:\n\n- **`/shell` command** — interactive shell commands from chat\n- **Cron exec jobs** — `[[cron]]` entries with `exec` field\n- **Hooks** — `[[hooks]]` entries with `type = \"command\"`\n- **Webhook exec** — webhook requests with `exec` field\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n\n---\n\n## FAQ\n\nQuick answers to questions that came up repeatedly in issues and that the\nmaintainers have resolved. Each entry links back to the originating issue\nor PR so you can dig further if needed.\n\n### Does cc-connect support OpenClaw? (issue #501)\n\nYes. OpenClaw is supported via the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents). cc-connect ships an `acp` agent type that talks to any ACP-compatible CLI, including OpenClaw's `openclaw acp` subcommand.\n\nMinimal config snippet (full version is in `config.example.toml` under\n`# --- Example: OpenClaw (Gateway-backed ACP bridge) ---`):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**Pairing is required for remote gateways.** If you point cc-connect at a\nremote OpenClaw Gateway (`args = [\"acp\", \"--url\", \"wss://...\"]`) you must\npair first or every reply comes back empty:\n\n1. Start the gateway: `openclaw acp --url wss://your-gateway:18789`\n2. In another terminal: `openclaw pair`\n3. Approve the pairing request in the OpenClaw UI\n4. Now cc-connect can talk to the authorized gateway\n\nEmpty responses from OpenClaw are almost always a missing pairing step\n(issue #432). Re-run `openclaw pair` and re-approve before debugging\nanything else. Reference: \n\n### Personal WeChat group chat — finding the right `chat_id` (issue #805)\n\nPersonal WeChat (the `weixin` platform) supports group chats. To bind the\nbot to a specific group, set `chat_id` in `[[projects.platforms.options]]`\nto the **group chat ID**, not an individual user ID. Group chat IDs always\nend with `@chatroom`, for example:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # group chats end with @chatroom\n```\n\n**How to find the group chat ID:**\n\n1. Start cc-connect and let the bot be in the target group.\n2. Send any message in the group from a known allowed account.\n3. Check the cc-connect logs — the incoming `chat_id` (ending in\n `@chatroom`) is logged at the moment the message is received. Copy\n that value into `chat_id`.\n\nLeave `chat_id` empty (or omit the key) to respond to every chat the bot\nis in. Set it to a specific value to restrict the bot to that group or\nuser only.\n\nCommon pitfalls:\n\n- **\"How do I add the bot to a group?\"** Personal WeChat bots are added\n by scanning the QR code *inside* the group with the linked WeChat\n account, or by sharing the QR via the personal chat and then opening\n it inside the target group. There is no API-side \"invite bot to group\"\n call; the bot becomes a group member the same way any other WeChat\n contact does.\n- **Bot never receives group messages** — make sure the group is bound\n to your cc-connect instance. If `allow_from` is set, the first user\n to message in the group is recorded; if the binding is to a\n different user, the bot stays silent.\n- **Bot replies in private but ignores the group (or vice versa)** —\n duplicate the `[[projects.platforms]]` block, one with `chat_id` set\n to the group and one without, to cover both surfaces.\n\nFor more on the `weixin` platform, see [docs/weixin.md](./weixin.md).\n\n### Telegram proxy / outbound restrictions (issue #245)\n\nThe Telegram platform supports HTTP and SOCKS5 forward proxies directly in\n`[projects.platforms.options]`. You do not need a system-wide proxy or a\nsidecar — set the proxy per Telegram instance.\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # or socks5://127.0.0.1:1080\nproxy_username = \"\" # leave empty if no auth\nproxy_password = \"\"\n```\n\n`proxy` accepts both `http://` and `socks5://` URLs. Authentication is\noptional. The proxy only affects the Telegram Bot API calls for that\nplatform instance; other platforms and the management API are not\ntunneled through it.\n\nFull reference: [docs/telegram.md](./telegram.md#21-optional-use-a-proxy).\nThis option was added in PR #389.\n"}, "8343c310b6881596c416e11e39b02c9c0c2fb402": {"t": 1785763841.0934715, "n": 42472, "h": "6d731b3e5d5e4232", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Shell Configuration](#shell-configuration)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n- Each attachment is capped at **50 MiB** by default. Configure it with `max_attachment_size_mb` (MiB) in config.toml, or override that value with the `CC_MAX_ATTACHMENT_SIZE_MB` env var (same MiB unit; takes precedence when set), e.g. `CC_MAX_ATTACHMENT_SIZE_MB=100 cc-connect send --file big.bin`.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- The target platform also enforces its own file-size/type limit at delivery; the effective per-attachment ceiling is the smaller of that limit and `max_attachment_size_mb` (a file that passes cc-connect may still be rejected by the platform).\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Shell Configuration\n\nBy default, cc-connect uses `sh` on Unix and `powershell.exe` on Windows for all shell execution (`/shell` commands, cron exec jobs, hooks, and webhook exec). You can override this to use a different shell.\n\n### Supported Shells\n\n| Shell | Config value | Flag |\n|-------|-------------|------|\n| sh (default on Unix) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd (Windows) | `cmd` | `/C` |\n| PowerShell (default on Windows) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\nThe flag is auto-detected from the shell name — no manual configuration needed.\n\n### Global Configuration\n\nSet `shell` at the top level of `config.toml` to change the default for all projects:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### Per-Project Override\n\nOverride the shell for a specific project:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\nUse `shell_profile` to prepend a setup script to every shell command. This is useful for sourcing your shell profile so that custom functions, aliases, and environment variables are available:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nThe shell profile and the user's command are joined with a newline and passed as a single script to the shell, avoiding quoting issues. For example, `/shell echo $MY_VAR` becomes:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` also supports per-project override:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### Affected Execution Paths\n\nThe shell configuration applies to all command execution in cc-connect:\n\n- **`/shell` command** — interactive shell commands from chat\n- **Cron exec jobs** — `[[cron]]` entries with `exec` field\n- **Hooks** — `[[hooks]]` entries with `type = \"command\"`\n- **Webhook exec** — webhook requests with `exec` field\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n\n---\n\n## FAQ\n\nQuick answers to questions that came up repeatedly in issues and that the\nmaintainers have resolved. Each entry links back to the originating issue\nor PR so you can dig further if needed.\n\n### Does cc-connect support OpenClaw? (issue #501)\n\nYes. OpenClaw is supported via the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents). cc-connect ships an `acp` agent type that talks to any ACP-compatible CLI, including OpenClaw's `openclaw acp` subcommand.\n\nMinimal config snippet (full version is in `config.example.toml` under\n`# --- Example: OpenClaw (Gateway-backed ACP bridge) ---`):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**Pairing is required for remote gateways.** If you point cc-connect at a\nremote OpenClaw Gateway (`args = [\"acp\", \"--url\", \"wss://...\"]`) you must\npair first or every reply comes back empty:\n\n1. Start the gateway: `openclaw acp --url wss://your-gateway:18789`\n2. In another terminal: `openclaw pair`\n3. Approve the pairing request in the OpenClaw UI\n4. Now cc-connect can talk to the authorized gateway\n\nEmpty responses from OpenClaw are almost always a missing pairing step\n(issue #432). Re-run `openclaw pair` and re-approve before debugging\nanything else. Reference: \n\n### Personal WeChat group chat — finding the right `chat_id` (issue #805)\n\nPersonal WeChat (the `weixin` platform) supports group chats. To bind the\nbot to a specific group, set `chat_id` in `[[projects.platforms.options]]`\nto the **group chat ID**, not an individual user ID. Group chat IDs always\nend with `@chatroom`, for example:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # group chats end with @chatroom\n```\n\n**How to find the group chat ID:**\n\n1. Start cc-connect and let the bot be in the target group.\n2. Send any message in the group from a known allowed account.\n3. Check the cc-connect logs — the incoming `chat_id` (ending in\n `@chatroom`) is logged at the moment the message is received. Copy\n that value into `chat_id`.\n\nLeave `chat_id` empty (or omit the key) to respond to every chat the bot\nis in. Set it to a specific value to restrict the bot to that group or\nuser only.\n\nCommon pitfalls:\n\n- **\"How do I add the bot to a group?\"** Personal WeChat bots are added\n by scanning the QR code *inside* the group with the linked WeChat\n account, or by sharing the QR via the personal chat and then opening\n it inside the target group. There is no API-side \"invite bot to group\"\n call; the bot becomes a group member the same way any other WeChat\n contact does.\n- **Bot never receives group messages** — make sure the group is bound\n to your cc-connect instance. If `allow_from` is set, the first user\n to message in the group is recorded; if the binding is to a\n different user, the bot stays silent.\n- **Bot replies in private but ignores the group (or vice versa)** —\n duplicate the `[[projects.platforms]]` block, one with `chat_id` set\n to the group and one without, to cover both surfaces.\n\nFor more on the `weixin` platform, see [docs/weixin.md](./weixin.md).\n\n### Telegram proxy / outbound restrictions (issue #245)\n\nThe Telegram platform supports HTTP and SOCKS5 forward proxies directly in\n`[projects.platforms.options]`. You do not need a system-wide proxy or a\nsidecar — set the proxy per Telegram instance.\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # or socks5://127.0.0.1:1080\nproxy_username = \"\" # leave empty if no auth\nproxy_password = \"\"\n```\n\n`proxy` accepts both `http://` and `socks5://` URLs. Authentication is\noptional. The proxy only affects the Telegram Bot API calls for that\nplatform instance; other platforms and the management API are not\ntunneled through it.\n\nFull reference: [docs/telegram.md](./telegram.md#21-optional-use-a-proxy).\nThis option was added in PR #389.\n"}, "ae8913c9b4bf0889e001cda8550936bd8c24410c": {"t": 1785763842.5490336, "n": 41992, "h": "8397d53ba96eb593", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Shell Configuration](#shell-configuration)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Shell Configuration\n\nBy default, cc-connect uses `sh` on Unix and `powershell.exe` on Windows for all shell execution (`/shell` commands, cron exec jobs, hooks, and webhook exec). You can override this to use a different shell.\n\n### Supported Shells\n\n| Shell | Config value | Flag |\n|-------|-------------|------|\n| sh (default on Unix) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd (Windows) | `cmd` | `/C` |\n| PowerShell (default on Windows) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\nThe flag is auto-detected from the shell name — no manual configuration needed.\n\n### Global Configuration\n\nSet `shell` at the top level of `config.toml` to change the default for all projects:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### Per-Project Override\n\nOverride the shell for a specific project:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\nUse `shell_profile` to prepend a setup script to every shell command. This is useful for sourcing your shell profile so that custom functions, aliases, and environment variables are available:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nThe shell profile and the user's command are joined with a newline and passed as a single script to the shell, avoiding quoting issues. For example, `/shell echo $MY_VAR` becomes:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` also supports per-project override:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### Affected Execution Paths\n\nThe shell configuration applies to all command execution in cc-connect:\n\n- **`/shell` command** — interactive shell commands from chat\n- **Cron exec jobs** — `[[cron]]` entries with `exec` field\n- **Hooks** — `[[hooks]]` entries with `type = \"command\"`\n- **Webhook exec** — webhook requests with `exec` field\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n\n---\n\n## FAQ\n\nQuick answers to questions that came up repeatedly in issues and that the\nmaintainers have resolved. Each entry links back to the originating issue\nor PR so you can dig further if needed.\n\n### Does cc-connect support OpenClaw? (issue #501)\n\nYes. OpenClaw is supported via the [Agent Client Protocol (ACP)](https://agentclientprotocol.com/get-started/agents). cc-connect ships an `acp` agent type that talks to any ACP-compatible CLI, including OpenClaw's `openclaw acp` subcommand.\n\nMinimal config snippet (full version is in `config.example.toml` under\n`# --- Example: OpenClaw (Gateway-backed ACP bridge) ---`):\n\n```toml\n[[projects]]\nname = \"openclaw-acp\"\n\n[projects.agent]\ntype = \"acp\"\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\ncommand = \"openclaw\"\nargs = [\"acp\"]\ndisplay_name = \"OpenClaw ACP\"\n```\n\n**Pairing is required for remote gateways.** If you point cc-connect at a\nremote OpenClaw Gateway (`args = [\"acp\", \"--url\", \"wss://...\"]`) you must\npair first or every reply comes back empty:\n\n1. Start the gateway: `openclaw acp --url wss://your-gateway:18789`\n2. In another terminal: `openclaw pair`\n3. Approve the pairing request in the OpenClaw UI\n4. Now cc-connect can talk to the authorized gateway\n\nEmpty responses from OpenClaw are almost always a missing pairing step\n(issue #432). Re-run `openclaw pair` and re-approve before debugging\nanything else. Reference: \n\n### Personal WeChat group chat — finding the right `chat_id` (issue #805)\n\nPersonal WeChat (the `weixin` platform) supports group chats. To bind the\nbot to a specific group, set `chat_id` in `[[projects.platforms.options]]`\nto the **group chat ID**, not an individual user ID. Group chat IDs always\nend with `@chatroom`, for example:\n\n```toml\n[[projects.platforms]]\ntype = \"weixin\"\n\n[projects.platforms.options]\ntoken = \"ilink_bot_bearer_token\"\nchat_id = \"your_group_chat_id@chatroom\" # group chats end with @chatroom\n```\n\n**How to find the group chat ID:**\n\n1. Start cc-connect and let the bot be in the target group.\n2. Send any message in the group from a known allowed account.\n3. Check the cc-connect logs — the incoming `chat_id` (ending in\n `@chatroom`) is logged at the moment the message is received. Copy\n that value into `chat_id`.\n\nLeave `chat_id` empty (or omit the key) to respond to every chat the bot\nis in. Set it to a specific value to restrict the bot to that group or\nuser only.\n\nCommon pitfalls:\n\n- **\"How do I add the bot to a group?\"** Personal WeChat bots are added\n by scanning the QR code *inside* the group with the linked WeChat\n account, or by sharing the QR via the personal chat and then opening\n it inside the target group. There is no API-side \"invite bot to group\"\n call; the bot becomes a group member the same way any other WeChat\n contact does.\n- **Bot never receives group messages** — make sure the group is bound\n to your cc-connect instance. If `allow_from` is set, the first user\n to message in the group is recorded; if the binding is to a\n different user, the bot stays silent.\n- **Bot replies in private but ignores the group (or vice versa)** —\n duplicate the `[[projects.platforms]]` block, one with `chat_id` set\n to the group and one without, to cover both surfaces.\n\nFor more on the `weixin` platform, see [docs/weixin.md](./weixin.md).\n\n### Telegram proxy / outbound restrictions (issue #245)\n\nThe Telegram platform supports HTTP and SOCKS5 forward proxies directly in\n`[projects.platforms.options]`. You do not need a system-wide proxy or a\nsidecar — set the proxy per Telegram instance.\n\n```toml\n[[projects.platforms]]\ntype = \"telegram\"\n\n[projects.platforms.options]\ntoken = \"${TELEGRAM_BOT_TOKEN}\"\nproxy = \"http://127.0.0.1:7890\" # or socks5://127.0.0.1:1080\nproxy_username = \"\" # leave empty if no auth\nproxy_password = \"\"\n```\n\n`proxy` accepts both `http://` and `socks5://` URLs. Authentication is\noptional. The proxy only affects the Telegram Bot API calls for that\nplatform instance; other platforms and the management API are not\ntunneled through it.\n\nFull reference: [docs/telegram.md](./telegram.md#21-optional-use-a-proxy).\nThis option was added in PR #389.\n"}, "6feaf90f2f8cccec2203169b4d0edc3edd538837": {"t": 1785763844.4353876, "n": 37782, "h": "a6fafb059733f8d1", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Shell Configuration](#shell-configuration)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Shell Configuration\n\nBy default, cc-connect uses `sh` on Unix and `powershell.exe` on Windows for all shell execution (`/shell` commands, cron exec jobs, hooks, and webhook exec). You can override this to use a different shell.\n\n### Supported Shells\n\n| Shell | Config value | Flag |\n|-------|-------------|------|\n| sh (default on Unix) | `sh` | `-c` |\n| bash | `/bin/bash` | `-c` |\n| zsh | `/bin/zsh` | `-c` |\n| fish | `/bin/fish` | `-c` |\n| cmd (Windows) | `cmd` | `/C` |\n| PowerShell (default on Windows) | `powershell.exe` | `-Command` |\n| PowerShell Core | `pwsh` | `-Command` |\n\nThe flag is auto-detected from the shell name — no manual configuration needed.\n\n### Global Configuration\n\nSet `shell` at the top level of `config.toml` to change the default for all projects:\n\n```toml\nshell = \"/bin/zsh\"\n```\n\n### Per-Project Override\n\nOverride the shell for a specific project:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\n```\n\n### Shell Profile\n\nUse `shell_profile` to prepend a setup script to every shell command. This is useful for sourcing your shell profile so that custom functions, aliases, and environment variables are available:\n\n```toml\nshell = \"/bin/zsh\"\nshell_profile = \"source ~/.zshrc\"\n```\n\nThe shell profile and the user's command are joined with a newline and passed as a single script to the shell, avoiding quoting issues. For example, `/shell echo $MY_VAR` becomes:\n\n```zsh\nsource ~/.zshrc\necho $MY_VAR\n```\n\n`shell_profile` also supports per-project override:\n\n```toml\n[[projects]]\nname = \"my-project\"\nshell = \"/bin/fish\"\nshell_profile = \"source ~/.config/fish/config.fish\"\n```\n\n### Affected Execution Paths\n\nThe shell configuration applies to all command execution in cc-connect:\n\n- **`/shell` command** — interactive shell commands from chat\n- **Cron exec jobs** — `[[cron]]` entries with `exec` field\n- **Hooks** — `[[hooks]]` entries with `type = \"command\"`\n- **Webhook exec** — webhook requests with `exec` field\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "1bd0d9529497121deae0070f1cb5daa4f36364b5": {"t": 1785763846.0744658, "n": 35769, "h": "929b03bf892d4a36", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible agent provider, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\n# Use https://api.minimaxi.com/v1 for China-region accounts.\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Platforms that implement audio sending, such as Feishu/Lark, DingTalk, Telegram, Max, and Weixin.\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"minimax\" # qwen | openai | minimax | mimo | espeak | pico | edge\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98 # provider-specific range; MiniMax commonly accepts 0.5-2.0\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.minimax]\napi_key = \"\" # optional: falls back to data_dir/config/minimax.json\nbase_url = \"\" # optional: default https://api.minimaxi.com\nmodel = \"speech-2.8-hd\"\n\n[tts.agents.assistant]\nvoice_id = \"Chinese (Mandarin)_Crisp_Girl\"\nspeed = 0.98\n\n[tts.agents.reviewer]\nvoice_id = \"Chinese (Mandarin)_Gentle_Senior\"\nspeed = 0.96\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image, File, and Voice Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`. When the user explicitly asks for a voice message, the agent can also send synthesized speech through the same CLI.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n- requested voice messages should be sent with `cc-connect send --tts`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`. Synthesized voice send-back uses the `[tts]` provider config and is controlled by TTS availability instead.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\ncc-connect send --tts \"Hello from cc-connect\"\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--tts` synthesizes text and sends the generated audio through the active TTS provider.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n4. The user asks the agent to \"send this as voice\" without typing a slash command.\n\n### Important notes\n\n- This command is for generated attachment and voice delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "527220d924b5a60cfa9d020f3bc96516f9ba5bf7": {"t": 1785763848.6315324, "n": 34622, "h": "3b91ce61b6a08e98", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Claude Code PermissionRequest Hooks](#claude-code-permissionrequest-hooks)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Claude Code PermissionRequest Hooks\n\nIf you have [PermissionRequest hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) configured in your Claude Code `settings.json`, cc-connect will respect them — matching hooks can auto-approve or deny tool requests before they reach the messaging platform.\n\n### Why hooks run twice\n\ncc-connect launches Claude Code with `--permission-prompt-tool stdio`, which means Claude Code's own hook execution output is discarded (stdout is consumed by the protocol). To make your hooks actually take effect, cc-connect reads the hook definitions from `settings.json` and **re-runs them independently**.\n\nThis means your hook command is executed **twice** per permission request:\n\n1. Once by Claude Code (result discarded)\n2. Once by cc-connect (result used)\n\n### Avoiding double cost for LLM-based hooks\n\nIf your hook is rule-based (e.g. \"deny `rm -rf`\"), running twice is harmless. But if your hook calls an LLM (like [ccgate](https://github.com/tak848/ccgate)), the first execution wastes tokens. Add this guard at the top of your hook:\n\n```bash\n#!/bin/bash\nif [ -n \"$CC_CONNECT_PERMISSION_HOOK_SKIP\" ]; then\n exit 0 # cc-connect will re-run us without this flag\nfi\n# ... your actual hook logic ...\n```\n\ncc-connect sets `CC_CONNECT_PERMISSION_HOOK_SKIP=1` in the Claude Code subprocess environment. When your hook sees this variable, it's running inside Claude Code (result will be discarded) — skip the expensive work. cc-connect strips this variable when it runs the hook itself, so the second execution proceeds normally.\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "1322565cb66d620c8cd8690a2f313ed72e77a007": {"t": 1785763850.8991714, "n": 32969, "h": "1739c8bde3d9e4a9", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- `/dir` is a privileged command. You must set `admin_from` under `[[projects]]` in `config.toml` before it can be used.\n- Do not put `admin_from` under `[projects.platforms.options]`, or it will be ignored.\n- Use `/whoami` or `/status` to get your current `User ID`, then place that ID into `admin_from`.\n- If you are the only user of this bot, `admin_from = \"*\"` also works, but it grants every allowed user privileged command access.\n- Restart `cc-connect` after updating `config.toml`.\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExample config:\n\n```toml\n[[projects]]\nname = \"my-project\"\nadmin_from = \"ou_xxx\"\n```\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "c580b68716a7cdc6a0e6702e5782c17d074a7978": {"t": 1785763852.6640632, "n": 32394, "h": "3d5728c6af79dff1", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron exec \ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "9cf496b973f1e814b071c5a43745217b0a0385ab": {"t": 1785763855.4512033, "n": 32364, "h": "0bb8263c8f3fd060", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or wps-xiezuo, dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "e04247e5765826a222b5ce51a34f9fb7910eb808": {"t": 1785763857.9115088, "n": 32352, "h": "384b2db7c66e5460", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\ncc-connect rotates to a fresh session automatically after long inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 30 # default when unset; set to 0 to disable\n```\n\nThe next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n**Why this is on by default:** without idle rotation, every workspace-pool eviction (~15 min) caused the next message to resume the previous transcript via `--continue`. Over many cycles this re-ingests stale chat history (failed commands, debugging noise, abandoned tangents) and the model's attention drifts away from the original intent. Rotating after 30 minutes of user inactivity gives a clean slate when you come back to a task, while preserving the old session for `/list` and `/switch`.\n\nTo restore the previous behavior of always continuing, set `reset_on_idle_mins = 0`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "57bd7be93986ca77d0b29932e5a978c0db95feeb": {"t": 1785763861.7823975, "n": 31732, "h": "de116e91c53c80f5", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\nYou can also configure automatic session rotation after inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\nWhen enabled, the next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron edit # e.g. cron_expr, prompt, enabled, mute, timeout_mins\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "12a6ffd11e6cccae8172b5a3f0556859f376b5a4": {"t": 1785763863.4119759, "n": 31630, "h": "de1e6d934f9cb765", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\nYou can also configure automatic session rotation after inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\nWhen enabled, the next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n### Model switch preserves history\n\n`/model` preserves the current session — the agent resumes the conversation with the new model (no extra token cost). Model switching affects the shared agent instance — if multiple platforms use the same project, the model change applies to all of them.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "4cf879b2b95389d2e5032e990a5c834e19a7640f": {"t": 1785763865.0111184, "n": 31338, "h": "c85405adf37a31c4", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\nYou can also configure automatic session rotation after inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\nWhen enabled, the next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Running agents as a different Unix user (`run_as_user`)\n\n> **Platform support**: Linux and macOS. Not supported on Windows.\n> **Agent support**: Claude Code today. Other agents fall back to the\n> supervisor user; see the tracking issue for migration status.\n\n### What this is\n\nBy default, every agent session cc-connect spawns runs as the same Unix\nuser that runs `cc-connect` itself. If an agent misbehaves — reads a\nsecret, overwrites a sibling repo, trashes `~/.ssh/` — it has the\nsupervisor user's full file-system reach.\n\n`run_as_user` sets a per-project target Unix user. When it is set,\ncc-connect spawns that project's agent command via\n\n```\nsudo -n -iu -- claude ...\n```\n\nThe target user is a real, unprivileged Unix account that you create.\nThe agent runs under that account's uid/gid, with **its own** home\ndirectory, shell profile, PATH, and tool credentials. File-system\nisolation is enforced by the kernel, not by hooks or allowlists.\n\n### Security guarantee and non-guarantee\n\n**This provides OS-user isolation from any file or process the target\nuser cannot reach.** An agent can no longer read or clobber the\nsupervisor's `~/.ssh/`, another project user's `~/.pgpass`, or a repo\nwhose UNIX permissions don't grant access to the target user.\n\n**This does not automatically isolate projects from each other** if they\nshare the same `run_as_user`. If you want per-project isolation, create\na separate Unix user per project.\n\n**This is not a sandbox in the sense of Linux namespaces, seccomp, or\ncontainer isolation.** It is strictly file-system scoping by uid.\n\n### Setup\n\n#### 1. Create the target user and install their tooling\n\nThe target user needs its own copy of everything the agent touches,\nbecause `sudo -i` loads the *target* user's login environment — not the\nsupervisor's.\n\n```bash\nsudo useradd -m -s /bin/bash partseeker-coder\nsudo -iu partseeker-coder\n\n# Install the agent CLI under the target user's PATH\n# (for Claude Code, follow the normal install instructions)\n\n# Set up the target user's ~/.claude/\nmkdir -p ~/.claude\n# Copy or re-create:\n# ~/.claude/settings.json (MCP servers, hooks, model settings)\n# ~/.claude.json (Claude Code auth)\n# ~/.claude/plugins/ (claude-mem and any other plugin state)\n\nexit\n```\n\n#### 2. Grant the supervisor passwordless sudo to the target\n\nAdd a scoped sudoers rule. Do **not** use `NOPASSWD: ALL` for the\nsupervisor — that grants the supervisor root, which is irrelevant here\nand dangerous.\n\n```\n# /etc/sudoers.d/cc-connect (install with `sudo visudo -f ...`)\npartseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL\n```\n\nAdjust the usernames for your setup. The rule says: *\"the supervisor\nuser may run any command as this specific target user, without a\npassword.\"*\n\n#### 3. Verify the target user cannot sudo\n\nThe whole point of stepping down into a target user is that the target\ncannot immediately escalate back. Verify:\n\n```bash\nsudo -n -iu partseeker-coder -- sudo -n true\n# must FAIL with \"a password is required\" or similar\n```\n\nIf that command succeeds, cc-connect will refuse to start. Remove any\n`NOPASSWD` sudo grants for the target user first.\n\n#### 4. Make the project's `work_dir` accessible to the target user\n\nThe target user needs read AND write on the project's `work_dir`. If\nthe directory is owned by the supervisor, either `chown` it to the\ntarget, add group ownership the target is in, or apply a POSIX ACL:\n\n```bash\nsudo setfacl -R -m u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\nsudo setfacl -R -dm u:partseeker-coder:rwX /home/leigh/workspace/sandboxed-repo\n```\n\ncc-connect refuses to start if the target user cannot read+write the\n`work_dir` root, and warns (non-fatal) for descendant paths that look\ninaccessible.\n\n#### 5. Audit the setup before starting cc-connect\n\n```bash\ncc-connect doctor user-isolation\n```\n\nThis runs the full preflight (the three go/no-go gates from\n[#496](https://github.com/chenhg5/cc-connect/issues/496)) and an\n**isolation probe**: it spawns a fixed shell script as the target user\nand reports what the target can read, what it's denied, and any\ncross-user leaks. Output goes to stdout plus a JSON report in\n`~/.cc-connect/audits/-.json`.\n\nExit code 0 = clean. Exit code 1 = at least one fatal problem.\n\nYou can inspect the probe script itself with:\n\n```bash\ncc-connect doctor user-isolation --print-script\n```\n\n### Configuration\n\n```toml\n[[projects]]\nname = \"claude-sandboxed\"\nrun_as_user = \"partseeker-coder\"\n\n# Optional: extend the default env var allowlist that crosses the sudo\n# boundary. The defaults (PATH, LANG, LC_*, TERM) are always included.\n# Only list vars the target user cannot reasonably set in their own\n# shell profile. Secrets belong in the target user's ~/.claude/settings.json\n# env block, NOT here.\nrun_as_env = [\"PGSSLROOTCERT\", \"PGSSLMODE\"]\n\n[projects.agent]\ntype = \"claudecode\"\n\n[projects.agent.options]\nmode = \"default\"\nmodel = \"sonnet\"\nwork_dir = \"/home/leigh/workspace/sandboxed-repo\"\n```\n\n### Environment propagation: what moves into the target user's home\n\nThis is the 2am-debugging section. When you switch a project to\n`run_as_user`, the supervisor's environment is **not** forwarded across\nthe sudo boundary — that's the whole point. Everything the agent needs\nhas to live in the target user's home.\n\nMigration checklist:\n\n- [ ] **Agent config** — `~/.claude/settings.json` (MCP servers, hooks,\n model settings), `~/.claude.json` (auth). Copy from the supervisor\n or re-create from scratch.\n- [ ] **Plugin state** — `~/.claude/plugins/` — claude-mem, any other\n Claude Code plugins.\n- [ ] **MCP server binaries** — must be on the target user's `PATH`, not\n just the supervisor's. Either install under the target user or\n reference full paths in `settings.json`.\n- [ ] **Postgres TLS** — `PGSSLROOTCERT`, `PGSSLCERT`, `PGSSLKEY` belong\n in the target user's `~/.claude/settings.json` `env` block. Their\n referenced cert files must be readable by the target user.\n- [ ] **Claude OAuth credentials** — if you authenticate via `claude.ai`\n (OAuth), the token lives in `~/.claude/.credentials.json`. OAuth\n access tokens expire after a few hours and are refreshed\n automatically by whichever Claude CLI session is running. The\n target user's token will **not** be refreshed unless the target\n user has an active session — which it often doesn't between\n cc-connect spawns. The recommended fix is to symlink the target\n user's credentials to the supervisor's file so both share one\n token that stays fresh:\n\n ```bash\n # Grant target user read access via ACL (keeps 600 for everyone else)\n setfacl -m u::rx ~/.claude/\n setfacl -m u::r ~/.claude/.credentials.json\n\n # Replace the target user's credentials with a symlink\n sudo -iu bash -c \\\n 'rm -f ~/.claude/.credentials.json && \\\n ln -s /home//.claude/.credentials.json \\\n ~/.claude/.credentials.json'\n ```\n\n **If you use an API key** (`ANTHROPIC_API_KEY`) instead of OAuth,\n this is not an issue — set the key in the target user's\n `~/.claude/settings.json` `env` block and it won't expire.\n- [ ] **Credential files** — `~/.pgpass`, `~/.gitconfig`, `~/.netrc`,\n `~/.aws/`, `~/.config/gh/`, `~/.kube/` — whichever the agent\n actually uses. Each needs its own copy or a group-readable shared\n copy.\n- [ ] **SSH keys** — `~/.ssh/id_ed25519` etc., if the agent runs `git\n push` over SSH. Same story: copy or group-share.\n- [ ] **Key material under** `~/keys/` — custom directories the\n supervisor uses need an equivalent under the target user's home\n or a group-readable shared copy.\n- [ ] **Language toolchains** — if the agent uses `asdf`, `mise`, `nvm`,\n `rustup`, etc., those live in `~`. The target user needs either\n its own install or a system-wide install that both users can run.\n- [ ] **Shell profile** — `~/.profile` / `~/.bashrc` on the target user\n needs to set `PATH` and any tool init the agent depends on. Test\n with `sudo -iu partseeker-coder` before wiring cc-connect.\n\nAfter migration, run `cc-connect doctor user-isolation` again. The\n`target home` section reports which expected paths are present and\nwhich are missing — missing isn't necessarily wrong, but it's your\nchecklist.\n\n### Opting out\n\nRemove `run_as_user` from the project entry, or set it to `\"\"`. Legacy\nbehavior (spawn as supervisor) returns on the next restart.\n\n### Failure modes and error messages\n\n- **\"passwordless sudo to user X is not configured\"** — step 2 of setup\n is missing or the sudoers rule is scoped to the wrong supervisor. Fix\n the rule, run `visudo -c` to validate syntax, then restart cc-connect.\n- **\"target user X can run passwordless sudo\"** — step 3 failed. The\n error includes the output of `sudo -l` from the target context; find\n the offending rule and remove it.\n- **\"target user X cannot read AND write work_dir Y\"** — step 4 failed.\n `chown` the directory or add an ACL as shown above.\n- **\"CROSS_LEAKED\"** or **\"SUPERVISOR_LEAKED\"** in the audit — the\n target user can read another user's secrets. Tighten the offending\n file's permissions (usually `chmod 600 file; chown user:user file`)\n and re-audit.\n- **\"descendant scan timed out\"** — non-fatal. The `work_dir` is large\n enough that the permission walk exceeded its timeout. Run\n `cc-connect doctor user-isolation` manually if you want the full\n walk, or narrow the project's `work_dir`.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "a0a7cc50f7e6137e893ce0a08d5b3654c423096e": {"t": 1785763866.4357586, "n": 21717, "h": "85ed210936f24325", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\nYou can also configure automatic session rotation after inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\nWhen enabled, the next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "d76639360cb4d67483dd9dee525aa4dd2240fa8e": {"t": 1785763868.3773973, "n": 21771, "h": "8ee7a43b51c5f5be", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\nYou can also configure automatic session rotation after inactivity:\n\n```toml\n[[projects]]\nname = \"demo\"\nreset_on_idle_mins = 60\n```\n\nWhen enabled, the next normal message after a long idle period starts in a fresh session automatically, without deleting the old session from `/list`.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "59098aaa2755d9b4780fe746c3de37a78fd7e8a5": {"t": 1785763870.8635476, "n": 21486, "h": "91d9a6e9cbdc591a", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n- Runtime platform config also supports an optional `domain` override for Feishu/Lark API endpoints; this does not change setup/onboarding URLs.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "5a9cf6ef2a7620a4945c5cdc9f94c5fdbfb69f8d": {"t": 1785763872.6616032, "n": 21341, "h": "60dd53f3c4201748", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Web Admin Dashboard (Beta)](#web-admin-dashboard-beta)\n- [Bridge — External Adapter Access (Beta)](#bridge--external-adapter-access-beta)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Web Admin Dashboard (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The UI and API may change in future releases.\n\nA full-featured management UI embedded in the binary — project CRUD, session management, cron job editor, global settings, chat interface, and i18n support.\n\n### Quick Setup (Chat Command)\n\nThe easiest way to enable web admin:\n\n```\n/web setup\n```\n\nThis automatically enables both the **Management API** and the **Bridge** in `config.toml`, generates tokens, and prints the access URL. You may need to run `/restart` for changes to take effect.\n\nAfter setup, open the URL shown (default `http://localhost:9820`) and log in with the token.\n\n### Check Status\n\n```\n/web # or /web status — show current web admin URL and status\n```\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[management]\nenabled = true\nport = 9820 # Management UI & API listen port\ntoken = \"your-secret-token\" # Login token; /web setup generates one automatically\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS headers\n```\n\nThen restart cc-connect.\n\n### Build Options\n\nWeb assets are compiled into the binary by default. To exclude them (saves ~1MB):\n\n```bash\nmake build-noweb\n# or\ngo build -tags 'no_web' ./cmd/cc-connect\n```\n\nWhen built with `no_web`, the `/web` command will report that web admin is not available.\n\n### Management API\n\nThe Management API is served on the same port as the UI. Base URL: `http://:/api/v1`\n\nAll API requests require the `Authorization: Bearer ` header.\n\nKey endpoints:\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/api/v1/status` | System status (version, uptime, platforms) |\n| `POST` | `/api/v1/restart` | Restart cc-connect |\n| `POST` | `/api/v1/reload` | Reload configuration |\n| `GET` | `/api/v1/projects` | List projects |\n| `GET` | `/api/v1/sessions?project=` | List sessions for a project |\n| `GET` | `/api/v1/cron` | List cron jobs |\n| `GET` | `/api/v1/settings` | Get global settings |\n| `PATCH` | `/api/v1/settings` | Update global settings |\n\nFull API reference: [management-api.md](./management-api.md)\n\n---\n\n## Bridge — External Adapter Access (Beta)\n\n> **Status: Beta.** This feature is available since v1.2.2-beta.5. The protocol may change in future releases.\n\nThe Bridge exposes a WebSocket + REST server so external adapters (custom UIs, bots, scripts) can interact with cc-connect sessions — send messages, receive events, manage sessions.\n\n### Enable via Chat\n\nThe `/web setup` command enables Bridge automatically alongside the Management API.\n\n### Manual Configuration\n\nAdd the following to `config.toml`:\n\n```toml\n[bridge]\nenabled = true\nport = 9810 # Bridge listen port (separate from management)\ntoken = \"your-bridge-secret\" # Auth token for WebSocket and REST\npath = \"/bridge/ws\" # WebSocket endpoint path\ncors_origins = [\"*\"] # Allowed CORS origins; empty = no CORS\n```\n\nThen restart cc-connect.\n\n### Authentication\n\nAll Bridge connections require a token. Supported methods:\n\n- Query parameter: `?token=`\n- Header: `Authorization: Bearer `\n- Header: `X-Bridge-Token: `\n\n### WebSocket\n\nConnect to:\n\n```\nws://:/bridge/ws?token=\n```\n\nThe WebSocket supports bidirectional messaging — send user messages to the agent and receive agent events (text, tool calls, permission requests, etc.) in real time.\n\n### REST API\n\nServed on the same port as the WebSocket.\n\n| Method | Path | Description |\n|--------|------|-------------|\n| `GET` | `/bridge/sessions?session_key=...&project=...` | List sessions |\n| `POST` | `/bridge/sessions` | Create a new session |\n| `GET` | `/bridge/sessions/{id}?session_key=...&project=...` | Get session detail + history |\n| `DELETE` | `/bridge/sessions/{id}?session_key=...&project=...` | Delete a session |\n| `POST` | `/bridge/sessions/switch` | Switch active session |\n\nFull protocol reference: [bridge-protocol.md](./bridge-protocol.md)\n\n### Port Summary\n\n| Service | Default Port | Config Block |\n|---------|-------------|--------------|\n| Management (Web UI + API) | 9820 | `[management]` |\n| Bridge (WebSocket + REST) | 9810 | `[bridge]` |\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "1225b7ee187e3ff58d35e501318b4fae36a3cbe3": {"t": 1785763874.081573, "n": 16891, "h": "9da66005995877c4", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Auto | `auto` | Claude decides when to ask for permission |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "fa9280b54350673de2e15ddd91337b74f97fb562": {"t": 1785763875.8009357, "n": 16829, "h": "d789d06f49fc4cdd", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Work Directory Switching (`/dir`, `/cd`)](#work-directory-switching-dir-cd)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/dir [path]` | Show or switch the agent work directory |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Work Directory Switching (`/dir`, `/cd`)\n\nSwitch where the next agent session starts, directly from chat.\n\n### Chat Commands\n\n```\n/dir Show current work directory and recent history\n/dir Switch to a path (relative or absolute)\n/dir Switch to a directory from history\n/dir - Switch back to previous directory\n/dir help Show command usage\n/cd Backward-compatible alias of /dir \n```\n\n### Behavior Notes\n\n- Directory changes apply to the next session in the current project.\n- Relative paths are resolved from the current agent work directory.\n- Directory history is project-scoped and can be switched by index.\n- `/cd` is kept for compatibility, but `/dir` is the primary command.\n\nExamples:\n\n```text\n/dir ../another-repo\n/dir 2\n/dir -\n```\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "00b719d21520ae6b1e0f2d3ed0a49c69b474b7f6": {"t": 1785763877.1439445, "n": 15830, "h": "5aeb48c3826dc4f8", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Weixin (personal) Setup CLI](#weixin-personal-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Weixin (personal) Setup CLI\n\nWeixin personal chat uses the **ilink bot HTTP API** (long polling + `sendMessage`, same family as OpenClaw `openclaw-weixin`). Use the CLI to scan a QR code or bind an existing Bearer token and write `config.toml`.\n\n**Full walkthrough (Chinese): [docs/weixin.md](./weixin.md).**\n\n```bash\ncc-connect weixin setup --project my-project\ncc-connect weixin bind --project my-project --token ''\ncc-connect weixin new --project my-project\n```\n\nNotes:\n- `setup` without `--token` runs QR login; with `--token` behaves like bind.\n- Auto-creates the project and/or a `weixin` platform block when missing.\n- After login, send a message from WeChat once so `context_token` is cached.\n- See `cc-connect weixin help` for flags (`--api-url`, `--cdn-url`, `--route-tag`, etc.).\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, weixin, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "253a7a73e8c3089f00dd2d69b2bfcedd0461dd02": {"t": 1785763879.01378, "n": 14955, "h": "2b18bcd6b1f993e9", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\nOptional: `--session-mode new-per-run` starts a fresh agent session on each run (default is `reuse`, same as before). `--timeout-mins N` sets how long the scheduler waits per run (`0` = no limit; omit = 30 minutes).\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "9df8d494ddd43a7e836fc8cea6b634b542875d5e": {"t": 1785763880.5164165, "n": 14738, "h": "5035b7388745f6e2", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [switch ]` | List available models or switch by alias |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model switch Switch to the model matching the alias\n/model switch Switch to the model by its full name\n/model Legacy syntax, still supported\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "50e22d44be1b50da3ac72a823648600036d82ea4": {"t": 1785763882.846743, "n": 14657, "h": "4a39d7a5f909bc1e", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [alias]` | List available models or switch by alias |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 1M context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.7\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model Switch to the model matching the alias\n/model Switch to the model by its full name\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "80ce4a5632941082471401cabe50a62e0523ab1a": {"t": 1785763886.7243009, "n": 14659, "h": "555461deddc63b31", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Model Selection](#model-selection)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/model [alias]` | List available models or switch by alias |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-sonnet-4-20250514\"\nalias = \"sonnet\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-opus-4-20250514\"\nalias = \"opus\"\n\n[[projects.agent.providers.models]]\nmodel = \"claude-haiku-3-5-20241022\"\nalias = \"haiku\"\n\n# MiniMax — OpenAI-compatible, 204K context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Model Selection\n\nPre-configure a list of selectable models per provider using `[[providers.models]]`. Each entry has a `model` identifier and an optional `alias` (short name shown in `/model`).\n\n### Configure Models\n\n```toml\n[[projects.agent.providers]]\nname = \"openai\"\napi_key = \"sk-xxx\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex\"\nalias = \"codex\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.4\"\nalias = \"gpt\"\n\n[[projects.agent.providers.models]]\nmodel = \"gpt-5.3-codex-spark\"\nalias = \"spark\"\n```\n\n### Chat Commands\n\n```\n/model List available models (format: alias - model)\n/model Switch to the model matching the alias\n/model Switch to the model by its full name\n```\n\nWhen `models` is configured, `/model` shows exactly that list without making an API round-trip. When omitted, models are fetched from the provider API or fall back to a built-in list.\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "db8f5f4c00b6e3d2686972d1dcd6b5b049c64f64": {"t": 1785763888.4912615, "n": 13368, "h": "c9191e00a1387610", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Image and File Send-Back](#image-and-file-send-back)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — OpenAI-compatible, 204K context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Image and File Send-Back\n\nWhen an agent generates a local image, PDF, report, bundle, or other file and needs to deliver it directly to the current chat, use attachment mode in `cc-connect send`.\n\n**Currently supported platforms:**\n- Feishu\n- Telegram\n\n### When to run setup first\n\nIf the current agent does not natively inject the system prompt, run this once in chat after upgrading:\n\n```text\n/bind setup\n```\n\nor:\n\n```text\n/cron setup\n```\n\nThese two commands write the same cc-connect instructions. Either one is enough. After that, the agent knows:\n- normal text replies should be returned normally\n- generated attachments should be sent back with `cc-connect send --image/--file`\n\nIf you have run setup before, run it again after upgrading so the instructions are refreshed to the latest version.\n\n### Config switch\n\nAdd this to `config.toml` if you want to disable agent-driven attachment send-back:\n\n```toml\nattachment_send = \"off\"\n```\n\nThe default is `on`. This switch is independent from the agent's `/mode` and only affects `cc-connect send --image/--file`.\n\n### CLI examples\n\n```bash\ncc-connect send --image /absolute/path/to/chart.png\ncc-connect send --file /absolute/path/to/report.pdf\ncc-connect send --file /absolute/path/to/report.pdf --image /absolute/path/to/chart.png\n```\n\nNotes:\n- `--image` is for image attachments.\n- `--file` is for any file attachment.\n- `--message` is optional and sends a text note before the attachments.\n- `--image` and `--file` can both be repeated.\n- Absolute paths are recommended so the command does not depend on the agent's current working directory.\n- With `attachment_send = \"off\"`, image/file send-back is blocked but ordinary text replies still work.\n\n### Typical use cases\n\n1. The agent generates a screenshot or chart and should send it directly to the user.\n2. The agent generates a PDF, Markdown export, log bundle, or patch file that should be delivered as an attachment.\n3. The agent wants to send a short status message together with one or more generated files.\n\n### Important notes\n\n- This command is for attachment delivery, not ordinary text replies.\n- The files must exist on the local machine where the agent runs.\n- There must be an active session; otherwise the command fails because cc-connect has no chat context to deliver to.\n- Platform-specific file size and file type limits still apply.\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job. For other agents that rely on memory files, run `/cron setup` or `/bind setup` once first; both write the same instructions.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "2f01442f75e37b74db7f61ae3332fd8134d3edec": {"t": 1785763892.0893123, "n": 10816, "h": "1e1ca237a746ac82", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Feishu Setup CLI](#feishu-setup-cli)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — OpenAI-compatible, 204K context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Feishu Setup CLI\n\nUse CLI to create or bind Feishu/Lark bot credentials and write them back to `config.toml`.\n\n```bash\n# Recommended: unified entry\ncc-connect feishu setup --project my-project\ncc-connect feishu setup --project my-project --app cli_xxx:sec_xxx\n\n# Force modes (usually unnecessary)\ncc-connect feishu new --project my-project\ncc-connect feishu bind --project my-project --app cli_xxx:sec_xxx\n```\n\nDifferences:\n- `setup`: unified entry. No credentials => behaves like `new`; with `--app` => behaves like `bind`.\n- `new`: force QR onboarding flow; rejects `--app`.\n- `bind`: force credential binding flow; requires credentials.\n\nBehavior:\n- `setup` uses QR onboarding by default, or bind mode when `--app` is provided.\n- If `--project` does not exist, it is created automatically.\n- If project exists but has no `feishu/lark` platform, one is added automatically.\n- The command writes credentials (`app_id`, `app_secret`); in QR onboarding flow, Feishu usually pre-configures permissions and event subscriptions.\n- Still verify app publish status and availability scope in Feishu Open Platform.\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "8817e58f81b2c0559bef19d479da05f0a093019c": {"t": 1785763893.4937584, "n": 9660, "h": "7a021786c5a6c762", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# MiniMax — OpenAI-compatible, 204K context\n[[projects.agent.providers]]\nname = \"minimax\"\napi_key = \"your-minimax-api-key\"\nbase_url = \"https://api.minimax.io/v1\"\nmodel = \"MiniMax-M2.5\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}, "334c58bbfbd510ef48ef674e7d9a081b6f05c1e9": {"t": 1785763894.8286061, "n": 9474, "h": "905f7ed5057dcdac", "c": "# Usage Guide\n\nComplete guide to using cc-connect features.\n\n## Table of Contents\n\n- [Session Management](#session-management)\n- [Permission Modes](#permission-modes)\n- [API Provider Management](#api-provider-management)\n- [Claude Code Router Integration](#claude-code-router-integration)\n- [Voice Messages (STT)](#voice-messages-speech-to-text)\n- [Voice Reply (TTS)](#voice-reply-text-to-speech)\n- [Scheduled Tasks (Cron)](#scheduled-tasks-cron)\n- [Multi-Bot Relay](#multi-bot-relay)\n- [Daemon Mode](#daemon-mode)\n- [Multi-Workspace Mode](#multi-workspace-mode)\n- [Configuration Reference](#configuration-reference)\n\n---\n\n## Session Management\n\nEach user gets an independent session with full conversation context. Manage sessions via slash commands:\n\n| Command | Description |\n|---------|-------------|\n| `/new [name]` | Start a new session |\n| `/list` | List all agent sessions for this project |\n| `/switch ` | Switch to a different session |\n| `/current` | Show current session info |\n| `/history [n]` | Show last n messages (default 10) |\n| `/usage` | Show account/model quota usage (if supported) |\n| `/provider [...]` | Manage API providers |\n| `/allow ` | Pre-allow a tool (next session) |\n| `/reasoning [level]` | View or switch reasoning effort (Codex) |\n| `/mode [name]` | View or switch permission mode |\n| `/quiet` | Toggle thinking/tool progress messages |\n| `/stop` | Stop current execution |\n| `/help` | Show available commands |\n\nDuring a session, the agent may request tool permissions. Reply **allow** / **deny** / **allow all**.\n\n---\n\n## Permission Modes\n\nAll agents support permission modes switchable at runtime via `/mode`.\n\n### Claude Code Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Every tool call requires approval |\n| Accept Edits | `acceptEdits` / `edit` | File edits auto-approved |\n| Plan Mode | `plan` | Claude only plans, no execution |\n| YOLO | `bypassPermissions` / `yolo` | All tools auto-approved |\n\n### Codex Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Suggest | `suggest` | Only trusted commands run without approval |\n| Auto Edit | `auto-edit` | Model decides when to ask |\n| Full Auto | `full-auto` | Auto-approve with sandbox |\n| YOLO | `yolo` | Bypass all approvals and sandbox |\n\n### Cursor Agent Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Trust workspace, ask before tools |\n| Force (YOLO) | `force` / `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only analysis |\n| Ask | `ask` | Q&A style, read-only |\n\n### Gemini CLI Modes\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Prompt for approval |\n| Auto Edit | `auto_edit` / `edit` | Auto-approve edits |\n| YOLO | `yolo` | Auto-approve all |\n| Plan | `plan` | Read-only plan mode |\n\n### Qoder CLI / OpenCode / iFlow CLI\n\n| Mode | Config Value | Behavior |\n|------|-------------|----------|\n| Default | `default` | Standard permissions |\n| YOLO | `yolo` | Skip all checks |\n\n### Configuration\n\n```toml\n[projects.agent.options]\nmode = \"default\"\n# allowed_tools = [\"Read\", \"Grep\", \"Glob\"]\n```\n\nSwitch at runtime:\n```\n/mode # show current and available modes\n/mode yolo # switch to YOLO mode\n/mode default # switch back\n```\n\n---\n\n## API Provider Management\n\nSwitch between API providers at runtime without restart.\n\n### Configure Providers\n\n```toml\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nprovider = \"anthropic\" # active provider\n\n[[projects.agent.providers]]\nname = \"anthropic\"\napi_key = \"sk-ant-xxx\"\n\n[[projects.agent.providers]]\nname = \"relay\"\napi_key = \"sk-xxx\"\nbase_url = \"https://api.relay-service.com\"\nmodel = \"claude-sonnet-4-20250514\"\n\n# For Bedrock, Vertex, etc.\n[[projects.agent.providers]]\nname = \"bedrock\"\nenv = { CLAUDE_CODE_USE_BEDROCK = \"1\", AWS_PROFILE = \"bedrock\" }\n```\n\n### CLI Commands\n\n```bash\ncc-connect provider add --project my-backend --name relay --api-key sk-xxx --base-url https://api.relay.com\ncc-connect provider list --project my-backend\ncc-connect provider remove --project my-backend --name relay\ncc-connect provider import --project my-backend # from cc-switch\n```\n\n### Chat Commands\n\n```\n/provider Show current provider\n/provider list List all providers\n/provider add [url] [model]\n/provider remove \n/provider switch \n/provider Shortcut for switch\n```\n\n### Env Var Mapping\n\n| Agent | api_key → | base_url → |\n|-------|-----------|------------|\n| Claude Code | `ANTHROPIC_API_KEY` | `ANTHROPIC_BASE_URL` |\n| Codex | `OPENAI_API_KEY` | `OPENAI_BASE_URL` |\n| Gemini CLI | `GEMINI_API_KEY` | use `env` map |\n| OpenCode | `ANTHROPIC_API_KEY` | use `env` map |\n| iFlow CLI | `IFLOW_API_KEY` | `IFLOW_BASE_URL` |\n\n---\n\n## Claude Code Router Integration\n\n[Claude Code Router](https://github.com/musistudio/claude-code-router) routes requests to different model providers.\n\n### Setup\n\n1. Install: `npm install -g @musistudio/claude-code-router`\n\n2. Configure `~/.claude-code-router/config.json`:\n```json\n{\n \"APIKEY\": \"your-secret-key\",\n \"Providers\": [\n {\n \"name\": \"deepseek\",\n \"api_base_url\": \"https://api.deepseek.com/chat/completions\",\n \"api_key\": \"sk-xxx\",\n \"models\": [\"deepseek-chat\", \"deepseek-reasoner\"],\n \"transformer\": { \"use\": [\"deepseek\"] }\n }\n ],\n \"Router\": {\n \"default\": \"deepseek,deepseek-chat\",\n \"think\": \"deepseek,deepseek-reasoner\"\n }\n}\n```\n\n3. Start: `ccr start`\n\n4. Configure cc-connect:\n```toml\n[projects.agent.options]\nrouter_url = \"http://127.0.0.1:3456\"\nrouter_api_key = \"your-secret-key\" # optional\n```\n\n---\n\n## Voice Messages (Speech-to-Text)\n\nSend voice messages — cc-connect transcribes them automatically.\n\n**Supported:** Feishu, WeChat Work, Telegram, LINE, Discord, Slack\n\n**Requirements:** OpenAI/Groq API key, `ffmpeg`\n\n### Configure\n\n```toml\n[speech]\nenabled = true\nprovider = \"openai\" # or \"groq\"\nlanguage = \"\" # \"zh\", \"en\", or auto-detect\n\n[speech.openai]\napi_key = \"sk-xxx\"\n# base_url = \"\"\n# model = \"whisper-1\"\n\n# [speech.groq]\n# api_key = \"gsk_xxx\"\n# model = \"whisper-large-v3-turbo\"\n```\n\n### Install ffmpeg\n\n```bash\n# Ubuntu/Debian\nsudo apt install ffmpeg\n\n# macOS\nbrew install ffmpeg\n```\n\n---\n\n## Voice Reply (Text-to-Speech)\n\nSynthesize AI replies into voice messages.\n\n**Supported:** Feishu (Lark)\n\n### Configure\n\n```toml\n[tts]\nenabled = true\nprovider = \"qwen\" # or \"openai\"\nvoice = \"Cherry\"\ntts_mode = \"voice_only\" # \"voice_only\" | \"always\"\nmax_text_len = 0 # 0 = no limit\n\n[tts.qwen]\napi_key = \"sk-xxx\"\n# model = \"qwen3-tts-flash\"\n```\n\n### TTS Modes\n\n| Mode | Behavior |\n|------|----------|\n| `voice_only` | Reply with voice only when user sends voice |\n| `always` | Always send voice reply |\n\nSwitch: `/tts always` or `/tts voice_only`\n\n---\n\n## Scheduled Tasks (Cron)\n\nCreate scheduled tasks that run automatically.\n\n### Chat Commands\n\n```\n/cron List all jobs\n/cron add Create job\n/cron del Delete job\n/cron enable Enable job\n/cron disable Disable job\n```\n\nExample:\n```\n/cron add 0 6 * * * Summarize GitHub trending repos\n```\n\n### CLI Commands\n\n```bash\ncc-connect cron add --cron \"0 6 * * *\" --prompt \"Summarize GitHub trending\" --desc \"Daily Trending\"\ncc-connect cron list\ncc-connect cron del \n```\n\n### Natural Language (Claude Code)\n\n> \"Every day at 6am, summarize GitHub trending\"\n\nClaude Code auto-creates the cron job.\n\n---\n\n## Multi-Bot Relay\n\nCross-platform bot communication in group chats.\n\n### Group Chat Binding\n\n```\n/bind Show bindings\n/bind claudecode Add claudecode project\n/bind gemini Add gemini project\n/bind -claudecode Remove claudecode\n```\n\n### Bot-to-Bot Communication\n\n```bash\ncc-connect relay send --to gemini \"What do you think about this architecture?\"\n```\n\n---\n\n## Daemon Mode\n\nRun as background service.\n\n```bash\ncc-connect daemon install --config ~/.cc-connect/config.toml\ncc-connect daemon start\ncc-connect daemon stop\ncc-connect daemon restart\ncc-connect daemon status\ncc-connect daemon logs [-f]\ncc-connect daemon uninstall\n```\n\n---\n\n## Multi-Workspace Mode\n\nOne bot serving multiple workspaces per channel.\n\n### Configure\n\n```toml\n[[projects]]\nname = \"my-project\"\nmode = \"multi-workspace\"\nbase_dir = \"~/workspaces\"\n\n[projects.agent]\ntype = \"claudecode\"\n```\n\n### Commands\n\n```\n/workspace Show current binding\n/workspace bind Bind local folder\n/workspace init Clone and bind repo\n/workspace unbind Remove binding\n/workspace list List all bindings\n```\n\n### How It Works\n\n- Channel name `#project-a` → auto-binds to `base_dir/project-a/`\n- Each channel has isolated sessions and agent state\n\n---\n\n## Configuration Reference\n\nSee [config.example.toml](../config.example.toml) for full examples.\n\n### Project Structure\n\n```toml\n[[projects]]\nname = \"my-project\"\n\n[projects.agent]\ntype = \"claudecode\" # or codex, cursor, gemini, qoder, opencode, iflow\n\n[projects.agent.options]\nwork_dir = \"/path/to/project\"\nmode = \"default\"\nprovider = \"anthropic\"\n\n[[projects.platforms]]\ntype = \"feishu\" # or dingtalk, telegram, slack, discord, wecom, line, qq, qqbot\n\n[projects.platforms.options]\n# platform-specific options\n```\n"}}, "provider-presets.json": {"f2e4ed83c6953297a92d66d49114196fc4402206": {"t": 1785809875.0489967, "n": 28371, "h": "fc1ff3950d6c3c78", "c": "{\n \"version\": 2,\n \"updated_at\": \"2026-07-03\",\n \"providers\": [\n {\n \"name\": \"kimi\",\n \"display_name\": \"Kimi\",\n \"invite_url\": \"https://platform.kimi.ai/?aff=cc-connect\",\n \"description\": \"Kimi K2.7 Code — coding-focused open-source agentic model from Moonshot AI. Reduces thinking-token usage by ~30% vs K2.6. cc-connect brings Kimi CLI to Feishu/DingTalk/Telegram/Slack/Discord/WeChat Work.\",\n \"description_zh\": \"Kimi K2.7 Code — Moonshot AI 推出的编程专用开源智能体模型,相比 K2.6 平均减少约 30% 的推理 Token 消耗。cc-connect 可将本地 Kimi CLI 接入飞书/钉钉/Telegram/Slack/Discord/企业微信。\",\n \"features\": [\"K2.7 Code\", \"30% Less Tokens\", \"Sponsor\", \"cc-connect Native\"],\n \"tier\": 1,\n \"website\": \"https://www.kimi.com/\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"],\n \"codex_config\": {\"wire_api\": \"responses\"}\n },\n \"opencode\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"]\n }\n }\n },\n {\n \"name\": \"kimi-cn\",\n \"display_name\": \"Kimi (中国站)\",\n \"invite_url\": \"https://platform.kimi.com/?aff=cc-connect\",\n \"description\": \"Kimi K3 — Moonshot AI 迄今能力最强的模型,也是全球首个开源 3T 级模型。K3 拥有 2.8T 参数、原生视觉能力与 100 万 Token 上下文。\",\n \"description_zh\": \"Kimi K3 — Moonshot AI 迄今能力最强的模型,也是全球首个开源 3T 级模型。K3 拥有 2.8T 参数、原生视觉能力与 100 万 Token 上下文。\",\n \"features\": [\"K3\", \"Open Source\", \"Sponsor\", \"cc-connect Native\"],\n \"tier\": 1,\n \"website\": \"https://www.kimi.com/\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.moonshot.cn/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.moonshot.cn/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"],\n \"codex_config\": {\"wire_api\": \"responses\"}\n },\n \"opencode\": {\n \"base_url\": \"https://api.moonshot.cn/v1\",\n \"model\": \"kimi-k2-7-code\",\n \"models\": [\"kimi-k2-7-code\", \"kimi-k2-7\", \"kimi-k2-6\"]\n }\n }\n },\n {\n \"name\": \"minimax\",\n \"display_name\": \"MiniMax\",\n \"invite_url\": \"https://platform.minimax.io/subscribe/token-plan?code=lqYrKBvjke&source=link\",\n \"description\": \"MiniMax M3 — frontier coding & agentic LLM with 1M context via MiniMax Sparse Attention, natively multimodal. Exclusive 12% off Token Plan for cc-connect users!\",\n \"description_zh\": \"MiniMax M3 — 前沿 Coding 与 Agentic 大模型,1M 上下文(MiniMax Sparse Attention),原生多模态。cc-connect 用户专享 Token 套餐 88 折!\",\n \"features\": [\"1M Context\", \"M3 Frontier\", \"Multimodal\", \"SWE-Bench Pro 59.0\"],\n \"tier\": 1,\n \"website\": \"https://platform.minimax.io\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.minimax.io/anthropic\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M3-highspeed\", \"MiniMax-M2.7\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.minimax.io/v1\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M2.7\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.minimax.io/v1\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M2.7\"]\n }\n }\n },\n {\n \"name\": \"minimax-cn\",\n \"display_name\": \"MiniMax (中国站)\",\n \"invite_url\": \"https://platform.minimaxi.com/subscribe/token-plan?code=lqYrKBvjke&source=link\",\n \"description\": \"MiniMax M3 China endpoint — frontier coding & agentic LLM, lower latency for users in mainland China.\",\n \"description_zh\": \"MiniMax M3 国内站 — 前沿 Coding 与 Agentic 大模型,大陆用户延迟更低。cc-connect 用户专享 Token 套餐 88 折!\",\n \"features\": [\"1M Context\", \"M3 Frontier\", \"Multimodal\", \"低延迟 (CN)\"],\n \"tier\": 1,\n \"website\": \"https://platform.minimaxi.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.minimaxi.com/anthropic\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M3-highspeed\", \"MiniMax-M2.7\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.minimaxi.com/v1\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M2.7\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.minimaxi.com/v1\",\n \"model\": \"MiniMax-M3\",\n \"models\": [\"MiniMax-M3\", \"MiniMax-M2.7\"]\n }\n }\n },\n {\n \"name\": \"zhipu-glm\",\n \"display_name\": \"Zhipu GLM (z.ai)\",\n \"invite_url\": \"https://z.ai/subscribe\",\n \"description\": \"Zhipu GLM Coding Plan — flat-rate monthly subscription for GLM-4.7 / GLM-5.2 (1M context) via z.ai's Anthropic- and OpenAI-compatible endpoints. Works in Claude Code, Codex and OpenCode.\",\n \"description_zh\": \"智谱 GLM Coding Plan(z.ai 国际站)— 包月订阅,提供 GLM-4.7 / GLM-5.2(1M 上下文),兼容 Anthropic 与 OpenAI 接口,可用于 Claude Code、Codex、OpenCode。订阅 key 按套餐配额计费,非按量。\",\n \"features\": [\"GLM-5.2\", \"1M Context\", \"订阅制 (非按量)\", \"高性价比\"],\n \"tier\": 1,\n \"website\": \"https://z.ai\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.z.ai/api/anthropic\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\", \"glm-4.6\", \"glm-4.5-air\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.z.ai/api/coding/paas/v4\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\"],\n \"codex_config\": { \"wire_api\": \"chat\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.z.ai/api/coding/paas/v4\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\"]\n }\n }\n },\n {\n \"name\": \"zhipu-glm-cn\",\n \"display_name\": \"智谱 GLM (中国站)\",\n \"invite_url\": \"https://bigmodel.cn/claude-code\",\n \"description\": \"Zhipu GLM Coding Plan, China endpoint (open.bigmodel.cn) — lower latency for users in mainland China. GLM-4.7 / GLM-5.2 via Anthropic- and OpenAI-compatible APIs.\",\n \"description_zh\": \"智谱 GLM Coding Plan 国内站(open.bigmodel.cn)— 大陆用户延迟更低。GLM-4.7 / GLM-5.2,兼容 Anthropic 与 OpenAI 接口,可用于 Claude Code、Codex、OpenCode。\",\n \"features\": [\"GLM-5.2\", \"1M Context\", \"订阅制 (非按量)\", \"低延迟 (CN)\"],\n \"tier\": 1,\n \"website\": \"https://bigmodel.cn\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://open.bigmodel.cn/api/anthropic\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\", \"glm-4.6\", \"glm-4.5-air\"]\n },\n \"codex\": {\n \"base_url\": \"https://open.bigmodel.cn/api/coding/paas/v4\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\"],\n \"codex_config\": { \"wire_api\": \"chat\" }\n },\n \"opencode\": {\n \"base_url\": \"https://open.bigmodel.cn/api/coding/paas/v4\",\n \"model\": \"glm-4.7\",\n \"models\": [\"glm-4.7\", \"glm-5.2\", \"glm-5.2[1m]\"]\n }\n }\n },\n {\n \"name\": \"aigocode\",\n \"display_name\": \"AIGoCode\",\n \"invite_url\": \"https://aigocode.com/invite/CYY3C85C\",\n \"description\": \"All-in-one platform: Claude Code, Codex & Gemini. Flexible plans, no VPN needed, fast response. 10% bonus credit on first top-up via link!\",\n \"description_zh\": \"集成 Claude Code、Codex、Gemini 的全能平台。灵活套餐,免翻墙,响应快速。通过链接注册首充额外赠送 10%!\",\n \"features\": [\"Claude Code\", \"Codex\", \"Gemini\", \"No VPN\"],\n \"tier\": 2,\n \"website\": \"https://aigocode.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.aigocode.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.aigocode.com\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://api.aigocode.com\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\", \"gemini-3.1-pro\"]\n },\n \"opencode\": {\n \"base_url\": \"https://api.aigocode.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"aihubmix\",\n \"display_name\": \"AIHubMix\",\n \"invite_url\": \"https://aihubmix.com/?aff=mGTx\",\n \"description\": \"500+ models in one API. Claude, GPT, Gemini, Qwen, DeepSeek all covered. Unlimited concurrency, Google Cloud infrastructure. Native OpenAI/Anthropic/Gemini format support, zero code migration.\",\n \"description_zh\": \"500+ 模型一站式覆盖,Claude/GPT/Gemini/Qwen/DeepSeek 全支持。无限并发,谷歌云集群稳定运行。支持 OpenAI/Anthropic/Gemini 三种原生格式,代码零改动迁移。\",\n \"features\": [\"500+ Models\", \"Unlimited Concurrency\", \"Google Cloud\", \"All Formats\"],\n \"tier\": 2,\n \"website\": \"https://aihubmix.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.aihubmix.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\", \"claude-opus-4-6\", \"claude-sonnet-4-6\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.aihubmix.com/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\", \"gpt-5.4-mini\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://api.aihubmix.com\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\", \"gemini-3.1-pro\"]\n },\n \"opencode\": {\n \"base_url\": \"https://api.aihubmix.com/v1\",\n \"model\": \"claude-sonnet-4-6\",\n \"models\": [\"claude-sonnet-4-6\", \"claude-opus-4-6\"]\n }\n }\n },\n {\n \"name\": \"shengsuanyun\",\n \"display_name\": \"Shengsuanyun (胜算云)\",\n \"invite_url\": \"https://www.shengsuanyun.com/?from=CH_67XCLZGS\",\n \"description\": \"Industrial-grade AI platform with 99.7% SLA. Smart routing, BYOK hosting, pay-as-you-go. Free $2 credit for new users!\",\n \"description_zh\": \"工业级 AI 平台,99.7% SLA 保障。智能路由,BYOK 密钥托管,按量计费。新用户注册赠送 $2!\",\n \"features\": [\"99.7% SLA\", \"Smart Routing\", \"BYOK\", \"Claude/Codex/Gemini\"],\n \"tier\": 2,\n \"website\": \"https://www.shengsuanyun.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://router.shengsuanyun.com/api\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\", \"claude-sonnet-4-6\", \"claude-opus-4-6\"]\n },\n \"codex\": {\n \"base_url\": \"https://router.shengsuanyun.com/api/v1\",\n \"model\": \"openai/gpt-5.3-codex\",\n \"models\": [\"openai/gpt-5.3-codex\", \"gpt-5.4\", \"gpt-5.4-mini\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://router.shengsuanyun.com/api\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\", \"gemini-3.1-pro\"]\n },\n \"opencode\": {\n \"base_url\": \"https://router.shengsuanyun.com/api/v1\",\n \"model\": \"claude-opus-4-6\",\n \"models\": [\"claude-opus-4-6\", \"claude-sonnet-4-6\"]\n }\n }\n },\n {\n \"name\": \"dmxapi\",\n \"display_name\": \"DMXAPI\",\n \"invite_url\": \"https://www.dmxapi.cn/register?aff=NDln\",\n \"description\": \"Global LLM API for 200+ enterprises. One key for all models. GPT/Claude/Gemini at 32% off, Claude Code models at 66% off!\",\n \"description_zh\": \"服务 200+ 企业的全球大模型 API。一个 Key 接入所有模型。GPT/Claude/Gemini 3.2 折,Claude Code 专属模型低至 6.6 折!\",\n \"features\": [\"All Models\", \"Unlimited Concurrency\", \"24/7 Support\"],\n \"tier\": 2,\n \"website\": \"https://www.dmxapi.cn\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://www.dmxapi.cn\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://www.dmxapi.cn/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://www.dmxapi.cn/v1\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"camel\",\n \"display_name\": \"CaMeL\",\n \"invite_url\": \"https://camel.kr777.top/register?aff=V2z8\",\n \"description\": \"In-depth cooperation with major research institutes and supercomputing centers, self-developed high-stability high-efficiency cache scheduling solution. Exclusive cc-connect benefit: New users get $10 credit upon registration!\",\n \"description_zh\": \"携手各大科研院所、超算中心深度合作,自研高稳高效缓存调度方案。CC-Connect专享新人注册认证即送$10!\",\n \"features\": [\"Research Institutes\", \"Cache Scheduling\", \"$10 New User Credit\"],\n \"tier\": 2,\n \"website\": \"https://camel.kr777.top\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.camel.kr777.top\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.camel.kr777.top/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"apikeyfun\",\n \"display_name\": \"APIKEY.FUN\",\n \"invite_url\": \"https://apikey.fun/register?aff=cc_connect\",\n \"description\": \"Enterprise-grade AI relay service. Claude, OpenAI, Gemini models from 7% of official price. Exclusive 5% permanent discount for cc-connect users!\",\n \"description_zh\": \"企业级 AI 中转站,Claude/OpenAI/Gemini 模型低至官方 7% 折,cc-connect 用户专属 95 折永久优惠!\",\n \"features\": [\"Enterprise\", \"Claude/OpenAI/Gemini\", \"7% Price\", \"95折\"],\n \"tier\": 2,\n \"website\": \"https://apikey.fun\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.apikey.fun\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.apikey.fun/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"aicodemirror\",\n \"display_name\": \"AICodeMirror\",\n \"invite_url\": \"https://www.aicodemirror.com/register?invitecode=KDHMUP\",\n \"description\": \"Official high-stability relay for Claude Code / Codex / Gemini. Enterprise concurrency, 24/7 support. 20% off first top-up for cc-connect users!\",\n \"description_zh\": \"Claude Code / Codex / Gemini 官方高稳定中转。企业级并发,24/7 技术支持。cc-connect 用户首充 8 折,企业最高 75 折!\",\n \"features\": [\"Claude Code\", \"Codex\", \"Gemini\", \"Enterprise\"],\n \"tier\": 2,\n \"website\": \"https://www.aicodemirror.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.aicodemirror.com/api/claudecode\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.aicodemirror.com/api/codex/backend-api/codex\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://api.aicodemirror.com/api/gemini\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\", \"gemini-3.1-pro\"]\n },\n \"opencode\": {\n \"base_url\": \"https://api.aicodemirror.com/api/claudecode\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"code0\",\n \"display_name\": \"Code0\",\n \"invite_url\": \"https://code0.ai/register?aff=5cGO\",\n \"description\": \"AI model aggregation relay for Chinese developers. OpenAI/Anthropic/Gemini compatible. ¥1.5 = $1, transparent pricing, domestic direct.\",\n \"description_zh\": \"面向国内开发者的 AI 模型聚合中转。兼容 OpenAI/Anthropic/Gemini 协议。¥1.5 = $1 固定汇率,透明定价,国内直连。\",\n \"features\": [\"All Protocols\", \"¥1.5=$1\", \"Domestic Direct\"],\n \"tier\": 2,\n \"website\": \"https://code0.ai\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.code0.ai\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.code0.ai/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://api.code0.ai\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\"]\n }\n }\n },\n {\n \"name\": \"dragoncode\",\n \"display_name\": \"DragonCode\",\n \"invite_url\": \"https://dragoncode.codes/register?ref=23ZELCPX\",\n \"description\": \"AI model API relay service. Register via link to get started.\",\n \"description_zh\": \"AI 模型 API 中转服务。通过链接注册即可开始体验。\",\n \"features\": [\"Claude Code\", \"Codex\", \"Gemini\"],\n \"tier\": 2,\n \"website\": \"https://dragoncode.codes\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.dragoncode.codes\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.dragoncode.codes/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.dragoncode.codes/v1\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"youyunzhisuan\",\n \"display_name\": \"优云智算 (UCloud AI)\",\n \"invite_url\": \"https://passport.compshare.cn/register?referral_code=H65IOClRGu5CM7nn5ykfad&ytag=GPU_YY_YX_git_cc-connect\",\n \"description\": \"UCloud AI Cloud Platform. One key for all domestic and international models. High-value Coding Plan packages, enterprise support. ¥5 free credit for new users!\",\n \"description_zh\": \"UCloud 旗下 AI 云平台,一个 key 调用国内外模型。高性价比 Coding Plan 套餐,企业级支持。新用户送 5 元体验金!\",\n \"features\": [\"UCloud\", \"Coding Plan\", \"Enterprise Support\", \"¥5 Free\"],\n \"tier\": 2,\n \"website\": \"https://passport.compshare.cn\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.compshare.cn\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.compshare.cn/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.compshare.cn/v1\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"claudeapi\",\n \"display_name\": \"claudeapi.com\",\n \"invite_url\": \"https://console.claudeapi.com/register?aff=GDbA\",\n \"description\": \"Premium direct Claude connection — official 1st-party Keys & AWS Bedrock. No reverse engineering, full capabilities preserved.\",\n \"description_zh\": \"高品质 Claude 直连服务 — 官方一手 Key + AWS Bedrock 官方通道。无逆向无降智,完整保留官方能力。\",\n \"features\": [\"Official Channel\", \"No Reverse Eng.\", \"Enterprise\"],\n \"tier\": 2,\n \"website\": \"https://console.claudeapi.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.claudeapi.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\", \"claude-haiku-3-5-20241022\"]\n },\n \"opencode\": {\n \"base_url\": \"https://api.claudeapi.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"nekocode\",\n \"display_name\": \"NekoCode\",\n \"invite_url\": \"https://nekocode.ai/?aff=CC-CONNECT\",\n \"description\": \"Reliable, stable API relay for Claude and CodeX. Transparent pricing. Exclusive 10% off for cc-connect users with code: CC-CONNECT.\",\n \"description_zh\": \"Claude 和 CodeX 可靠稳定高效的 API 中转站,价格透明。cc-connect 用户专属 9 折福利码:CC-CONNECT。\",\n \"features\": [\"Claude Code\", \"CodeX\", \"Transparent Pricing\", \"10% Off\"],\n \"tier\": 2,\n \"website\": \"https://nekocode.ai\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.nekocode.cc\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.nekocode.cc/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"opencode\": {\n \"base_url\": \"https://api.nekocode.cc/v1\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"visioncoder\",\n \"display_name\": \"VisionCoder\",\n \"invite_url\": \"https://coder.visioncoder.cn\",\n \"description\": \"Reliable API relay for Claude Code, Codex, Gemini. Limited-time Token Plan: buy 1 month, get 1 month free.\",\n \"description_zh\": \"可靠高效的 API 中继服务,支持 Claude Code、Codex、Gemini。Token Plan 限时活动:购买 1 个月,赠送 1 个月。\",\n \"features\": [\"Claude Code\", \"Codex\", \"Gemini\", \"Buy 1 Get 1 Free\"],\n \"tier\": 2,\n \"website\": \"https://coder.visioncoder.cn\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://coder.visioncoder.cn\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://coder.visioncoder.cn/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n },\n \"gemini\": {\n \"base_url\": \"https://coder.visioncoder.cn\",\n \"model\": \"gemini-2.5-pro\",\n \"models\": [\"gemini-2.5-pro\"]\n },\n \"opencode\": {\n \"base_url\": \"https://coder.visioncoder.cn/v1\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n }\n }\n },\n {\n \"name\": \"anyroute\",\n \"display_name\": \"AnyRoute.io\",\n \"invite_url\": \"https://cc.anyroute.io/register?aff=CR455DSQSKEV\",\n \"description\": \"Reliable API relay platform integrating Claude Code and Codex models. Transparent pricing, rates as low as 0.7x official price, supports invoicing and enterprise-grade high-concurrency.\",\n \"description_zh\": \"可靠稳定高效的 API 中转平台,集成 Claude Code、Codex 最新模型。价格透明,最低低至官方 0.7 折,支持开票和企业高并发。\",\n \"features\": [\"Claude Code\", \"Codex\", \"0.7x Price\", \"Enterprise\"],\n \"tier\": 2,\n \"website\": \"https://cc.anyroute.io\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.anyroute.io\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.anyroute.io/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"aicanapi\",\n \"display_name\": \"aicanapi.com\",\n \"invite_url\": \"https://aicanapi.com/register?aff=rIEy\",\n \"description\": \"High-performance API relay for enterprises and developers. Claude Code models up to 84% off, other models at 20% of official price. Doubao Seedance 2 with queue-free access.\",\n \"description_zh\": \"高性能 API 接口服务,支持 Claude、GPT、Gemini 等主流模型。Claude Code 最低 1.6 折,其余模型 2 折。豆包 Seedance 2 免排队调用。\",\n \"features\": [\"Claude Code\", \"GPT\", \"Gemini\", \"Doubao\", \"16% Price\"],\n \"tier\": 2,\n \"website\": \"https://aicanapi.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.aicanapi.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.aicanapi.com/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"pateway\",\n \"display_name\": \"Pateway\",\n \"invite_url\": \"https://pateway.ai/?ch=2qn568&aff=DRA4VUFS\",\n \"description\": \"Premium API relay for serious AI developers. 100% official direct access to Claude and Codex models — no reverse engineering, no quality degradation. $3 free trial, up to 40% off.\",\n \"description_zh\": \"面向重度 AI 开发者的优质 API 中转。100% 官方源直供 Claude/Codex,不掺假不注水。注册送 $3 试用额度,充值低至 6 折。\",\n \"features\": [\"Claude Code\", \"Codex\", \"Official Direct\", \"$3 Trial\"],\n \"tier\": 2,\n \"website\": \"https://pateway.ai\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.pateway.ai\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.pateway.ai/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"10dianai\",\n \"display_name\": \"10点AI\",\n \"invite_url\": \"https://cy.10dianai.com/register?aff=3FQn\",\n \"description\": \"AI API gateway for developers and enterprises. Aggregates GPT, Claude, Gemini, DeepSeek. Production-optimized with high concurrency, stable operation. Register for ¥5 free credit.\",\n \"description_zh\": \"面向开发者和企业的 AI API 中转平台,聚合 GPT、Claude、Gemini、DeepSeek 等主流模型。生产环境优化,高并发稳定运行。注册即送 ¥5。\",\n \"features\": [\"GPT\", \"Claude\", \"Gemini\", \"DeepSeek\", \"¥5 Free\"],\n \"tier\": 2,\n \"website\": \"https://cy.10dianai.com\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.10dianai.com\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.10dianai.com/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n },\n {\n \"name\": \"siliconflow\",\n \"display_name\": \"SiliconFlow\",\n \"invite_url\": \"https://cloud.siliconflow.cn/i/650Yh2Z7\",\n \"description\": \"High-performance AI infrastructure and model API platform. Fast access to language, speech, image, and video models. Pay-as-you-go, multimodal support, enterprise-grade stability. ¥20 bonus for new users!\",\n \"description_zh\": \"高性能 AI 基础设施和模型 API 平台,提供语言、语音、图片、视频等多种模型快速访问。按量计费,多模态支持,企业级稳定性。新用户注册送 ¥20!\",\n \"features\": [\"Multimodal\", \"Pay-as-you-go\", \"¥20 Bonus\", \"Fast Inference\"],\n \"tier\": 2,\n \"website\": \"https://siliconflow.cn\",\n \"agents\": {\n \"claudecode\": {\n \"base_url\": \"https://api.siliconflow.cn\",\n \"model\": \"claude-sonnet-4-20250514\",\n \"models\": [\"claude-sonnet-4-20250514\", \"claude-opus-4-20250514\"]\n },\n \"codex\": {\n \"base_url\": \"https://api.siliconflow.cn/v1\",\n \"model\": \"gpt-5.4\",\n \"models\": [\"gpt-5.4\"],\n \"codex_config\": { \"wire_api\": \"responses\" }\n }\n }\n }\n ]\n}\n"}}}}