cc-ding 0.3.1 → 0.4.1

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
@@ -97,7 +97,7 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
97
97
  | 命令 | 说明 |
98
98
  |------|------|
99
99
  | `/ls [目录] [层数]` | 查看目录结构 |
100
- | `/bash <命令>` | 执行任意命令(覆盖 pwd/mkdir/touch/rm 等) |
100
+ | `/bash <命令>` | 执行任意命令(仅 owner/管理员,执行记录审计日志 `bash-audit.log`) |
101
101
 
102
102
  #### 管理命令(仅 owner)
103
103
 
@@ -152,9 +152,15 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
152
152
  | `apiKeyCfg` | API Key 池化:429 自动切换、每日 0 点重置 |
153
153
  | `useLocalOcr` | 图片本地 OCR(默认 `true`),模型支持图片时可设 `false` |
154
154
  | `linkConversationId` | 关联群 ID,多群共享同一 Claude 会话上下文 |
155
- | `permissionMode` | Claude 进程权限模式(默认 `bypassPermissions`),可选: `default`、`acceptEdits`、`plan`、`auto`、`bypassPermissions`、`dontAsk` |
155
+ | `permissionMode` | Claude 进程权限模式(默认 `acceptEdits`;`bypassPermissions` 需显式配置,启动时会告警),可选: `default`、`acceptEdits`、`plan`、`auto`、`bypassPermissions`、`dontAsk` |
156
156
  | `preBash` | 全局 `/bash` 前置命令 |
157
157
 
158
+ #### 安全说明
159
+
160
+ - 敏感字段(`clientSecret`、`dingToken`、`defaultDingToken`、`apiKeyCfg[].apiKey`)支持 `$ENV:VAR_NAME` 形式引用环境变量,避免明文落盘,例如 `"clientSecret": "$ENV:DING_SECRET"`
161
+ - `config.json` 与 `settings-ding.json` 写入时自动收紧为 `600` 权限
162
+ - `/bash` 仅限 owner/管理员执行,所有命令记录到 `~/.cc-ding/{clientId}/bash-audit.log`
163
+
158
164
  ### 数据存储
159
165
 
160
166
  所有数据存储在 `~/.cc-ding/{clientId}/` 目录下:
@@ -263,7 +269,7 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
263
269
  | Command | Description |
264
270
  |---------|-------------|
265
271
  | `/ls [dir] [depth]` | View directory structure |
266
- | `/bash <cmd>` | Execute arbitrary commands (covers pwd/mkdir/touch/rm etc.) |
272
+ | `/bash <cmd>` | Execute arbitrary commands (owner/admin only, audited in `bash-audit.log`) |
267
273
 
268
274
  #### Admin (owner only)
269
275
 
