chatccc 0.2.16 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,7 +27,7 @@ ChatCCC 把 Claude Code、Cursor Agent、Codex (OpenAI) 接入了飞书群聊:
27
27
  ## 为什么选 ChatCCC
28
28
 
29
29
  - **一群一会话,心智最简单** —— `/new` 直接建一个新飞书群,群本身就是 AI 会话上下文。换会话就是换群,没有 thread / 子话题概念,手机端切换最直观
30
- - **零配置成本** —— 只用 `.env`,没有 TOML、没有 Web 后台。`npm i -g chatccc` `cd` 到项目目录直接 `chatccc` 就跑
30
+ - **零配置成本** —— 单一 `config.json`,没有 TOML 也没有零散环境变量。`npm i -g chatccc` 后**任意目录**直接 `chatccc` 就跑,首次启动自动弹出本地 Web 配置向导
31
31
  - **群里能跑 git** —— `/git status`、`/git pull`、`/git log` 在飞书群里直接执行 stdout/stderr 回发,不用回电脑
32
32
  - **代码极简易改** —— 纯 TypeScript 实现,核心只有 20 多个文件,统一 `ToolAdapter` 接口屏蔽 Claude / Cursor / Codex 差异,看得懂、改得动
33
33
 
@@ -43,21 +43,17 @@ ChatCCC 把 Claude Code、Cursor Agent、Codex (OpenAI) 接入了飞书群聊:
43
43
  npm install -g chatccc
44
44
  ```
45
45
 
46
- 要求 Node.js >= 20。安装完成后,**先进入你的项目根目录**(该目录里应有 `src/`、`.env`,可参照 `.env.example` 创建 `.env`),再启动:
46
+ 要求 Node.js >= 20。安装完成后,**在任意目录**直接启动即可:
47
47
 
48
48
  ```bash
49
- cd /path/to/your/project # Windows 示例: cd D:\code\ChatCCC
50
49
  chatccc
51
50
  ```
52
51
 
53
- 所有相对路径(`.env`、`src/index.ts`)都相对**当前终端所在目录**。若在用户主目录(如 `C:\Users\1`)执行,会出现 `.env: not found` 或找不到 `src/index.ts`。
52
+ > ChatCCC 的所有数据(`config.json`、`logs/`、`state/`)都保存在 npm 包安装目录下,与你当前终端所在目录无关。**不需要先 `cd` 到任何特定目录。**
54
53
 
55
- 若不用全局命令、改用 tsx 直接跑,同样要在项目根目录执行:
54
+ 首次启动时若 `config.json` 还没有有效凭证,会自动起一个本地 Web 配置向导(默认 `http://127.0.0.1:18080`),用浏览器把飞书 App ID / App Secret 等填进去,保存即开始运行。
56
55
 
57
- ```bash
58
- cd /path/to/your/project
59
- npx tsx --env-file=.env src/index.ts
60
- ```
56
+ > 已在运行的实例,启动完成后控制台底部 banner 也会打印「配置面板」地址,随时可以打开浏览器查看状态、修改配置(多数改动无需重启即可生效)。停止 / 重启请通过页面顶部按钮或终端 `Ctrl+C`,**面板上不再提供"启动"按钮**——服务停止后页面随进程退出,需要回到终端重新执行 `chatccc`。
61
57
 
62
58
  #### 从源码安装
63
59
 
@@ -68,7 +64,7 @@ npm install
68
64
  npm run dev
69
65
  ```
70
66
 
71
- 启动后机器人通过 WebSocket 连接飞书服务器,日志会写入 `logs/` 目录。
67
+ 启动后机器人通过 WebSocket 连接飞书服务器,日志会写入仓库根目录下的 `logs/`。
72
68
 
73
69
  #### Cursor Agent CLI(使用 Cursor 会话时需要)
74
70
 
@@ -102,19 +98,25 @@ agent --version
102
98
  cursor-agent --version
103
99
  ```
104
100
 
105
- ChatCCC 启动时会按以下顺序探测 Cursor Agent CLI:
101
+ ChatCCC 启动时会按以下顺序确定 Cursor Agent CLI:
106
102
 
