cc-ding 0.0.5 → 0.2.0

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
@@ -4,29 +4,37 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/cc-ding.svg?style=flat-square)](https://www.npmjs.com/package/cc-ding)
5
5
  [![License](https://img.shields.io/npm/l/cc-ding.svg?style=flat-square)](LICENSE)
6
6
  [![Node.js](https://img.shields.io/node/v/cc-ding.svg?style=flat-square)](https://nodejs.org)
7
+ [![GitHub stars](https://img.shields.io/github/stars/yihuineng/cc-ding.svg?style=flat-square)](https://github.com/yihuineng/cc-ding/stargazers)
7
8
 
8
- 将钉钉机器人接入本地 [Claude Code](https://claude.ai/code),实现群聊多轮对话、任务队列、定时任务等能力。
9
+ > Claude Code 接入钉钉,构建企业级 AI 协作工作流。
10
+ >
11
+ > Connect Claude Code to DingTalk for enterprise-grade AI collaboration.
9
12
 
10
- ## 功能特性
13
+ **[中文](#中文--简体中文)** | **[English](#english)**
11
14
 
12
- - **多轮对话** — 支持私聊 / 群聊多轮会话,`/new` `/end` `/resume` 灵活切换
13
- - **群内多用户** — 白名单内所有成员均可参与同一会话
14
- - **任务队列** — `/task` 提交任务,按队列顺序执行,完成后自动回复
15
- - **定时任务** — 自然语言创建 cron,支持暂停 / 恢复 / 删除
16
- - **图片消息** — 自动接收钉钉图片 / 富文本内嵌图片,可选本地 OCR 识别
17
- - **API Key 池化** — 429 自动切换、跨天重置,提升服务稳定性
18
- - **关联群** — 多个群共享同一个 Claude 会话上下文
15
+ ---
19
16
 
20
- ## 快速开始
17
+ ## 中文 | 简体中文
21
18
 
22
- ### 安装
19
+ Claude Code 接入钉钉,实现双向通信。支持多轮对话、任务队列、定时任务、图片识别,帮助团队以最低成本构建可私有化部署的 AI 助手。
20
+
21
+ ### 目录
22
+
23
+ - [快速开始](#快速开始)
24
+ - [命令参考](#命令参考)
25
+ - [配置说明](#配置说明)
26
+ - [数据存储](#数据存储)
27
+ - [开发](#开发)
28
+
29
+ ### 快速开始
30
+
31
+ #### 安装
23
32
 
24
33
  ```bash
25
34
  pnpm i cc-ding -g
26
- cc-ding --help
27
35
  ```
28
36
 
29
- ### 1. 初始化配置
37
+ #### 初始化
30
38
 
31
39
  ```bash
32
40
  cc-ding init -ci {clientId} -cs {clientSecret} -m {手机号}
@@ -34,107 +42,79 @@ cc-ding init -ci {clientId} -cs {clientSecret} -m {手机号}
34
42
 
35
43
  | 参数 | 说明 |
36
44
  |------|------|
37
- | `-ci, --clientId` | 钉钉应用的 ClientId |
45
+ | `-ci, --clientId` | 钉钉应用 ClientId |
38
46
  | `-cs, --clientSecret` | 钉钉 Stream 连接密钥 |
39
47
  | `-m, --mobile` | 管理员手机号(自动加入白名单) |
40
48
  | `-cn, --clientName` | 机器人名称(可选,默认 "cc助手") |
41
49
 
42
- ### 2. 编辑配置
50
+ #### 编辑配置
43
51
 
44
- 配置文件位于 `~/.cc-ding/{clientId}/config.json`,按 [配置文件示例](#配置文件示例) 补充 `conversations` 等字段。
52
+ 配置文件位于 `~/.cc-ding/{clientId}/config.json`,参考下方 [配置文件示例](#配置文件示例)
45
53
 
46
- ### 3. 启动
54
+ #### 启动
47
55
 
48
56
  ```bash
49
57
  # 直接启动
50
58
  cc-ding run -ci {clientId}
51
59
 
52
- # 推荐:PM2 守护进程方式
60
+ # 推荐:PM2 守护进程
53
61
  pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientId}
54
62
  ```
55
63
 
56
- ## 使用指南
64
+ ### 命令参考
57
65
 
58
- ### 会话模式
66
+ #### 会话
59
67
 
60
68
  | 命令 | 说明 |
61
69
  |------|------|
62
- | `/help` | 查看所有可用命令 |
63
- | `/log [行数]` | 查看最近会话日志 |
64
- | `/new [初始消息]` | 开始新的对话 |
65
- | `/resume [会话ID]` | 继续历史会话(不指定则恢复最近一个) |
70
+ | `/help` | 查看所有命令 |
71
+ | `/log [行数]` | 查看会话日志 |
72
+ | `/new [消息]` | 开始新对话 |
73
+ | `/resume [ID]` | 恢复历史会话(不指定则恢复最近一个) |
66
74
  | `/end` | 结束当前会话 |
67
75
 
68
- - 会话自动持久化到 `active.json`,服务重启后自动恢复
69
- - 群内所有白名单用户均可参与对话
76
+ > 会话自动持久化到 `active.json`,重启后无缝恢复。群内所有白名单用户均可参与。
70
77
 
71
- ### 任务模式
78
+ #### 任务
72
79
 
73
80
  ```
74
- /task <任务描述> # 提交任务到队列
75
- /task cancel # 取消任务
81
+ /task <描述> # 提交任务(自动排队顺序执行)
82
+ /task cancel # 取消任务
76
83
  ```
77
84
 
78
- ### 定时任务
85
+ #### 定时任务
79
86
 
80
87
  ```
81
- /cron <自然语言描述> # Claude 自动生成 cron 表达式
82
- /cron 0 9 * * * <任务描述> # 直接指定 cron 表达式
83
- /cron list # 查看列表
84
- /cron pause <id> / resume <id> # 暂停 / 恢复
85
- /cron delete <id> # 删除
88
+ /cron <自然语言> # Claude 自动生成 cron 表达式
89
+ /cron 0 9 * * * <描述> # 直接指定 cron
90
+ /cron list # 查看列表
91
+ /cron pause <id> | resume <id> # 暂停 / 恢复
92
+ /cron delete <id> # 删除
86
93
  ```
87
94
 
88
- ### 文件操作
95
+ #### 文件操作
89
96
 
90
97
  | 命令 | 说明 |
91
98
  |------|------|
92
- | `/pwd` | 显示工作目录绝对路径 |
99
+ | `/pwd` | 显示工作目录 |
93
100
  | `/ls [目录] [层数]` | 查看目录结构 |
94
- | `/mkdir <路径>` | 创建文件夹 |
95
- | `/touch <路径>` | 创建空文件 |
96
- | `/rm <路径>` | 删除文件或目录 |
101
+ | `/mkdir` / `/touch` / `/rm` | 创建目录 / 创建空文件 / 删除 |
97
102
 
98
- ### 管理命令(仅 owner)
103
+ #### 管理命令(仅 owner)
99
104
 
100
105
  | 命令 | 说明 |
101
106
  |------|------|
102
- | `/info [robot\|session\|task]` | 查看群配置、会话和任务信息 |
103
- | `/version` | 查看版本信息 |
104
- | `/open [shell]` | 在文件管理器或终端中打开工作目录 |
105
- | `/clean [all]` | 清除历史会话和缓存 |
107
+ | `/info [robot\|session\|task]` | 查看配置/会话/任务信息 |
108
+ | `/version` | 版本信息 |
109
+ | `/open [shell]` | 打开工作目录 |
110
+ | `/clean [all]` | 清除历史和缓存 |
106
111
  | `/reset-apikeycfg` | 重置 API Key 配置 |
107
112
  | `/cfg` | 注册当前群到配置 |
108
113
  | `/auth [add\|del <用户>]` | 管理群级白名单 |
109
114
 
110
- ## 配置说明
111
-
112
- ### 白名单
113
-
114
- - **全局白名单**:`config.json` 中的 `whiteUserList`
115
- - **群级白名单**:`conversations[].whiteUserList`(优先级高于全局)
116
- - 支持手机号和 userId 两种格式,手机号自动解析为 userId
117
-
118
- ### API Key 池化
119
-
120
- 配置 `apiKeyCfg` 后启用:
121
-
122
- - 429 错误自动切换到可用 Key
123
- - 连续 TPM 不稳定时自动换 Key
124
- - 每日 0 点自动重置 API Key 状态
125
-
126
- ### 图片消息
127
-
128
- - 支持 `picture` 和 `richText`(含内嵌图片)消息类型
129
- - 图片自动下载到 `.images/` 目录
130
- - `useLocalOcr: true`(默认)使用本地 OCR 识别,同时传入原图路径供 Claude 自主查看
131
- - 设置 `useLocalOcr: false` 关闭 OCR(适用于支持图片识别的模型)
132
-
133
- ### 关联群
115
+ ### 配置说明
134
116
 
135
- 通过 `linkConversationId` 实现多个群共享同一个 Claude 会话上下文,消息自动路由到同一活跃会话。
136
-
137
- ## 配置文件示例
117
+ #### 配置文件示例
138
118
 
139
119
  ```json
140
120
  {
@@ -151,9 +131,7 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
151
131
  "whiteUserList": ["工号1", "工号2"],
152
132
  "agent": "指定agent(可选)",
153
133
  "useLocalOcr": true,
154
- "taskCfg": {
155
- "skill": "指定技能(可选)"
156
- }
134
+ "taskCfg": { "skill": "指定技能(可选)" }
157
135
  }
158
136
  ],
159
137
  "taskQueueSize": 50,
@@ -161,34 +139,220 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
161
139
  "sessionMaxConcurrency": 20,
162
140
  "includeThinking": false,
163
141
  "resultOnly": true,
164
- "debug": false
142
+ "debug": false,
143
+ "skipSandbox": false
165
144
  }
166
145
  ```
167
146
 
168
- ## 数据存储
147
+ #### 配置项速查
148
+
149
+ | 配置 | 说明 |
150
+ |------|------|
151
+ | `whiteUserList` | 全局白名单(手机号或 userId) |
152
+ | `conversations[].whiteUserList` | 群级白名单,优先级高于全局 |
153
+ | `apiKeyCfg` | API Key 池化:429 自动切换、每日 0 点重置 |
154
+ | `useLocalOcr` | 图片本地 OCR(默认 `true`),模型支持图片时可设 `false` |
155
+ | `linkConversationId` | 关联群 ID,多群共享同一 Claude 会话上下文 |
156
+ | `skipSandbox` | 跳过沙箱,允许完整文件系统访问(默认 `false`) |
157
+
158
+ ### 数据存储
169
159
 
170
160
  所有数据存储在 `~/.cc-ding/{clientId}/` 目录下:
171
161
 
172
162
  | 类型 | 路径 |
173
163
  |------|------|
174
- | 会话数据 | `{MD5}/.sessions/{claudeSessionId}/session.{json,log}` |
175
- | 任务数据 | `{MD5}/.tasks/{时间戳}/task.{json,log}` |
164
+ | 会话 | `{MD5}/.sessions/{claudeSessionId}/session.{json,log}` |
165
+ | 任务 | `{MD5}/.tasks/{时间戳}/task.{json,log}` |
176
166
  | 定时任务 | `cron.json` |
177
167
  | 图片缓存 | `{MD5}/.images/` |
178
168
  | 手机号映射 | `phone-map.json` |
179
169
 
180
- ## 开发
170
+ ### 开发
181
171
 
182
172
  ```bash
183
173
  pnpm install
184
- pnpm run lint # 代码检查
185
- pnpm run test # 运行测试
186
- pnpm run build # 构建
174
+ pnpm run lint
175
+ pnpm run test
176
+ pnpm run build
177
+ ```
178
+
179
+ **系统要求:** Node.js >= 24
180
+
181
+ ---
182
+
183
+ ## English
184
+
185
+ Connect Claude Code to DingTalk for bidirectional communication. Supports multi-turn conversations, task queues, scheduled jobs, and image recognition — helping teams build privately deployable AI assistants at minimal cost.
186
+
187
+ ### Table of Contents
188
+
189
+ - [Quick Start](#quick-start)
190
+ - [Commands](#commands)
191
+ - [Configuration](#configuration)
192
+ - [Data Storage](#data-storage)
193
+ - [Development](#development)
194
+
195
+ ### Quick Start
196
+
197
+ #### Install
198
+
199
+ ```bash
200
+ pnpm i cc-ding -g
201
+ ```
202
+
203
+ #### Initialize
204
+
205
+ ```bash
206
+ cc-ding init -ci {clientId} -cs {clientSecret} -m {phone_number}
187
207
  ```
188
208
 
189
- ## 系统要求
209
+ | Parameter | Description |
210
+ |-----------|-------------|
211
+ | `-ci, --clientId` | DingTalk app ClientId |
212
+ | `-cs, --clientSecret` | DingTalk Stream connection secret |
213
+ | `-m, --mobile` | Admin phone number (auto-added to whitelist) |
214
+ | `-cn, --clientName` | Bot name (optional, default "cc助手") |
215
+
216
+ #### Edit Config
217
+
218
+ Config file is at `~/.cc-ding/{clientId}/config.json`. See [config example](#configuration-example) below.
219
+
220
+ #### Start
221
+
222
+ ```bash
223
+ # Direct start
224
+ cc-ding run -ci {clientId}
225
+
226
+ # Recommended: PM2 daemon
227
+ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientId}
228
+ ```
229
+
230
+ ### Commands
231
+
232
+ #### Session
233
+
234
+ | Command | Description |
235
+ |---------|-------------|
236
+ | `/help` | View all commands |
237
+ | `/log [lines]` | View session logs |
238
+ | `/new [msg]` | Start a new conversation |
239
+ | `/resume [ID]` | Resume a previous session (latest if omitted) |
240
+ | `/end` | End the current session |
241
+
242
+ > Sessions are auto-persisted to `active.json` and restored on restart. All whitelisted users in the group can participate.
243
+
244
+ #### Task
245
+
246
+ ```
247
+ /task <description> # Submit task (auto-queued, sequential execution)
248
+ /task cancel # Cancel a task
249
+ ```
250
+
251
+ #### Scheduled
252
+
253
+ ```
254
+ /cron <natural language> # Claude auto-generates cron expression
255
+ /cron 0 9 * * * <description> # Specify cron directly
256
+ /cron list # View all
257
+ /cron pause <id> | resume <id> # Pause / resume
258
+ /cron delete <id> # Delete
259
+ ```
260
+
261
+ #### File Operations
262
+
263
+ | Command | Description |
264
+ |---------|-------------|
265
+ | `/pwd` | Show working directory |
266
+ | `/ls [dir] [depth]` | View directory structure |
267
+ | `/mkdir` / `/touch` / `/rm` | Create dir / Create empty file / Delete |
268
+
269
+ #### Admin (owner only)
270
+
271
+ | Command | Description |
272
+ |---------|-------------|
273
+ | `/info [robot\|session\|task]` | View config/session/task info |
274
+ | `/version` | Version info |
275
+ | `/open [shell]` | Open working directory |
276
+ | `/clean [all]` | Clear history and cache |
277
+ | `/reset-apikeycfg` | Reset API Key configuration |
278
+ | `/cfg` | Register current group to config |
279
+ | `/auth [add\|del <user>]` | Manage group whitelist |
280
+
281
+ ### Configuration
282
+
283
+ #### Configuration Example
284
+
285
+ ```json
286
+ {
287
+ "clientName": "cc助手",
288
+ "owner": "your_phone_number",
289
+ "whiteUserList": ["your_phone_number"],
290
+ "clientSecret": "dingtalk_stream_secret",
291
+ "defaultDingToken": "fallback_dingtalk_bot_token",
292
+ "conversations": [
293
+ {
294
+ "conversationId": "group_id",
295
+ "conversationTitle": "group_name",
296
+ "dingToken": "group_bot_token",
297
+ "whiteUserList": ["emp_id_1", "emp_id_2"],
298
+ "agent": "specified_agent (optional)",
299
+ "useLocalOcr": true,
300
+ "taskCfg": { "skill": "specified_skill (optional)" }
301
+ }
302
+ ],
303
+ "taskQueueSize": 50,
304
+ "taskHandlerCount": 1,
305
+ "sessionMaxConcurrency": 20,
306
+ "includeThinking": false,
307
+ "resultOnly": true,
308
+ "debug": false,
309
+ "skipSandbox": false
310
+ }
311
+ ```
312
+
313
+ #### Config Quick Reference
314
+
315
+ | Config | Description |
316
+ |--------|-------------|
317
+ | `whiteUserList` | Global whitelist (phone or userId) |
318
+ | `conversations[].whiteUserList` | Group-level whitelist, higher priority than global |
319
+ | `apiKeyCfg` | API Key pooling: auto-switch on 429, daily reset at midnight |
320
+ | `useLocalOcr` | Local image OCR (default `true`); set `false` if model supports images natively |
321
+ | `linkConversationId` | Link groups to share one Claude session context |
322
+ | `skipSandbox` | Skip sandbox for full filesystem access (default `false`) |
323
+
324
+ ### Data Storage
325
+
326
+ All data is stored under `~/.cc-ding/{clientId}/`:
327
+
328
+ | Type | Path |
329
+ |------|------|
330
+ | Sessions | `{MD5}/.sessions/{claudeSessionId}/session.{json,log}` |
331
+ | Tasks | `{MD5}/.tasks/{timestamp}/task.{json,log}` |
332
+ | Cron jobs | `cron.json` |
333
+ | Image cache | `{MD5}/.images/` |
334
+ | Phone mapping | `phone-map.json` |
335
+
336
+ ### Development
337
+
338
+ ```bash
339
+ pnpm install
340
+ pnpm run lint
341
+ pnpm run test
342
+ pnpm run build
343
+ ```
344
+
345
+ **Requirements:** Node.js >= 24
346
+
347
+ ---
348
+
349
+ ## Star History
350
+
351
+ [![Star History Chart](https://api.star-history.com/svg?repos=yihuineng/cc-ding&type=Date)](https://github.com/yihuineng/cc-ding/stargazers)
352
+
353
+ ## Contributors
190
354
 
191
- - Node.js >= 24
355
+ [![Contributors](https://contrib.rocks/image?repo=yihuineng/cc-ding)](https://github.com/yihuineng/cc-ding/graphs/contributors)
192
356
 
193
357
  ## License
194
358
 
@@ -1,2 +1,37 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';const a0_0xcee1f1=a0_0x347a;(function(_0xc08000,_0x11f325){const _0x128719=a0_0x347a,_0x4723b0=_0xc08000();while(!![]){try{const _0x10cc7e=-parseInt(_0x128719(0x14d))/0x1*(-parseInt(_0x128719(0x182))/0x2)+-parseInt(_0x128719(0x18a))/0x3*(-parseInt(_0x128719(0x183))/0x4)+-parseInt(_0x128719(0x180))/0x5+parseInt(_0x128719(0x15d))/0x6*(-parseInt(_0x128719(0x170))/0x7)+-parseInt(_0x128719(0x197))/0x8+parseInt(_0x128719(0x185))/0x9*(-parseInt(_0x128719(0x156))/0xa)+parseInt(_0x128719(0x17b))/0xb*(parseInt(_0x128719(0x16d))/0xc);if(_0x10cc7e===_0x11f325)break;else _0x4723b0['push'](_0x4723b0['shift']());}catch(_0x2c7237){_0x4723b0['push'](_0x4723b0['shift']());}}}(a0_0x4127,0x36217));var __importDefault=this&&this[a0_0xcee1f1(0x152)]||function(_0x3a124f){const _0x5e8a33=a0_0xcee1f1;return _0x3a124f&&_0x3a124f[_0x5e8a33(0x160)]?_0x3a124f:{'default':_0x3a124f};};Object[a0_0xcee1f1(0x154)](exports,'__esModule',{'value':!![]});const common_1=require(a0_0xcee1f1(0x157)),commander_1=require('commander'),session_1=require(a0_0xcee1f1(0x15e)),path_1=__importDefault(require('path')),cc_ding_cli_1=require(a0_0xcee1f1(0x16a)),lock_1=require(a0_0xcee1f1(0x18c)),doctor_1=require(a0_0xcee1f1(0x18e)),fs_1=__importDefault(require('fs'));(0x0,common_1[a0_0xcee1f1(0x175)])(),process[a0_0xcee1f1(0x184)](a0_0xcee1f1(0x14c)),process[a0_0xcee1f1(0x195)](0x0),process['on'](a0_0xcee1f1(0x187),function(_0x4a679f){const _0x14c170=a0_0xcee1f1;console[_0x14c170(0x199)]('Caught\x20exception:\x20'+_0x4a679f),process[_0x14c170(0x172)](0x1);});function a0_0x4127(){const _0x59cdf8=['\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20功能:\x20钉钉机器人对接本地Claude,\x20支持会话模式和任务队列模式\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20会话数据路径:\x20~/.cc-ding/{clientId}/{MD5}/.sessions/{claudeSessionId}/session.{json|log}\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20任务数据路径:\x20~/.cc-ding/{clientId}/{MD5}/.tasks/{时间戳}/task.{json|log}\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20定时任务数据:\x20~/.cc-ding/{clientId}/cron.json\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20启动方式:\x20pm2\x20start\x20--name\x20\x22cc-ding-{clientId}\x22\x20npx\x20--\x20-p\x20cc-ding\x20run\x20-ci\x20{clientId}\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20会话模式说明\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20会话ID:\x20由\x20Claude\x20分配的\x20claudeSessionId\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20结束会话:\x20/end\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20新会话:\x20/new\x20[初始消息]\x20强制结束当前会话并开启新会话\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20恢复会话:\x20/resume\x20[会话ID]\x20恢复指定历史会话,\x20不指定则恢复最近一个\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20会话持久化:\x20活跃会话自动保存到\x20active.json,\x20服务重启后自动恢复\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20群内多用户:\x20允许群内所有白名单用户参与对话\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20/help:\x20查看所有可用命令(含版本、作者、文档链接);\x20/{命令}\x20--help\x20查看命令详细用法\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20图片消息支持\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20支持接收钉钉图片消息(picture)和富文本消息(richText,\x20含内嵌图片)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20图片自动下载保存到\x20<会话目录>/.images/\x20下\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20useLocalOcr:\x20默认开启,\x20使用本地OCR识别图片文字,\x20同时传入原图路径供Claude自主查看\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20配置方式:\x20conversations[].useLocalOcr\x20=\x20false\x20可关闭OCR(适用于支持图片识别的模型)\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20任务模式说明\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20任务ID:\x20任务接收时间戳\x0a\x20\x20\x20\x20\x20\x20\x20\x20-\x20API\x20Key\x20池化管理(可选,\x20配置apiKeyCfg后启用)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20429自动切换:\x20自动切换到API\x20Key模式\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20Key轮换:\x20API\x20Key遇到429或连续TPM不稳定时自动换Key\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20跨天重置:\x20每日自动重置API\x20Key状态\x0a\x20\x20\x20\x20\x20\x20','.cc-ding','loadEnv','requiredOption','projUtil','mobile','version','DingClaude','187gWvOis','printDoctorResults','split','default','\x20\x203.\x20推荐PM2启动:','14515aPEdpU','existsSync','44kSGmHO','68KugMSB','removeAllListeners','314343boNSZN','clientName','uncaughtException','<兜底钉钉机器人Token-用于无dingToken群的消息接收>','\x0a💡\x20请升级\x20Node\x20版本后重新运行\x0a','69777wxREnk','acquirePidLock','../src/biz/lock','slice','../src/biz/doctor','parse','clientSecret\x20(钉钉Stream连接密钥)','-m,\x20--mobile\x20<value>','\x20\x20要求:Node\x20>=\x2024','-cs,\x20--clientSecret\x20<value>','clientId','setMaxListeners','\x20\x201.\x20编辑\x20config.json\x20添加\x20conversations\x20配置(群聊需配置dingToken)','388760AgOatj','-ci,\x20--clientId\x20<value>','log','\x0a❌\x20Node\x20版本过低,无法执行\x20init\x20命令','warning','4584NVoFKA','description','mobile\x20(自己的手机号,\x20自动加入白名单)','before','doctor','__importDefault','after','defineProperty','runDoctor','50xqbjkp','../src/common','addHelpText','argv','command','后续步骤:','\x22\x20npx\x20--\x20-p\x20cc-ding\x20cc-ding\x20run\x20-ci\x20','44778TevGVj','../src/biz/session','option','__esModule','初始化cc-ding配置文件,\x20生成最简config.json','join','/.cc-ding/','配置文件已生成:','\x20\x202.\x20启动机器人:\x20cc-ding\x20run\x20-ci','cc助手','/config.json','配置文件已存在:\x20','action','../src/biz/cc-ding-cli','clientSecret','Command','239772xXEeAW','getHomeDir','initClientDir','364XgtIWc','检查指定client的配置文件schema合法性和有效性','exit'];a0_0x4127=function(){return _0x59cdf8;};return a0_0x4127();}const program=new commander_1[(a0_0xcee1f1(0x16c))]();function a0_0x347a(_0x37abab,_0x2fc1c4){_0x37abab=_0x37abab-0x14b;const _0x4127a0=a0_0x4127();let _0x347a0c=_0x4127a0[_0x37abab];return _0x347a0c;}program[a0_0xcee1f1(0x158)](a0_0xcee1f1(0x150),'\x0a\x20\x20\x20\x20cc-ding\x20for\x20connect\x20ClaudeCode\x20to\x20DingDingRobot\x0a\x20\x20')[a0_0xcee1f1(0x158)](a0_0xcee1f1(0x153),'\x0aExamples:\x0a\x20\x20$\x20cc-ding\x20init\x20-ci\x20{clientId}\x20-cs\x20{clientSecret}\x20-m\x20{mobile}\x0a\x20\x20$\x20cc-ding\x20run\x20-ci\x20{clientId}\x0a')['version']((0x0,common_1[a0_0xcee1f1(0x177)])()['getPkgVersion']()),program[a0_0xcee1f1(0x15a)]('init')[a0_0xcee1f1(0x14e)](a0_0xcee1f1(0x161))['requiredOption']('-ci,\x20--clientId\x20<value>',a0_0xcee1f1(0x194))[a0_0xcee1f1(0x176)](a0_0xcee1f1(0x193),a0_0xcee1f1(0x190))[a0_0xcee1f1(0x176)](a0_0xcee1f1(0x191),a0_0xcee1f1(0x14f))[a0_0xcee1f1(0x15f)]('-cn,\x20--clientName\x20<value>','clientName\x20(机器人名称,\x20可选)')[a0_0xcee1f1(0x169)](async _0x29e2d8=>{const _0x291c1d=a0_0xcee1f1,_0x2f4809=process[_0x291c1d(0x179)][_0x291c1d(0x18d)](0x1),_0x3d8b46=parseInt(_0x2f4809[_0x291c1d(0x17d)]('.')[0x0],0xa);_0x3d8b46<0x18&&(console['log'](_0x291c1d(0x14b)),console[_0x291c1d(0x199)]('\x20\x20当前版本:'+_0x2f4809),console[_0x291c1d(0x199)](_0x291c1d(0x192)),console[_0x291c1d(0x199)](_0x291c1d(0x189)),process[_0x291c1d(0x172)](0x1));const _0x30fda1=(0x0,session_1[_0x291c1d(0x16e)])()+_0x291c1d(0x163)+_0x29e2d8[_0x291c1d(0x194)],_0x3d01e0=_0x30fda1+_0x291c1d(0x167);fs_1[_0x291c1d(0x17e)][_0x291c1d(0x181)](_0x3d01e0)&&(console['log'](_0x291c1d(0x168)+_0x3d01e0),console[_0x291c1d(0x199)]('如需重新初始化,\x20请先删除已有配置文件'),process['exit'](0x1));const _0x169d61={'clientName':_0x29e2d8[_0x291c1d(0x186)]||_0x291c1d(0x166),'owner':_0x29e2d8['mobile'],'whiteUserList':[_0x29e2d8[_0x291c1d(0x178)]],'clientSecret':_0x29e2d8[_0x291c1d(0x16b)],'defaultDingToken':_0x291c1d(0x188),'conversations':[],'includeThinking':![],'resultOnly':!![],'debug':![],'taskQueueSize':0xa,'taskHandlerCount':0x1,'sessionMaxConcurrency':0x14};(0x0,session_1[_0x291c1d(0x16f)])(_0x29e2d8[_0x291c1d(0x194)],_0x169d61),console[_0x291c1d(0x199)](_0x291c1d(0x164),_0x3d01e0),console['log'](''),console['log'](_0x291c1d(0x15b)),console[_0x291c1d(0x199)](_0x291c1d(0x196)),console['log'](_0x291c1d(0x165),_0x29e2d8['clientId']),console[_0x291c1d(0x199)](_0x291c1d(0x17f)),console[_0x291c1d(0x199)]('\x20\x20\x20\x20\x20pm2\x20start\x20--name\x20\x22cc-ding-'+_0x29e2d8[_0x291c1d(0x194)]+_0x291c1d(0x15c)+_0x29e2d8[_0x291c1d(0x194)]);}),program[a0_0xcee1f1(0x15a)]('run')[a0_0xcee1f1(0x14e)](a0_0xcee1f1(0x173))[a0_0xcee1f1(0x176)](a0_0xcee1f1(0x198),a0_0xcee1f1(0x194))[a0_0xcee1f1(0x169)](async _0x146f17=>{const _0x18f1d0=a0_0xcee1f1;(0x0,session_1['ensureClientDir'])(_0x146f17[_0x18f1d0(0x194)]);const _0x3898d8=path_1[_0x18f1d0(0x17e)]['join']((0x0,session_1[_0x18f1d0(0x16e)])(),_0x18f1d0(0x174),_0x146f17['clientId']);(0x0,lock_1[_0x18f1d0(0x18b)])(_0x3898d8,_0x146f17[_0x18f1d0(0x194)]),await new cc_ding_cli_1[(_0x18f1d0(0x17a))](_0x146f17['clientId'])['run']();}),program[a0_0xcee1f1(0x15a)](a0_0xcee1f1(0x151))['description'](a0_0xcee1f1(0x171))[a0_0xcee1f1(0x176)](a0_0xcee1f1(0x198),a0_0xcee1f1(0x194))[a0_0xcee1f1(0x169)](async _0x431d8e=>{const _0x4338b0=a0_0xcee1f1,_0x223aad=path_1['default'][_0x4338b0(0x162)]((0x0,session_1['getHomeDir'])(),_0x4338b0(0x174),_0x431d8e[_0x4338b0(0x194)]),_0x39e1d6=(0x0,doctor_1[_0x4338b0(0x155)])(_0x223aad);(0x0,doctor_1[_0x4338b0(0x17c)])(_0x39e1d6);}),program[a0_0xcee1f1(0x18f)](process[a0_0xcee1f1(0x159)]);
2
+ "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const common_1=require("../src/common"),commander_1=require("commander"),session_1=require("../src/biz/session"),path_1=__importDefault(require("path")),cc_ding_cli_1=require("../src/biz/cc-ding-cli"),lock_1=require("../src/biz/lock"),doctor_1=require("../src/biz/doctor"),notify_1=require("../src/biz/notify"),fs_1=__importDefault(require("fs"));(0,common_1.loadEnv)(),process.removeAllListeners("warning"),process.setMaxListeners(0),process.on("uncaughtException",function(e){console.log("Caught exception: "+e),process.exit(1)});const program=new commander_1.Command;program.addHelpText("before",`
3
+ cc-ding for connect ClaudeCode to DingDingRobot
4
+ `).addHelpText("after",`
5
+ Examples:
6
+ $ cc-ding init -ci {clientId} -cs {clientSecret} -m {mobile}
7
+ $ cc-ding run -ci {clientId}
8
+ `).version((0,common_1.projUtil)().getPkgVersion()),program.command("init").description("\u521D\u59CB\u5316cc-ding\u914D\u7F6E\u6587\u4EF6, \u751F\u6210\u6700\u7B80config.json").requiredOption("-ci, --clientId <value>","clientId").requiredOption("-cs, --clientSecret <value>","clientSecret (\u9489\u9489Stream\u8FDE\u63A5\u5BC6\u94A5)").requiredOption("-m, --mobile <value>","mobile (\u81EA\u5DF1\u7684\u624B\u673A\u53F7, \u81EA\u52A8\u52A0\u5165\u767D\u540D\u5355)").option("-cn, --clientName <value>","clientName (\u673A\u5668\u4EBA\u540D\u79F0, \u53EF\u9009)").action(async e=>{const n=process.version.slice(1);parseInt(n.split(".")[0],10)<24&&(console.log(`
9
+ \u274C Node \u7248\u672C\u8FC7\u4F4E\uFF0C\u65E0\u6CD5\u6267\u884C init \u547D\u4EE4`),console.log(` \u5F53\u524D\u7248\u672C\uFF1A${n}`),console.log(" \u8981\u6C42\uFF1ANode >= 24"),console.log(`
10
+ \u{1F4A1} \u8BF7\u5347\u7EA7 Node \u7248\u672C\u540E\u91CD\u65B0\u8FD0\u884C
11
+ `),process.exit(1));const i=`${`${(0,session_1.getHomeDir)()}/.cc-ding/${e.clientId}`}/config.json`;fs_1.default.existsSync(i)&&(console.log(`\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728: ${i}`),console.log("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316, \u8BF7\u5148\u5220\u9664\u5DF2\u6709\u914D\u7F6E\u6587\u4EF6"),process.exit(1));const t={clientName:e.clientName||"cc\u52A9\u624B",owner:e.mobile,whiteUserList:[e.mobile],clientSecret:e.clientSecret,defaultDingToken:"<\u515C\u5E95\u9489\u9489\u673A\u5668\u4EBAToken-\u7528\u4E8E\u65E0dingToken\u7FA4\u7684\u6D88\u606F\u63A5\u6536>",conversations:[],includeThinking:!1,resultOnly:!0,debug:!1,taskQueueSize:10,taskHandlerCount:1,sessionMaxConcurrency:20,skipSandbox:!1};(0,session_1.initClientDir)(e.clientId,t),console.log("\u914D\u7F6E\u6587\u4EF6\u5DF2\u751F\u6210:",i),console.log(""),console.log("\u540E\u7EED\u6B65\u9AA4:"),console.log(" 1. \u7F16\u8F91 config.json \u6DFB\u52A0 conversations \u914D\u7F6E(\u7FA4\u804A\u9700\u914D\u7F6EdingToken)"),console.log(" 2. \u542F\u52A8\u673A\u5668\u4EBA: cc-ding run -ci",e.clientId),console.log(" 3. \u63A8\u8350PM2\u542F\u52A8:"),console.log(` pm2 start --name "cc-ding-${e.clientId}" npx -- -p cc-ding cc-ding run -ci ${e.clientId}`)}),program.command("run").description(`
12
+ - \u529F\u80FD: \u9489\u9489\u673A\u5668\u4EBA\u5BF9\u63A5\u672C\u5730Claude, \u652F\u6301\u4F1A\u8BDD\u6A21\u5F0F\u548C\u4EFB\u52A1\u961F\u5217\u6A21\u5F0F
13
+ - \u4F1A\u8BDD\u6570\u636E\u8DEF\u5F84: ~/.cc-ding/{clientId}/{MD5}/.sessions/{claudeSessionId}/session.{json|log}
14
+ - \u4EFB\u52A1\u6570\u636E\u8DEF\u5F84: ~/.cc-ding/{clientId}/{MD5}/.tasks/{\u65F6\u95F4\u6233}/task.{json|log}
15
+ - \u5B9A\u65F6\u4EFB\u52A1\u6570\u636E: ~/.cc-ding/{clientId}/cron.json
16
+ - \u542F\u52A8\u65B9\u5F0F: pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding run -ci {clientId}
17
+ - \u4F1A\u8BDD\u6A21\u5F0F\u8BF4\u660E
18
+ - \u4F1A\u8BDDID: \u7531 Claude \u5206\u914D\u7684 claudeSessionId
19
+ - \u7ED3\u675F\u4F1A\u8BDD: /end
20
+ - \u65B0\u4F1A\u8BDD: /new [\u521D\u59CB\u6D88\u606F] \u5F3A\u5236\u7ED3\u675F\u5F53\u524D\u4F1A\u8BDD\u5E76\u5F00\u542F\u65B0\u4F1A\u8BDD
21
+ - \u6062\u590D\u4F1A\u8BDD: /resume [\u4F1A\u8BDDID] \u6062\u590D\u6307\u5B9A\u5386\u53F2\u4F1A\u8BDD, \u4E0D\u6307\u5B9A\u5219\u6062\u590D\u6700\u8FD1\u4E00\u4E2A
22
+ - \u4F1A\u8BDD\u6301\u4E45\u5316: \u6D3B\u8DC3\u4F1A\u8BDD\u81EA\u52A8\u4FDD\u5B58\u5230 active.json, \u670D\u52A1\u91CD\u542F\u540E\u81EA\u52A8\u6062\u590D
23
+ - \u7FA4\u5185\u591A\u7528\u6237: \u5141\u8BB8\u7FA4\u5185\u6240\u6709\u767D\u540D\u5355\u7528\u6237\u53C2\u4E0E\u5BF9\u8BDD
24
+ - /help: \u67E5\u770B\u6240\u6709\u53EF\u7528\u547D\u4EE4(\u542B\u7248\u672C\u3001\u4F5C\u8005\u3001\u6587\u6863\u94FE\u63A5); /{\u547D\u4EE4} --help \u67E5\u770B\u547D\u4EE4\u8BE6\u7EC6\u7528\u6CD5
25
+ - \u56FE\u7247\u6D88\u606F\u652F\u6301
26
+ - \u652F\u6301\u63A5\u6536\u9489\u9489\u56FE\u7247\u6D88\u606F(picture)\u548C\u5BCC\u6587\u672C\u6D88\u606F(richText, \u542B\u5185\u5D4C\u56FE\u7247)
27
+ - \u56FE\u7247\u81EA\u52A8\u4E0B\u8F7D\u4FDD\u5B58\u5230 <\u4F1A\u8BDD\u76EE\u5F55>/.images/ \u4E0B
28
+ - useLocalOcr: \u9ED8\u8BA4\u5F00\u542F, \u4F7F\u7528\u672C\u5730OCR\u8BC6\u522B\u56FE\u7247\u6587\u5B57, \u540C\u65F6\u4F20\u5165\u539F\u56FE\u8DEF\u5F84\u4F9BClaude\u81EA\u4E3B\u67E5\u770B
29
+ - \u914D\u7F6E\u65B9\u5F0F: conversations[].useLocalOcr = false \u53EF\u5173\u95EDOCR(\u9002\u7528\u4E8E\u652F\u6301\u56FE\u7247\u8BC6\u522B\u7684\u6A21\u578B)
30
+ - \u4EFB\u52A1\u6A21\u5F0F\u8BF4\u660E
31
+ - \u4EFB\u52A1ID: \u4EFB\u52A1\u63A5\u6536\u65F6\u95F4\u6233
32
+ - API Key \u6C60\u5316\u7BA1\u7406(\u53EF\u9009, \u914D\u7F6EapiKeyCfg\u540E\u542F\u7528)
33
+ - 429\u81EA\u52A8\u5207\u6362: \u81EA\u52A8\u5207\u6362\u5230API Key\u6A21\u5F0F
34
+ - Key\u8F6E\u6362: API Key\u9047\u5230429\u6216\u8FDE\u7EEDTPM\u4E0D\u7A33\u5B9A\u65F6\u81EA\u52A8\u6362Key
35
+ - \u8DE8\u5929\u91CD\u7F6E: \u6BCF\u65E5\u81EA\u52A8\u91CD\u7F6EAPI Key\u72B6\u6001
36
+ `).requiredOption("-ci, --clientId <value>","clientId").action(async e=>{(0,session_1.ensureClientDir)(e.clientId);const n=path_1.default.join((0,session_1.getHomeDir)(),".cc-ding",e.clientId);(0,lock_1.acquirePidLock)(n,e.clientId),await new cc_ding_cli_1.DingClaude(e.clientId).run()}),program.command("doctor").description("\u68C0\u67E5\u6307\u5B9Aclient\u7684\u914D\u7F6E\u6587\u4EF6schema\u5408\u6CD5\u6027\u548C\u6709\u6548\u6027").requiredOption("-ci, --clientId <value>","clientId").action(async e=>{const n=path_1.default.join((0,session_1.getHomeDir)(),".cc-ding",e.clientId),c=(0,doctor_1.runDoctor)(n);(0,doctor_1.printDoctorResults)(c)}),program.command("notify").description("\u901A\u8FC7\u9489\u9489\u673A\u5668\u4EBA\u53D1\u9001\u6D88\u606F\u5230\u6307\u5B9A\u7FA4").requiredOption("-ci, --clientId <value>","clientId").requiredOption("-c, --conversations <value>","\u76EE\u6807\u4F1A\u8BDDID\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF09").requiredOption("-m, --message <value>","\u6D88\u606F\u5185\u5BB9").option("-at, --atUserIds <value>","@ \u6307\u5B9A\u7528\u6237\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF09").option("-md, --markdown","\u4F7F\u7528 Markdown \u683C\u5F0F\u53D1\u9001",!1).action(async e=>{const n=e.conversations.split(",").map(i=>i.trim()).filter(Boolean),c=e.atUserIds?e.atUserIds.split(",").map(i=>i.trim()).filter(Boolean):[];console.log(`\u{1F4E4} \u53D1\u9001\u6D88\u606F\u5230 ${n.length} \u4E2A\u4F1A\u8BDD...`);const o=await(0,notify_1.sendNotify)({clientId:e.clientId,message:e.message,conversationIds:n,atUserIds:c,markdown:e.markdown});console.log(`
37
+ \u2705 \u6210\u529F: ${o.success}, \u274C \u5931\u8D25: ${o.fail}`),process.exit(o.fail>0?1:0)}),program.parse(process.argv);
Binary file
Binary file
@@ -1 +1,3 @@
1
- 'use strict';const a1_0x456413=a1_0x125f;function a1_0x125f(_0x2322b8,_0x55c887){_0x2322b8=_0x2322b8-0xa7;const _0x2d464d=a1_0x2d46();let _0x125f8b=_0x2d464d[_0x2322b8];return _0x125f8b;}(function(_0x8d2d5b,_0x4b8ce8){const _0x5707e7=a1_0x125f,_0x4f4026=_0x8d2d5b();while(!![]){try{const _0x37fee5=-parseInt(_0x5707e7(0xb2))/0x1+-parseInt(_0x5707e7(0x128))/0x2*(parseInt(_0x5707e7(0xc9))/0x3)+-parseInt(_0x5707e7(0xe9))/0x4*(parseInt(_0x5707e7(0x11c))/0x5)+parseInt(_0x5707e7(0x10f))/0x6+parseInt(_0x5707e7(0x10c))/0x7+parseInt(_0x5707e7(0xf4))/0x8+-parseInt(_0x5707e7(0xf2))/0x9*(-parseInt(_0x5707e7(0xd1))/0xa);if(_0x37fee5===_0x4b8ce8)break;else _0x4f4026['push'](_0x4f4026['shift']());}catch(_0x203ac8){_0x4f4026['push'](_0x4f4026['shift']());}}}(a1_0x2d46,0x2df3a));var __importDefault=this&&this['__importDefault']||function(_0x39459d){const _0x115bea=a1_0x125f;return _0x39459d&&_0x39459d[_0x115bea(0xa9)]?_0x39459d:{'default':_0x39459d};};Object['defineProperty'](exports,'__esModule',{'value':!![]}),exports[a1_0x456413(0xfd)]=saveClientConfig,exports[a1_0x456413(0xf6)]=resetApiKeyCfg,exports[a1_0x456413(0xdc)]=scheduleApiKeyCfgDailyReset,exports[a1_0x456413(0xd6)]=settingLabel,exports[a1_0x456413(0x104)]=rotateApiKey,exports[a1_0x456413(0x11f)]=pickValidApiKey,exports[a1_0x456413(0xc4)]=ensureSettingsWithApiKey,exports[a1_0x456413(0xc7)]=isQuotaExhaustedError,exports['isAuthenticationError']=isAuthenticationError,exports[a1_0x456413(0x121)]=readApiKeyFromSettings,exports[a1_0x456413(0xea)]=getForceEnabledSettingsPath,exports['startupCheck']=startupCheck;function a1_0x2d46(){const _0x445905=['default','slice',']\x20==============================\x0a','./session','clientSecret\x20(钉钉\x20Stream\x20Client\x20密钥)','\x20个群配置','settings-tpl.json\x20根元素不是对象','apiKeyCfg.claudeSettings\x20为空,无可用\x20Key','29215HYPKIS','.cc-ding','whiteUserList','pickValidApiKey','keys','readApiKeyFromSettings','claudeSettings','getHomeDir','ANTHROPIC_AUTH_TOKEN','claude\x20命令不可用,请确认\x20Claude\x20Code\x20CLI\x20已安装','CLAUDE_SMALL_FAST_MODEL','settings-tpl.json','34faJCWU','settings-tpl.json\x20解析失败:\x20','exit','toISOString','...','PASS','level','settings-tpl.json\x20不存在:\x20','\x20警告,\x20','getFullYear','dateUtil','push','__esModule','linkConversationId','getClientDir','getMonth',',\x20model:\x20','isArray','config.json\x20','timestamp','clientSecret','256485YBmdUB','群工作目录已就绪:\x20','add','settings-tpl.json\x20有效,env\x20包含:\x20','filter','owner\x20(机器人\x20owner)','pipe','conversationId','\x20致命','which\x20claude','apiKey','apiKeyCfg.claudeSettings\x20不是数组,API\x20Key\x20轮换功能不可用','\x20缺少\x20apiKey','conversations[','random','\x20isValid\x20类型异常:\x20','config.json\x20缺少必填字段:\x20',']\x20启动自检发现致命错误,进程退出','ensureSettingsWithApiKey','[WARN]\x20','settings-ding.json','isQuotaExhaustedError','\x20conversationId\x20重复:\x20','46971EZvtsP','path','conversations','工作目录不可写:\x20','join','some','message','readFileSync','4078590VtDhNZ','群工作目录创建失败:\x20',']\x20已写入\x20Claude\x20配置到\x20','utf-8','resetTime','settingLabel','test','env',',\x20smallModel:\x20',']\x20apiKeyCfg\x20已重置\x20(所有\x20Claude\x20Setting\x20isValid=true)','\x20缺少\x20model','scheduleApiKeyCfgDailyReset','apiKeyCfg','boolean',']\x20从模板创建\x20settings-ding.json:\x20','conversations\x20共\x20','getConversationDir','existsSync','conversations\x20为空数组,可通过\x20/reg\x20命令动态注册','model','FATAL','format','baseUrl','log','140tCFMSL','getForceEnabledSettingsPath','conversationTitle','has','\x20—\x20','\x20apiKey\x20重复:\x20','stringify','WARN','memo','9SeODzh','isValid','509520wkVQIN','\x20缺少\x20conversationId','resetApiKeyCfg',',创建\x20settings-ding.json\x20时将使用空模板','utils-ok','getTime','writeFileSync','/config.json',']\x20检测到\x20settings-ding.json\x20FORCE_ENABLE=','saveClientConfig','getDate',']\x20==========\x20启动自检\x20==========','length','claude\x20命令可用',']\x20Claude\x20Setting\x20已失效:\x20','\x22\x20未在\x20conversations\x20中找到','rotateApiKey','ANTHROPIC_BASE_URL','parse','\x20项,有效\x20','owner','smallModel','object',']\x20apiKeyCfg\x20每日重置已调度,下次重置:\x20','671349pwfSYb','\x20通过,\x20','apiKeyCfg.claudeSettings\x20共\x20','2087526KwKxzg','.claude','ANTHROPIC_MODEL','config','find'];a1_0x2d46=function(){return _0x445905;};return a1_0x2d46();}const fs_1=__importDefault(require('fs')),path_1=__importDefault(require(a1_0x456413(0xca))),child_process_1=require('child_process'),session_1=require(a1_0x456413(0x117)),utils_ok_1=require(a1_0x456413(0xf8));function saveClientConfig(_0x57d208){const _0x24e7bb=a1_0x456413,_0x491d4b=_0x57d208[_0x24e7bb(0xab)]()+_0x24e7bb(0xfb);try{fs_1['default'][_0x24e7bb(0xfa)](_0x491d4b,JSON[_0x24e7bb(0xef)](_0x57d208[_0x24e7bb(0x112)],null,0x2),'utf-8');}catch(_0xee673){console['error']('['+(0x0,session_1[_0x24e7bb(0xb0)])()+']\x20保存\x20config.json\x20失败:',_0xee673);}}function resetApiKeyCfg(_0x2a9ab5){const _0x46343e=a1_0x456413,_0x585bc4=_0x2a9ab5[_0x46343e(0x112)][_0x46343e(0xdd)];if(!_0x585bc4)return;const _0x35e080=new Date();_0x585bc4['resetTime']=utils_ok_1[_0x46343e(0xa7)]['mm'](_0x35e080[_0x46343e(0xf9)]())[_0x46343e(0xe6)]('YYYY-MM-DD\x20HH:mm:ss');let _0xe07065=0x0;for(const _0x3bb3d3 of _0x585bc4['claudeSettings']){!_0x3bb3d3[_0x46343e(0xf3)]&&(_0x3bb3d3['isValid']=!![],_0xe07065++);}_0xe07065>0x0&&console[_0x46343e(0xe8)]('['+(0x0,session_1[_0x46343e(0xb0)])()+']\x20'+_0xe07065+'\x20个已失效\x20Claude\x20Setting\x20重新标记为有效'),saveClientConfig(_0x2a9ab5),console[_0x46343e(0xe8)]('['+(0x0,session_1[_0x46343e(0xb0)])()+_0x46343e(0xda));}function scheduleApiKeyCfgDailyReset(_0x23c28b){const _0x5138b2=()=>{const _0x54fbae=a1_0x125f,_0x4abd55=new Date(),_0x431ffc=new Date(_0x4abd55[_0x54fbae(0x131)](),_0x4abd55[_0x54fbae(0xac)](),_0x4abd55[_0x54fbae(0xfe)]()+0x1,0x0,0x0,0x0,0x0),_0x53e0be=_0x431ffc[_0x54fbae(0xf9)]()-_0x4abd55[_0x54fbae(0xf9)]();setTimeout(()=>{const _0x337bc5=_0x54fbae;console[_0x337bc5(0xe8)]('['+(0x0,session_1[_0x337bc5(0xb0)])()+']\x20定时重置\x20apiKeyCfg\x20(每天0点)'),resetApiKeyCfg(_0x23c28b),_0x5138b2();},_0x53e0be),console[_0x54fbae(0xe8)]('['+(0x0,session_1[_0x54fbae(0xb0)])()+_0x54fbae(0x10b)+_0x431ffc[_0x54fbae(0x12b)]());};_0x5138b2();}function settingLabel(_0x349385){const _0xd39266=a1_0x456413;return _0x349385[_0xd39266(0xf1)]?_0x349385[_0xd39266(0xf1)]:_0xd39266(0x12c)+_0x349385[_0xd39266(0xbc)][_0xd39266(0x115)](-0x6);}function findSettingLabel(_0x216c79,_0x8db208){const _0x55955a=a1_0x456413,_0x30e9d6=_0x216c79[_0x55955a(0x113)](_0x245786=>_0x245786['apiKey']===_0x8db208);return _0x30e9d6?settingLabel(_0x30e9d6):_0x55955a(0x12c)+_0x8db208['slice'](-0x6);}function rotateApiKey(_0x5dfeeb,_0x4fbfe4){const _0x218b8b=a1_0x456413,_0x12c5f6=_0x5dfeeb[_0x218b8b(0x112)]['apiKeyCfg'];if(!_0x12c5f6)return null;for(const _0x55972d of _0x12c5f6['claudeSettings']){if(_0x55972d[_0x218b8b(0xbc)]===_0x4fbfe4&&_0x55972d['isValid']){_0x55972d[_0x218b8b(0xf3)]=![];break;}}const _0x530b84=_0x12c5f6[_0x218b8b(0x122)]['filter'](_0xc75af3=>_0xc75af3[_0x218b8b(0xf3)])[_0x218b8b(0x100)],_0x1507ca=findSettingLabel(_0x12c5f6[_0x218b8b(0x122)],_0x4fbfe4);return console[_0x218b8b(0xe8)]('['+(0x0,session_1[_0x218b8b(0xb0)])()+_0x218b8b(0x102)+_0x1507ca+',\x20剩余有效:\x20'+_0x530b84),saveClientConfig(_0x5dfeeb),pickValidApiKey(_0x5dfeeb);}function pickValidApiKey(_0x3eb232){const _0x312d9a=a1_0x456413,_0x3bfbb7=_0x3eb232[_0x312d9a(0x112)]['apiKeyCfg'];if(!_0x3bfbb7)return null;const _0xe7ac5=_0x3bfbb7[_0x312d9a(0x122)][_0x312d9a(0xb6)](_0xe5f137=>_0xe5f137[_0x312d9a(0xf3)]);if(_0xe7ac5['length']===0x0)return null;return _0xe7ac5[Math['floor'](Math[_0x312d9a(0xc0)]()*_0xe7ac5[_0x312d9a(0x100)])];}function ensureSettingsWithApiKey(_0x403d89,_0x42d31e){const _0x243186=a1_0x456413,_0x5b20ce=path_1[_0x243186(0x114)]['join'](_0x403d89,_0x243186(0x110)),_0x448ece=path_1[_0x243186(0x114)][_0x243186(0xcd)](_0x5b20ce,'settings-ding.json');let _0x527e0a={};if(fs_1[_0x243186(0x114)]['existsSync'](_0x448ece))try{_0x527e0a=JSON['parse'](fs_1[_0x243186(0x114)][_0x243186(0xd0)](_0x448ece,_0x243186(0xd4)));}catch{_0x527e0a={};}else{const _0x2da54f=path_1['default'][_0x243186(0xcd)]((0x0,session_1[_0x243186(0x123)])(),_0x243186(0x11d),_0x243186(0x127));if(fs_1[_0x243186(0x114)][_0x243186(0xe2)](_0x2da54f))try{_0x527e0a=JSON[_0x243186(0x106)](fs_1['default'][_0x243186(0xd0)](_0x2da54f,_0x243186(0xd4))),console[_0x243186(0xe8)]('['+(0x0,session_1[_0x243186(0xb0)])()+_0x243186(0xdf)+_0x2da54f);}catch{_0x527e0a={};}}!_0x527e0a[_0x243186(0xd8)]&&(_0x527e0a[_0x243186(0xd8)]={});let _0x536c7e=![];_0x527e0a[_0x243186(0xd8)][_0x243186(0x124)]!==_0x42d31e['apiKey']&&(_0x527e0a[_0x243186(0xd8)][_0x243186(0x124)]=_0x42d31e[_0x243186(0xbc)],_0x536c7e=!![]);_0x42d31e[_0x243186(0xe7)]&&_0x527e0a[_0x243186(0xd8)]['ANTHROPIC_BASE_URL']!==_0x42d31e[_0x243186(0xe7)]&&(_0x527e0a[_0x243186(0xd8)][_0x243186(0x105)]=_0x42d31e[_0x243186(0xe7)],_0x536c7e=!![]);_0x42d31e[_0x243186(0xe4)]&&_0x527e0a['env'][_0x243186(0x111)]!==_0x42d31e[_0x243186(0xe4)]&&(_0x527e0a['env'][_0x243186(0x111)]=_0x42d31e[_0x243186(0xe4)],_0x536c7e=!![]);const _0x29297a=_0x42d31e[_0x243186(0x109)]||_0x42d31e['model'];return _0x29297a&&_0x527e0a['env'][_0x243186(0x126)]!==_0x29297a&&(_0x527e0a[_0x243186(0xd8)]['CLAUDE_SMALL_FAST_MODEL']=_0x29297a,_0x536c7e=!![]),_0x536c7e&&(fs_1[_0x243186(0x114)]['mkdirSync'](_0x5b20ce,{'recursive':!![]}),fs_1[_0x243186(0x114)][_0x243186(0xfa)](_0x448ece,JSON['stringify'](_0x527e0a,null,0x2),_0x243186(0xd4)),console[_0x243186(0xe8)]('['+(0x0,session_1[_0x243186(0xb0)])()+_0x243186(0xd3)+_0x448ece+'\x20('+settingLabel(_0x42d31e)+_0x243186(0xad)+_0x42d31e[_0x243186(0xe4)]+_0x243186(0xd9)+_0x29297a+')')),_0x448ece;}function isQuotaExhaustedError(_0x1eca93){const _0x5642fb=a1_0x456413;if(/Request\s+rejected.*429/i[_0x5642fb(0xd7)](_0x1eca93))return!![];if(/429.*Request\s+rejected/i['test'](_0x1eca93))return!![];if(/429.*(?:超过.*上限|使用上限|配额|quota|capacity)/i[_0x5642fb(0xd7)](_0x1eca93))return!![];if(/(?:超过.*上限|使用上限|配额|quota|capacity).*429/i[_0x5642fb(0xd7)](_0x1eca93))return!![];return![];}function isAuthenticationError(_0x434481){const _0x5285ad=a1_0x456413;if(/authentication_error/i[_0x5285ad(0xd7)](_0x434481))return!![];if(/401.*(?:未授权|unauthorized|invalid\s*(?:key|token|api)|auth)/i[_0x5285ad(0xd7)](_0x434481))return!![];if(/(?:未授权|unauthorized|invalid\s*(?:key|token|api)|auth).*401/i['test'](_0x434481))return!![];return![];}function readApiKeyFromSettings(_0x31972b){const _0x201b62=a1_0x456413,_0x239751=path_1[_0x201b62(0x114)][_0x201b62(0xcd)](_0x31972b,'.claude',_0x201b62(0xc6));if(!fs_1[_0x201b62(0x114)][_0x201b62(0xe2)](_0x239751))return null;try{const _0xe85b1a=JSON[_0x201b62(0x106)](fs_1[_0x201b62(0x114)][_0x201b62(0xd0)](_0x239751,_0x201b62(0xd4)));return _0xe85b1a[_0x201b62(0xd8)]?.[_0x201b62(0x124)]||null;}catch{return null;}}function getForceEnabledSettingsPath(_0x35eef9){const _0xe00be4=a1_0x456413,_0x19a6c5=path_1['default'][_0xe00be4(0xcd)](_0x35eef9,_0xe00be4(0x110),'settings-ding.json');if(!fs_1[_0xe00be4(0x114)]['existsSync'](_0x19a6c5))return null;try{const _0x1c2687=JSON[_0xe00be4(0x106)](fs_1[_0xe00be4(0x114)][_0xe00be4(0xd0)](_0x19a6c5,_0xe00be4(0xd4))),_0x4ee1d3=_0x1c2687[_0xe00be4(0xd8)]?.['FORCE_ENABLE'];if(_0x4ee1d3!==undefined&&_0x4ee1d3!==![]&&_0x4ee1d3!=='')return console[_0xe00be4(0xe8)]('['+(0x0,session_1[_0xe00be4(0xb0)])()+_0xe00be4(0xfc)+_0x4ee1d3+',强制使用该配置'),_0x19a6c5;return null;}catch{return null;}}function startupCheck(_0x2f159f){const _0xa5f20c=a1_0x456413,_0x5dc717=[],_0x4ff22e=_0x2f159f['config'],_0x220af4=_0x2f159f[_0xa5f20c(0xab)](),_0x491db5=[{'key':_0xa5f20c(0xb1),'label':_0xa5f20c(0x118)},{'key':_0xa5f20c(0x11e),'label':'whiteUserList\x20(白名单用户)'},{'key':_0xa5f20c(0x108),'label':_0xa5f20c(0xb7)}];for(const {key:_0xb88534,label:_0x471542}of _0x491db5){const _0x50b952=_0x4ff22e[_0xb88534];_0x50b952===undefined||_0x50b952===null||_0x50b952===''||Array[_0xa5f20c(0xae)](_0x50b952)&&_0x50b952[_0xa5f20c(0x100)]===0x0?_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xe5),'message':_0xa5f20c(0xc2)+_0x471542}):_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0xaf)+_0x471542+'\x20✓'});}if(!Array[_0xa5f20c(0xae)](_0x4ff22e[_0xa5f20c(0xcb)]))_0x5dc717[_0xa5f20c(0xa8)]({'level':'FATAL','message':'conversations\x20应为数组或已配置'});else{if(_0x4ff22e['conversations'][_0xa5f20c(0x100)]===0x0)_0x5dc717['push']({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0xe3)});else{const _0x405c9c=new Set();for(let _0x18a2a7=0x0;_0x18a2a7<_0x4ff22e[_0xa5f20c(0xcb)]['length'];_0x18a2a7++){const _0x482d52=_0x4ff22e[_0xa5f20c(0xcb)][_0x18a2a7],_0x202b21=_0xa5f20c(0xbf)+_0x18a2a7+']';if(!_0x482d52['conversationId'])_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xe5),'message':_0x202b21+_0xa5f20c(0xf5)});else _0x405c9c[_0xa5f20c(0xec)](_0x482d52['conversationId'])?_0x5dc717[_0xa5f20c(0xa8)]({'level':'WARN','message':_0x202b21+_0xa5f20c(0xc8)+_0x482d52['conversationId']}):_0x405c9c[_0xa5f20c(0xb4)](_0x482d52[_0xa5f20c(0xb9)]);_0x482d52[_0xa5f20c(0xaa)]&&!_0x4ff22e[_0xa5f20c(0xcb)][_0xa5f20c(0xce)](_0x3bd877=>_0x3bd877[_0xa5f20c(0xb9)]===_0x482d52[_0xa5f20c(0xaa)])&&_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0x202b21+'\x20linkConversationId\x20\x22'+_0x482d52['linkConversationId']+_0xa5f20c(0x103)});}_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0xe0)+_0x4ff22e[_0xa5f20c(0xcb)]['length']+_0xa5f20c(0x119)});}}if(_0x4ff22e[_0xa5f20c(0xdd)]){const _0x45d464=_0x4ff22e[_0xa5f20c(0xdd)];_0x45d464['resetTime']&&_0x5dc717[_0xa5f20c(0xa8)]({'level':'PASS','message':'apiKeyCfg\x20上次重置时间:\x20'+_0x45d464[_0xa5f20c(0xd5)]});if(!Array['isArray'](_0x45d464[_0xa5f20c(0x122)]))_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0xa5f20c(0xbd)});else{if(_0x45d464[_0xa5f20c(0x122)][_0xa5f20c(0x100)]===0x0)_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0xa5f20c(0x11b)});else{const _0x2c2488=new Set();for(let _0xf2cc34=0x0;_0xf2cc34<_0x45d464[_0xa5f20c(0x122)][_0xa5f20c(0x100)];_0xf2cc34++){const _0x1078cc=_0x45d464['claudeSettings'][_0xf2cc34],_0x33dc9f='apiKeyCfg.claudeSettings['+_0xf2cc34+']';if(!_0x1078cc['apiKey'])_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xe5),'message':_0x33dc9f+_0xa5f20c(0xbe)});else _0x2c2488[_0xa5f20c(0xec)](_0x1078cc[_0xa5f20c(0xbc)])?_0x5dc717[_0xa5f20c(0xa8)]({'level':'WARN','message':_0x33dc9f+_0xa5f20c(0xee)+settingLabel(_0x1078cc)}):_0x2c2488['add'](_0x1078cc[_0xa5f20c(0xbc)]);!_0x1078cc[_0xa5f20c(0xe7)]&&_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0x33dc9f+'\x20缺少\x20baseUrl'}),!_0x1078cc[_0xa5f20c(0xe4)]&&_0x5dc717['push']({'level':_0xa5f20c(0xf0),'message':_0x33dc9f+_0xa5f20c(0xdb)}),typeof _0x1078cc[_0xa5f20c(0xf3)]!==_0xa5f20c(0xde)&&_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0x33dc9f+_0xa5f20c(0xc1)+typeof _0x1078cc['isValid']});}const _0x40e1fc=_0x45d464[_0xa5f20c(0x122)][_0xa5f20c(0xb6)](_0x441640=>_0x441640['isValid'])[_0xa5f20c(0x100)];_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0x10e)+_0x45d464[_0xa5f20c(0x122)][_0xa5f20c(0x100)]+_0xa5f20c(0x107)+_0x40e1fc});}}}const _0x3dacab=path_1[_0xa5f20c(0x114)][_0xa5f20c(0xcd)]((0x0,session_1['getHomeDir'])(),_0xa5f20c(0x11d),'settings-tpl.json');if(fs_1[_0xa5f20c(0x114)][_0xa5f20c(0xe2)](_0x3dacab))try{const _0x2da787=JSON['parse'](fs_1['default'][_0xa5f20c(0xd0)](_0x3dacab,_0xa5f20c(0xd4)));if(typeof _0x2da787!==_0xa5f20c(0x10a)||_0x2da787===null)_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0xa5f20c(0x11a)});else{if(!_0x2da787[_0xa5f20c(0xd8)]||typeof _0x2da787[_0xa5f20c(0xd8)]!=='object')_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':'settings-tpl.json\x20缺少\x20env\x20字段,创建\x20settings-ding.json\x20时将不包含预配置环境变量'});else{const _0x3b17c1=Object[_0xa5f20c(0x120)](_0x2da787[_0xa5f20c(0xd8)]);_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0xb5)+(_0x3b17c1['join'](',\x20')||'(空)')});}}}catch(_0x443629){_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xf0),'message':_0xa5f20c(0x129)+(_0x443629 instanceof Error?_0x443629['message']:_0x443629)});}else _0x5dc717['push']({'level':_0xa5f20c(0xf0),'message':_0xa5f20c(0x12f)+_0x3dacab+_0xa5f20c(0xf7)});try{(0x0,child_process_1['execSync'])(_0xa5f20c(0xbb),{'stdio':_0xa5f20c(0xb8)}),_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0x101)});}catch{_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xe5),'message':_0xa5f20c(0x125)});}try{const _0xbbeccc=path_1[_0xa5f20c(0x114)][_0xa5f20c(0xcd)](_0x220af4,'.healthcheck');fs_1[_0xa5f20c(0x114)][_0xa5f20c(0xfa)](_0xbbeccc,'ok',_0xa5f20c(0xd4)),fs_1['default']['unlinkSync'](_0xbbeccc),_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':'工作目录可写:\x20'+_0x220af4});}catch(_0x268cb2){_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0xe5),'message':_0xa5f20c(0xcc)+_0x220af4+_0xa5f20c(0xed)+(_0x268cb2 instanceof Error?_0x268cb2['message']:_0x268cb2)});}if(Array['isArray'](_0x4ff22e[_0xa5f20c(0xcb)]))for(const _0x9d62dc of _0x4ff22e[_0xa5f20c(0xcb)]){const _0x17023c=_0x2f159f[_0xa5f20c(0xe1)](_0x9d62dc[_0xa5f20c(0xb9)]);try{fs_1[_0xa5f20c(0x114)]['mkdirSync'](_0x17023c,{'recursive':!![]}),_0x5dc717[_0xa5f20c(0xa8)]({'level':_0xa5f20c(0x12d),'message':_0xa5f20c(0xb3)+(_0x9d62dc[_0xa5f20c(0xeb)]||_0x9d62dc['conversationId'])});}catch(_0x36c496){_0x5dc717[_0xa5f20c(0xa8)]({'level':'WARN','message':_0xa5f20c(0xd2)+_0x17023c+_0xa5f20c(0xed)+(_0x36c496 instanceof Error?_0x36c496[_0xa5f20c(0xcf)]:_0x36c496)});}}console[_0xa5f20c(0xe8)]('\x0a['+(0x0,session_1[_0xa5f20c(0xb0)])()+_0xa5f20c(0xff));const _0x47b19d=_0x5dc717[_0xa5f20c(0xce)](_0x2a2e30=>_0x2a2e30[_0xa5f20c(0x12e)]===_0xa5f20c(0xe5));for(const _0x21bd38 of _0x5dc717){const _0x1ceb28=_0x21bd38[_0xa5f20c(0x12e)]===_0xa5f20c(0x12d)?'✓':_0x21bd38[_0xa5f20c(0x12e)]===_0xa5f20c(0xe5)?'✗':'⚠',_0x4348c6=_0x21bd38[_0xa5f20c(0x12e)]===_0xa5f20c(0x12d)?_0x21bd38[_0xa5f20c(0xcf)]:_0x21bd38[_0xa5f20c(0x12e)]==='FATAL'?'[FATAL]\x20'+_0x21bd38[_0xa5f20c(0xcf)]:_0xa5f20c(0xc5)+_0x21bd38[_0xa5f20c(0xcf)];console['log']('\x20\x20'+_0x1ceb28+'\x20'+_0x4348c6);}const _0x45b838=_0x5dc717[_0xa5f20c(0xb6)](_0x5abbfb=>_0x5abbfb[_0xa5f20c(0x12e)]===_0xa5f20c(0x12d))[_0xa5f20c(0x100)],_0x21fbc1=_0x5dc717[_0xa5f20c(0xb6)](_0x4a3a62=>_0x4a3a62[_0xa5f20c(0x12e)]===_0xa5f20c(0xf0))[_0xa5f20c(0x100)],_0x4dc19c=_0x5dc717[_0xa5f20c(0xb6)](_0x25703d=>_0x25703d[_0xa5f20c(0x12e)]===_0xa5f20c(0xe5))[_0xa5f20c(0x100)];console['log']('['+(0x0,session_1[_0xa5f20c(0xb0)])()+']\x20自检完成:\x20'+_0x45b838+_0xa5f20c(0x10d)+_0x21fbc1+_0xa5f20c(0x130)+_0x4dc19c+_0xa5f20c(0xba)),console[_0xa5f20c(0xe8)]('['+(0x0,session_1[_0xa5f20c(0xb0)])()+_0xa5f20c(0x116)),_0x47b19d&&(console['error']('['+(0x0,session_1[_0xa5f20c(0xb0)])()+_0xa5f20c(0xc3)),process[_0xa5f20c(0x12a)](0x1));}
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.saveClientConfig=saveClientConfig,exports.resetApiKeyCfg=resetApiKeyCfg,exports.scheduleApiKeyCfgDailyReset=scheduleApiKeyCfgDailyReset,exports.settingLabel=settingLabel,exports.rotateApiKey=rotateApiKey,exports.pickValidApiKey=pickValidApiKey,exports.ensureSettingsWithApiKey=ensureSettingsWithApiKey,exports.isQuotaExhaustedError=isQuotaExhaustedError,exports.isAuthenticationError=isAuthenticationError,exports.readApiKeyFromSettings=readApiKeyFromSettings,exports.getForceEnabledSettingsPath=getForceEnabledSettingsPath,exports.startupCheck=startupCheck;const fs_1=__importDefault(require("fs")),path_1=__importDefault(require("path")),child_process_1=require("child_process"),session_1=require("./session"),utils_ok_1=require("utils-ok");function saveClientConfig(s){const e=`${s.getClientDir()}/config.json`;try{fs_1.default.writeFileSync(e,JSON.stringify(s.config,null,2),"utf-8")}catch(n){console.error(`[${(0,session_1.timestamp)()}] \u4FDD\u5B58 config.json \u5931\u8D25:`,n)}}function resetApiKeyCfg(s){const e=s.config.apiKeyCfg;if(!e)return;const n=new Date;e.resetTime=utils_ok_1.dateUtil.mm(n.getTime()).format("YYYY-MM-DD HH:mm:ss");let i=0;for(const l of e.claudeSettings)l.isValid||(l.isValid=!0,i++);i>0&&console.log(`[${(0,session_1.timestamp)()}] ${i} \u4E2A\u5DF2\u5931\u6548 Claude Setting \u91CD\u65B0\u6807\u8BB0\u4E3A\u6709\u6548`),saveClientConfig(s),console.log(`[${(0,session_1.timestamp)()}] apiKeyCfg \u5DF2\u91CD\u7F6E (\u6240\u6709 Claude Setting isValid=true)`)}function scheduleApiKeyCfgDailyReset(s){const e=()=>{const n=new Date,i=new Date(n.getFullYear(),n.getMonth(),n.getDate()+1,0,0,0,0),l=i.getTime()-n.getTime();setTimeout(()=>{console.log(`[${(0,session_1.timestamp)()}] \u5B9A\u65F6\u91CD\u7F6E apiKeyCfg (\u6BCF\u59290\u70B9)`),resetApiKeyCfg(s),e()},l),console.log(`[${(0,session_1.timestamp)()}] apiKeyCfg \u6BCF\u65E5\u91CD\u7F6E\u5DF2\u8C03\u5EA6\uFF0C\u4E0B\u6B21\u91CD\u7F6E: ${i.toISOString()}`)};e()}function settingLabel(s){return s.memo?s.memo:`...${s.apiKey.slice(-6)}`}function findSettingLabel(s,e){const n=s.find(i=>i.apiKey===e);return n?settingLabel(n):`...${e.slice(-6)}`}function rotateApiKey(s,e){const n=s.config.apiKeyCfg;if(!n)return null;for(const r of n.claudeSettings)if(r.apiKey===e&&r.isValid){r.isValid=!1;break}const i=n.claudeSettings.filter(r=>r.isValid).length,l=findSettingLabel(n.claudeSettings,e);return console.log(`[${(0,session_1.timestamp)()}] Claude Setting \u5DF2\u5931\u6548: ${l}, \u5269\u4F59\u6709\u6548: ${i}`),saveClientConfig(s),pickValidApiKey(s)}function pickValidApiKey(s){const e=s.config.apiKeyCfg;if(!e)return null;const n=e.claudeSettings.filter(i=>i.isValid);return n.length===0?null:n[Math.floor(Math.random()*n.length)]}function ensureSettingsWithApiKey(s,e){const n=path_1.default.join(s,".claude"),i=path_1.default.join(n,"settings-ding.json");let l={};if(fs_1.default.existsSync(i))try{l=JSON.parse(fs_1.default.readFileSync(i,"utf-8"))}catch{l={}}else{const g=path_1.default.join((0,session_1.getHomeDir)(),".cc-ding","settings-tpl.json");if(fs_1.default.existsSync(g))try{l=JSON.parse(fs_1.default.readFileSync(g,"utf-8")),console.log(`[${(0,session_1.timestamp)()}] \u4ECE\u6A21\u677F\u521B\u5EFA settings-ding.json: ${g}`)}catch{l={}}}l.env||(l.env={});let r=!1;l.env.ANTHROPIC_AUTH_TOKEN!==e.apiKey&&(l.env.ANTHROPIC_AUTH_TOKEN=e.apiKey,r=!0),e.baseUrl&&l.env.ANTHROPIC_BASE_URL!==e.baseUrl&&(l.env.ANTHROPIC_BASE_URL=e.baseUrl,r=!0),e.model&&l.env.ANTHROPIC_MODEL!==e.model&&(l.env.ANTHROPIC_MODEL=e.model,r=!0);const f=e.smallModel||e.model;return f&&l.env.CLAUDE_SMALL_FAST_MODEL!==f&&(l.env.CLAUDE_SMALL_FAST_MODEL=f,r=!0),r&&(fs_1.default.mkdirSync(n,{recursive:!0}),fs_1.default.writeFileSync(i,JSON.stringify(l,null,2),"utf-8"),console.log(`[${(0,session_1.timestamp)()}] \u5DF2\u5199\u5165 Claude \u914D\u7F6E\u5230 ${i} (${settingLabel(e)}, model: ${e.model}, smallModel: ${f})`)),i}function isQuotaExhaustedError(s){return!!(/Request\s+rejected.*429/i.test(s)||/429.*Request\s+rejected/i.test(s)||/429.*(?:超过.*上限|使用上限|配额|quota|capacity)/i.test(s)||/(?:超过.*上限|使用上限|配额|quota|capacity).*429/i.test(s))}function isAuthenticationError(s){return!!(/authentication_error/i.test(s)||/401.*(?:未授权|unauthorized|invalid\s*(?:key|token|api)|auth)/i.test(s)||/(?:未授权|unauthorized|invalid\s*(?:key|token|api)|auth).*401/i.test(s))}function readApiKeyFromSettings(s){const e=path_1.default.join(s,".claude","settings-ding.json");if(!fs_1.default.existsSync(e))return null;try{return JSON.parse(fs_1.default.readFileSync(e,"utf-8")).env?.ANTHROPIC_AUTH_TOKEN||null}catch{return null}}function getForceEnabledSettingsPath(s){const e=path_1.default.join(s,".claude","settings-ding.json");if(!fs_1.default.existsSync(e))return null;try{const i=JSON.parse(fs_1.default.readFileSync(e,"utf-8")).env?.FORCE_ENABLE;return i!==void 0&&i!==!1&&i!==""?(console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 settings-ding.json FORCE_ENABLE=${i}\uFF0C\u5F3A\u5236\u4F7F\u7528\u8BE5\u914D\u7F6E`),e):null}catch{return null}}function startupCheck(s){const e=[],n=s.config,i=s.getClientDir(),l=[{key:"clientSecret",label:"clientSecret (\u9489\u9489 Stream Client \u5BC6\u94A5)"},{key:"whiteUserList",label:"whiteUserList (\u767D\u540D\u5355\u7528\u6237)"},{key:"owner",label:"owner (\u673A\u5668\u4EBA owner)"}];for(const{key:t,label:a}of l){const o=n[t];o==null||o===""||Array.isArray(o)&&o.length===0?e.push({level:"FATAL",message:`config.json \u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5: ${a}`}):e.push({level:"PASS",message:`config.json ${a} \u2713`})}if(!Array.isArray(n.conversations))e.push({level:"FATAL",message:"conversations \u5E94\u4E3A\u6570\u7EC4\u6216\u5DF2\u914D\u7F6E"});else if(n.conversations.length===0)e.push({level:"PASS",message:"conversations \u4E3A\u7A7A\u6570\u7EC4\uFF0C\u53EF\u901A\u8FC7 /reg \u547D\u4EE4\u52A8\u6001\u6CE8\u518C"});else{const t=new Set;for(let a=0;a<n.conversations.length;a++){const o=n.conversations[a],c=`conversations[${a}]`;o.conversationId?t.has(o.conversationId)?e.push({level:"WARN",message:`${c} conversationId \u91CD\u590D: ${o.conversationId}`}):t.add(o.conversationId):e.push({level:"FATAL",message:`${c} \u7F3A\u5C11 conversationId`}),o.linkConversationId&&!n.conversations.some(u=>u.conversationId===o.linkConversationId)&&e.push({level:"WARN",message:`${c} linkConversationId "${o.linkConversationId}" \u672A\u5728 conversations \u4E2D\u627E\u5230`})}e.push({level:"PASS",message:`conversations \u5171 ${n.conversations.length} \u4E2A\u7FA4\u914D\u7F6E`})}if(n.apiKeyCfg){const t=n.apiKeyCfg;if(t.resetTime&&e.push({level:"PASS",message:`apiKeyCfg \u4E0A\u6B21\u91CD\u7F6E\u65F6\u95F4: ${t.resetTime}`}),!Array.isArray(t.claudeSettings))e.push({level:"WARN",message:"apiKeyCfg.claudeSettings \u4E0D\u662F\u6570\u7EC4\uFF0CAPI Key \u8F6E\u6362\u529F\u80FD\u4E0D\u53EF\u7528"});else if(t.claudeSettings.length===0)e.push({level:"WARN",message:"apiKeyCfg.claudeSettings \u4E3A\u7A7A\uFF0C\u65E0\u53EF\u7528 Key"});else{const a=new Set;for(let c=0;c<t.claudeSettings.length;c++){const u=t.claudeSettings[c],d=`apiKeyCfg.claudeSettings[${c}]`;u.apiKey?a.has(u.apiKey)?e.push({level:"WARN",message:`${d} apiKey \u91CD\u590D: ${settingLabel(u)}`}):a.add(u.apiKey):e.push({level:"FATAL",message:`${d} \u7F3A\u5C11 apiKey`}),u.baseUrl||e.push({level:"WARN",message:`${d} \u7F3A\u5C11 baseUrl`}),u.model||e.push({level:"WARN",message:`${d} \u7F3A\u5C11 model`}),typeof u.isValid!="boolean"&&e.push({level:"WARN",message:`${d} isValid \u7C7B\u578B\u5F02\u5E38: ${typeof u.isValid}`})}const o=t.claudeSettings.filter(c=>c.isValid).length;e.push({level:"PASS",message:`apiKeyCfg.claudeSettings \u5171 ${t.claudeSettings.length} \u9879\uFF0C\u6709\u6548 ${o}`})}}const r=path_1.default.join((0,session_1.getHomeDir)(),".cc-ding","settings-tpl.json");if(fs_1.default.existsSync(r))try{const t=JSON.parse(fs_1.default.readFileSync(r,"utf-8"));if(typeof t!="object"||t===null)e.push({level:"WARN",message:"settings-tpl.json \u6839\u5143\u7D20\u4E0D\u662F\u5BF9\u8C61"});else if(!t.env||typeof t.env!="object")e.push({level:"WARN",message:"settings-tpl.json \u7F3A\u5C11 env \u5B57\u6BB5\uFF0C\u521B\u5EFA settings-ding.json \u65F6\u5C06\u4E0D\u5305\u542B\u9884\u914D\u7F6E\u73AF\u5883\u53D8\u91CF"});else{const a=Object.keys(t.env);e.push({level:"PASS",message:`settings-tpl.json \u6709\u6548\uFF0Cenv \u5305\u542B: ${a.join(", ")||"(\u7A7A)"}`})}}catch(t){e.push({level:"WARN",message:`settings-tpl.json \u89E3\u6790\u5931\u8D25: ${t instanceof Error?t.message:t}`})}else e.push({level:"WARN",message:`settings-tpl.json \u4E0D\u5B58\u5728: ${r}\uFF0C\u521B\u5EFA settings-ding.json \u65F6\u5C06\u4F7F\u7528\u7A7A\u6A21\u677F`});try{(0,child_process_1.execSync)("which claude",{stdio:"pipe"}),e.push({level:"PASS",message:"claude \u547D\u4EE4\u53EF\u7528"})}catch{e.push({level:"FATAL",message:"claude \u547D\u4EE4\u4E0D\u53EF\u7528\uFF0C\u8BF7\u786E\u8BA4 Claude Code CLI \u5DF2\u5B89\u88C5"})}try{const t=path_1.default.join(i,".healthcheck");fs_1.default.writeFileSync(t,"ok","utf-8"),fs_1.default.unlinkSync(t),e.push({level:"PASS",message:`\u5DE5\u4F5C\u76EE\u5F55\u53EF\u5199: ${i}`})}catch(t){e.push({level:"FATAL",message:`\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u53EF\u5199: ${i} \u2014 ${t instanceof Error?t.message:t}`})}if(Array.isArray(n.conversations))for(const t of n.conversations){const a=s.getConversationDir(t.conversationId);try{fs_1.default.mkdirSync(a,{recursive:!0}),e.push({level:"PASS",message:`\u7FA4\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5C31\u7EEA: ${t.conversationTitle||t.conversationId}`})}catch(o){e.push({level:"WARN",message:`\u7FA4\u5DE5\u4F5C\u76EE\u5F55\u521B\u5EFA\u5931\u8D25: ${a} \u2014 ${o instanceof Error?o.message:o}`})}}console.log(`
2
+ [${(0,session_1.timestamp)()}] ========== \u542F\u52A8\u81EA\u68C0 ==========`);const f=e.some(t=>t.level==="FATAL");for(const t of e){const a=t.level==="PASS"?"\u2713":t.level==="FATAL"?"\u2717":"\u26A0",o=t.level==="PASS"?t.message:t.level==="FATAL"?`[FATAL] ${t.message}`:`[WARN] ${t.message}`;console.log(` ${a} ${o}`)}const g=e.filter(t=>t.level==="PASS").length,p=e.filter(t=>t.level==="WARN").length,v=e.filter(t=>t.level==="FATAL").length;console.log(`[${(0,session_1.timestamp)()}] \u81EA\u68C0\u5B8C\u6210: ${g} \u901A\u8FC7, ${p} \u8B66\u544A, ${v} \u81F4\u547D`),console.log(`[${(0,session_1.timestamp)()}] ==============================
3
+ `),f&&(console.error(`[${(0,session_1.timestamp)()}] \u542F\u52A8\u81EA\u68C0\u53D1\u73B0\u81F4\u547D\u9519\u8BEF\uFF0C\u8FDB\u7A0B\u9000\u51FA`),process.exit(1))}