Files
chenhg5-cc-connect/config.example.toml
Han 355793eaee refactor(agent): centralize cmd/env option parsing into core with unified cmd field (#1297)
* refactor: centralize cmd/env option parsing into core

- Add core.ParseCmdOpts() to unify cmd/cli_path/command option
  parsing across all agents, with deprecation warnings for old keys
- Add core.ParseConfigEnv() to parse [projects.agent.options.env]
  from config into []string KEY=VALUE format
- Rename cliBin/command struct fields to cmd consistently
- Add cliExtraArgs support so cmd="binary arg1 arg2" works
- Add configEnv field for static env that persists across SetSessionEnv
- Fix env merge order: configEnv < providerEnv < sessionEnv (was
  inconsistent in copilot and opencode agents)
- Update all tests for renamed fields

* fix(claudecode): add backward compat for deprecated cli_args_flag

Users with cli_args_flag in their config.toml will see a deprecation
warning directing them to the new cmd_args_flag key.

* docs(config): update config examples to use cmd instead of deprecated keys

- config.example.toml: cli_path → cmd, command(S) → S(6 occurrences)
- claudecode/claudecode.go: comment cli_path → cmd
- copilot/copilot_test.go: comment cliBin/cli_path → cmd

* test(core): add direct unit tests for ParseCmdOpts and ParseConfigEnv

Address review feedback on PR #1297 (P2). The two helper functions in
core/cmdopts.go are depended on by 13 agent packages; previously their
behavior was only covered indirectly via agent-level New() tests. This
commit adds direct unit tests covering:

- ParseCmdOpts: four-tier priority (cmd / cli_path / command / default),
  empty/whitespace boundaries, tokenization of extra args, no-warning
  for canonical cmd field, and capture of deprecation warnings.
- ParseConfigEnv: nil / missing key, map[string]string, map[string]any
  (TOML parser output), non-string value filtering, unsupported types,
  and input non-mutation.

Also adds structured slog attrs (deprecated_key, new_key) to all three
deprecation warnings (cli_path, command, cli_args_flag) so that future
log aggregation can scan deprecated-key usage without code changes
(review feedback P3).

Ref: PR #1297 review.

* fix(codex): use local cmd var (not stale cliBin name) in struct init

Post-rebase fixup: the struct field was renamed cliBin -> cmd in
PR #1297, and the local variable returned by core.ParseCmdOpts is
also named cmd. The rebased struct initializer still referenced
the old name 'cliBin', which no longer exists in scope. Assign
the local cmd variable to the cmd struct field.
2026-06-23 07:05:16 +08:00

2031 lines
104 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# cc-connect configuration
# cc-connect 配置文件
#
# Copy this file to config.toml and fill in your credentials.
# 复制此文件为 config.toml填入你的凭证信息。
#
# String values support ${VAR_NAME} environment variable substitution.
# Example: token = "${TELEGRAM_BOT_TOKEN}" / 所有字符串值都支持 ${VAR_NAME} 环境变量替换。
# 例如token = "${TELEGRAM_BOT_TOKEN}"
#
# Each [[projects]] entry binds one code directory to its own agent + platforms.
# A single cc-connect process can manage multiple projects simultaneously.
# 每个 [[projects]] 将一个代码目录绑定到独立的 agent 和平台。
# 单个 cc-connect 进程可以同时管理多个项目。
# =============================================================================
# Global Settings / 全局设置
# =============================================================================
# Language for bot messages / 机器人消息语言
# - "en": English
# - "zh": 中文
# - "" (empty/not set): Auto-detect from user's first message / 留空自动检测
# language = "en"
# Shell for /shell commands, cron exec, hooks, and webhook exec.
# /shell 命令、cron exec、hooks 和 webhook exec 使用的 shell。
# Default / 默认: "sh" (Unix) or "powershell.exe" (Windows)
# Supported / 支持: sh, bash, zsh, fish, cmd, powershell, pwsh
# shell = "/bin/zsh"
# Init command prepended to every shell command. Useful for sourcing profiles
# so user-defined functions and aliases are available.
# 初始化命令,会添加到每条 shell 命令前面。用于加载 profile使自定义函数和别名可用。
# shell_profile = "source ~/.zshrc"
# Session data storage directory (default: ~/.cc-connect)
# Stores conversation history and session state as JSON files.
# 会话数据存储目录(默认 ~/.cc-connect以 JSON 文件保存对话历史和会话状态。
# data_dir = "/path/to/custom/dir"
# Attachment send-back switch for `cc-connect send --image/--file`.
# Independent from the agent's /mode. Set to "off" to block IM image/file send-back.
# `cc-connect send --message` without attachments is unaffected.
# 附件回传开关,用于控制 `cc-connect send --image/--file`。
# 它与 agent 的 /mode 独立;设为 "off" 会禁用通过 IM 回传图片/文件。
# 不带附件的 `cc-connect send --message` 不受影响。
# attachment_send = "on"
# Maximum size of a single attachment (in MiB) for `cc-connect send
# --file/--image/--audio/--video` and the /send API. Default: 50 (i.e. 50 MiB).
# Set 0 to keep the default. Raise it to send larger files; the /send request
# body limit scales with this value to fit base64-encoded attachments.
# Can also be overridden by the CC_MAX_ATTACHMENT_SIZE_MB env var (same MiB
# unit; takes precedence over this option when set).
# `cc-connect send` 单个附件的最大大小(单位 MiB。默认 50即 50 MiB设 0 保持默认。
# 调大可发送更大文件;/send 请求体上限会随之按 base64 膨胀自动放大。
# 也可用环境变量 CC_MAX_ATTACHMENT_SIZE_MB 覆盖(同样单位 MiB设置后优先级高于本配置项
# max_attachment_size_mb = 50
[log]
level = "info" # debug, info, warn, error
# =============================================================================
# Global Providers / 全局服务商
# =============================================================================
# Define providers once globally; projects reference them by name via provider_refs.
# 在此统一定义服务商,项目通过 provider_refs 按名称引用。
# This avoids duplicating API keys across projects.
# 避免在多个项目中重复配置 API Key。
#
# Remote presets URL (fetches recommended providers list from GitHub/Gitee)
# 远程预设列表 URL从 GitHub/Gitee 拉取推荐服务商)
# provider_presets_url = "https://raw.githubusercontent.com/chenhg5/cc-connect/main/provider-presets.json"
# [[providers]]
# name = "anthropic"
# api_key = "${ANTHROPIC_API_KEY}"
# agent_types = ["claudecode"] # only for Claude Code projects
# [[providers]]
# name = "minimaxi-claude"
# api_key = "${MINIMAXI_API_KEY}"
# base_url = "https://api.minimaxi.chat/v1"
# agent_types = ["claudecode"]
# model = "claude-sonnet-4-20250514"
# [[providers]]
# name = "minimaxi-codex"
# api_key = "${MINIMAXI_API_KEY}"
# base_url = "https://api.minimaxi.chat/v1"
# agent_types = ["codex"]
# model = "MiniMax-M2.7"
# [[providers]]
# name = "dashscope"
# api_key = "${DASHSCOPE_API_KEY}"
# base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
# model = "glm-5.1"
# thinking = "disabled"
# =============================================================================
# Display Settings / 显示设置
# =============================================================================
# Controls how intermediate messages (thinking, tool use) are shown in chat.
# 控制中间消息(思考过程、工具调用)在聊天中的显示方式。
#
# Set to 0 to disable truncation (show full content).
# 设为 0 表示不截断(显示完整内容)。
# [display]
# mode = "full" # Display mode: "full" (default), "compact", or "quiet"
# # full: show thinking + tool messages as separate messages
# # 显示思考和工具消息,每条单独发送
# # compact: hide thinking/tool, each text segment sent separately
# # 隐藏思考和工具消息,每段文本独立发送
# # quiet: hide thinking/tool, all text in one card, done emoji at end
# # 隐藏思考和工具消息,所有文本合并到同一张卡片,完成后发送 done emoji
# thinking_messages = true # Show/hide thinking messages (default: true) / 是否显示思考消息(默认 true
# thinking_max_len = 300 # Max chars for thinking messages (default: 300) / 思考消息最大字符数(默认 300
# tool_max_len = 500 # Max chars for tool use messages (default: 500) / 工具调用消息最大字符数(默认 500
# history_max_len = 1000 # Max chars per /history entry (default: 1000; 0 = no truncation) / 每条历史记录最大字符数(默认 10000 表示不截断)
# tool_messages = true # Show/hide tool progress messages (default: true) / 是否显示工具进度消息(默认 true
# show_context_indicator = true # Show "[ctx: ~N%]" suffix on assistant replies (default: true)
# # 在助手回复末尾显示「[ctx: ~N%]」上下文占用提示(默认 true 显示)
# reply_footer = true # Show Codex-like footer on assistant replies (default: true)
# # 在助手回复底部显示类似 Codex 的状态行(默认 true 显示)
# Per-project override: each [[projects]] entry may have its own [projects.display]
# block that overrides individual fields of the global [display] block above.
# Resolution order is per-field — set fields win, unset fields fall back to global,
# then to built-in defaults. Useful when one project should be quiet while others
# stay verbose, or vice versa.
# 每个 [[projects]] 条目可以有自己的 [projects.display] 块,逐字段覆盖全局
# [display]。已设字段优先,未设字段回落到全局值,再回落到默认值。
#
# [[projects]]
# name = "noisy-project"
# [projects.display]
# thinking_messages = false # Override only this field; others inherit from global
# tool_messages = false
# Agent idle timeout: max minutes between consecutive agent events before
# considering the session stuck. Set to 0 to disable the timeout entirely.
# Agent 空闲超时:两次 agent 事件之间的最大等待分钟数,超时则认为会话卡住。设为 0 禁用。
# idle_timeout_mins = 120 # default: 120 (2 hours) / 默认 1202 小时)
# Absolute wall-clock cap per agent turn in minutes. Unlike idle_timeout_mins
# (which resets on every event), this timer is never reset — it guarantees the
# session is released even when a long bash command generates periodic tool events.
# Recommended: 3060 minutes for most use cases. Default: 0 (disabled).
# 每次 agent 对话的绝对时间上限(分钟)。与 idle_timeout_mins 不同,此计时器不会因
# 工具调用事件而重置,可防止长时间运行的 bash 命令永久占用会话(#1091
# 推荐值3060。默认 0禁用
# max_turn_time_mins = 0 # default: disabled / 默认禁用
# Auto-reset the active session after the user has been inactive for a while.
# Unlike idle_timeout_mins, this does not detect stuck agent execution. It
# rotates to a fresh cc-connect session when the user comes back after being idle.
# This avoids "context drift", where stale chat history (failed commands,
# debugging noise, abandoned tangents) gets re-ingested via --continue every
# time the workspace pool evicts the session, and starts to dominate the model's
# attention. The previous session is preserved and remains accessible via
# /list and /switch.
#
# Default: 30 minutes when unset. Set to 0 to opt out and always continue the
# previous session (the pre-default behavior).
# 用户长时间未发消息后,自动切换到一个新的活跃会话。
# 这与 idle_timeout_mins 不同:它不是检测 agent 卡住,而是用户回来后自动开始新会话。
# 默认值为 30 分钟(未设置时)。设为 0 可以禁用此行为,恢复始终继续上次会话。
# [[projects]]
# reset_on_idle_mins = 30 # default when unset / 未设置时的默认值;设为 0 表示禁用
# =============================================================================
# OS-user isolation via run_as_user (Linux/macOS only)
# 通过 run_as_user 实现 OS 用户隔离(仅限 Linux/macOS
# =============================================================================
#
# Spawn a project's agent command under a different Unix user via
# `sudo -n -iu <user>`. This provides OS-level file-system isolation from
# the supervisor user that runs cc-connect itself, so a misbehaving agent
# cannot read files outside the target user's permission scope.
#
# Currently supported by: claudecode.
# Other agents use the supervisor user until migrated in a follow-up PR.
#
# Setup (one-time):
# 1. Create the target Unix user and install their tooling:
# sudo useradd -m -s /bin/bash partseeker-coder
# sudo -iu partseeker-coder
# # install claude CLI, set up ~/.claude/settings.json, PGSSL certs,
# # ~/.pgpass, plugin state, anything the agent needs.
# 2. Grant the supervisor user passwordless sudo to the target:
# # /etc/sudoers.d/cc-connect
# partseeker-orchestrator ALL=(partseeker-coder) NOPASSWD: ALL
# 3. Ensure the target user does NOT have passwordless sudo to anywhere
# else. `sudo -n -iu partseeker-coder -- sudo -n true` must fail.
# 4. Ensure the target user can read AND write the project's work_dir.
# 5. Run `cc-connect doctor user-isolation` to audit the setup before
# starting cc-connect.
#
# cc-connect refuses to start if any preflight gate fails (missing sudo,
# target can escalate, work_dir inaccessible) or if the isolation probe
# detects that the target user can read another user's secrets.
#
# [[projects]]
# name = "claude-sandboxed"
# run_as_user = "partseeker-coder"
# # Extra env vars to forward across the sudo boundary. The default
# # allowlist (PATH, LANG, LC_*, TERM) is always included; only list
# # names that the target user cannot reasonably set in their own shell
# # profile. Secrets belong in the target user's ~/.claude/settings.json
# # env block, NOT here.
# run_as_env = ["PGSSLROOTCERT", "PGSSLMODE"]
# =============================================================================
# Streaming Preview / 流式预览
# =============================================================================
# Real-time message preview: shows agent output as it streams, updating the
# message in-place (like a "typing" indicator). Supported on Telegram, Discord,
# and Feishu. The message is edited periodically until the final response is sent.
# 实时流式预览Agent 输出时实时更新消息(类似"正在输入"效果)。
# 支持 Telegram、Discord 和飞书。消息会定期编辑,直到最终回复发送。
# [stream_preview]
# enabled = true # Enable/disable streaming preview (default: true) / 启用/禁用流式预览(默认 true
# interval_ms = 1500 # Min ms between updates (default: 1500) / 更新最小间隔毫秒数(默认 1500
# min_delta_chars = 30 # Min new chars before sending update (default: 30) / 发送更新前最少新增字符数(默认 30
# max_chars = 2000 # Max preview length (default: 2000) / 预览最大长度(默认 2000
# =============================================================================
# Instant Reply / 即时确认回复
# =============================================================================
# Send an immediate confirmation message when a user message is received,
# before the agent starts processing. This gives users quick feedback
# that their message was received (e.g. "🤔 Thinking...").
# 收到用户消息后立即发送确认消息(在 Agent 开始处理之前),让用户知道消息已收到。
#
# Platforms with streaming card support (e.g. DingTalk with AI Card configured)
# will skip instant reply since the card itself provides a "processing" indicator.
# 已配置流式卡片的平台(如钉钉 AI Card会自动跳过即时回复因为卡片本身已提供处理指示。
# [instant_reply]
# enabled = false # Enable/disable instant reply (default: false) / 启用/禁用即时确认回复(默认 false
# content = "🤔 Thinking..." # Custom reply text; empty = use i18n default ("⏳ Processing...")
# # 自定义回复内容;留空则使用 i18n 默认值("⏳ 处理中..."
# =============================================================================
# Rate Limiting / 速率限制
# =============================================================================
# Per-session sliding-window rate limiter. Prevents users from flooding the bot
# with too many messages. When exceeded, a friendly "slow down" message is sent.
# 每会话滑动窗口速率限制。防止用户刷消息。超限时返回友好的提示。
# [rate_limit]
# max_messages = 20 # Max messages per window; 0 = disabled (default: 20) / 窗口内最大消息数0 = 禁用(默认 20
# window_secs = 60 # Window size in seconds (default: 60) / 窗口时间秒数(默认 60
# =============================================================================
# Outgoing Rate Limit / 出站速率限制
# Throttle how fast messages are sent TO platforms.
# Prevents account bans on platforms with strict API rate limits (e.g. WeChat Work).
# 限制向平台发送消息的速率,防止因频率过高被封号(如企业微信)。
# =============================================================================
# [outgoing_rate_limit]
# max_per_second = 0 # Global default msgs/sec; 0 = unlimited (default) / 全局默认每秒消息数0 = 无限制
# burst = 3 # Max burst size; default = ceil(max_per_second) / 最大突发数量
# # For fractional rates (e.g. 0.2), default burst becomes ceil(max_per_second).
# Per-platform overrides / 每平台覆盖配置:
# [outgoing_rate_limit.platforms.wecom]
# max_per_second = 1
# [outgoing_rate_limit.platforms.telegram]
# max_per_second = 25
# [outgoing_rate_limit.platforms.feishu]
# max_per_second = 5
# =============================================================================
# Relay Settings / Relay 设置
# =============================================================================
# Bot-to-bot relay settings. timeout_secs controls how long cc-connect waits for
# the target bot to finish responding during `cc-connect relay send`.
# visibility controls the extra group-chat echo only; the caller still receives
# the target response from the relay command when visibility is "none".
# Bot 间 relay 设置。timeout_secs 控制 `cc-connect relay send` 等待目标 bot
# 完成回复的最长时间。visibility 只控制群内额外可见消息;设为 "none" 时调用方
# 仍会从 relay 命令拿到目标回复。
# [relay]
# timeout_secs = 120 # Max relay wait in seconds; 0 = disabled (default: 120) / relay 最大等待秒数0 = 禁用(默认 120
# visibility = "full" # "full" (default), "summary", or "none" / 群内可见消息:完整、摘要或不显示
# =============================================================================
# Auto-Compress / 自动压缩
# =============================================================================
# Automatically trigger /compress when estimated token usage exceeds threshold.
# 当估算 token 超过阈值时自动触发 /compress。
#
# [projects.auto_compress]
# enabled = true
# max_tokens = 12000 # estimated token threshold to trigger compression
# min_gap_mins = 30 # minimum minutes between auto-compress runs (default 30)
# [projects.observe]
# enabled = true # Forward native terminal sessions to Slack
# channel = "C0AL13PN4BG" # Slack channel ID to post observations to
# =============================================================================
# Cron Settings / 定时任务设置
# =============================================================================
# Controls cron job behavior.
# 控制定时任务行为。
# [cron]
# silent = false # Suppress "⏰ task name" notification when cron starts (default: false)
# # 静默模式:不发送定时任务开始执行的通知消息(默认 false
# session_mode = "reuse" # Default session mode for all cron jobs: "reuse" (default) or "new_per_run"
# # 定时任务默认会话模式:"reuse"(复用活跃会话)或 "new_per_run"(每次新建会话)
# =============================================================================
# Webhook / 外部 Webhook 端点
# =============================================================================
# Exposes an HTTP endpoint for external systems (git hooks, CI/CD, file watchers)
# to trigger agent prompts or shell commands.
# 暴露一个 HTTP 端点供外部系统git hook、CI/CD、文件监听触发 agent 或 shell 命令。
#
# [webhook]
# enabled = true
# port = 9111 # Listen port (default: 9111) / 监听端口(默认 9111
# token = "your-secret-token" # Shared secret for auth; empty = no auth / 认证密钥;为空则不验证
# path = "/hook" # URL path (default: "/hook") / URL 路径(默认 "/hook"
#
# Usage / 使用方式:
#
# # Trigger an agent prompt / 触发 agent 执行
# curl -X POST http://localhost:9111/hook \
# -H "Authorization: Bearer your-secret-token" \
# -H "Content-Type: application/json" \
# -d '{"session_key":"telegram:123:123","prompt":"review latest commit","event":"git:commit"}'
#
# # Execute a shell command / 执行 shell 命令
# curl -X POST http://localhost:9111/hook \
# -H "Authorization: Bearer your-secret-token" \
# -H "Content-Type: application/json" \
# -d '{"session_key":"telegram:123:123","exec":"git log -3 --oneline","event":"git:push"}'
#
# # Git post-commit hook example (.git/hooks/post-commit):
# # #!/bin/sh
# # MSG=$(git log -1 --pretty=format:"%s")
# # curl -sX POST http://localhost:9111/hook \
# # -H "Authorization: Bearer your-secret-token" \
# # -H "Content-Type: application/json" \
# # -d "{\"session_key\":\"telegram:123:123\",\"event\":\"git:commit\",\"prompt\":\"New commit: $MSG. Review it briefly.\"}"
# =============================================================================
# Bridge Platform (External Adapters via WebSocket)
# Bridge 平台(通过 WebSocket 接入外部适配器)
# =============================================================================
# Allow external adapters written in any language to connect at runtime.
# 允许使用任何语言编写的外部适配器在运行时动态接入。
# See docs/bridge-protocol.md for the full protocol specification.
# 完整协议规范请参阅 docs/bridge-protocol.md。
#
# [bridge]
# enabled = true
# port = 9810 # WebSocket listen port (default: 9810) / 监听端口
# token = "your-bridge-secret" # Auth token (required) / 认证密钥(必填)
# path = "/bridge/ws" # URL path (default: "/bridge/ws") / URL 路径
# =============================================================================
# Management API (External Management Tools)
# 管理 API外部管理工具
# =============================================================================
# HTTP REST API for external apps (web dashboards, TUI, GUI, Mac tray apps).
# 为外部应用Web 管理面板、TUI、GUI、Mac 托盘应用)提供 HTTP REST API。
# See docs/management-api.md for the full API specification.
# 完整 API 规范请参阅 docs/management-api.md。
#
# [management]
# enabled = true
# port = 9820 # HTTP listen port (default: 9820) / 监听端口
# token = "your-mgmt-secret" # Auth token (required) / 认证密钥(必填)
# cors_origins = ["http://localhost:3000"] # Allowed CORS origins / 允许的 CORS 来源
# =============================================================================
# Hooks (Event Triggers / 事件钩子)
# =============================================================================
# Execute shell commands or send HTTP requests when lifecycle events occur.
# 在生命周期事件发生时执行 Shell 命令或发送 HTTP 请求。
#
# Supported events / 支持的事件:
# message.received — user message arrives / 用户消息到达
# message.sent — agent reply sent / Agent 回复发送完成
# session.started — agent session spawned / Agent 会话启动
# session.ended — agent session stopped / Agent 会话结束
# cron.triggered — cron job fires / 定时任务触发
# permission.requested — agent asks for permission / Agent 请求权限
# error — an error occurs / 发生错误
# * — match all events / 匹配所有事件
#
# Handler types / 处理器类型:
# command — run a shell command; event context in CC_HOOK_* env vars
# — 执行 Shell 命令;事件上下文通过 CC_HOOK_* 环境变量传递
# http — POST JSON to a URL with event payload
# — 向 URL 发送 POST JSON 请求,包含事件数据
#
# [[hooks]]
# event = "message.received"
# type = "command"
# command = "echo $CC_HOOK_USER_NAME >> /tmp/cc-messages.log"
# async = true # default true; set false to block until done
# timeout = 10 # seconds; default 10s for command, 5s for http
#
# [[hooks]]
# event = "error"
# type = "http"
# url = "https://my-server.com/cc-connect/on-error"
#
# [[hooks]]
# event = "*"
# type = "http"
# url = "https://my-server.com/cc-connect/events"
# =============================================================================
# Speech-to-Text (Voice Messages) / 语音转文字(语音消息)
# =============================================================================
# Enable to transcribe voice messages to text before sending to agents.
# 启用后,语音消息会先转为文字再发送给 Agent。
#
# Requires ffmpeg for audio format conversion (AMR/OGG → MP3).
# 需要安装 ffmpeg 进行音频格式转换AMR/OGG → MP3
# [speech]
# enabled = true
# provider = "openai" # "openai", "groq", or "qwen" / "openai"、"groq" 或 "qwen"
# language = "" # e.g. "zh", "en"; empty = auto-detect / 如 "zh"、"en";留空自动检测
#
# [speech.openai]
# api_key = "sk-xxx" # OpenAI API key
# base_url = "" # optional: custom endpoint (OpenAI-compatible) / 可选:自定义端点(兼容 OpenAI 接口)
# model = "whisper-1" # default model / 默认模型
#
# # Alternative: Groq (faster, free tier available)
# # 备选Groq更快有免费额度
# [speech.groq]
# api_key = "gsk_xxx"
# model = "whisper-large-v3-turbo"
# =============================================================================
# Text-to-Speech (Voice Reply) / 文字转语音(语音回复)
# =============================================================================
# Enable to synthesize AI replies into voice messages sent back to users.
# 启用后AI 的文字回复会合成为语音消息发送给用户。
#
# tts_mode:
# "voice_only" (default) - only reply with voice when user sends a voice message
# 仅当用户发送语音消息时AI 才用语音回复
# "always" - always send a voice reply regardless of input type
# 无论用户发文字还是语音AI 始终额外发一条语音回复
#
# Runtime command: /tts [always|voice_only]
# 运行时命令:/tts [always|voice_only]
#
# Requires ffmpeg for WAV → Opus conversion (needed by Feishu audio messages).
# 需要安装 ffmpeg 进行 WAV → Opus 转换(飞书语音消息要求 Opus 格式)。
# [tts]
# enabled = true
# provider = "qwen" # "qwen" | "openai" | "minimax" | "mimo" | "espeak" | "pico" | "edge"
# voice = "Cherry" # default voice / 默认音色千问支持Cherry/Serena/Ethan/Chelsie 等MiMo 支持mimo_default/冰糖/茉莉/苏打/白桦/Mia/Chloe/Milo/Dean
# voice_id = "" # optional alias for voice, useful for MiniMax voice IDs / 可选MiniMax 音色 ID 可写这里
# speed = 0 # optional speed multiplier; 0 = provider default; valid range is provider-specific
# # 可选语速0 表示服务商默认;有效范围取决于具体 provider
# language_type = "" # optional provider-specific language hint / 可选语言提示
# tts_mode = "voice_only" # "voice_only" (default) | "always"
# max_text_len = 0 # max rune count before skipping TTS; 0 = no limit
# # 超过此长度则跳过 TTS0 表示不限制
# # Qwen TTS 建议参考官方文档https://help.aliyun.com/zh/model-studio/qwen-tts
# # OpenAI TTS 限制请参考https://platform.openai.com/docs/guides/text-to-speech
#
# # Qwen TTS (Alibaba DashScope / 阿里百炼)
# [tts.qwen]
# api_key = "sk-xxx" # DashScope API key / 阿里百炼 API Key
# base_url = "" # optional: leave empty for default endpoint / 留空使用默认地址
# model = "qwen3-tts-flash" # "qwen3-tts-flash" | "qwen3-tts-instruct-flash"
#
# # Alternative: OpenAI TTS (OpenAI-compatible)
# # 备选OpenAI TTS兼容 OpenAI 接口)
# [tts.openai]
# api_key = "sk-xxx"
# base_url = "" # optional: custom endpoint / 可选:自定义端点
# model = "tts-1" # "tts-1" | "tts-1-hd"
#
# # Alternative: MiniMax TTS (T2A v2 streaming API)
# # 备选MiniMax TTST2A v2 流式 API
# # Docs: https://platform.minimaxi.com/document/T2A%20V2
# [tts.minimax]
# api_key = "your-minimax-api-key" # optional: if empty, cc-connect reads ~/.cc-connect/config/minimax.json
# base_url = "" # optional: default "https://api.minimaxi.com" / 留空使用默认地址
# model = "speech-2.8-hd" # "speech-2.8-hd" | "speech-2.8"
# config_file = "" # optional MiniMax JSON config path; default data_dir/config/minimax.json
#
# # Per-project/agent voice overrides. Keys match [[projects]].name.
# # 每个项目/Agent 可单独覆盖音色key 与 [[projects]].name 一致。
# # Agent tool command: cc-connect send --tts <text>
# # Agent 工具命令cc-connect send --tts <文本>
# [tts.agents.assistant]
# voice_id = "Chinese (Mandarin)_Crisp_Girl"
# speed = 0.98
#
# [tts.agents.reviewer]
# voice_id = "Chinese (Mandarin)_Gentle_Senior"
# speed = 0.96
#
# # Alternative: Xiaomi MiMo-V2.5-TTS (OpenAI-compatible chat completions style)
# # 备选:小米 MiMo-V2.5-TTSOpenAI 兼容的 chat completions 风格)
# # Docs: https://platform.xiaomimimo.com/#/docs/usage-guide/speech-synthesis
# [tts.mimo]
# api_key = "your-mimo-api-key"
# base_url = "" # optional: default "https://api.xiaomimimo.com/v1" / 留空使用默认地址
# # Token Plan 国内地址https://token-plan-cn.xiaomimimo.com/v1
# model = "mimo-v2.5-tts" # "mimo-v2.5-tts" | "mimo-v2.5-tts-voicedesign" | "mimo-v2.5-tts-voiceclone"
# =============================================================================
# Daemon Mode / 守护进程模式
# =============================================================================
# Run cc-connect as a background service (systemd user / launchd LaunchAgent).
# 将 cc-connect 作为后台服务运行systemd 用户服务 / launchd LaunchAgent
#
# CLI: cc-connect daemon install|uninstall|start|stop|restart|status|logs
# Install: --log-file PATH, --log-max-size N (MB), --work-dir DIR, --force
# Logs: -f/--follow, -n N, --log-file PATH
# 配置均通过 CLI 参数,无需在此文件中设置。
# =============================================================================
# Custom Skills (Slash Commands) / 自定义命令
# =============================================================================
# Define reusable prompt templates as global slash commands (available in all projects).
# 定义可复用的 prompt 模板作为全局 slash 命令(所有项目通用)。
#
# Two types of commands are supported / 支持两种类型的命令:
# 1. Prompt commands — expand template and send to AI agent
# Prompt 命令 — 展开模板后发送给 AI Agent
# 2. Exec commands — execute shell command directly
# Exec 命令 — 直接执行 shell 命令
#
# Placeholders (for both prompt and exec) / 占位符prompt 和 exec 都支持):
# {{1}}, {{2}} — positional argument / 位置参数
# {{1:default}} — positional with default value / 带默认值的位置参数
# {{2*}} — argument N and everything after / 第 N 个及之后所有参数
# {{2*:default}} — same, with default / 同上,带默认值
# {{args}} — all arguments / 所有参数
# {{args:default}} — all arguments, with default if none / 所有参数,无参数时使用默认值
# (no placeholder — args appended to end / 无占位符则参数追加到末尾)
#
# Default values are used when the corresponding argument is not provided.
# 当对应参数未提供时,使用默认值替代。
#
# Usage / 用法:
# /finduser 张三 → expands prompt with "张三" and sends to agent
# /push → executes "git push" directly
# [[commands]]
# name = "finduser"
# description = "Look up user info by name / 按姓名查找用户信息"
# prompt = "Search the database for user「{{1}}」and return details including registration time, last login, and permissions."
# [[commands]]
# name = "review"
# description = "Code review with focus area / 代码审查(可指定关注点)"
# prompt = "Please review {{1}} focusing on: {{2*:code quality and potential bugs}}"
# [[commands]]
# name = "translate"
# description = "Translate text to specified language / 翻译文本到指定语言"
# prompt = "Translate the following text to {{1:English}}:\n{{2*}}"
# [[commands]]
# name = "daily"
# description = "Generate daily progress report / 生成每日进度报告"
# prompt = "Summarize today's code changes and project progress. Generate a concise daily report."
# Exec commands - execute shell commands directly
# Exec 命令 — 直接执行 shell 命令
# [[commands]]
# name = "push"
# description = "Push to remote / 推送到远程"
# exec = "git push"
# [[commands]]
# name = "status"
# description = "Show git status / 显示 git 状态"
# exec = "git status {{args}}"
# [[commands]]
# name = "branch"
# description = "Create and checkout new branch / 创建并切换到新分支"
# exec = "git checkout -b {{1}}"
# [[commands]]
# name = "build"
# description = "Build the project / 构建项目"
# exec = "npm run build"
# work_dir = "/path/to/project" # Optional: override working directory / 可选:指定工作目录
#
# You can also add/remove commands at runtime via chat:
# 也可以在聊天中动态添加/删除命令:
# /commands add finduser Search the database for user「{{1}}」
# /commands addexec push git push
# /commands addexec --work-dir /path/to/project build npm run build
# /commands del finduser
# /commands — list all custom commands
#
# In addition, cc-connect auto-discovers .md files from the agent's commands
# directory (e.g. .claude/commands/*.md, .gemini/commands/*.md).
# 此外cc-connect 还会自动发现 Agent 的 commands 目录下的 .md 文件。
# =============================================================================
# Banned Words / 违禁词
# =============================================================================
#
# Messages containing any of these words will be blocked and NOT forwarded to
# the AI agent. Matching is case-insensitive.
# 消息中包含以下任一违禁词时,将被拦截,不会转发给 AI Agent。匹配不区分大小写。
# banned_words = ["违禁词1", "违禁词2", "secret_project"]
# =============================================================================
# Command Aliases / 命令别名
# =============================================================================
#
# Create aliases for commands — like Linux shell aliases.
# 为命令创建别名,类似 Linux shell 的 alias。
#
# When a user sends a message matching the alias trigger (exact match on first
# word), it is automatically replaced with the target command.
# 当用户发送的消息首词匹配别名触发词时,自动替换为目标命令。
#
# Example: typing "帮助" triggers "/help", typing "新建 测试" triggers "/new 测试".
# 示例:输入"帮助"触发 "/help",输入"新建 测试"触发 "/new 测试"。
# [[aliases]]
# name = "帮助"
# command = "/help"
# [[aliases]]
# name = "新建"
# command = "/new"
# [[aliases]]
# name = "列表"
# command = "/list"
#
# You can also add/remove aliases at runtime via chat:
# 也可以在聊天中动态添加/删除别名:
# /alias add 帮助 /help
# /alias del 帮助
# /alias — list all aliases
#
# =============================================================================
# Multi-workspace Mode / 多工作区模式
# =============================================================================
# Single bot, multiple workspaces. Channel name maps to ~/workspace/<channel-name>
# automatically. Use /workspace init <url> to clone and bind a new repo.
# 单个 bot 服务多个工作区。频道名称自动映射到 ~/workspace/<频道名>。
# 使用 /workspace init <url> 克隆并绑定新仓库。
#
# [[projects]]
# name = "claude-multi"
# mode = "multi-workspace"
# skip_git = true # skip bind git repo, create a dir directly
# base_dir = "~/workspace"
# workspace_init_allow_local_paths = true # Optional: allow /workspace init <local-dir>; default false keeps init git-URL only
#
# [projects.agent]
# type = "claudecode"
#
# [projects.agent.options]
# mode = "yolo" # "default" | "acceptEdits" (edit) | "plan" | "auto" | "bypassPermissions" (yolo)
#
# [[projects.platforms]]
# type = "slack"
# [projects.platforms.options]
# bot_token = "xoxb-..."
# app_token = "xapp-..."
# =============================================================================
# Project 1 / 项目 1
# =============================================================================
[[projects]]
name = "my-backend"
# reply_footer = false # Master toggle for the per-turn reply footer (default: true / show)
# # 每条助手回复底部状态 footer 总开关(默认 true 显示)
# show_context_indicator = false # Hide the footer's first line: model · [effort ·] out/in/cw/cr · ctx % (default: true)
# # 隐藏 footer 第一行model · [effort ·] out/in/cw/cr · ctx %(默认 true 显示)
# show_workdir_indicator = false # Hide the footer's second line: workspace directory (default: true)
# # 隐藏 footer 第二行:工作区目录(默认 true 显示)
# disabled_commands = ["restart", "upgrade", "cron"] # Disable specific commands for this project
# # 禁用该项目的指定命令
#
# filter_external_sessions: when true, /list /switch /delete only show sessions
# created by cc-connect, hiding sessions from direct CLI usage in the same work_dir.
# Default false = show all sessions from the agent.
# filter_external_sessions = false
# filter_external_sessions为 true 时,/list /switch /delete 仅显示由 cc-connect 创建的会话,
# 隐藏在相同 work_dir 下通过直接 CLI 创建的会话。默认 false = 显示 agent 的全部会话。
#
# shell = "/bin/fish" # Per-project shell override / 项目级 shell 覆盖
# shell_profile = "source ~/.config/fish/config.fish" # Per-project shell profile / 项目级 shell profile
#
# admin_from controls who can run privileged commands (/dir, /shell, /restart, /upgrade, /commands addexec, /cron addexec).
# admin_from 控制谁可以执行特权命令(/dir, /shell, /restart, /upgrade, /commands addexec, /cron addexec
#
# admin_from must be defined at the [[projects]] level.
# Do NOT put it under [projects.platforms.options], or it will be ignored.
# admin_from 必须写在 [[projects]] 这一层。
# 不要写到 [projects.platforms.options] 下面,否则会被忽略。
#
# 💡 TIP: Send /whoami or /status to the bot to get your User ID for allow_from / admin_from.
# 💡 提示:向机器人发送 /whoami 或者 /status 即可获取你的 User ID用于填写 allow_from / admin_from。
#
# Not set (default): privileged commands are blocked for all users.
# 未设置(默认):所有用户均无法使用特权命令。
#
# Explicit user list: only these users can run privileged commands.
# 指定用户列表:仅这些用户可执行特权命令。
# admin_from = "user_id_1,user_id_2"
#
# ⚠️ RISK WARNING / 风险提示:
# Setting admin_from = "*" grants ALL allowed users full shell access to the host machine.
# Only use this for personal single-user deployments where you trust every allowed user.
# 设置 admin_from = "*" 将授予所有已允许的用户对主机的完整 shell 访问权限。
# 仅在个人单用户部署中使用此配置,确保所有允许的用户均可信任。
# admin_from = "*"
# Multi-user mode — per-user rate limits and role-based command ACL
# 多用户模式 — 按用户速率限制和基于角色的命令权限控制
#
# When [projects.users] is configured, each user is matched to a role.
# Roles control which commands are available and the rate limit for that user.
# If not configured, behavior is unchanged (backward compatible).
#
# 配置 [projects.users] 后,每个用户会被分配到一个角色。
# 角色控制该用户可用的命令和速率限制。未配置时行为不变(向后兼容)。
#
# [projects.users]
# default_role = "member"
#
# [projects.users.roles.admin]
# user_ids = ["platform_user_id_1", "platform_user_id_2"]
# disabled_commands = [] # no restrictions
# rate_limit = { max_messages = 50, window_secs = 60 }
#
# [projects.users.roles.member]
# user_ids = ["*"] # matches all unassigned users
# disabled_commands = ["*"] # disable all built-in commands
# rate_limit = { max_messages = 10, window_secs = 60 }
# Heartbeat — periodic awareness check / 心跳 — 周期性巡检
# The agent wakes up at a fixed interval to check the environment.
# Agent 会按固定间隔唤醒,检查环境状态。
#
# Unlike cron (precise scheduling, isolated tasks), heartbeat runs in the
# main session with full context — ideal for status monitoring and continuing
# unfinished work.
# 与 cron精确调度、独立任务不同heartbeat 在主会话中运行并共享上下文
# —— 适合状态监控和继续未完成的工作。
#
# [projects.heartbeat]
# enabled = true
# interval_mins = 30 # Interval in minutes (default: 30) / 间隔分钟数(默认 30
# session_key = "telegram:123:123" # Target session key (required) / 目标会话 key必填
# only_when_idle = true # Skip if session is busy (default: true) / 会话忙碌时跳过(默认 true
# silent = true # Suppress "💓" notification (default: true) / 不发送心跳通知(默认 true
# timeout_mins = 30 # Max execution time (default: 30) / 最大执行时间(默认 30 分钟)
# prompt = "check inbox and tasks" # Explicit prompt; if empty, reads HEARTBEAT.md from work_dir
# # 显式提示词;为空时从 work_dir 读取 HEARTBEAT.md
#
# HEARTBEAT.md example / HEARTBEAT.md 示例:
# On heartbeat:
# - check inbox
# - check background tasks
# - continue unfinished work
[projects.agent]
type = "claudecode"
[projects.agent.options]
work_dir = "/path/to/backend"
mode = "default" # "default" | "acceptEdits" (edit) | "plan" | "auto" | "bypassPermissions" (yolo)
# Mode options / 模式说明:
# - "default": Every tool call requires user approval. / 每次工具调用都需要用户确认。
# - "acceptEdits" (edit): File edit tools auto-approved; other tools still ask. / 文件编辑自动通过,其他仍需确认。
# - "plan": Claude only plans — no execution until you approve. / 只做规划不执行,审批后再执行。
# - "auto": Claude automatically decides when a permission prompt is needed. / Claude 自动判断何时需要确认。
# - "bypassPermissions" (yolo): All tool calls auto-approved. Use with caution. / 全部自动通过,请谨慎使用。
# - "dontAsk" (dont-ask): Auto-deny tools unless pre-approved via allowed_tools or settings allow rules. / 未预授权的工具自动拒绝,安全推荐。
#
# When using IM platforms, you can reply "允许"/"allow" to grant permission.
# 在 IM 平台中,可回复"允许"或"allow"来授权操作。
# Optional: set reasoning effort level (passed to claude --effort)
# 可选:设置推理强度等级(传递给 claude --effort
# reasoning_effort = "high" # "low" | "medium" | "high" | "max"
# In default/acceptEdits mode, you can pre-approve specific tools:
# 在 default/acceptEdits 模式下,可预授权特定工具:
# allowed_tools = ["Read", "Grep", "Glob", "Bash", "Edit", "Write"]
# You can also disallow specific tools (passed to --disallowedTools):
# 也可以禁用特定工具(传递给 --disallowedTools
# disallowed_tools = ["WebSearch", "WebFetch"]
# Optional: specify a custom system prompt / 可选:指定自定义系统提示
# Replaces Claude's default system prompt (passed via --system-prompt).
# 替换 Claude 默认系统提示(通过 --system-prompt 传入)。
# system_prompt = "You are a helpful AI assistant that specializes in Python development."
# Optional: append extra text to the system prompt / 可选:向系统提示追加额外内容
# Keeps Claude's default system prompt and appends this text (via --append-system-prompt).
# Use this instead of system_prompt when you want to add instructions without
# discarding Claude's defaults. Can be combined with system_prompt.
# 保留 Claude 默认系统提示,并在其后追加本内容(通过 --append-system-prompt
# 想在不丢弃默认提示的前提下补充指令时用它;可与 system_prompt 同时使用。
# append_system_prompt = "Always respond in Chinese and prefer concise answers."
# Optional: specify a model / 可选:指定模型
# model = "claude-sonnet-4-20250514"
# Optional: per-project environment variables injected into Claude Code sessions.
# This allows different projects to use different model providers (Kimi, Mimo, DeepSeek, etc.)
# without modifying global ~/.claude/settings.json.
# 可选:为每个项目单独配置环境变量,注入到 Claude Code 会话中。
# 这样不同项目可以使用不同的模型供应商,无需修改全局的 ~/.claude/settings.json。
#
# [projects.agent.options.env]
# ANTHROPIC_BASE_URL = "https://api.kimi.com/coding"
# ANTHROPIC_AUTH_TOKEN = "sk-kimi-xxx"
# ANTHROPIC_MODEL = "K2.6"
# ANTHROPIC_REASONING_MODEL = "K2.6"
# ANTHROPIC_DEFAULT_HAIKU_MODEL = "K2.6"
# ANTHROPIC_DEFAULT_SONNET_MODEL = "K2.6"
# ANTHROPIC_DEFAULT_OPUS_MODEL = "K2.6"
# Claude Code Router Integration / Claude Code Router 集成
# Route Claude Code requests through Claude Code Router to use different model providers.
# 通过 Claude Code Router 路由 Claude Code 请求,使用不同的模型提供商。
# See: https://github.com/musistudio/claude-code-router
#
# router_url = "http://127.0.0.1:3456" # Claude Code Router URL (default: http://127.0.0.1:3456)
# router_api_key = "your-router-api-key" # Optional: API key if router requires authentication / 可选:如果 router 需要认证
#
# When router_url is set, cc-connect will automatically:
# 设置 router_url 后cc-connect 会自动:
# - Set ANTHROPIC_BASE_URL to router_url
# - Set NO_PROXY=127.0.0.1 to prevent proxy interference
# - Disable telemetry and cost warnings for cleaner integration
#
# Note: When using router, provider settings below are ignored as the router handles model selection.
# 注意:使用 router 时,下方的 provider 设置将被忽略,因为 router 负责模型选择。
# Active provider (matches a name in [[projects.agent.providers]] or provider_refs)
# 当前激活的 provider对应下方 providers 或 provider_refs 中的 name
# provider = "anthropic"
# Reference global [[providers]] by name — avoids duplicating keys per project
# 引用全局 [[providers]] — 避免每个项目重复配置
# provider_refs = ["minimaxi", "dashscope"]
# API Providers — switch between them via /provider command in chat
# or via CLI: cc-connect provider add --project my-backend --name relay --api-key sk-xxx
# API Provider 管理 — 可通过聊天命令 /provider 或 CLI 命令切换
#
# [[projects.agent.providers]]
# name = "anthropic"
# api_key = "sk-ant-xxx"
#
# [[projects.agent.providers]]
# name = "relay"
# api_key = "sk-xxx"
# base_url = "https://api.relay-service.com"
# model = "claude-sonnet-4-20250514"
# # Optional: pre-configure available models shown by /model command (alias - model)
# # /model switch [alias] switches to the model; omit to auto-fetch from the API.
# # 可选:预先配置 /model 命令显示的可用模型列表,格式为 alias - model
# # 使用 /model switch [alias] 切换模型;留空则自动从 API 获取
# [[projects.agent.providers.models]]
# model = "claude-sonnet-4-20250514"
# alias = "sonnet"
# [[projects.agent.providers.models]]
# model = "claude-opus-4-20250514"
# alias = "opus"
# [[projects.agent.providers.models]]
# model = "claude-haiku-3-5-20241022"
# alias = "haiku"
#
# # Third-party provider with thinking override / 第三方 Provider 并覆盖 thinking 参数
# # Some providers (e.g. SiliconFlow) don't support Claude's adaptive thinking.
# # Set thinking = "disabled" to auto-rewrite via a local proxy.
# # 部分第三方 Provider如硅基流动不支持 Claude 的 adaptive thinking
# # 设置 thinking = "disabled" 后 cc-connect 会通过本地代理自动改写请求。
# [[projects.agent.providers]]
# name = "siliconflow"
# api_key = "sk-xxx"
# base_url = "https://api.siliconflow.cn"
# model = "deepseek-ai/DeepSeek-V3"
# thinking = "disabled"
#
# # MiniMax — OpenAI-compatible agent provider with 1M context window
# # MiniMax — 兼容 OpenAI 接口的大模型 Agent provider支持 1M 超长上下文
# # Models: MiniMax-M2.7 (flagship, 1M context), MiniMax-M2.7-highspeed, MiniMax-M2.5, MiniMax-M2.5-highspeed
# # Docs: https://platform.minimaxi.com
# # China-region accounts may use https://api.minimaxi.com/v1 / 中国区账号可使用 https://api.minimaxi.com/v1
# [[projects.agent.providers]]
# name = "minimax"
# api_key = "your-minimax-api-key"
# base_url = "https://api.minimax.io/v1"
# model = "MiniMax-M2.7"
# thinking = "disabled"
# [[projects.agent.providers.models]]
# model = "MiniMax-M2.7"
# alias = "m27"
# [[projects.agent.providers.models]]
# model = "MiniMax-M2.7-highspeed"
# alias = "m27fast"
# [[projects.agent.providers.models]]
# model = "MiniMax-M2.5"
# alias = "m25"
# [[projects.agent.providers.models]]
# model = "MiniMax-M2.5-highspeed"
# alias = "m25fast"
#
# # For special setups (Bedrock, Vertex, Foundry), use the env map:
# # 特殊环境Bedrock、Vertex、Foundry使用 env 字段:
# [[projects.agent.providers]]
# name = "bedrock"
# env = { CLAUDE_CODE_USE_BEDROCK = "1", AWS_PROFILE = "bedrock" }
# # For Bedrock/Vertex/Foundry that don't support adaptive thinking,
# # add thinking = "disabled" to enable automatic request rewriting.
# # 对于不支持 adaptive thinking 的 Bedrock/Vertex/Foundry
# # 设置 thinking = "disabled" 启用自动请求重写。
# thinking = "disabled"
# Reference normalization and rendering / 本地引用标准化与展示优化
# Disabled by default. When enabled, cc-connect can normalize Codex / Claude Code
# local file references (paths, line refs, markdown file links) and re-render them
# into a more readable platform-friendly form before sending to supported IMs.
# 默认关闭。启用后cc-connect 可对 Codex / Claude Code 的本地文件引用
# 路径、行号引用、Markdown 文件链接)做标准化,并在发送到支持的平台前
# 重新渲染为更易读的展示形式。
#
# Supported today / 当前已支持:
# normalize_agents: codex | claudecode | all
# render_platforms: feishu | weixin | all
# Note: render depends on normalize. If normalize_agents is empty, render_platforms
# alone has no effect.
# 注意render 依赖 normalize。若 normalize_agents 为空,仅设置 render_platforms 不生效。
#
# [projects.references]
# normalize_agents = ["codex", "claudecode"]
# render_platforms = ["feishu", "weixin"]
# display_path = "dirname_basename" # absolute | relative | basename | dirname_basename | smart
# marker_style = "emoji" # none | ascii | emoji
# enclosure_style = "code" # none | bracket | angle | fullwidth | code
# Feishu / Lark / 飞书
# 1. Create an app at https://open.feishu.cn / 在 https://open.feishu.cn 创建应用
# 2. Enable Bot capability / 开启机器人能力
# 3. Add im.message.receive_v1 event, select WebSocket long-connection mode
# 添加 im.message.receive_v1 事件,选择 WebSocket 长连接模式
# 4. Fill in app_id and app_secret below / 填入下方 app_id 和 app_secret
# Quick setup via CLI:
# cc-connect feishu setup --project <project_name>
# (可通过 CLI 快速配置cc-connect feishu setup --project <project_name>
# Note: No WebSocket URL needed — the SDK auto-negotiates the connection.
# 注意:无需配置 WebSocket URLSDK 会自动通过凭证建立连接。
[[projects.platforms]]
type = "feishu"
[projects.platforms.options]
app_id = "your-feishu-app-id"
app_secret = "your-feishu-app-secret"
# domain = "https://open.feishu.cn" # Optional runtime API/WebSocket base URL override / 可选:运行时 API/WebSocket 域名覆盖
# enable_feishu_card = true # Enable Feishu interactive cards (default: true); set false to force plain-text replies
# # 启用飞书交互式卡片(默认 true设为 false 时强制回退纯文本回复
# allow_from = "*" # Allowed user open_ids, comma-separated; "*" = all (default). Use /whoami to get your open_id.
# # 允许的用户 open_id逗号分隔"*" 表示所有(默认)。发送 /whoami 获取你的 open_id。
# allow_chat = "*" # Allowed group chat_ids, comma-separated; "*" = all (default). Find chat_id in group settings.
# # 允许的群聊 chat_id逗号分隔"*" 表示所有(默认)。在群设置中查看 chat_id。
# group_only = false # If true, only respond to group chat messages; ignore private (P2P) messages (default: false)
# # 设为 true 时仅响应群聊消息忽略私聊P2P消息默认 false
# reaction_emoji = "OnIt" # Emoji reaction on incoming messages (default: "OnIt"); set to "none" to disable
# # 收到消息时添加的表情回复(默认 "OnIt");设为 "none" 可禁用
# done_emoji = "none" # Emoji reaction when agent finishes a reply (e.g. "Done"); set to "none" to disable
# # Agent 完成回复后添加的表情回复(如 "Done");设为 "none" 可禁用
# group_reply_all = false # If true, respond to ALL group messages without requiring @mention
# # 设为 true 时,群聊中无需 @机器人 也会响应所有消息(默认 false
# share_session_in_channel = false # If true, all users in a group share one agent session
# # 设为 true 时,群聊内所有用户共享同一个 Agent 会话
# thread_isolation = false # If true, group messages use Feishu reply threads as session boundaries (one thread/root = one agent session)
# # 设为 true 时,群聊按飞书话题/根消息隔离会话(一个 thread/root 对应一个 Agent 会话)
# reply_to_trigger = true # Default: bot uses “reply to message” API (quotes the users message). Set false to post plain chat messages instead.
# # 默认 true用「回复消息」API引用用户消息。设为 false 则在会话里发普通消息、不引用触发消息。
# progress_style = "legacy" # Progress rendering style: legacy | compact | card
# # 进度消息展示风格legacy逐条消息| compact单消息持续更新| card结构化卡片
# resolve_mentions = false # Auto-resolve @name in outgoing messages to Feishu at tags by matching group member names
# # 自动将发出消息中的 @显示名 替换为飞书 at 标签(通过匹配群成员名称)
# image_batch_window_ms = 500 # Coalesce window for consecutive images from the same session (default: 500ms).
# # When the Feishu mobile client sends multiple images, each arrives as a separate
# # event; cc-connect buffers them and dispatches a single multi-image message once
# # no new image arrives within this window. Raise it (e.g. 8001200ms) if your
# # network or device routinely sends images more than 500ms apart and they still
# # split into multiple agent turns; lower it for snappier single-image responses.
# # 来自同一会话的连续图片消息的合批窗口(默认 500ms。飞书手机端连续发图时每张
# # 都是独立事件cc-connect 会在窗口内将它们合并成一条多图消息再分发;如果你的
# # 网络或设备发送间隔超过 500ms 且仍被拆成多轮,可调高(如 8001200ms如果
# # 只是单图发送,希望响应更快,也可以适当调低。
# Lark (International Version) / Lark 国际版
# Lark now supports WebSocket long-connection too; webhook mode is only needed
# when you explicitly configure encrypt_key.
# Lark 国际版现已支持 WebSocket 长连接;只有显式配置 encrypt_key 时才需要 Webhook 模式。
# 1. Create an app at https://open.larksuite.com / 在 https://open.larksuite.com 创建应用
# 2. Enable Bot capability / 开启机器人能力
# 3. Add im.message.receive_v1 event and enable WebSocket long-connection mode (recommended)
# 添加 im.message.receive_v1 事件,并启用 WebSocket 长连接模式(推荐)
# 4. Fill in app_id and app_secret below; port/callback_path are only used for webhook mode
# 填入下方 app_id 和 app_secretport/callback_path 仅在 Webhook 模式下使用
# [[projects.platforms]]
# type = "lark"
#
# [projects.platforms.options]
# app_id = "your-lark-app-id"
# app_secret = "your-lark-app-secret"
# domain = "https://open.larksuite.com" # Optional runtime API base URL override / 可选:运行时 API 域名覆盖
# port = "8080" # Webhook server port / Webhook 服务器端口
# callback_path = "/feishu/webhook" # Webhook callback path / Webhook 回调路径
# encrypt_key = "" # Event encrypt key (optional) / 事件加密密钥(可选)
# enable_feishu_card = true
# allow_from = "*"
# reaction_emoji = "OnIt"
# done_emoji = "none"
# progress_style = "legacy" # legacy | compact | card
# DingTalk / 钉钉 (uncomment to enable / 取消注释以启用)
# 1. Create an app at https://open-dev.dingtalk.com / 在钉钉开放平台创建应用
# 2. Under "App Features > Bot", enable bot and select Stream mode
# 在"应用功能 > 机器人"中启用机器人并选择 Stream 模式
# 3. Fill in client_id (AppKey) and client_secret (AppSecret) below
# 填入下方 client_id (AppKey) 和 client_secret (AppSecret)
# [[projects.platforms]]
# type = "dingtalk"
#
# [projects.platforms.options]
# client_id = "your-dingtalk-client-id"
# client_secret = "your-dingtalk-client-secret"
# allow_from = "*" # Allowed staff IDs / 允许的员工 ID
# share_session_in_channel = false # If true, all users in a group share one agent session / 群聊共享会话
# reaction_emoji = "🤔Thinking" # Emotion on incoming messages (default: "🤔Thinking"); set to "none" to disable
# # 收到消息时添加的表情回复(默认 "🤔Thinking");设为 "none" 可禁用
# done_emoji = "none" # Emotion when agent finishes a reply (e.g. "🥳Done"); set to "none" to disable
# # Agent 完成回复后添加的表情回复(如 "🥳Done");设为 "none" 可禁用
# WPS Xiezuo / WPS 协作 (uncomment to enable / 取消注释以启用)
# 1. Create a WPS Open Platform app and enable event WebSocket delivery
# 创建 WPS 开放平台应用,并启用事件 WebSocket 推送
# 2. Subscribe to app chat message events such as kso.app_chat.message
# 订阅应用会话消息事件,如 kso.app_chat.message
# 3. Fill in app_id and app_secret below
# 填入下方 app_id 和 app_secret
# Connection: WebSocket — no public URL required / 无需公网地址
# [[projects.platforms]]
# type = "wps-xiezuo"
#
# [projects.platforms.options]
# app_id = "your-wps-xiezuo-app-id"
# app_secret = "your-wps-xiezuo-app-secret"
# allow_from = "*" # Allowed WPS user IDs / 允许的 WPS 用户 ID
# clean_reply = false # Strip thinking/tool progress lines from replies / 过滤思考和工具进度行
# base_url = "https://openapi.wps.cn" # Optional API base URL override / 可选 API 基础地址覆盖
# Telegram (uncomment to enable / 取消注释以启用)
# 1. Message @BotFather on Telegram, send /newbot to create a bot
# 在 Telegram 中找 @BotFather发送 /newbot 创建机器人
# 2. Copy the bot token below / 复制 token 到下方
# Connection: Long polling (no public URL needed) / 长轮询(无需公网 IP
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
# allow_from = "*" # Allowed Telegram user IDs, e.g. "123456789,987654321"; "*" = all
# # 允许的 Telegram 用户 ID如 "123456789,987654321""*" 表示所有
# proxy = "http://127.0.0.1:7890" # Optional HTTP/SOCKS5 proxy for Telegram Bot API / 可选 HTTP/SOCKS5 代理
# proxy_username = "" # Optional proxy auth username / 代理用户名
# proxy_password = "" # Optional proxy auth password / 代理密码
# group_reply_all = false # If true, respond to ALL group messages without @mention / 设为 true 群聊无需 @ 也响应
# share_session_in_channel = false # If true, all users in a group share one agent session / 群聊共享会话
# enable_reactions = false # If true, add ⚡ reaction to incoming messages / 设为 true 收到消息时添加 ⚡ 表情
# progress_style = "compact" # Progress rendering: legacy | compact (default). Telegram has no rich card UI,
# # so "card" is normalized to "compact". Set "legacy" to disable streaming edits.
# # 进度展示legacy | compact默认。Telegram 不支持富卡片,"card" 会被规整为 "compact"。
# # 设为 "legacy" 可关闭流式 edit。
# Matrix (uncomment to enable / 取消注释以启用)
# 1. Create an account on your Matrix homeserver (matrix.org or self-hosted)
# 在 Matrix 服务器上创建账号matrix.org 或自建服务器)
# 2. Get an access token via curl (recommended, ensures E2EE works):
# curl -XPOST "https://matrix.org/_matrix/client/v3/login" \
# -H "Content-Type: application/json" \
# -d '{"type":"m.login.password","user":"YOUR_USER","password":"YOUR_PASS","device_id":"CC-CONNECT"}'
# 通过 curl 获取 access token推荐确保 E2EE 正常工作):
# curl -XPOST "https://matrix.org/_matrix/client/v3/login" \
# -H "Content-Type: application/json" \
# -d '{"type":"m.login.password","user":"你的用户名","password":"你的密码","device_id":"CC-CONNECT"}'
# Connection: Long polling via /sync (no public URL needed) / 长轮询,无需公网 IP
# [[projects.platforms]]
# type = "matrix"
#
# [projects.platforms.options]
# homeserver = "https://matrix.org"
# access_token = "syt_xxx_xxx"
# user_id = "@bot:matrix.org" # optional, auto-detected via /whoami / 可选,自动检测
# allow_from = "*" # Matrix user IDs, e.g. "@user:matrix.org,@other:example.com"
# auto_join = true # auto-join room invites (default true) / 自动加入被邀请的房间(默认 true
# auto_verify = true # auto-accept SAS key verification (default true) / 自动接受 SAS 密钥验证(默认 true
# cross_signing_password = "" # bot account password for cross-signing setup (one-time) / 跨签名初始化密码(一次性)
# # Or use env var MATRIX_CROSS_SIGNING_PASSWORD (takes precedence) / 也可用环境变量 MATRIX_CROSS_SIGNING_PASSWORD优先级更高
# share_session_in_channel = false # share one agent session per room / 房间内所有用户共享会话
# group_reply_all = false # respond to all room messages without @mention / 群聊无需 @ 也响应
# proxy = "" # optional HTTP/SOCKS5 proxy / 可选代理
# Webex (Cisco) (uncomment to enable / 取消注释以启用)
# 1. Create a bot at https://developer.webex.com/my-apps/new/bot
# 在 https://developer.webex.com/my-apps/new/bot 创建机器人
# 2. Copy the bot access token below / 复制 access token 到下方
# Connection: WebSocket — no public URL required / 无需公网地址
# [[projects.platforms]]
# type = "webex"
#
# [projects.platforms.options]
# token = "YOUR_WEBEX_BOT_ACCESS_TOKEN" # from developer.webex.com (Bot)
# allow_from = "you@cisco.com" # comma-separated email allowlist / 逗号分隔的邮箱白名单
# MAX messenger (uncomment to enable / 取消注释以启用)
# 1. Create a bot via @MasterBot in MAX, get the access token
# 在 MAX 中通过 @MasterBot 创建机器人,获取 access token
# 2. Paste the token below / 填入下方 token
# Connection: long-poll by default; webhook supported (see docs/max-webhook.md)
# 默认长轮询;如需 webhook 模式见 docs/max-webhook.md
# [[projects.platforms]]
# type = "max"
#
# [projects.platforms.options]
# token = "your-max-bot-token"
# allow_from = "*" # Allowed MAX user IDs, e.g. "66624886,12345678"; "*" = all
# # 允许的 MAX 用户 ID如 "66624886,12345678""*" 表示所有
# api_base = "https://platform-api.max.ru" # optional override / 可选覆盖默认 API
#
# --- Webhook mode (optional) ---
# Set webhook_url to switch from long-poll to webhook. Required for high-traffic
# bots since MAX throttles long-poll to 2 RPS from 2026-05-11.
# 设置 webhook_url 即切换为 webhook 模式高流量场景必需MAX 自 2026-05-11 起限制长轮询为 2 RPS
# Full guide with nginx/Caddy/systemd samples: docs/max-webhook.md
# webhook_url = "https://bot.example.com/webhook"
# webhook_listen = "127.0.0.1:8090" # bot binds here; reverse proxy in front
# webhook_path = "/webhook" # default; must match the path in webhook_url
# webhook_secret = "long-random-string" # optional; checked via X-Webhook-Secret header or ?s= query
# Slack (uncomment to enable / 取消注释以启用)
# 1. Create an app at https://api.slack.com/apps / 创建应用
# 2. Enable Socket Mode (Settings > Socket Mode) / 开启 Socket Mode
# 3. Subscribe to bot events: message.channels, message.im
# 订阅事件message.channels, message.im
# 4. Install app to workspace, copy Bot Token (xoxb-...) and App Token (xapp-...)
# 安装应用到工作区,复制 Bot Token 和 App Token
# Connection: Socket Mode WebSocket (no public URL needed) / 无需公网 IP
# [[projects.platforms]]
# type = "slack"
#
# [projects.platforms.options]
# bot_token = "xoxb-your-bot-token"
# app_token = "xapp-your-app-level-token"
# allow_from = "*" # Allowed Slack user IDs / 允许的 Slack 用户 ID
# share_session_in_channel = false # If true, all users in a channel share one agent session / 频道共享会话
# session_scope = "user" # Session granularity: "user" (default, per channel+user) |
# # "channel" (one session per channel, same as share_session_in_channel) |
# # "thread" (one session per Slack thread — a new top-level message starts
# # a fresh session, replies in the same thread continue it).
# # 会话粒度:"user"(默认) | "channel"(整个频道一个会话) | "thread"(每个 Slack 话题串一个会话)
# Discord (uncomment to enable / 取消注释以启用)
# 1. Create an app at https://discord.com/developers/applications / 创建应用
# 2. Under "Bot", create a bot and copy the token / 创建 Bot 并复制 token
# 3. Enable "Message Content Intent" under Privileged Gateway Intents
# 在 Privileged Gateway Intents 中开启 Message Content Intent
# 4. Invite bot with OAuth2 URL Generator:
# 通过 OAuth2 URL 邀请 Bot 到服务器:
# Scopes: bot + applications.commands (BOTH required for slash command menu)
# Scopes 需要同时勾选: bot + applications.commands缺少后者则 / 菜单不会出现)
# Bot Permissions: Send Messages, Use Slash Commands
# Bot 权限: Send Messages, Use Slash Commands
# Connection: Gateway WebSocket (no public URL needed) / 无需公网 IP
#
# NOTE: Global slash commands may take up to 1 hour to appear in Discord.
# Set guild_id for instant per-guild registration (recommended for testing).
# 注意:全局 slash 命令最多需 1 小时生效。设置 guild_id 可秒级生效(推荐测试时使用)。
# To find your guild ID: Discord Settings > Advanced > Developer Mode ON, then right-click server > Copy Server ID
# 获取 guild_idDiscord 设置 > 高级 > 开启开发者模式,然后右键服务器 > 复制服务器 ID
# [[projects.platforms]]
# type = "discord"
#
# [projects.platforms.options]
# token = "your-discord-bot-token"
# allow_from = "*" # Allowed Discord user IDs / 允许的 Discord 用户 ID
# guild_id = "" # Optional: set for instant slash command registration (per-guild)
# # 可选:设置后 slash 命令秒级生效(仅该服务器)
# group_reply_all = false # If true, respond to ALL guild messages without @mention / 设为 true 群聊无需 @ 也响应
# group_reply_all_guilds = "" # Comma-separated guild IDs where group_reply_all is active (overrides group_reply_all)
# # e.g. "123456789012345678,987654321098765432"; takes precedence over group_reply_all
# # 逗号分隔的服务器 ID仅在这些服务器无需 @ 也响应(优先于 group_reply_all
# share_session_in_channel = false # If true, all users in a channel share one agent session / 频道共享会话
# thread_isolation = false # If true, cc-connect creates/uses Discord threads as session boundaries when the channel supports threads
# # 设为 true 时cc-connect 会在支持 thread 的 Discord 频道内按 thread 隔离会话
# progress_style = "legacy" # Progress rendering: legacy | compact | card / 进度展示方式legacy | compact | card
# # card = one editable Discord embed progress card / card = 单条可编辑的 Discord 嵌入式进度卡
# reply_hud = false # If true, append final-reply HUD line (model/context/tokens) in Discord only
# # 设为 true 时,仅在 Discord 最终回复末尾附加 HUD模型/上下文/tokens
# respond_to_at_everyone_and_here = false # If true, treat @everyone/@here as a direct mention so the bot responds
# # 设为 true 时,将 @everyone/@here 视为直接 @ 机器人,使机器人响应
# proxy = "http://127.0.0.1:7890" # Optional HTTP/SOCKS5 proxy for Discord API & Gateway / 可选代理
# proxy_username = "" # Optional proxy auth username / 代理用户名
# proxy_password = "" # Optional proxy auth password / 代理密码
# LINE (uncomment to enable / 取消注释以启用)
# 1. Create a channel at https://developers.line.biz/console/ (Messaging API)
# 在 LINE Developers 创建 Messaging API Channel
# 2. Copy Channel Secret and Channel Access Token (long-lived)
# 复制 Channel Secret 和 Channel Access Token
# 3. Set your webhook URL to: http(s)://<your-domain>:<port>/callback
# 设置 Webhook URLhttp(s)://<你的域名>:<端口>/callback
# Connection: HTTP Webhook — you need a public URL (use ngrok, cloudflared, etc.)
# 连接方式HTTP Webhook — 需要公网 URL可用 ngrok、cloudflared 等)
# [[projects.platforms]]
# type = "line"
#
# [projects.platforms.options]
# channel_secret = "your-line-channel-secret"
# channel_token = "your-line-channel-access-token"
# port = "8080"
# callback_path = "/callback"
# allow_from = "*" # Allowed LINE user IDs / 允许的 LINE 用户 ID
# Weibo / 微博私信 (uncomment to enable / 取消注释以启用)
# 1. Register an app at https://open.weibo.com/ via 微博龙虾助手
# 在微博开放平台注册应用,获取 app_id 和 app_secret
# 2. The bot receives and sends DMs via WebSocket (open-im.api.weibo.com)
# 机器人通过 WebSocket 收发微博私信
# Connection: WebSocket — no public URL required / 无需公网地址
# [[projects.platforms]]
# type = "weibo"
#
# [projects.platforms.options]
# app_id = "your-weibo-app-id"
# app_secret = "your-weibo-app-secret"
# allow_from = "*" # Allowed Weibo user IDs / 允许的微博用户 ID
# token_endpoint = "" # Optional: override token endpoint / 可选:自定义 token 接口地址
# ws_endpoint = "" # Optional: override WebSocket endpoint / 可选:自定义 WebSocket 地址
# WeChat Work / 企业微信 (uncomment to enable / 取消注释以启用)
# 1. Log in to https://work.weixin.qq.com/wework_admin/frame
# 登录企业微信管理后台
# 2. App Management > Create a custom app > note AgentId + Secret
# 应用管理 > 创建自建应用 > 记录 AgentId 和 Secret
# 3. My Enterprise > note Corp ID / 我的企业 > 记录 Corp ID
# 4. App > Receive Messages > Set API Receive:
# 应用 > 接收消息 > 设置 API 接收:
# URL: http(s)://<your-domain>:<port>/wecom/callback
# Token: any random string / 任意随机字符串
# EncodingAESKey: click "Random Generate" (43 chars) / 点击"随机生成"43位
# (Start cc-connect FIRST, then save to pass verification)
# (先启动 cc-connect再保存以通过验证
# 5. App > Trusted IP > add your server's outbound IP
# 应用 > 企业可信 IP > 添加服务器出口 IP
# 6. (Optional) My Enterprise > WeChat Plugin > scan QR to link personal WeChat
# (可选)我的企业 > 微信插件 > 扫码关联个人微信
# Connection: HTTP Webhook — you need a public URL
# 连接方式HTTP Webhook — 需要公网 URL
# [[projects.platforms]]
# type = "wecom"
#
# [projects.platforms.options]
# corp_id = "your-corp-id"
# corp_secret = "your-app-secret"
# agent_id = "1000002"
# callback_token = "your-callback-token"
# callback_aes_key = "your-43-char-encoding-aes-key"
# port = "8081"
# callback_path = "/wecom/callback"
# api_base_url = "https://qyapi.weixin.qq.com" # optional: WeCom API base URL override / 可选:企业微信 API 基础地址覆盖
# enable_markdown = false # set true to send Markdown (only renders in WeChat Work app, NOT personal WeChat)
# # 设为 true 发送 Markdown仅企业微信应用内可渲染个人微信显示"暂不支持"
# allow_from = "*" # Allowed WeChat Work user IDs / 允许的企业微信用户 ID
# Inbound (HTTP callback): text, image, voice, and file messages are passed to the agent.
# 入站HTTP 回调):文本、图片、语音与文件会交给 Agent如 Claude Code处理。
# WebSocket 智能机器人:文本、语音(转文字)、图片、文件、图文混排与引用中的图片/文件URL+aeskey 下载解密)。
# proxy = "" # optional: forward proxy for API calls if your IP is dynamic
# # 可选:正向代理,用于 IP 不固定的场景
# # e.g. "http://your-vps-ip:8888" — the VPS IP goes into trusted IP list
# # 示例:"http://你的VPS-IP:8888" — 将 VPS IP 加入可信 IP 列表
# proxy_username = "" # optional: proxy authentication username / 代理认证用户名
# proxy_password = "" # optional: proxy authentication password / 代理认证密码
# WeChat Work WebSocket / 企业微信长连接模式 (uncomment to enable / 取消注释以启用)
# No public URL, no message encryption, no IP allowlist needed!
# 无需公网 URL、无需消息加解密、无需 IP 白名单!
# 1. Create a "智能机器人" (AI Bot) in WeChat Work admin console
# 在企业微信管理后台创建「智能机器人」
# 2. Get BotID and Secret / 获取 BotID 和 Secret
# 3. Fill in config below / 填入下方配置
# Connection: WebSocket long-connection (client-initiated, no public URL needed)
# 连接方式WebSocket 长连接(客户端主动连接,无需公网 URL
# [[projects.platforms]]
# type = "wecom"
#
# [projects.platforms.options]
# mode = "websocket"
# bot_id = "your-bot-id"
# bot_secret = "your-bot-secret"
# allow_from = "*" # Allowed user IDs / 允许的用户 ID
# Weixin personal (ilink bot) / 微信个人号ilink 机器人网关)
# Same HTTP API as OpenClaw @tencent-weixin/openclaw-weixin: long-poll getUpdates + sendMessage.
# 与 OpenClaw 插件 openclaw-weixin 使用同一套网关:长轮询收消息 + sendMessage 下发。
#
# 1. Easiest: run `cc-connect weixin setup --project <name>` — terminal shows a QR; scan with WeChat to obtain token.
# Or: `cc-connect weixin bind --project <name> --token <bearer>` if you already have a token (e.g. from OpenClaw).
# 2. Manual: set token below. Optional: base_url (default https://ilinkai.weixin.qq.com).
# 3. allow_from: comma-separated Weixin user IDs (e.g. user@im.wechat) or "*".
# State files (get_updates cursor + context_token cache) live under:
# <data_dir>/weixin/<project>/<account_id>/
#
# Inbound images / files / video / raw voice (SILK) are downloaded from Weixin CDN and AES-128-ECB decrypted
# when encrypt_query_param + aes_key are present (aligned with OpenClaw openclaw-weixin).
# 入站图片、文件、视频、无转写文字时的语音会从微信 CDN 拉取并按 AES-128-ECB 解密(与 OpenClaw 插件一致)。
# [[projects.platforms]]
# type = "weixin"
#
# [projects.platforms.options]
# token = "your-ilink-bot-bearer-token"
# base_url = "https://ilinkai.weixin.qq.com" # optional / 可选
# cdn_base_url = "https://novac2c.cdn.weixin.qq.com/c2c" # optional; CDN download/upload / 可选 CDN 根路径
# allow_from = "*" # or "user1@im.wechat,user2@im.wechat"
# account_id = "default" # optional: isolate state dirs / 可选:区分多账号状态目录
# route_tag = "" # optional SKRouteTag header / 可选路由头
# long_poll_timeout_ms = 35000 # optional / 可选
# state_dir = "" # optional: override persistence directory / 可选覆盖状态目录
# proxy = "" # optional HTTP proxy / 可选代理
# proxy_username = ""
# proxy_password = ""
# =============================================================================
# Project 2: Using Cursor Agent / 项目 2使用 Cursor Agent (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: Cursor Agent CLI (`agent`) — install via Cursor IDE or `npm i -g @anthropic-ai/cursor-agent`
# 需要安装Cursor Agent CLI (`agent`) — 通过 Cursor IDE 或 npm 安装
# Uses `agent --print --output-format stream-json` under the hood.
# 底层使用 `agent --print --output-format stream-json` 命令。
# [[projects]]
# name = "my-cursor-project"
#
# [projects.agent]
# type = "cursor"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "force" # "default" | "force" (yolo) | "plan" | "ask"
# cmd = "agent" # CLI binary name (default: "agent") / CLI 二进制名称(默认 "agent"
#
# Mode options / 模式说明:
# - "default": Trust workspace, ask before tool use / 信任工作区,工具调用前询问
# Note: Shell tool is restricted to safe commands (e.g. ls) in this mode
# 注意:此模式下 Shell 工具仅允许安全命令(如 ls
# - "force": Auto-approve all tool calls, full shell access (same as --force/--yolo)
# 自动批准所有工具调用,完整 Shell 访问(等同 --force/--yolo
# - "plan": Read-only analysis, no edits / 只读分析,不做修改
# - "ask": Q&A style, read-only / 问答风格,只读
#
# Optional: specify a model / 可选:指定模型
# model = "claude-sonnet-4-20250514"
#
# [[projects.platforms]]
# type = "feishu"
#
# [projects.platforms.options]
# app_id = "your-feishu-app-id"
# app_secret = "your-feishu-app-secret"
# =============================================================================
# Project 3: Using Gemini CLI / 项目 3使用 Gemini CLI (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: npm install -g @google/gemini-cli
# 需要安装npm install -g @google/gemini-cli
# Gemini CLI uses `gemini -p --output-format stream-json` under the hood.
# Gemini CLI 底层使用 `gemini -p --output-format stream-json` 命令。
#
# Authentication / 认证方式:
# - Google Account login (free: 60 req/min, 1000 req/day) / Google 账号登录(免费额度)
# - GEMINI_API_KEY env var / 环境变量
# - Vertex AI (GOOGLE_API_KEY + GOOGLE_GENAI_USE_VERTEXAI=true)
# [[projects]]
# name = "my-gemini-project"
#
# [projects.agent]
# type = "gemini"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "yolo" # "default" | "auto_edit" | "yolo" | "plan"
# cmd = "gemini" # CLI binary name (default: "gemini") / CLI 二进制名称(默认 "gemini"
# timeout_mins = 30 # 每次对话超时时间分钟0 表示不限制
#
# Mode options / 模式说明:
# - "default": Prompt for approval on each tool use / 每次工具调用都需要确认
# - "auto_edit": Auto-approve edit tools, ask for others / 编辑工具自动通过,其他仍需确认
# - "yolo": Auto-approve all tool calls (-y flag) / 自动批准所有工具调用
# - "plan": Read-only plan mode, no execution / 只读规划模式,不做修改
#
# Optional: specify a model / 可选:指定模型
# model = "gemini-2.5-flash"
#
# # Provider with API key / 使用 API Key 的 Provider
# [[projects.agent.providers]]
# name = "google"
# api_key = "your-gemini-api-key" # GEMINI_API_KEY
#
# # Vertex AI provider / Vertex AI 提供商
# [[projects.agent.providers]]
# name = "vertex"
# env = { GOOGLE_API_KEY = "your-key", GOOGLE_GENAI_USE_VERTEXAI = "true" }
#
# [[projects.platforms]]
# type = "feishu"
#
# [projects.platforms.options]
# app_id = "your-feishu-app-id"
# app_secret = "your-feishu-app-secret"
# =============================================================================
# Project 4: Using Codex agent / 项目 4使用 Codex agent (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: npm install -g @openai/codex
# 需要安装npm install -g @openai/codex
# Codex uses `codex exec --json` under the hood.
# Codex 底层使用 `codex exec --json` 命令。
# [[projects]]
# name = "my-codex-project"
#
# [projects.agent]
# type = "codex"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "suggest" # "suggest" | "auto-edit" | "full-auto" | "yolo"
#
# Mode options / 模式说明:
# - "suggest": ask permission for every tool call (default, safest) / 每次调用都需确认(默认,最安全)
# - "auto-edit": auto-approve file edits, ask for shell commands / 文件编辑自动通过Shell 命令仍需确认
# - "full-auto": auto-approve everything with workspace sandbox / 全部自动通过,工作区沙箱保护
# - "yolo": bypass all approvals and sandbox (dangerous) / 跳过所有审批和沙箱(危险)
#
# Optional: specify a model / 可选:指定模型
# model = "o3"
#
# Optional: specify Codex reasoning effort / 可选:指定 Codex 推理强度
# reasoning_effort = "high" # "minimal" | "low" | "medium" | "high" | "xhigh"
#
# Optional: project system prompt / 可选:项目系统提示
# Codex has no native system-prompt flag, so cc-connect injects this as a
# preamble prepended to your first message of each new session (resumed
# sessions are not re-injected).
# Codex 没有原生的系统提示参数cc-connect 会将其作为前导内容注入到每个新
# 会话的第一条消息之前(恢复的会话不会重复注入)。
# system_prompt = "You are a helpful AI assistant that specializes in Python development."
#
# Optional: additional project instructions / 可选:追加的项目指令
# Appended after system_prompt in the same injected preamble. Can be used
# alone or combined with system_prompt.
# 追加在 system_prompt 之后,包含在同一段注入的前导内容中。可单独使用,也可与
# system_prompt 同时使用。
# append_system_prompt = "Always respond in Chinese and prefer concise answers."
#
# # Active provider / 当前激活的 provider
# # provider = "openai"
#
# [[projects.agent.providers]]
# name = "openai"
# api_key = "sk-xxx"
#
# [[projects.agent.providers]]
# name = "custom"
# api_key = "sk-xxx"
# base_url = "https://custom-api.com/v1"
# model = "gpt-4o"
#
# # MiniMax — OpenAI-compatible, works natively with Codex
# # MiniMax — 兼容 OpenAI 接口,可直接用于 Codex
# [[projects.agent.providers]]
# name = "minimax"
# api_key = "your-minimax-api-key"
# base_url = "https://api.minimax.io/v1"
# model = "MiniMax-M2.7"
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# QQ (via NapCat / OneBot v11) (uncomment to enable / 取消注释以启用)
# Requires a OneBot v11 implementation running alongside your QQ client:
# 需要一个 OneBot v11 实现配合 QQ 客户端运行:
# - NapCat (recommended / 推荐): https://github.com/NapNeko/NapCatQQ
# - Docker: docker run -d --name napcat -e ACCOUNT=<QQ号> -p 3001:3001 -p 6099:6099 mlikiowa/napcat-docker:latest
# - Enable Forward WebSocket in NapCat WebUI (http://localhost:6099), default port 3001
# 在 NapCat WebUI 中启用正向 WebSocket默认端口 3001
# - LLOneBot: https://github.com/LLOneBot/LLOneBot (NTQQ plugin / NTQQ 插件)
#
# allow_from: comma-separated QQ user IDs that are allowed to interact, or "*" for all.
# 允许交互的 QQ 号列表(逗号分隔),设为 "*" 允许所有人。
# token: optional access_token for WebSocket authentication (must match NapCat config).
# 可选的 WebSocket 鉴权 token需与 NapCat 配置一致)。
# [[projects.platforms]]
# type = "qq"
#
# [projects.platforms.options]
# ws_url = "ws://127.0.0.1:3001" # NapCat Forward WebSocket URL
# token = "" # optional: access_token / 可选鉴权 token
# http_url = "" # optional: OneBot HTTP API URL for file operations, e.g. "http://127.0.0.1:3000"
# # Required for SendFile. Useful when OneBot runs in WSL/Docker.
# # 可选OneBot HTTP API 地址用于文件发送。OneBot 在 WSL/Docker 中时必须配置。
# allow_from = "*" # allowed QQ user IDs, e.g. "12345,67890" or "*" for all
# # 允许的 QQ 号,如 "12345,67890""*" 表示所有
# share_session_in_channel = false # If true, all users in a group share one agent session / 群聊共享会话
# QQ Bot (Official / 官方 QQ 机器人) (uncomment to enable / 取消注释以启用)
# Uses the official QQ Bot Platform API — no third-party adapter needed.
# 使用 QQ 官方机器人 API无需第三方适配器。
# 1. Register at https://q.qq.com → create bot → get AppID & AppSecret
# 在 https://q.qq.com 注册 → 创建机器人 → 获取 AppID 和 AppSecret
# 2. Connection: WebSocket (no public IP needed) / WebSocket 连接(无需公网 IP
# 3. In group chats, bot only receives messages when @mentioned
# 群聊中,机器人仅在被 @ 时收到消息
# [[projects.platforms]]
# type = "qqbot"
#
# [projects.platforms.options]
# app_id = "" # Bot AppID / 机器人 AppID
# app_secret = "" # Bot AppSecret / 机器人 AppSecret
# sandbox = false # Use sandbox API endpoint / 使用沙箱环境
# allow_from = "*" # Allowed user openids, e.g. "OPEN_ID_1,OPEN_ID_2"; "*" = all
# # 允许的用户 openid如 "OPEN_ID_1,OPEN_ID_2""*" 表示所有
# share_session_in_channel = false # If true, all users in a group share one agent session / 群聊共享会话
# markdown_support = false # Enable Markdown messages (msg_type: 2). Requires bot permission. / 启用 Markdown 消息msg_type: 2。需要机器人具备该权限。
# intents = 100663296 # WebSocket identify intents. Default: (1<<25)|(1<<26) = 100663296
# # bit 25 (33554432): GROUP_AT_MESSAGE_CREATE — 群聊 @ 消息
# # bit 26 (67108864): INTERACTION_CREATE — 按键交互回调inline keyboard 必需)
# # If you override this, include both bits for full functionality.
# # Override 时需包含 bit 25+26否则群聊 @消息或按键交互可能失效。
# # QQ 开放平台需申请对应 Intent 权限。
# =============================================================================
# Project 5: Using Qoder CLI / 项目 5使用 Qoder CLI (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: curl -fsSL https://qoder.com/install | bash
# 需要安装curl -fsSL https://qoder.com/install | bash
# Qoder CLI uses `qodercli -p <prompt> -f stream-json` under the hood.
# Qoder CLI 底层使用 `qodercli -p <prompt> -f stream-json` 命令。
# [[projects]]
# name = "my-qoder-project"
#
# [projects.agent]
# type = "qoder"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "default" # "default" | "yolo"
#
# Mode options / 模式说明:
# - "default": Standard permissions / 标准权限模式
# - "yolo": Skip all permission checks (--dangerously-skip-permissions) / 跳过所有权限检查
#
# Optional: specify a model tier / 可选:指定模型级别
# model = "auto" # "auto" | "ultimate" | "performance" | "efficient" | "lite"
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project: Using tmux / 使用 tmux (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: tmux — https://github.com/tmux/tmux
# Attaches to a named tmux session and routes messages as shell commands.
# Output is captured by polling capture-pane; done is detected via shell prompt.
#
# [[projects]]
# name = "my-tmux-project"
#
# [projects.agent]
# type = "tmux"
#
# [projects.agent.options]
# session = "mywork" # tmux session name (required)
# pane = "0" # pane target within the session (default: "0")
# work_dir = "/path/to/dir" # working directory when auto-creating the session
# auto_create = true # create session if it doesn't exist (default: true)
# shell = "" # shell to use when creating a new session (default: system default)
# init_command = "" # command to run once when a NEW session is created (e.g. "claude")
# startup_wait_ms = 2000 # milliseconds to wait after init_command before accepting messages (default: 2000 when init_command is set)
# prompt_pattern = '[\$#>%]\s*$' # regex to detect shell prompt = command done (default shown)
# poll_interval_ms = 200 # output poll interval in milliseconds (default: 200)
# window_per_session = false # When true, each cc-connect session gets its OWN tmux window
# # (own init_command/agent instance) instead of sharing one pane.
# # Enable this for true isolation when the platform splits sessions
# # (e.g. Slack session_scope = "thread"); otherwise all sessions
# # share a single agent and their conversations interleave.
# # 为 true 时每个会话独占一个 tmux 窗口(独立 agent 实例),实现真正隔离。
#
# --- Running Claude Code inside tmux ---
# Set init_command to start claude automatically; adjust prompt_pattern to match
# Claude Code's input prompt ("> ") rather than a shell prompt:
#
# session = "claude-work"
# work_dir = "/path/to/project"
# init_command = "claude --dangerously-skip-permissions"
# startup_wait_ms = 3000
# prompt_pattern = '>\s*$'
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project 6: Using OpenCode / 项目 6使用 OpenCode (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: OpenCode CLI — https://github.com/opencode-ai/opencode
# 需要安装OpenCode CLI
# Uses `opencode run --format json` under the hood.
# 底层使用 `opencode run --format json` 命令。
# [[projects]]
# name = "my-opencode-project"
#
# [projects.agent]
# type = "opencode"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "default" # "default" | "yolo"
#
# Mode options / 模式说明:
# - "default": Standard mode / 标准模式
# - "yolo": Auto-approve all tool calls / 自动批准所有工具调用
#
# Optional: pass --agent to opencode (for plugin-defined agents) / 可选:传递 --agent 给 opencode适用于插件定义的 agent
# agent = "Sisyphus - Ultraworker"
#
# Optional: specify a model (provider/model format) / 可选:指定模型
# model = "anthropic/claude-sonnet-4-20250514"
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project: Devin CLI (Cognition, https://cli.devin.ai/) / 使用 Devin CLI
# =============================================================================
# Devin speaks the Agent Client Protocol (ACP) over stdio via its `devin acp`
# subcommand. cc-connect ships a first-class `type = "devin"` agent that pins
# the command / args / display name so you don't have to.
# Devin 通过 `devin acp` 子命令使用 ACP 协议与 cc-connect 通信。cc-connect 内置
# `type = "devin"` 的一级支持:无需手动指定 command/args默认值就能跑通。
#
# Prerequisites / 前置条件:
# 1. Install Devin CLI per the official docs at https://cli.devin.ai/
# 安装 Devin CLI见官方文档 https://cli.devin.ai/
# 2. Run `devin auth login` once — credentials are stored locally and the
# ACP subprocess reads them automatically. cc-connect never sees the token.
# 运行一次 `devin auth login` 完成登录ACP 子进程会自动读取本地凭证,
# cc-connect 全程不接触 token。
# 3. Windsurf Enterprise users can alternatively inject WINDSURF_API_KEY
# via the agent env option (see below).
# Windsurf 企业版用户也可以通过下面的 env 注入 WINDSURF_API_KEY。
# [[projects]]
# name = "my-devin-project"
#
# [projects.agent]
# type = "devin"
#
# [projects.agent.options]
# work_dir = "/path/to/your/code"
# # Optional: override only if the `devin` binary is at a non-standard path.
# # Always use an absolute path when running under launchd / systemd where
# # $PATH is minimal (e.g. ~/.local/bin may not be included).
# # cmd = "/Users/me/.local/bin/devin"
# #
# # Optional: initial permission mode applied to new sessions via
# # session/set_mode. Valid ids: normal, ask, plan, accept-edits, bypass.
# # 可选新会话的初始权限模式。合法值normal / ask / plan / accept-edits / bypass
# # mode = "normal"
# #
# # Optional: Windsurf Enterprise API key (overrides `devin auth login`).
# # 可选Windsurf 企业版 API Key优先级高于 `devin auth login` 的本地凭证)。
# # [projects.agent.options.env]
# # WINDSURF_API_KEY = "wk_xxx"
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project: ACP (Agent Client Protocol) agent / 使用 ACP 子进程
# =============================================================================
# Runs any binary that speaks ACP over stdio (newline-delimited JSON-RPC 2.0).
# See: https://agentclientprotocol.com/
# 启动符合 ACP 的 Agent 进程,通过标准输入输出进行 JSON-RPC 通信。
# Same agent type works for Cursor Agent CLI, OpenClaw bridge, GitHub Copilot CLI, etc.:
# set command + args to match each tool's documented ACP entrypoint.
# 同一 type=acp通过 command/args 指向各工具文档中的 ACP 启动方式即可。
# For Devin specifically, prefer the dedicated `type = "devin"` section above.
# 针对 Devin 建议直接使用上面的 type = "devin";下面的 type = "acp" 主要给其他
# 通用 ACP 工具使用。
# --- Example: Cursor Agent CLI (npm: @anthropic-ai/cursor-agent) ---
# [[projects]]
# name = "cursor-acp"
#
# [projects.agent]
# type = "acp"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# cmd = "agent"
# args = ["acp"]
# auth_method = "cursor_login"
# display_name = "Cursor ACP"
# --- Example: OpenClaw (Gateway-backed ACP bridge) ---
# Docs: https://docs.openclaw.ai/cli/acp
# Install the OpenClaw CLI, run a Gateway, then point cc-connect at `openclaw acp`.
#
# IMPORTANT: Remote OpenClaw requires pairing authorization before use!
#
# For remote gateways, you MUST complete the pairing process:
# 1. Start OpenClaw gateway: openclaw acp --url wss://your-gateway:18789
# 2. In another terminal, run: openclaw pair
# 3. Approve the pairing request in the OpenClaw UI
# 4. Now cc-connect can communicate with the authorized gateway
#
# Without pairing, OpenClaw will return empty responses ("pairing required" error).
# Reference: https://zhuanlan.zhihu.com/p/2005687480976970296
#
# [[projects]]
# name = "openclaw-acp"
#
# [projects.agent]
# type = "acp"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# cmd = "openclaw"
# args = ["acp"]
# # Remote gateway (use token-file on shared hosts — avoid --token in argv):
# # args = ["acp", "--url", "wss://gateway-host:18789", "--token-file", "/path/to/gateway.token"]
# # Optional: bind to an existing session key
# # args = ["acp", "--session", "agent:main:main"]
# display_name = "OpenClaw ACP"
# # env = { OPENCLAW_GATEWAY_TOKEN = "..." }
# --- Example: Trae CLI ACP (https://www.trae.ai/) ---
# [[projects]]
# name = "trae-acp"
#
# [projects.agent]
# type = "acp"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# cmd = "traecli"
# args = ["acp", "serve"]
# display_name = "Trae CLI ACP"
# --- Example: COCO ACP ---
# [[projects]]
# name = "coco-acp"
#
# [projects.agent]
# type = "acp"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# cmd = "coco"
# args = ["acp", "serve"]
# display_name = "COCO ACP"
# --- Example: GitHub Copilot CLI (public preview) ---
# Docs: https://docs.github.com/en/copilot/reference/copilot-cli-reference/acp-server
# Requires Copilot CLI installed and authenticated; no auth_method for ACP subprocess.
# [[projects]]
# name = "copilot-acp"
#
# [projects.agent]
# type = "acp"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# cmd = "copilot"
# args = ["--acp", "--stdio"]
# display_name = "Copilot ACP"
# # cmd = "/absolute/path/to/copilot" # if not on PATH (see COPILOT_CLI_PATH in GitHub docs)
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project 7: Using iFlow CLI / 项目 7使用 iFlow CLI (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: npm install -g @iflow-ai/iflow-cli
# 需要安装npm install -g @iflow-ai/iflow-cli
# Uses `iflow -i` in interactive mode with session resume (`-r`) and execution info output (`-o`).
# 底层使用 `iflow -i` 交互模式,结合 `-r` 会话续聊和 `-o` 执行信息输出。
# [[projects]]
# name = "my-iflow-project"
#
# [projects.agent]
# type = "iflow"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "default" # "default" | "auto-edit" | "plan" | "yolo"
# cmd = "iflow" # CLI binary name (default: "iflow") / CLI 二进制名称(默认 "iflow"
#
# Mode options / 模式说明:
# - "default": Manual approval mode / 手动审批模式
# - "auto-edit": Auto-edit mode / 自动编辑模式
# - "plan": Read-only planning mode / 只读规划模式
# - "yolo": Auto-approve all tool calls / 自动批准所有工具调用
#
# Optional: specify a model / 可选:指定模型
# model = "Qwen3-Coder"
#
# # Active provider / 当前激活的 provider
# # provider = "iflow-openai-compatible"
#
# [[projects.agent.providers]]
# name = "iflow-openai-compatible"
# api_key = "sk-xxx"
# base_url = "https://api.example.com/v1"
# model = "Qwen3-Coder"
# env = { IFLOW_selectedAuthType = "openai-compatible" }
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project: Using Kimi CLI / 项目:使用 Kimi CLI (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: pip install kimi-cli
# 需要安装pip install kimi-cli
# Kimi CLI uses `kimi --print --output-format stream-json` under the hood.
# Kimi CLI 底层使用 `kimi --print --output-format stream-json` 命令。
#
# Authentication / 认证方式:
# - Kimi account login (kimi login) / Kimi 账号登录
# - MOONSHOT_API_KEY env var / 环境变量
# [[projects]]
# name = "my-kimi-project"
#
# [projects.agent]
# type = "kimi"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "default" # "default" | "yolo" | "plan" | "quiet"
# cmd = "kimi" # CLI binary name (default: "kimi") / CLI 二进制名称(默认 "kimi"
# timeout_mins = 30 # 每次对话超时时间分钟0 表示不限制
#
# Mode options / 模式说明:
# - "default": Standard print mode / 标准打印模式
# - "yolo": Auto-approve all tool calls / 自动批准所有工具调用
# - "plan": Read-only plan mode / 只读规划模式
# - "quiet": Quiet mode (final message only) / 静默模式(仅最终消息)
#
# Optional: specify a model / 可选:指定模型
# model = "kimi-k2-0711-preview"
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project: Using GitHub Copilot / 项目:使用 GitHub Copilot (uncomment to enable / 取消注释以启用)
# =============================================================================
# Prerequisites / 前置条件:
# - Install GitHub Copilot CLI: https://docs.github.com/copilot/how-tos/copilot-cli
# Example: brew install github/copilot/copilot
# - copilot login (GitHub authentication)
#
# GitHub Copilot CLI uses --headless --stdio for JSON-RPC communication.
# GitHub Copilot CLI 使用 --headless --stdio 进行 JSON-RPC 通信。
# The generic ACP configuration above is also supported; this first-class agent
# adds cc-connect model/mode switching plus session list/delete integration.
# [[projects]]
# name = "my-copilot-project"
#
# [projects.agent]
# type = "copilot"
#
# [projects.agent.options]
# work_dir = "/path/to/code"
# model = "gpt-4.1" # or claude-sonnet-4.6, o3-mini, etc.
# mode = "default" # "default" or "bypassPermissions" (yolo)
# cmd = "copilot" # CLI binary name or path (default: "copilot")
#
# [[projects.platforms]]
# type = "telegram"
#
# [projects.platforms.options]
# token = "your-telegram-bot-token"
# =============================================================================
# Project 8: Another example / 项目 8更多示例 (uncomment to enable / 取消注释以启用)
# =============================================================================
# [[projects]]
# name = "my-frontend"
#
# [projects.agent]
# type = "claudecode"
#
# [projects.agent.options]
# work_dir = "/path/to/frontend"
# mode = "auto"
# mode = "bypassPermissions"
#
# [[projects.platforms]]
# type = "discord"
#
# [projects.platforms.options]
# token = "your-discord-bot-token"
# =============================================================================
# Project 9: Using Antigravity CLI / 项目 9使用 Antigravity CLI (uncomment to enable / 取消注释以启用)
# =============================================================================
# Requires: agy installed locally (refer to https://antigravity.google/docs/cli-overview)
# 需要安装:本地已安装 agy 命令 (参考 https://antigravity.google/docs/cli-overview)
# Antigravity CLI uses `agy -p` under the hood.
# Antigravity CLI 底层使用 `agy -p` 命令。
#
# [[projects]]
# name = "my-antigravity-project"
#
# [projects.agent]
# type = "antigravity"
#
# [projects.agent.options]
# work_dir = "/path/to/project"
# mode = "default" # "default" | "yolo" | "plan"
# cmd = "agy" # CLI binary name (default: "agy") / CLI 二进制名称(默认 "agy"
# timeout_mins = 30 # Timeout per conversation turn (minutes) / 每次对话超时时间(分钟)
#
# Mode options / 模式说明:
# - "default": Prompt for approval on each tool use / 每次工具调用都需要确认
# - "yolo": Auto-approve all tool calls (--dangerously-skip-permissions) / 自动批准所有工具调用
# - "plan": Read-only plan mode with terminal sandbox constraints (--sandbox) / 只读沙箱规划模式
#
# Optional: specify a model / 可选:指定模型
# model = "gemini-3.1-pro-preview"
#
# # Provider with API key / 使用 API Key 的 Provider
# [[projects.agent.providers]]
# name = "google"
# api_key = "your-gemini-api-key" # GEMINI_API_KEY