107
- 1. 环境变量 `CHATCCC_CURSOR_COMMAND` 指定的路径(若已设置)
103
+ 1. `config.json` 中的 `cursor.path` 指定的路径(若已配置)
108
104
  2. Windows 上 Cursor IDE 默认安装位置 `%LOCALAPPDATA%\cursor-agent\agent.cmd`(自动识别)
109
105
  3. PATH 中的 `agent` 命令
110
106
 
111
- 若以上都找不到,或你想用一个非默认的可执行文件(例如 `cursor-agent`),在 `.env` 中显式指定:
107
+ > 首次启动 ChatCCC 时,如果 `config.json` 不存在,会从 `config.sample.json` 复制一份并**立即探测一次** Cursor / Codex CLI 的绝对路径,命中就写入 `cursor.path` / `codex.path`,无须手动编辑。
112
108
 
113
- ```env
114
- CHATCCC_CURSOR_COMMAND=/path/to/agent
109
+ 若想强制使用某个非默认的可执行文件(例如 `cursor-agent` 而不是 `agent`),可在 `config.json` 中显式指定:
110
+
111
+ ```json
112
+ {
113
+ "cursor": {
114
+ "path": "/path/to/agent"
115
+ }
116
+ }
115
117
  ```
116
118
 
117
- > 高级用户如需覆盖默认 CLI 参数,可设置 `CHATCCC_CURSOR_ARGS`,一般无需修改。
119
+ > 旧版字段 `cursor.command` 仍可读取(启动时会打印一次 warning 提示改名),新配置请统一使用 `cursor.path`。
118
120
 
119
121
  > **说明**:只使用 Claude Code(`/new claude` 或 `/new`)的用户无需安装 Cursor CLI。
120
122
 
@@ -138,21 +140,23 @@ codex login
138
140
  codex --version
139
141
  ```
140
142
 
