cc-ding 0.4.0 → 1.0.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/dist/bin/cc-ding.js +5 -5
- package/dist/src/biz/api-key-manager.js +3 -3
- package/dist/src/biz/cc-ding-cli.js +65 -66
- package/dist/src/biz/claude-process.js +33 -32
- package/dist/src/biz/claude-sdk.js +3 -2
- package/dist/src/biz/command-route.js +1 -1
- package/dist/src/biz/commands.js +6 -6
- package/dist/src/biz/cron.js +6 -6
- package/dist/src/biz/doctor.js +2 -2
- package/dist/src/biz/image.js +8 -8
- package/dist/src/biz/lock.js +1 -1
- package/dist/src/biz/menu.js +2 -2
- package/dist/src/biz/messaging.js +5 -5
- package/dist/src/biz/notify.js +1 -1
- package/dist/src/biz/platform.js +2 -2
- package/dist/src/biz/quote.js +5 -5
- package/dist/src/biz/recorder.js +9 -9
- package/dist/src/biz/secrets.js +1 -1
- package/dist/src/biz/session.js +13 -13
- package/dist/src/biz/task.js +23 -22
- package/dist/src/biz/todo.js +6 -6
- package/dist/src/common.js +1 -1
- package/dist/src/constants.js +1 -1
- package/package.json +4 -5
package/dist/bin/cc-ding.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";var
|
|
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,
|
|
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,
|
|
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,
|
|
37
|
-
\u2705 \u6210\u529F: ${i.success}, \u274C \u5931\u8D25: ${i.fail}`),process.exit(i.fail>0?1:0)}),
|
|
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"),secrets_1=require("./secrets"),platform_1=require("./platform");function saveClientConfig(s){const e=`${s.getClientDir()}/config.json`;try{fs_1.default.writeFileSync(e,JSON.stringify(s.config,null,2),{encoding:"utf-8",mode:(0,platform_1.isWindows)()?void 0:384}),(0,platform_1.isWindows)()||fs_1.default.chmodSync(e,384)}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=>(0,secrets_1.resolveSecret)(i.apiKey)===(0,secrets_1.resolveSecret)(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((0,secrets_1.resolveSecret)(r.apiKey)===(0,secrets_1.resolveSecret)(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;const f=(0,secrets_1.resolveSecret)(e.apiKey);l.env.ANTHROPIC_AUTH_TOKEN!==f&&(l.env.ANTHROPIC_AUTH_TOKEN=f,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 d=e.smallModel||e.model;return d&&l.env.CLAUDE_SMALL_FAST_MODEL!==d&&(l.env.CLAUDE_SMALL_FAST_MODEL=d,r=!0),r&&(fs_1.default.mkdirSync(n,{recursive:!0}),fs_1.default.writeFileSync(i,JSON.stringify(l,null,2),{encoding:"utf-8",mode:(0,platform_1.isWindows)()?void 0:384}),(0,platform_1.isWindows)()||fs_1.default.chmodSync(i,384),console.log(`[${(0,session_1.timestamp)()}] \u5DF2\u5199\u5165 Claude \u914D\u7F6E\u5230 ${i} (${settingLabel(e)}, model: ${e.model}, smallModel: ${d})`)),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:o}of l){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: ${o}`}):e.push({level:"PASS",message:`config.json ${o} \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 o=0;o<n.conversations.length;o++){const a=n.conversations[o],c=`conversations[${o}]`;a.conversationId?t.has(a.conversationId)?e.push({level:"WARN",message:`${c} conversationId \u91CD\u590D: ${a.conversationId}`}):t.add(a.conversationId):e.push({level:"FATAL",message:`${c} \u7F3A\u5C11 conversationId`}),a.linkConversationId&&!n.conversations.some(u=>u.conversationId===a.linkConversationId)&&e.push({level:"WARN",message:`${c} 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 o=t.conversationTitle||t.conversationId;e.push({level:"WARN",message:`\u4F1A\u8BDD "${o}" \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,platform_1.isWindows)()){const t=path_1.default.join(i,"config.json");try{const o=fs_1.default.statSync(t).mode&511;o&63&&(fs_1.default.chmodSync(t,384),e.push({level:"WARN",message:`config.json \u6743\u9650\u8FC7\u5BBD (${o.toString(8)})\uFF0C\u5DF2\u81EA\u52A8\u6536\u7D27\u4E3A 600`}))}catch{}}const r=[{value:n.clientSecret,label:"clientSecret"},{value:n.defaultDingToken,label:"defaultDingToken"},...(n.conversations||[]).map((t,o)=>({value:t.dingToken,label:`conversations[${o}].dingToken`})),...(n.apiKeyCfg?.claudeSettings||[]).map((t,o)=>({value:t.apiKey,label:`apiKeyCfg.claudeSettings[${o}].apiKey`}))];for(const{value:t,label:o}of r)(0,secrets_1.isEnvRef)(t)&&!(0,secrets_1.resolveSecret)(t)&&e.push({level:"FATAL",message:`${o} \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 o=new Set;for(let c=0;c<t.claudeSettings.length;c++){const u=t.claudeSettings[c],p=`apiKeyCfg.claudeSettings[${c}]`;u.apiKey?o.has(u.apiKey)?e.push({level:"WARN",message:`${p} apiKey \u91CD\u590D: ${settingLabel(u)}`}):o.add(u.apiKey):e.push({level:"FATAL",message:`${p} \u7F3A\u5C11 apiKey`}),u.baseUrl||e.push({level:"WARN",message:`${p} \u7F3A\u5C11 baseUrl`}),u.model||e.push({level:"WARN",message:`${p} \u7F3A\u5C11 model`}),typeof u.isValid!="boolean"&&e.push({level:"WARN",message:`${p} isValid \u7C7B\u578B\u5F02\u5E38: ${typeof u.isValid}`})}const a=t.claudeSettings.filter(c=>c.isValid).length;e.push({level:"PASS",message:`apiKeyCfg.claudeSettings \u5171 ${t.claudeSettings.length} \u9879\uFF0C\u6709\u6548 ${a}`})}}const f=path_1.default.join((0,session_1.getHomeDir)(),".cc-ding","settings-tpl.json");if(fs_1.default.existsSync(f))try{const t=JSON.parse(fs_1.default.readFileSync(f,"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 o=Object.keys(t.env);e.push({level:"PASS",message:`settings-tpl.json \u6709\u6548\uFF0Cenv \u5305\u542B: ${o.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: ${f}\uFF0C\u521B\u5EFA settings-ding.json \u65F6\u5C06\u4F7F\u7528\u7A7A\u6A21\u677F`});try{(0,child_process_1.execSync)(process.platform==="win32"?"where claude":"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 o=s.getConversationDir(t.conversationId);try{fs_1.default.mkdirSync(o,{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: ${o} \u2014 ${a instanceof Error?a.message:a}`})}}console.log(`
|
|
2
|
-
[${(0,
|
|
3
|
-
`),
|
|
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))}
|