@@ -318,9 +324,15 @@ pm2 start --name "cc-ding-{clientId}" npx -- -p cc-ding cc-ding run -ci {clientI
318
324
  | `apiKeyCfg` | API Key pooling: auto-switch on 429, daily reset at midnight |
319
325
  | `useLocalOcr` | Local image OCR (default `true`); set `false` if model supports images natively |
320
326
  | `linkConversationId` | Link groups to share one Claude session context |
321
- | `permissionMode` | Claude process permission mode (default `bypassPermissions`), options: `default`, `acceptEdits`, `plan`, `auto`, `bypassPermissions`, `dontAsk` |
327
+ | `permissionMode` | Claude process permission mode (default `acceptEdits`; `bypassPermissions` must be set explicitly and warns at startup), options: `default`, `acceptEdits`, `plan`, `auto`, `bypassPermissions`, `dontAsk` |
322
328
  | `preBash` | Global pre-bash command for `/bash` |
323
329
 
330
+ #### Security Notes
331
+
332
+ - Sensitive fields (`clientSecret`, `dingToken`, `defaultDingToken`, `apiKeyCfg[].apiKey`) support `$ENV:VAR_NAME` references to environment variables, e.g. `"clientSecret": "$ENV:DING_SECRET"`
333
+ - `config.json` and `settings-ding.json` are written with `600` permissions
334
+ - `/bash` is restricted to owner/admin; all commands are audited in `~/.cc-ding/{clientId}/bash-audit.log`
335
+
324
336
  ### Data Storage
325
337
 
326
338
  All data is stored under `~/.cc-ding/{clientId}/`:
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
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",`
2
+ "use strict";var r=exports&&exports.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const a=require("../src/common"),g=require("commander"),t=require("../src/biz/session"),d=r(require("path")),m=require("../src/biz/cc-ding-cli"),I=require("../src/biz/lock"),u=require("../src/biz/doctor"),p=require("../src/biz/notify"),f=r(require("fs"));(0,a.loadEnv)(),process.removeAllListeners("warning"),process.setMaxListeners(0),process.on("uncaughtException",function(e){console.log("Caught exception: "+e),process.exit(1)});const o=new g.Command;o.addHelpText("before",`
3
3
  cc-ding for connect ClaudeCode to DingDingRobot
4
4
  `).addHelpText("after",`
5
5
  Examples:
6
6
  $ cc-ding init -ci {clientId} -cs {clientSecret} -m {mobile}
7
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(`
8
+ `).version((0,a.projUtil)().getPkgVersion()),o.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
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
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 c={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};(0,session_1.initClientDir)(e.clientId,c),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(`
11
+ `),process.exit(1));const i=`${`${(0,t.getHomeDir)()}/.cc-ding/${e.clientId}`}/config.json`;f.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 c={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};(0,t.initClientDir)(e.clientId,c),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}`)}),o.command("run").description(`
12
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
13
  - \u4F1A\u8BDD\u6570\u636E\u8DEF\u5F84: ~/.cc-ding/{clientId}/{MD5}/.sessions/{claudeSessionId}/session.{json|log}
14
14
  - \u4EFB\u52A1\u6570\u636E\u8DEF\u5F84: ~/.cc-ding/{clientId}/{MD5}/.tasks/{\u65F6\u95F4\u6233}/task.{json|log}
@@ -33,5 +33,5 @@ Examples:
33
33
  - 429\u81EA\u52A8\u5207\u6362: \u81EA\u52A8\u5207\u6362\u5230API Key\u6A21\u5F0F
34
34
  - Key\u8F6E\u6362: API Key\u9047\u5230429\u6216\u8FDE\u7EEDTPM\u4E0D\u7A33\u5B9A\u65F6\u81EA\u52A8\u6362Key
35
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),o=(0,doctor_1.runDoctor)(n);(0,doctor_1.printDoctorResults)(o)}),program.command("notify").description("\u901A\u8FC7\u9489\u9489\u673A\u5668\u4EBA\u53D1\u9001\u6D88\u606F\u5230\u6307\u5B9A\u7FA4\u6216\u5355\u804A").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("-mo, --mobile <value>","\u5355\u804A\u76EE\u6807\u624B\u673A\u53F7\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF0C\u4E0E conversations \u4E00\u4E00\u5BF9\u5E94\uFF09").option("-md, --markdown","\u4F7F\u7528 Markdown \u683C\u5F0F\u53D1\u9001",!1).action(async e=>{const n=e.conversations.split(",").map(c=>c.trim()).filter(Boolean),o=e.atUserIds?e.atUserIds.split(",").map(c=>c.trim()).filter(Boolean):[],t=e.mobile?e.mobile.split(",").map(c=>c.trim()).filter(Boolean):[];console.log(`\u{1F4E4} \u53D1\u9001\u6D88\u606F\u5230 ${n.length} \u4E2A\u4F1A\u8BDD...`);const i=await(0,notify_1.sendNotify)({clientId:e.clientId,message:e.message,conversationIds:n,atUserIds:o,mobiles:t,markdown:e.markdown});console.log(`
37
- \u2705 \u6210\u529F: ${i.success}, \u274C \u5931\u8D25: ${i.fail}`),process.exit(i.fail>0?1:0)}),program.parse(process.argv);
36
+ `).requiredOption("-ci, --clientId <value>","clientId").action(async e=>{(0,t.ensureClientDir)(e.clientId);const n=d.default.join((0,t.getHomeDir)(),".cc-ding",e.clientId);(0,I.acquirePidLock)(n,e.clientId),await new m.DingClaude(e.clientId).run()}),o.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=d.default.join((0,t.getHomeDir)(),".cc-ding",e.clientId),s=(0,u.runDoctor)(n);(0,u.printDoctorResults)(s)}),o.command("notify").description("\u901A\u8FC7\u9489\u9489\u673A\u5668\u4EBA\u53D1\u9001\u6D88\u606F\u5230\u6307\u5B9A\u7FA4\u6216\u5355\u804A").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("-mo, --mobile <value>","\u5355\u804A\u76EE\u6807\u624B\u673A\u53F7\uFF08\u591A\u4E2A\u7528\u9017\u53F7\u5206\u9694\uFF0C\u4E0E conversations \u4E00\u4E00\u5BF9\u5E94\uFF09").option("-md, --markdown","\u4F7F\u7528 Markdown \u683C\u5F0F\u53D1\u9001",!1).action(async e=>{const n=e.conversations.split(",").map(c=>c.trim()).filter(Boolean),s=e.atUserIds?e.atUserIds.split(",").map(c=>c.trim()).filter(Boolean):[],l=e.mobile?e.mobile.split(",").map(c=>c.trim()).filter(Boolean):[];console.log(`\u{1F4E4} \u53D1\u9001\u6D88\u606F\u5230 ${n.length} \u4E2A\u4F1A\u8BDD...`);const i=await(0,p.sendNotify)({clientId:e.clientId,message:e.message,conversationIds:n,atUserIds:s,mobiles:l,markdown:e.markdown});console.log(`
37
+ \u2705 \u6210\u529F: ${i.success}, \u274C \u5931\u8D25: ${i.fail}`),process.exit(i.fail>0?1:0)}),o.parse(process.argv);
@@ -1,3 +1,3 @@
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))}
1
+ "use strict";var C=exports&&exports.__importDefault||function(s){return s&&s.__esModule?s:{default:s}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.saveClientConfig=$,exports.resetApiKeyCfg=K,exports.scheduleApiKeyCfgDailyReset=R,exports.settingLabel=A,exports.rotateApiKey=L,exports.pickValidApiKey=T,exports.ensureSettingsWithApiKey=P,exports.isQuotaExhaustedError=E,exports.isAuthenticationError=b,exports.readApiKeyFromSettings=k,exports.getForceEnabledSettingsPath=D,exports.startupCheck=O;const r=C(require("fs")),d=C(require("path")),c=require("./session"),j=require("utils-ok"),v=require("./secrets"),S=require("./platform");function $(s){const e=`${s.getClientDir()}/config.json`;try{r.default.writeFileSync(e,JSON.stringify(s.config,null,2),{encoding:"utf-8",mode:(0,S.isWindows)()?void 0:384}),(0,S.isWindows)()||r.default.chmodSync(e,384)}catch(n){console.error(`[${(0,c.timestamp)()}] \u4FDD\u5B58 config.json \u5931\u8D25:`,n)}}function K(s){const e=s.config.apiKeyCfg;if(!e)return;const n=new Date;e.resetTime=j.dateUtil.mm(n.getTime()).format("YYYY-MM-DD HH:mm:ss");let i=0;for(const o of e.claudeSettings)o.isValid||(o.isValid=!0,i++);i>0&&console.log(`[${(0,c.timestamp)()}] ${i} \u4E2A\u5DF2\u5931\u6548 Claude Setting \u91CD\u65B0\u6807\u8BB0\u4E3A\u6709\u6548`),$(s),console.log(`[${(0,c.timestamp)()}] apiKeyCfg \u5DF2\u91CD\u7F6E (\u6240\u6709 Claude Setting isValid=true)`)}function R(s){const e=()=>{const n=new Date,i=new Date(n.getFullYear(),n.getMonth(),n.getDate()+1,0,0,0,0),o=i.getTime()-n.getTime();setTimeout(()=>{console.log(`[${(0,c.timestamp)()}] \u5B9A\u65F6\u91CD\u7F6E apiKeyCfg (\u6BCF\u59290\u70B9)`),K(s),e()},o),console.log(`[${(0,c.timestamp)()}] apiKeyCfg \u6BCF\u65E5\u91CD\u7F6E\u5DF2\u8C03\u5EA6\uFF0C\u4E0B\u6B21\u91CD\u7F6E: ${i.toISOString()}`)};e()}function A(s){return s.memo?s.memo:`...${s.apiKey.slice(-6)}`}function F(s,e){const n=s.find(i=>(0,v.resolveSecret)(i.apiKey)===(0,v.resolveSecret)(e));return n?A(n):`...${e.slice(-6)}`}function L(s,e){const n=s.config.apiKeyCfg;if(!n)return null;for(const u of n.claudeSettings)if((0,v.resolveSecret)(u.apiKey)===(0,v.resolveSecret)(e)&&u.isValid){u.isValid=!1;break}const i=n.claudeSettings.filter(u=>u.isValid).length,o=F(n.claudeSettings,e);return console.log(`[${(0,c.timestamp)()}] Claude Setting \u5DF2\u5931\u6548: ${o}, \u5269\u4F59\u6709\u6548: ${i}`),$(s),T(s)}function T(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 P(s,e){const n=d.default.join(s,".claude"),i=d.default.join(n,"settings-ding.json");let o={};if(r.default.existsSync(i))try{o=JSON.parse(r.default.readFileSync(i,"utf-8"))}catch{o={}}else{const h=d.default.join((0,c.getHomeDir)(),".cc-ding","settings-tpl.json");if(r.default.existsSync(h))try{o=JSON.parse(r.default.readFileSync(h,"utf-8")),console.log(`[${(0,c.timestamp)()}] \u4ECE\u6A21\u677F\u521B\u5EFA settings-ding.json: ${h}`)}catch{o={}}}o.env||(o.env={});let u=!1;const p=(0,v.resolveSecret)(e.apiKey);o.env.ANTHROPIC_AUTH_TOKEN!==p&&(o.env.ANTHROPIC_AUTH_TOKEN=p,u=!0),e.baseUrl&&o.env.ANTHROPIC_BASE_URL!==e.baseUrl&&(o.env.ANTHROPIC_BASE_URL=e.baseUrl,u=!0),e.model&&o.env.ANTHROPIC_MODEL!==e.model&&(o.env.ANTHROPIC_MODEL=e.model,u=!0);const m=e.smallModel||e.model;return m&&o.env.CLAUDE_SMALL_FAST_MODEL!==m&&(o.env.CLAUDE_SMALL_FAST_MODEL=m,u=!0),u&&(r.default.mkdirSync(n,{recursive:!0}),r.default.writeFileSync(i,JSON.stringify(o,null,2),{encoding:"utf-8",mode:(0,S.isWindows)()?void 0:384}),(0,S.isWindows)()||r.default.chmodSync(i,384),console.log(`[${(0,c.timestamp)()}] \u5DF2\u5199\u5165 Claude \u914D\u7F6E\u5230 ${i} (${A(e)}, model: ${e.model}, smallModel: ${m})`)),i}function E(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 b(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 k(s){const e=d.default.join(s,".claude","settings-ding.json");if(!r.default.existsSync(e))return null;try{return JSON.parse(r.default.readFileSync(e,"utf-8")).env?.ANTHROPIC_AUTH_TOKEN||null}catch{return null}}function D(s){const e=d.default.join(s,".claude","settings-ding.json");if(!r.default.existsSync(e))return null;try{const i=JSON.parse(r.default.readFileSync(e,"utf-8")).env?.FORCE_ENABLE;return i!==void 0&&i!==!1&&i!==""?(console.log(`[${(0,c.timestamp)()}] \u68C0\u6D4B\u5230 settings-ding.json FORCE_ENABLE=${i}\uFF0C\u5F3A\u5236\u4F7F\u7528\u8BE5\u914D\u7F6E`),e):null}catch{return null}}function O(s){const e=[],n=s.config,i=s.getClientDir(),o=[{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:l}of o){const a=n[t];a==null||a===""||Array.isArray(a)&&a.length===0?e.push({level:"FATAL",message:`config.json \u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5: ${l}`}):e.push({level:"PASS",message:`config.json ${l} \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 l=0;l<n.conversations.length;l++){const a=n.conversations[l],f=`conversations[${l}]`;a.conversationId?t.has(a.conversationId)?e.push({level:"WARN",message:`${f} conversationId \u91CD\u590D: ${a.conversationId}`}):t.add(a.conversationId):e.push({level:"FATAL",message:`${f} \u7F3A\u5C11 conversationId`}),a.linkConversationId&&!n.conversations.some(g=>g.conversationId===a.linkConversationId)&&e.push({level:"WARN",message:`${f} linkConversationId "${a.linkConversationId}" \u672A\u5728 conversations \u4E2D\u627E\u5230`})}e.push({level:"PASS",message:`conversations \u5171 ${n.conversations.length} \u4E2A\u7FA4\u914D\u7F6E`})}for(const t of n.conversations||[])if(t.permissionMode==="bypassPermissions"){const l=t.conversationTitle||t.conversationId;e.push({level:"WARN",message:`\u4F1A\u8BDD "${l}" \u914D\u7F6E\u4E86 bypassPermissions\uFF0CClaude \u5C06\u8DF3\u8FC7\u6240\u6709\u6743\u9650\u786E\u8BA4\uFF0C\u8BF7\u786E\u8BA4\u8BE5\u7FA4\u6210\u5458\u53EF\u4FE1`})}if(!(0,S.isWindows)()){const t=d.default.join(i,"config.json");try{const l=r.default.statSync(t).mode&511;l&63&&(r.default.chmodSync(t,384),e.push({level:"WARN",message:`config.json \u6743\u9650\u8FC7\u5BBD (${l.toString(8)})\uFF0C\u5DF2\u81EA\u52A8\u6536\u7D27\u4E3A 600`}))}catch{}}const u=[{value:n.clientSecret,label:"clientSecret"},{value:n.defaultDingToken,label:"defaultDingToken"},...(n.conversations||[]).map((t,l)=>({value:t.dingToken,label:`conversations[${l}].dingToken`})),...(n.apiKeyCfg?.claudeSettings||[]).map((t,l)=>({value:t.apiKey,label:`apiKeyCfg.claudeSettings[${l}].apiKey`}))];for(const{value:t,label:l}of u)(0,v.isEnvRef)(t)&&!(0,v.resolveSecret)(t)&&e.push({level:"FATAL",message:`${l} \u5F15\u7528\u7684\u73AF\u5883\u53D8\u91CF\u672A\u8BBE\u7F6E: ${t}`});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 l=new Set;for(let f=0;f<t.claudeSettings.length;f++){const g=t.claudeSettings[f],y=`apiKeyCfg.claudeSettings[${f}]`;g.apiKey?l.has(g.apiKey)?e.push({level:"WARN",message:`${y} apiKey \u91CD\u590D: ${A(g)}`}):l.add(g.apiKey):e.push({level:"FATAL",message:`${y} \u7F3A\u5C11 apiKey`}),g.baseUrl||e.push({level:"WARN",message:`${y} \u7F3A\u5C11 baseUrl`}),g.model||e.push({level:"WARN",message:`${y} \u7F3A\u5C11 model`}),typeof g.isValid!="boolean"&&e.push({level:"WARN",message:`${y} isValid \u7C7B\u578B\u5F02\u5E38: ${typeof g.isValid}`})}const a=t.claudeSettings.filter(f=>f.isValid).length;e.push({level:"PASS",message:`apiKeyCfg.claudeSettings \u5171 ${t.claudeSettings.length} \u9879\uFF0C\u6709\u6548 ${a}`})}}const p=d.default.join((0,c.getHomeDir)(),".cc-ding","settings-tpl.json");if(r.default.existsSync(p))try{const t=JSON.parse(r.default.readFileSync(p,"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 l=Object.keys(t.env);e.push({level:"PASS",message:`settings-tpl.json \u6709\u6548\uFF0Cenv \u5305\u542B: ${l.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: ${p}\uFF0C\u521B\u5EFA settings-ding.json \u65F6\u5C06\u4F7F\u7528\u7A7A\u6A21\u677F`});(0,S.commandExists)("claude")?e.push({level:"PASS",message:"claude \u547D\u4EE4\u53EF\u7528"}):e.push({level:"FATAL",message:"claude \u547D\u4EE4\u4E0D\u53EF\u7528\uFF0C\u8BF7\u786E\u8BA4 Claude Code CLI \u5DF2\u5B89\u88C5"});try{const t=d.default.join(i,".healthcheck");r.default.writeFileSync(t,"ok","utf-8"),r.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 l=s.getConversationDir(t.conversationId);try{r.default.mkdirSync(l,{recursive:!0}),e.push({level:"PASS",message:`\u7FA4\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5C31\u7EEA: ${t.conversationTitle||t.conversationId}`})}catch(a){e.push({level:"WARN",message:`\u7FA4\u5DE5\u4F5C\u76EE\u5F55\u521B\u5EFA\u5931\u8D25: ${l} \u2014 ${a instanceof Error?a.message:a}`})}}console.log(`
2
+ [${(0,c.timestamp)()}] ========== \u542F\u52A8\u81EA\u68C0 ==========`);const m=e.some(t=>t.level==="FATAL");for(const t of e){const l=t.level==="PASS"?"\u2713":t.level==="FATAL"?"\u2717":"\u26A0",a=t.level==="PASS"?t.message:t.level==="FATAL"?`[FATAL] ${t.message}`:`[WARN] ${t.message}`;console.log(` ${l} ${a}`)}const h=e.filter(t=>t.level==="PASS").length,N=e.filter(t=>t.level==="WARN").length,_=e.filter(t=>t.level==="FATAL").length;console.log(`[${(0,c.timestamp)()}] \u81EA\u68C0\u5B8C\u6210: ${h} \u901A\u8FC7, ${N} \u8B66\u544A, ${_} \u81F4\u547D`),console.log(`[${(0,c.timestamp)()}] ==============================
3
+ `),m&&(console.error(`[${(0,c.timestamp)()}] \u542F\u52A8\u81EA\u68C0\u53D1\u73B0\u81F4\u547D\u9519\u8BEF\uFF0C\u8FDB\u7A0B\u9000\u51FA`),process.exit(1))}