141
- Codex 会话的模型和努力程度由 `config.toml`(`~/.codex/config.toml`)决定,也可通过环境变量指定:
142
-
143
- ```env
144
- # 不设置或设为 default 时由 codex config.toml 决定
145
- CHATCCC_CODEX_MODEL=default
143
+ Codex 会话的模型和努力程度由 `config.toml`(`~/.codex/config.toml`)决定,也可在 `config.json` 中显式覆盖:
146
144
 
147
- # 不设置或设为 default 时由 codex config.toml 决定(通过 -c model_reasoning_effort 传递)
148
- CHATCCC_CODEX_EFFORT=default
145
+ ```json
146
+ {
147
+ "codex": {
148
+ "path": "",
149
+ "model": "",
150
+ "effort": ""
151
+ }
152
+ }
149
153
  ```
150
154
 
151
- 也可通过环境变量指定自定义 Codex 可执行文件路径:
155
+ - `codex.path`:留空时直接调用 PATH 中的 `codex`;可填绝对路径指向自定义可执行文件(首次创建 `config.json` 时会自动探测并填入)
156
+ - `codex.model`:留空时由 `~/.codex/config.toml` 决定
157
+ - `codex.effort`:留空时由 `~/.codex/config.toml` 决定(通过 `-c model_reasoning_effort` 传递)
152
158
 
153
- ```env
154
- CHATCCC_CODEX_COMMAND=/path/to/codex
155
- ```
159
+ > 旧版字段 `codex.command` 仍可读取(启动时会打印一次 warning 提示改名),新配置请统一使用 `codex.path`。
156
160
 
157
161
  > **说明**:只使用 Claude Code 或 Cursor 的用户无需安装 Codex CLI。
158
162
 
@@ -162,7 +166,7 @@ CHATCCC_CODEX_COMMAND=/path/to/codex
162
166
 
163
167
  > **第一步:添加机器人(千万别忘!)**
164
168
  >
165
- > 创建应用后,立刻在「应用功能」中开启「机器人」能力。没有机器人,群聊里就收不到消息,整个 ChatCCC 无法工作。
169
+ > 创建应用后,立刻在「应用功能」中开启「机器人」能力。没有机器人,就根本找不到哪里和这个机器人对话,整个 ChatCCC 无法工作。
166
170
 
167
171
  **权限配置(重要)**(在「权限管理」中按前缀搜索,**将以下两类前缀开头的权限全部开通**):
168
172
 
@@ -191,103 +195,93 @@ CHATCCC_CODEX_COMMAND=/path/to/codex
191
195
 
192
196
  在飞书应用详情页的「凭证与基础信息」中,复制 **App ID** 和 **App Secret**。
193
197
 
194
- ### 4. 配置环境变量
195
-
196
- ```bash
197
- cp .env.example .env
198
- ```
199
-
200
- 编辑 `.env`,填入上一步拿到的凭证:
201
-
202
- ```env
203
- CHATCCC_APP_ID=cli_xxxxxxxxxxxx
204
- CHATCCC_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxx
205
- ```
206
-
207
- 若你曾使用旧版变量名 `FEISHU_CLAUDER_APP_ID` / `FEISHU_CLAUDER_APP_SECRET`,请改为上表中的 `CHATCCC_APP_ID` / `CHATCCC_APP_SECRET`。
208
-
209
- 可选:Claude 模型与思考深度:
210
-
211
- ```env
212
- # 网关或服务商文档中的 model;设为 default(任意大小写)或不写则交给 SDK/CLI 默认
213
- CHATCCC_ANTHROPIC_MODEL=default
214
-
215
- # 如 low / medium / high / max;设为 default(任意大小写)或不写则不向 SDK 传入 effort
216
- CHATCCC_ANTHROPIC_EFFORT=max
217
- ```
218
-
219
- Cursor Agent CLI 模型(仅 Cursor 会话相关,省略或 `default` 时不传 `--model`):
220
-
221
- ```env
222
- # Cursor 会话实际使用的模型 ID(如 claude-opus-4-7-max / claude-opus-4-7-thinking-max 等)
223
- # 可用 `agent --list-models` 查看所有支持的模型 ID
224
- CHATCCC_CURSOR_MODEL=claude-opus-4-7-max
225
-
226
- # 高级用户可覆盖默认 CLI 参数(一般无需修改)
227
- # CHATCCC_CURSOR_ARGS=-p --force --output-format stream-json --stream-partial-output
228
- ```
229
-
230
- Codex CLI 模型与努力程度(仅 Codex 会话相关,省略或 `default` 时不传对应参数):
231
-
232
- ```env
233
- # Codex 会话使用的模型;不设置或设为 default 时由 codex config.toml 决定
234
- CHATCCC_CODEX_MODEL=default
235
-
236
- # Codex 会话的努力程度(low/medium/high);不设置或设为 default 时由 codex config.toml 决定
237
- CHATCCC_CODEX_EFFORT=default
238
-
239
- # 也可指定自定义 Codex 可执行文件路径
240
- # CHATCCC_CODEX_COMMAND=/path/to/codex
198
+ ### 4. 配置 `config.json`
199
+
200
+ ChatCCC 的所有运行参数都集中在包根目录的 `config.json`。
201
+
202
+ #### 推荐:用 Web 配置向导(首次启动自动弹出)
203
+
204
+ 第一次运行 `chatccc` 时,如果 `config.json` 还没有有效凭证,会自动起一个本地 Web 服务(默认 `http://127.0.0.1:18080`)。在浏览器里把上一步拿到的 **App ID** / **App Secret** 等填进去,保存即写入 `config.json`,进程立即继续启动飞书 WebSocket。
205
+
206
+ #### 备选:手动编辑 `config.json`
207
+
208
+ `config.json` 不存在时,ChatCCC 会从 `config.sample.json` 复制一份,结构如下:
209
+
210
+ ```json
211
+ {
212
+ "feishu": {
213
+ "appId": "cli_xxxxxxxxxxxx",
214
+ "appSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxx"
215
+ },
216
+ "port": 18080,
217
+ "gitTimeoutSeconds": 180,
218
+ "claude": {
219
+ "enabled": false,
220
+ "model": "",
221
+ "effort": "",
222
+ "apiKey": "",
223
+ "baseUrl": ""
224
+ },
225
+ "cursor": {
226
+ "enabled": false,
227
+ "path": "",
228
+ "model": ""
229
+ },
230
+ "codex": {
231
+ "enabled": false,
232
+ "path": "",
233
+ "model": "",
234
+ "effort": ""
235
+ }
236
+ }
241
237
  ```
242
238
 
243
- #### 注意!第三方 API(如 DeepSeek)与鉴权 403
239
+ 各字段含义:
244
240
 
245
- 若你通过 **Anthropic 兼容网关**(例如 DeepSeek `/anthropic` 端点)调用模型,除了官方 Claude 以外,需要配置 **`ANTHROPIC_API_KEY`**(API 密钥)与 **`ANTHROPIC_BASE_URL`**(写入系统环境变量,见下表)。
241
+ | 字段 | 必填 | 说明 |
242
+ | --- | --- | --- |
243
+ | `feishu.appId` / `feishu.appSecret` | 是 | 飞书应用「凭证与基础信息」中的 App ID / App Secret |
244
+ | `port` | 否 | 本地 WebSocket 中继 + Web 向导监听端口,默认 `18080`;同机多实例时改成不同值即可 |
245
+ | `gitTimeoutSeconds` | 否 | `/git` 命令在会话工作目录执行时的单次超时秒数,默认 `180`,允许范围 `1–3600`,超时会被 `SIGKILL` 强制终止 |
246
+ | `claude.enabled` / `cursor.enabled` / `codex.enabled` | 否 | 是否启用对应 AI Agent;Web 向导/管理页只展示 `enabled: true` 的 agent 卡片。字段缺省时按「任一配置字段非空」自动判定(向后兼容) |
247
+ | `claude.model` | 否 | Claude Code 会话使用的模型;留空(`""` / 全空白)→ 不向 SDK 传 `model`,由 SDK / 服务商默认决定 |
248
+ | `claude.effort` | 否 | Claude 思考深度(如 `low` / `medium` / `high` / `max`);留空 → 不向 SDK 传 `effort` |
249
+ | `claude.apiKey` | 否 | 第三方 Anthropic 兼容网关的 API 密钥;**官方 Claude 用户保持 `""` 即可**,详见下文「第三方 API」一节 |
250
+ | `claude.baseUrl` | 否 | 第三方 Anthropic 兼容网关的 base URL(例如 `https://api.deepseek.com/anthropic`);**官方 Claude 用户保持 `""` 即可** |
251
+ | `cursor.model` | 否 | Cursor 会话使用的模型 ID(如 `claude-opus-4-7-max`);留空时不传 `--model`,可用 `agent --list-models` 查看支持的模型 |
252
+ | `codex.model` | 否 | Codex 会话使用的模型;留空时由 `~/.codex/config.toml` 决定 |
253
+ | `codex.effort` | 否 | Codex 努力程度(`low` / `medium` / `high`);留空时由 `~/.codex/config.toml` 决定 |
246
254
 
247
- 不少用户会把这些写在 **`~/.claude/settings.json`**(Windows 一般为 `C:\Users\<用户名>\.claude\settings.json`)的 `env` 字段里,供本机 **交互式 Claude Code** 使用。但 **Claude Agent SDK 在启动时拉起的是子进程**,其行为与直接打开终端跑 Claude Code 并不完全一致,**子进程未必会按你预期读取 `.claude` 目录下 `settings.json` 里的 `ANTHROPIC_API_KEY`、`ANTHROPIC_BASE_URL` 等**,从而出现类似:
255
+ > `claude.model` / `claude.effort` 的旧值 `"default"` 仍兼容,启动时会按留空处理并打印一次 warning,请尽快改成 `""`。
248
256
 
249
- `Failed to authenticate. API Error: 403 Request not allowed`
257
+ > `cursor.path` / `codex.path` 由首次启动时的自动探测填入,一般无需手动修改。
250
258
 
251
- **建议(最稳妥)**:把 **`ANTHROPIC_BASE_URL`** 与 **`ANTHROPIC_API_KEY`**(API 密钥)写进 **操作系统环境变量**(当前用户的「用户变量」即可,一般无需管理员),例如:
259
+ #### 第三方 API(如 DeepSeek):填 `claude.apiKey` 与 `claude.baseUrl`
252
260
 
253
- | 变量名 | 说明 |
254
- | ------ | ---- |
255
- | `ANTHROPIC_API_KEY` | 在服务商控制台获取的 **API 密钥**,填入本环境变量。Anthropic 兼容网关普遍使用该名称;若服务商文档要求使用其它环境变量名,以文档为准。 |
256
- | `ANTHROPIC_BASE_URL` | 兼容 Anthropic API 的 base URL,例如 DeepSeek:`https://api.deepseek.com/anthropic` |
261
+ 若你通过 **Anthropic 兼容网关**(例如 DeepSeek 的 `/anthropic` 端点)调用模型,需要把网关凭证填到 `config.json` 的 `claude.apiKey` 与 `claude.baseUrl`。**官方 Claude 用户**(本机已通过 `claude` CLI 完成 OAuth 登录)保持这两项 `""` 即可,无需任何额外配置。
257
262
 
258
- 若你在 `settings.json` 里还为 Sonnet/Haiku/Opus 配置了默认模型名,可一并同步到用户环境变量(如 `ANTHROPIC_MODEL`、`ANTHROPIC_DEFAULT_SONNET_MODEL` 等),与文档及网关要求保持一致。
263
+ 两条等价的填写路径:
259
264
 
260
- 修改环境变量后,请 **完全退出并重新打开** 终端、IDE(如 Cursor)以及 ChatCCC 进程,再试飞书对话或本地 `npm run demo:claude-hi`,确保子进程继承到新变量。
265
+ **1. Web 配置向导(推荐)**
261
266
 
262
- **Windows** 上可用 PowerShell 写入当前用户的持久变量(示例,请把第二行里的字符串换成你在服务商控制台复制的 **API 密钥**,即 **`ANTHROPIC_API_KEY`** 的值):
267
+ 打开 `http://127.0.0.1:18080`(首次启动自动弹出,已在运行的实例也可手动访问),在「Claude Agent」一节顶部把「API 来源」从 **官方 API(Anthropic 直连)** 切换到 **第三方 API(自定义网关)**——切换后会出现 API Key / Base URL 两个输入框,填进去保存即可。**切回官方模式后保存,已填的密钥会被自动清空**,不会残留在 `config.json` 中。
263
268
 
264
- ```powershell
265
- [Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://api.deepseek.com/anthropic", "User")
266
- [Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "你的_API_密钥", "User")
267
- ```
268
-
269
- 也可在 **系统属性 → 环境变量** 中手动添加。Linux / macOS 可将 `export` 写入 `~/.bashrc`、`~/.zshrc` 等,或使用 systemd、`launchctl` 等按你的部署方式注入。
270
-
271
- > **说明**:项目根目录的 `.env` 若通过 `tsx --env-file=.env` 加载,其中的变量会进入 Node 进程环境,**多数情况下**会随进程继承给 SDK 子进程;但各家网关与 Claude Code 版本组合较多,**仍推荐**将 **`ANTHROPIC_API_KEY`** 与 **`ANTHROPIC_BASE_URL`** 放在系统/用户环境变量中,与 `settings.json` 形成双保险,避免仅依赖 `.claude/settings.json` 时在 SDK 场景下踩坑。
269
+ **2. 直接编辑 `config.json`**
272
270
 
273
- **`CHATCCC_PORT`(可选)**:默认端口为 `18080`。若在一台机器上同时运行多个 ChatCCC 实例,可在各自的 `.env` 中设置不同端口:
274
-
275
- ```env
276
- # 实例 A(项目1)的 .env
277
- CHATCCC_PORT=18080
278
-
279
- # 实例 B(项目2)的 .env
280
- CHATCCC_PORT=18081
271
+ ```json
272
+ {
273
+ "claude": {
274
+ "model": "",
275
+ "effort": "",
276
+ "apiKey": "你的_API_密钥",
277
+ "baseUrl": "https://api.deepseek.com/anthropic"
278
+ }
279
+ }
281
280
  ```
282
281
 
283
- 不同端口的实例互不冲突,启动时会自动清理各自端口上的旧进程。
282
+ > ChatCCC 不会把这两个值写入主进程的环境变量;它们仅在调用 Claude Agent SDK 时被注入到 SDK 拉起的子进程,跟主进程 env 完全隔离。两项留空 / 缺失时,子进程沿用主进程默认的鉴权行为(即官方 Claude 的 OAuth)。
284
283
 
285
- **`CHATCCC_GIT_TIMEOUT_SECONDS`(可选)**:`/git <子命令>` 在会话工作目录执行 git 命令时的单次超时秒数,默认 `180`,允许范围 `1–3600`。配置非法(非整数、越界等)时启动日志会标红提示并回退为默认值;命令超时则会被 `SIGKILL` 强制终止,并把已收集到的输出(带「⏱️ 命令超时被强制终止」标记)回发到群里。
286
-
287
- ```env
288
- # 调高到 600 秒,适合 git fsck、git gc 等耗时操作
289
- CHATCCC_GIT_TIMEOUT_SECONDS=600
290
- ```
284
+ > 所有运行参数(端口、`/git` 超时、各 AI 工具模型 / 路径等)都在第 4 节展示的 `config.json` 里配置,不再使用 `CHATCCC_*` 环境变量。多实例共存只需在每个实例的 `config.json` 里把 `port` 设为不同值即可(例如 `18080` / `18081`),ChatCCC 启动时会自动清理各自端口上的旧进程。
291
285
 
292
286
  > **权限说明**:目前 ChatCCC 以 `bypassPermissions` 模式运行,即跳过所有权限确认、允许所有操作。后续会考虑引入细粒度权限控制,让你可以按需放行特定操作。
293
287
 
@@ -311,7 +305,7 @@ CHATCCC_GIT_TIMEOUT_SECONDS=600
311
305
  | `/cd` | 查看/切换工作目录 |
312
306
  | `/sessions` | 查看所有会话状态 |
313
307
  | `/forget` | 重置当前会话(创建新 Session,保留工作目录,同一群内继续) |
314
- | `/git <子命令>` | 在**当前会话工作目录**执行 `git ...` 并把 stdout/stderr 回发到群里(仅会话群内可用,超时见 `CHATCCC_GIT_TIMEOUT_SECONDS`) |
308
+ | `/git <子命令>` | 在**当前会话工作目录**执行 `git ...` 并把 stdout/stderr 回发到群里(仅会话群内可用,超时见 `config.json` 的 `gitTimeoutSeconds` 字段) |
315
309
  | `/restart` | 重启机器人进程 |
316
310
 
317
311
 
package/bin/chatccc.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync } from "node:child_process";
3
- import { existsSync } from "node:fs";
4
3
  import { createRequire } from "node:module";
5
4
  import { dirname, join } from "node:path";
6
5
 
@@ -10,18 +9,7 @@ const pkgRoot = dirname(require.resolve("../package.json"));
10
9
  const indexTs = join(pkgRoot, "src", "index.ts");
11
10
  const tsxCli = require.resolve("tsx/cli");
12
11
 
13
- // npm run dev 一致:当前工作目录下的 .env 会被加载(全局安装时 cwd 一般为你的项目根)
14
- const envFile = join(process.cwd(), ".env");
15
- if (!existsSync(envFile)) {
16
- console.error(`[chatccc] 当前目录下未找到 .env,不会自动加载环境变量: ${envFile}`);
17
- console.error(" 将只使用系统/用户环境变量。若未设置 CHATCCC_APP_ID / CHATCCC_APP_SECRET,启动会失败。");
18
- console.error(" 建议: cd 到项目根目录,复制 .env.example 为 .env 并填写后再运行 chatccc。\n");
19
- }
20
- const tsxArgs = existsSync(envFile)
21
- ? [tsxCli, "--env-file", envFile, indexTs, ...process.argv.slice(2)]
22
- : [tsxCli, indexTs, ...process.argv.slice(2)];
23
-
24
- const result = spawnSync(process.execPath, tsxArgs, {
12
+ const result = spawnSync(process.execPath, [tsxCli, indexTs, ...process.argv.slice(2)], {
25
13
  stdio: "inherit",
26
14
  cwd: process.cwd(),
27
15
  env: process.env,
@@ -33,4 +21,4 @@ if (code !== 0) {
33
21
  console.error("chatccc 子进程已结束,服务没有在后台运行。");
34
22
  }
35
23
 
36
- process.exit(code);
24
+ process.exit(code);
@@ -0,0 +1,26 @@
1
+ {
2
+ "feishu": {
3
+ "appId": "",
4
+ "appSecret": ""
5
+ },
6
+ "port": 18080,
7
+ "gitTimeoutSeconds": 180,
8
+ "claude": {
9
+ "enabled": false,
10
+ "model": "",
11
+ "effort": "",
12
+ "apiKey": "",
13
+ "baseUrl": ""
14
+ },
15
+ "cursor": {
16
+ "enabled": false,
17
+ "path": "",
18
+ "model": ""
19
+ },
20
+ "codex": {
21
+ "enabled": false,
22
+ "path": "",
23
+ "model": "",
24
+ "effort": ""
25
+ }
26
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatccc",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Feishu bot bridge for Claude Code",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -11,21 +11,22 @@
11
11
  "files": [
12
12
  "src/",
13
13
  "bin/",
14
+ "images/",
14
15
  "package.json",
15
16
  "README.md",
16
- ".env.example"
17
+ "config.sample.json"
17
18
  ],
18
19
  "scripts": {
19
- "dev": "tsx --env-file=.env src/index.ts",
20
- "chatccc": "tsx --env-file=.env src/index.ts",
21
- "start": "tsx --env-file=.env src/index.ts",
22
- "demo:bot-test": "tsx --env-file=.env demo/bot_test.ts",
23
- "demo:bot-test:local": "tsx --env-file=.env demo/bot_test.ts --local",
24
- "demo:create-group": "tsx --env-file=.env src/index.ts",
25
- "demo:create-group:local": "tsx --env-file=.env src/index.ts --local",
26
- "demo:permission-check": "tsx --env-file=.env demo/permission_check.ts",
27
- "demo:claude-hi": "tsx --env-file=.env demo/claude_say_hi.ts",
28
- "demo:codex-hi": "tsx --env-file=.env demo/codex_say_hi.ts",
20
+ "dev": "tsx src/index.ts",
21
+ "chatccc": "tsx src/index.ts",
22
+ "start": "tsx src/index.ts",
23
+ "demo:bot-test": "tsx demo/bot_test.ts",
24
+ "demo:bot-test:local": "tsx demo/bot_test.ts --local",
25
+ "demo:create-group": "tsx src/index.ts",
26
+ "demo:create-group:local": "tsx src/index.ts --local",
27
+ "demo:permission-check": "tsx demo/permission_check.ts",
28
+ "demo:claude-hi": "tsx demo/claude_say_hi.ts",
29
+ "demo:codex-hi": "tsx demo/codex_say_hi.ts",
29
30
  "test": "vitest run",
30
31
  "test:watch": "vitest"
31
32
  },
@@ -338,8 +338,8 @@ describe("buildSessionsCard", () => {
338
338
 
339
339
  it("separates Claude Code and Cursor sessions", () => {
340
340
  const card = buildSessionsCard([
341
- { sessionId: "c1", active: false, turnCount: 1, elapsedSeconds: null, model: "default", tool: "claude" },
342
- { sessionId: "c2", active: false, turnCount: 2, elapsedSeconds: null, model: "default", tool: "cursor" },
341
+ { sessionId: "c1", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
342
+ { sessionId: "c2", active: false, turnCount: 2, elapsedSeconds: null, model: "claude-opus-4-7-max", tool: "cursor" },
343
343
  ]);
344
344
  const parsed = JSON.parse(card);
345
345
  const content: string = parsed.elements[0].text.content;
@@ -349,7 +349,7 @@ describe("buildSessionsCard", () => {
349
349
 
350
350
  it("omits Cursor section when no Cursor sessions", () => {
351
351
  const card = buildSessionsCard([
352
- { sessionId: "c1", active: false, turnCount: 1, elapsedSeconds: null, model: "default", tool: "claude" },
352
+ { sessionId: "c1", active: false, turnCount: 1, elapsedSeconds: null, model: "(留空)", tool: "claude" },
353
353
  ]);
354
354
  const parsed = JSON.parse(card);
355
355
  const content: string = parsed.elements[0].text.content;