cc-ding 0.3.0-beta.1 → 0.3.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.
@@ -1,24 +1,23 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTaskInfo=formatTaskInfo,exports.countTodoTask=countTodoTask,exports.getOneTodoTask=getOneTodoTask,exports.finishTask=finishTask,exports.cancelTask=cancelTask,exports.parseTaskCancelCommand=parseTaskCancelCommand,exports.handleTask=handleTask,exports.runTaskHandlerLoop=runTaskHandlerLoop,exports.saveTask=saveTask;const utils_ok_1=require("utils-ok"),fs_1=__importDefault(require("fs")),path_1=__importDefault(require("path")),child_process_1=require("child_process"),common_1=require("../common"),messaging_1=require("./messaging"),claude_process_1=require("./claude-process"),session_1=require("./session"),api_key_manager_1=require("./api-key-manager"),MAX_RETRY_COUNT=3;function formatTaskInfo(t){const e=[],i=[],s=[],r=[];for(const l of t.config.conversations){const o=(0,session_1.getTasksDir)(t,l.conversationId);if(!fs_1.default.existsSync(o))continue;const u=utils_ok_1.fileUtil.dirWalker(o);for(const p of u){const c=path_1.default.basename(p);try{const g=utils_ok_1.fileUtil.getJSON(p);if(!g)continue;c==="task.json"?e.push(g):c==="task-doing.json"?i.push(g):c==="task-done.json"?s.push(g):c==="task-failed.json"&&r.push(g)}catch{}}}e.sort((l,o)=>l.startTime-o.startTime),i.sort((l,o)=>l.startTime-o.startTime),s.sort((l,o)=>o.startTime-l.startTime),r.sort((l,o)=>o.startTime-l.startTime);const a=[];if(i.length>0){const l=i.map(o=>`#${o.startTime} ${o.senderNickName||o.senderStaffId}: ${taskDisplayName(o)}`);a.push(`**\u23F3 \u5904\u7406\u4E2D (${i.length})**
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(t){return t&&t.__esModule?t:{default:t}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTaskInfo=formatTaskInfo,exports.countTodoTask=countTodoTask,exports.getOneTodoTask=getOneTodoTask,exports.finishTask=finishTask,exports.cancelTask=cancelTask,exports.parseTaskCancelCommand=parseTaskCancelCommand,exports.handleTask=handleTask,exports.runTaskHandlerLoop=runTaskHandlerLoop,exports.saveTask=saveTask;const utils_ok_1=require("utils-ok"),fs_1=__importDefault(require("fs")),path_1=__importDefault(require("path")),child_process_1=require("child_process"),common_1=require("../common"),messaging_1=require("./messaging"),claude_process_1=require("./claude-process"),session_1=require("./session"),api_key_manager_1=require("./api-key-manager"),MAX_RETRY_COUNT=3;function formatTaskInfo(t){const e=[],i=[],s=[],r=[];for(const l of t.config.conversations){const n=(0,session_1.getTasksDir)(t,l.conversationId);if(!fs_1.default.existsSync(n))continue;const u=utils_ok_1.fileUtil.dirWalker(n);for(const m of u){const c=path_1.default.basename(m);try{const g=utils_ok_1.fileUtil.getJSON(m);if(!g)continue;c==="task.json"?e.push(g):c==="task-doing.json"?i.push(g):c==="task-done.json"?s.push(g):c==="task-failed.json"&&r.push(g)}catch{}}}e.sort((l,n)=>l.startTime-n.startTime),i.sort((l,n)=>l.startTime-n.startTime),s.sort((l,n)=>n.startTime-l.startTime),r.sort((l,n)=>n.startTime-l.startTime);const a=[];if(i.length>0){const l=i.map(n=>`#${n.startTime} ${n.senderNickName||n.senderStaffId}: ${taskDisplayName(n)}`);a.push(`**\u23F3 \u5904\u7406\u4E2D (${i.length})**
2
2
  ${l.join(`
3
3
  `)}`)}else a.push(`**\u23F3 \u5904\u7406\u4E2D**
4
- \u65E0`);if(e.length>0){const l=e.map(o=>`#${o.startTime} ${o.senderNickName||o.senderStaffId}: ${taskDisplayName(o)}`);a.push(`**\u{1F4CB} \u5F85\u529E\u961F\u5217 (${e.length})**
4
+ \u65E0`);if(e.length>0){const l=e.map(n=>`#${n.startTime} ${n.senderNickName||n.senderStaffId}: ${taskDisplayName(n)}`);a.push(`**\u{1F4CB} \u5F85\u529E\u961F\u5217 (${e.length})**
5
5
  ${l.join(`
6
6
  `)}`)}else a.push(`**\u{1F4CB} \u5F85\u529E\u961F\u5217**
7
- \u65E0`);const n=s.slice(0,5);if(n.length>0){const l=n.map(o=>`#${o.startTime} ${o.senderNickName||o.senderStaffId}: ${taskDisplayName(o)}`);a.push(`**\u2705 \u6700\u8FD1\u5B8C\u6210 (top ${n.length}/${s.length})**
7
+ \u65E0`);const o=s.slice(0,5);if(o.length>0){const l=o.map(n=>`#${n.startTime} ${n.senderNickName||n.senderStaffId}: ${taskDisplayName(n)}`);a.push(`**\u2705 \u6700\u8FD1\u5B8C\u6210 (top ${o.length}/${s.length})**
8
8
  ${l.join(`
9
9
  `)}`)}else a.push(`**\u2705 \u6700\u8FD1\u5B8C\u6210**
10
- \u65E0`);if(r.length>0){const l=r.map(o=>`#${o.startTime} ${o.senderNickName||o.senderStaffId}: ${taskDisplayName(o)}${o.retryCount?` (\u91CD\u8BD5${o.retryCount}\u6B21)`:""}`);a.push(`**\u274C \u5931\u8D25 (${r.length})**
10
+ \u65E0`);if(r.length>0){const l=r.map(n=>`#${n.startTime} ${n.senderNickName||n.senderStaffId}: ${taskDisplayName(n)}${n.retryCount?` (\u91CD\u8BD5${n.retryCount}\u6B21)`:""}`);a.push(`**\u274C \u5931\u8D25 (${r.length})**
11
11
  ${l.join(`
12
12
  `)}`)}return a.join(`
13
13
 
14
- `)}function truncatePrompt(t,e=80){const i=t.replace(/\n/g," ").trim();return i.length>e?i.slice(0,e)+"...":i}function taskDisplayName(t){return t.title?t.title:truncatePrompt(t.prompt)}async function preprocessTask(t,e,i){const s=(0,session_1.getConversationDir)(t,e),r="claude",a=["--permission-mode","bypassPermissions","--print"],n=(0,claude_process_1.resolveClaudeSettingsPath)(t,s);n&&a.push("--settings",n);const l=["\u8BF7\u5BF9\u4EE5\u4E0B\u4EFB\u52A1\u9700\u6C42\u8FDB\u884C\u9884\u5904\u7406\uFF0C\u751F\u6210\u7B80\u77ED\u6807\u9898\u548C\u4F18\u5316\u540E\u7684\u9700\u6C42\u63CF\u8FF0\u3002","\u76F4\u63A5\u8FD4\u56DEJSON\uFF0C\u4E0D\u8981markdown\u4EE3\u7801\u5757\u6216\u5176\u4ED6\u5185\u5BB9\u3002",'\u683C\u5F0F: {"title":"\u7B80\u77ED\u6807\u9898(15\u5B57\u4EE5\u5185)","promptSimply":"\u4F18\u5316\u540E\u7684\u9700\u6C42\u63CF\u8FF0\uFF0C\u4FDD\u7559\u539F\u59CB\u9700\u6C42\u7684\u6240\u6709\u5173\u952E\u4FE1\u606F\uFF0C\u4F7F\u63CF\u8FF0\u66F4\u6E05\u6670\u3001\u7ED3\u6784\u5316"}',"",`\u539F\u59CB\u9700\u6C42: ${i}`].join(`
15
- `);a.push(l);const o=3e4;return new Promise(u=>{let p="";const c=(0,child_process_1.spawn)(r,a,{cwd:s,stdio:["ignore","pipe","pipe"]}),g=setTimeout(()=>{c.kill("SIGTERM"),setTimeout(()=>{try{c.kill("SIGKILL")}catch{}},3e3)},o);c.stdout.on("data",f=>{p+=f.toString()}),c.stderr.on("data",()=>{}),c.on("close",f=>{if(clearTimeout(g),f!==0||!p.trim()){console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5931\u8D25(\u9000\u51FA\u7801:${f})\uFF0C\u4F7F\u7528\u539F\u59CBprompt`),u(null);return}try{let d=p.trim();const j=d.match(/\{[\s\S]*\}/);j&&(d=j[0]);const m=JSON.parse(d);m.title&&m.promptSimply?(console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5B8C\u6210: title="${m.title}"`),u({title:String(m.title),promptSimply:String(m.promptSimply)})):(console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u8FD4\u56DE\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u4F7F\u7528\u539F\u59CBprompt`),u(null))}catch(d){console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406JSON\u89E3\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u539F\u59CBprompt: ${d}`),u(null)}}),c.on("error",f=>{clearTimeout(g),console.error(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u8FDB\u7A0B\u9519\u8BEF:`,f),u(null)})})}function countTodoTask(t){let e=0;for(const i of t.config.conversations){const s=(0,session_1.getTasksDir)(t,i.conversationId);if(fs_1.default.existsSync(s)){const a=utils_ok_1.fileUtil.dirWalker(s).filter(n=>path_1.default.basename(n)==="task.json");e+=a.length}}return e}async function getOneTodoTask(t){for(const e of t.config.conversations){const i=(0,session_1.getTasksDir)(t,e.conversationId);if(!fs_1.default.existsSync(i))continue;const r=utils_ok_1.fileUtil.dirWalker(i).filter(n=>path_1.default.basename(n)==="task.json");if(r.length===0)continue;const a=r.map(n=>{try{const l=utils_ok_1.fileUtil.getJSON(n);return l?{file:n,task:l}:null}catch{return console.error(`\u4EFB\u52A1\u6587\u4EF6\u89E3\u6790\u5931\u8D25\uFF0C\u8DF3\u8FC7: ${n}`),null}}).filter(n=>n!==null).sort((n,l)=>n.task.startTime-l.task.startTime);if(a.length>0){const{file:n,task:l}=a[0];return common_1.utils.addSuffixToFile(n,"-doing"),l}}}async function finishTask(t,e){const i=`${e}/task-doing.json`;let s;try{s=utils_ok_1.fileUtil.getJSON(i)}catch(l){console.error(`\u8BFB\u53D6\u4EFB\u52A1\u6587\u4EF6\u5931\u8D25: ${i}`,l);return}const r=`${e}/result.md`,a=fs_1.default.existsSync(r)?utils_ok_1.fileUtil.getFileStr(r):"\u62B1\u6B49,\u4EFB\u52A1\u5904\u7406\u5F02\u5E38...";await(0,messaging_1.sendDingMessage)(t,{conversationId:s.conversationId,sessionWebhook:s.sessionWebhook,atUserId:s.senderStaffId,content:a,msgType:"markdown"});const n=i.replace("-doing.json","-done.json");utils_ok_1.fileUtil.rename(i,n)}async function failTask(t,e,i){const s=`${e}/task-doing.json`;let r;try{r=utils_ok_1.fileUtil.getJSON(s)}catch(n){console.error(`\u8BFB\u53D6\u4EFB\u52A1\u6587\u4EF6\u5931\u8D25: ${s}`,n);return}await(0,messaging_1.sendDingMessage)(t,{conversationId:r.conversationId,sessionWebhook:r.sessionWebhook,atUserId:r.senderStaffId,content:`\u274C \u4EFB\u52A1\u5931\u8D25: ${taskDisplayName(r)}
16
- \u539F\u56E0: ${i}`,msgType:"markdown"});const a=s.replace("-doing.json","-failed.json");utils_ok_1.fileUtil.rename(s,a)}async function resetTaskToTodo(t,e,i){const s=`${e}/task-doing.json`,r=`${e}/task.json`;if(!fs_1.default.existsSync(s))return!1;try{const a=utils_ok_1.fileUtil.getJSON(s),n=(a.retryCount||0)+1;if(n>=MAX_RETRY_COUNT)return console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u91CD\u8BD5\u6B21\u6570\u5DF2\u8FBE\u4E0A\u9650(${n}/${MAX_RETRY_COUNT})\uFF0C\u6807\u8BB0\u4E3A\u5931\u8D25: ${a.title||a.prompt}`),a.retryCount=n,fs_1.default.writeFileSync(s,JSON.stringify(a,null,2),"utf-8"),await failTask(t,e,`${i} (\u5DF2\u91CD\u8BD5${n}\u6B21)`),!1;a.retryCount=n,fs_1.default.writeFileSync(s,JSON.stringify(a,null,2),"utf-8"),console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E (\u91CD\u8BD5${n}/${MAX_RETRY_COUNT}): ${a.title||a.prompt}`)}catch(a){console.error(`[${(0,session_1.timestamp)()}] \u66F4\u65B0\u4EFB\u52A1\u91CD\u8BD5\u8BA1\u6570\u5931\u8D25:`,a)}return fs_1.default.existsSync(s)&&utils_ok_1.fileUtil.rename(s,r),!0}function cancelTask(t,e,i){const s=[],r=e.trim(),a=i?t.config.conversations.filter(u=>u.conversationId===i):t.config.conversations;for(const u of a){const p=(0,session_1.getTasksDir)(t,u.conversationId);if(!fs_1.default.existsSync(p))continue;const g=utils_ok_1.fileUtil.dirWalker(p).filter(f=>path_1.default.basename(f)==="task.json");for(const f of g)try{const d=utils_ok_1.fileUtil.getJSON(f);if(!d)continue;if(String(d.startTime)===r){s.push({file:f,task:d});continue}if(d.title&&d.title.includes(r)){s.push({file:f,task:d});continue}}catch{}}if(s.length===0)return`\u672A\u627E\u5230\u5339\u914D\u7684\u5F85\u529E\u4EFB\u52A1: ${r}`;let n=0;for(const{file:u,task:p}of s)try{fs_1.default.unlinkSync(u),n++,console.log(`[${(0,session_1.timestamp)()}] \u5DF2\u53D6\u6D88\u4EFB\u52A1: #${p.startTime} ${p.title||p.prompt}`)}catch(c){console.error(`[${(0,session_1.timestamp)()}] \u53D6\u6D88\u4EFB\u52A1\u5931\u8D25: ${u}`,c)}const l=s.slice(0,5).map(u=>`#${u.task.startTime} ${taskDisplayName(u.task)}`).join(`
17
- `),o=n>5?`
18
- ...\u5171\u53D6\u6D88 ${n} \u4E2A\u4EFB\u52A1`:"";return`\u5DF2\u53D6\u6D88 ${n} \u4E2A\u5F85\u529E\u4EFB\u52A1:
19
- ${l}${o}`}function parseTaskCancelCommand(t){const i=t.trim().match(/^\/task\s+cancel\s+(.+)$/i);return i?i[1].trim():null}function updateCmdArgsSettings(t,e){const i=t.indexOf("--settings");i!==-1&&t.splice(i,2),e&&t.push("--settings",e)}async function handleTask(t){const e=await getOneTodoTask(t);if(!e){(0,session_1.debugLog)(t,"\u672A\u53D1\u73B0\u5F85\u529E\u4EFB\u52A1...");return}const i=(0,session_1.getConversationConfig)(t,e.conversationId),s=(0,session_1.getConversationDir)(t,e.conversationId),r=`${(0,session_1.getTasksDir)(t,e.conversationId)}/${e.startTimeStr}`;if(!fs_1.default.existsSync(r)){console.error(`\u4EFB\u52A1\u76EE\u5F55\u4E0D\u5B58\u5728: ${r}`);return}e.type!=="cron"&&await(0,messaging_1.sendDingMessage)(t,{conversationId:e.conversationId,sessionWebhook:e.sessionWebhook,atUserId:e.senderStaffId,content:`\u{1F504} \u5F00\u59CB\u5904\u7406\u4EFB\u52A1: ${taskDisplayName(e)}`});const a=`${r}/result.md`,n=`${r}/task.log`;console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u5904\u7406\u4E2D: ${e.title||e.prompt}`);const l=e.senderNickName&&e.senderStaffId?`${e.senderNickName}(${e.senderStaffId}), `:"unknown",o=t.config.apiKeyCfg,u=(0,api_key_manager_1.getForceEnabledSettingsPath)(s);let p=!1,c=null;if(u)console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 FORCE_ENABLE\uFF0C\u5F3A\u5236\u4F7F\u7528 settings-ding.json`);else if(o){if(c=(0,api_key_manager_1.pickValidApiKey)(t),!c){console.log(`[${(0,session_1.timestamp)()}] \u65E0\u53EF\u7528\u914D\u989D\uFF0C\u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E`),await resetTaskToTodo(t,r,"\u65E0\u53EF\u7528\u914D\u989D");return}p=!0,console.log(`[${(0,session_1.timestamp)()}] \u5207\u6362\u5230 API Key \u6A21\u5F0F`)}const g=i?.taskCfg?.skill,f=i?.agent,d=e.promptSimply||e.prompt,m=["--permission-mode","bypassPermissions","--print",`${g?`/${g}`:""} \u7528\u6237: ${l}, \u9700\u6C42: ${d}; \u6700\u540E\u5C06\u56DE\u590D\u5185\u5BB9\u4FDD\u5B58\u81F3: ${a}`.trim()];if(u)m.push("--settings",u);else if(p&&c){const $=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);m.push("--settings",$)}else if(!o){const $=path_1.default.join(s,".claude","settings.json");fs_1.default.existsSync($)&&(m.push("--settings",$),console.log(`[${(0,session_1.timestamp)()}] \u81EA\u52A8\u68C0\u6D4B\u5230 settings.json: ${$}`))}f&&m.push("--agent",f),(0,session_1.debugLog)(t,`\u6267\u884C\u547D\u4EE4: claude ${m.join(" ")}`);const O=600*1e3,N=20,x=1e4,D=1e4,I="claude",M=$=>{const k=Date.now();return new Promise(y=>{const _=[];let F=!1,P=!1;const C=(0,child_process_1.spawn)(I,$,{cwd:s,stdio:["ignore","pipe","pipe"]}),A=setTimeout(()=>{F||(P=!0,console.error("\u4EFB\u52A1\u6267\u884C\u8D85\u65F6(10\u5206\u949F)\uFF0C\u7EC8\u6B62\u8FDB\u7A0B"),C.kill("SIGTERM"),setTimeout(()=>{F||C.kill("SIGKILL")},5e3))},O);C.stdout.on("data",w=>{const v=w.toString();process.stdout.write(v),_.push(v)}),C.stderr.on("data",w=>{const v=w.toString();process.stderr.write(v),_.push(v)}),C.on("close",w=>{F=!0,clearTimeout(A),y({exitCode:w??1,output:_.join(""),elapsed:Date.now()-k,timedOut:P})}),C.on("error",w=>{console.error("\u8FDB\u7A0B\u6267\u884C\u9519\u8BEF:",w),_.push(`\u8FDB\u7A0B\u6267\u884C\u9519\u8BEF: ${w.message}`)})})};let h,S,b=!1,T=0;for(;;){const $=await M(m);if(h=$.exitCode,S=$.output,b=$.timedOut,h!==0){if(b){console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u6267\u884C\u8D85\u65F6\uFF0C\u91CD\u7F6E\u4E3A\u5F85\u529E`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${I} ${m.join(" ")}`,`[${(0,session_1.timestamp)()}] \u8D85\u65F6(${O/1e3}s)`,S].join(`
20
- `);fs_1.default.writeFileSync(n,k),await resetTaskToTodo(t,r,"\u6267\u884C\u8D85\u65F6");return}if((0,api_key_manager_1.isQuotaExhaustedError)(S)&&o){if(p){if(c){const y=(0,api_key_manager_1.rotateApiKey)(t,c.apiKey);if(y){c=y,T=0;const _=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(m,_),console.log(`[${(0,session_1.timestamp)()}] API Key \u914D\u989D\u8017\u5C3D(429)\uFF0C\u5207\u6362\u5230\u65B0 Key: ${(0,api_key_manager_1.settingLabel)(y)}`);continue}}}else if(c=(0,api_key_manager_1.pickValidApiKey)(t),c){p=!0,T=0;const y=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(m,y),console.log(`[${(0,session_1.timestamp)()}] \u5207\u6362\u5230 API Key \u6A21\u5F0F`);continue}console.log(`[${(0,session_1.timestamp)()}] \u65E0\u53EF\u7528\u914D\u989D\uFF0C\u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${I} ${m.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,S].join(`
21
- `);fs_1.default.writeFileSync(n,k),await resetTaskToTodo(t,r,"\u65E0\u53EF\u7528\u914D\u989D(429)");return}if((0,api_key_manager_1.isAuthenticationError)(S)){console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230\u8BA4\u8BC1\u9519\u8BEF(401)\uFF0C\u6807\u8BB0\u4EFB\u52A1\u5931\u8D25`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${I} ${m.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,S].join(`
22
- `);fs_1.default.writeFileSync(n,k),await failTask(t,r,"\u8BA4\u8BC1\u5931\u8D25(401)\uFF0CAPI Key \u65E0\u6548\u6216\u670D\u52A1\u672A\u6388\u6743");return}if((0,claude_process_1.isRetryableApiError)(S)){if($.elapsed<D&&p&&c&&o){if(T++,T>=N){const k=(0,api_key_manager_1.rotateApiKey)(t,c.apiKey);if(k){c=k,T=0;const y=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(m,y),console.log(`[${(0,session_1.timestamp)()}] TPM \u9650\u6D41\u8FDE\u7EED\u5FEB\u901F\u5931\u8D25 ${N} \u6B21\uFF0C\u5207\u6362\u5230\u65B0 Key: ${(0,api_key_manager_1.settingLabel)(k)}`),await utils_ok_1.baseUtil.sleep(x);continue}}}else if($.elapsed<D){if(T++,T>=N){console.log(`[${(0,session_1.timestamp)()}] TPM \u9650\u6D41\u5FEB\u901F\u5931\u8D25\u8FDE\u7EED${N}\u6B21\uFF0C\u91CD\u7F6E\u4EFB\u52A1\u4E3A\u5F85\u529E`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${I} ${m.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,S].join(`
23
- `);fs_1.default.writeFileSync(n,k),await resetTaskToTodo(t,r,"TPM\u9650\u6D41\u5FEB\u901F\u5931\u8D25\u6B21\u6570\u8FC7\u591A");return}console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 TPM \u9650\u6D41(\u5FEB\u901F\u5931\u8D25)\uFF0C${x/1e3}s \u540E\u91CD\u8BD5 (${T}/${N})`)}else T=0,console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 TPM \u9650\u6D41(\u8FDB\u7A0B\u5DF2\u8FD0\u884C\u4E00\u6BB5\u65F6\u95F4)\uFF0C\u91CD\u7F6E\u5FEB\u901F\u5931\u8D25\u8BA1\u6570\uFF0C${x/1e3}s \u540E\u91CD\u8BD5`);await utils_ok_1.baseUtil.sleep(x);continue}}break}const U=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${I} ${m.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,S].join(`
24
- `);if(fs_1.default.writeFileSync(n,U),h!==0){console.error(`\u547D\u4EE4\u6267\u884C\u5931\u8D25, \u9000\u51FA\u7801: ${h}`),await failTask(t,r,`\u6267\u884C\u5931\u8D25(\u9000\u51FA\u7801: ${h})`);return}if(fs_1.default.existsSync(a))console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u5904\u7406\u5B8C\u6210`);else{console.error("\u4EFB\u52A1\u672A\u6309\u9884\u671F\u5904\u7406"),await failTask(t,r,"\u672A\u751F\u6210\u7ED3\u679C\u6587\u4EF6");return}await finishTask(t,r)}async function runTaskHandlerLoop(t){for(;;)await handleTask(t).catch(e=>console.error(e)),await utils_ok_1.baseUtil.sleep(1e4)}async function saveTask(t,e){const{conversationId:i,prompt:s,senderStaffId:r,senderNickName:a,sessionWebhook:n,type:l="normal"}=e,o=Date.now(),u=utils_ok_1.dateUtil.mm(o).format("YYYY-MM-DD-HH-mm-ss"),p=`${(0,session_1.getTasksDir)(t,i)}/${u}`,c=`${p}/task.json`,g={conversationId:i,startTime:o,startTimeStr:u,prompt:s,senderStaffId:r,senderNickName:a||"",sessionWebhook:n,type:l};await utils_ok_1.fileUtil.saveFileStr(JSON.stringify(g,null,2),c),(0,session_1.debugLog)(t,`\u4EFB\u52A1\u5DF2\u4FDD\u5B58: ${c}`),preprocessTask(t,i,s).then(f=>{if(f)try{const d=`${p}/task-doing.json`,j=fs_1.default.existsSync(d)?d:fs_1.default.existsSync(c)?c:null;if(!j){console.log(`[${(0,session_1.timestamp)()}] \u9884\u5904\u7406\u5B8C\u6210\u4F46\u4EFB\u52A1\u6587\u4EF6\u5DF2\u4E0D\u5B58\u5728: ${p}`);return}const m=utils_ok_1.fileUtil.getJSON(j);m.title=f.title,m.promptSimply=f.promptSimply,fs_1.default.writeFileSync(j,JSON.stringify(m,null,2),"utf-8"),console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u7ED3\u679C\u5DF2\u66F4\u65B0: ${f.title}`)}catch(d){console.error(`[${(0,session_1.timestamp)()}] \u66F4\u65B0\u4EFB\u52A1\u9884\u5904\u7406\u7ED3\u679C\u5931\u8D25:`,d)}}).catch(f=>{console.error(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5F02\u5E38:`,f)})}
14
+ `)}function truncatePrompt(t,e=80){const i=t.replace(/\n/g," ").trim();return i.length>e?i.slice(0,e)+"...":i}function taskDisplayName(t){return t.title?t.title:truncatePrompt(t.prompt)}async function preprocessTask(t,e,i){const s=(0,session_1.getConversationDir)(t,e),r="claude",a=["--permission-mode","bypassPermissions","--print"],o=(0,claude_process_1.resolveClaudeSettingsPath)(t,s);o&&a.push("--settings",o);const l=["\u8BF7\u5BF9\u4EE5\u4E0B\u4EFB\u52A1\u9700\u6C42\u8FDB\u884C\u9884\u5904\u7406\uFF0C\u751F\u6210\u7B80\u77ED\u6807\u9898\u548C\u4F18\u5316\u540E\u7684\u9700\u6C42\u63CF\u8FF0\u3002","\u76F4\u63A5\u8FD4\u56DEJSON\uFF0C\u4E0D\u8981markdown\u4EE3\u7801\u5757\u6216\u5176\u4ED6\u5185\u5BB9\u3002",'\u683C\u5F0F: {"title":"\u7B80\u77ED\u6807\u9898(15\u5B57\u4EE5\u5185)","promptSimply":"\u4F18\u5316\u540E\u7684\u9700\u6C42\u63CF\u8FF0\uFF0C\u4FDD\u7559\u539F\u59CB\u9700\u6C42\u7684\u6240\u6709\u5173\u952E\u4FE1\u606F\uFF0C\u4F7F\u63CF\u8FF0\u66F4\u6E05\u6670\u3001\u7ED3\u6784\u5316"}',"",`\u539F\u59CB\u9700\u6C42: ${i}`].join(`
15
+ `);a.push(l);const n=3e4;return new Promise(u=>{let m="";const c=(0,child_process_1.spawn)(r,a,{cwd:s,stdio:["ignore","pipe","pipe"]}),g=setTimeout(()=>{c.kill("SIGTERM"),setTimeout(()=>{try{c.kill("SIGKILL")}catch{}},3e3)},n);c.stdout.on("data",d=>{m+=d.toString()}),c.stderr.on("data",()=>{}),c.on("close",d=>{if(clearTimeout(g),d!==0||!m.trim()){console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5931\u8D25(\u9000\u51FA\u7801:${d})\uFF0C\u4F7F\u7528\u539F\u59CBprompt`),u(null);return}try{let f=m.trim();const I=f.match(/\{[\s\S]*\}/);I&&(f=I[0]);const p=JSON.parse(f);p.title&&p.promptSimply?(console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5B8C\u6210: title="${p.title}"`),u({title:String(p.title),promptSimply:String(p.promptSimply)})):(console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u8FD4\u56DE\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u4F7F\u7528\u539F\u59CBprompt`),u(null))}catch(f){console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406JSON\u89E3\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u539F\u59CBprompt: ${f}`),u(null)}}),c.on("error",d=>{clearTimeout(g),console.error(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u8FDB\u7A0B\u9519\u8BEF:`,d),u(null)})})}function countTodoTask(t){let e=0;for(const i of t.config.conversations){const s=(0,session_1.getTasksDir)(t,i.conversationId);if(fs_1.default.existsSync(s)){const a=utils_ok_1.fileUtil.dirWalker(s).filter(o=>path_1.default.basename(o)==="task.json");e+=a.length}}return e}async function getOneTodoTask(t){for(const e of t.config.conversations){const i=(0,session_1.getTasksDir)(t,e.conversationId);if(!fs_1.default.existsSync(i))continue;const r=utils_ok_1.fileUtil.dirWalker(i).filter(o=>path_1.default.basename(o)==="task.json");if(r.length===0)continue;const a=r.map(o=>{try{const l=utils_ok_1.fileUtil.getJSON(o);return l?{file:o,task:l}:null}catch{return console.error(`\u4EFB\u52A1\u6587\u4EF6\u89E3\u6790\u5931\u8D25\uFF0C\u8DF3\u8FC7: ${o}`),null}}).filter(o=>o!==null).sort((o,l)=>o.task.startTime-l.task.startTime);if(a.length>0){const{file:o,task:l}=a[0];return common_1.utils.addSuffixToFile(o,"-doing"),l}}}async function finishTask(t,e){const i=`${e}/task-doing.json`;let s;try{s=utils_ok_1.fileUtil.getJSON(i)}catch(l){console.error(`\u8BFB\u53D6\u4EFB\u52A1\u6587\u4EF6\u5931\u8D25: ${i}`,l);return}const r=`${e}/result.md`,a=fs_1.default.existsSync(r)?utils_ok_1.fileUtil.getFileStr(r):"\u62B1\u6B49,\u4EFB\u52A1\u5904\u7406\u5F02\u5E38...";await(0,messaging_1.sendDingMessage)(t,{conversationId:s.conversationId,sessionWebhook:s.sessionWebhook,atUserId:s.senderStaffId,content:a,msgType:"markdown"});const o=i.replace("-doing.json","-done.json");utils_ok_1.fileUtil.rename(i,o)}async function failTask(t,e,i){const s=`${e}/task-doing.json`;let r;try{r=utils_ok_1.fileUtil.getJSON(s)}catch(o){console.error(`\u8BFB\u53D6\u4EFB\u52A1\u6587\u4EF6\u5931\u8D25: ${s}`,o);return}await(0,messaging_1.sendDingMessage)(t,{conversationId:r.conversationId,sessionWebhook:r.sessionWebhook,atUserId:r.senderStaffId,content:`\u274C \u4EFB\u52A1\u5931\u8D25: ${taskDisplayName(r)}
16
+ \u539F\u56E0: ${i}`,msgType:"markdown"});const a=s.replace("-doing.json","-failed.json");utils_ok_1.fileUtil.rename(s,a)}async function resetTaskToTodo(t,e,i){const s=`${e}/task-doing.json`,r=`${e}/task.json`;if(!fs_1.default.existsSync(s))return!1;try{const a=utils_ok_1.fileUtil.getJSON(s),o=(a.retryCount||0)+1;if(o>=MAX_RETRY_COUNT)return console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u91CD\u8BD5\u6B21\u6570\u5DF2\u8FBE\u4E0A\u9650(${o}/${MAX_RETRY_COUNT})\uFF0C\u6807\u8BB0\u4E3A\u5931\u8D25: ${a.title||a.prompt}`),a.retryCount=o,fs_1.default.writeFileSync(s,JSON.stringify(a,null,2),"utf-8"),await failTask(t,e,`${i} (\u5DF2\u91CD\u8BD5${o}\u6B21)`),!1;a.retryCount=o,fs_1.default.writeFileSync(s,JSON.stringify(a,null,2),"utf-8"),console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E (\u91CD\u8BD5${o}/${MAX_RETRY_COUNT}): ${a.title||a.prompt}`)}catch(a){console.error(`[${(0,session_1.timestamp)()}] \u66F4\u65B0\u4EFB\u52A1\u91CD\u8BD5\u8BA1\u6570\u5931\u8D25:`,a)}return fs_1.default.existsSync(s)&&utils_ok_1.fileUtil.rename(s,r),!0}function cancelTask(t,e,i){const s=[],r=e.trim(),a=i?t.config.conversations.filter(u=>u.conversationId===i):t.config.conversations;for(const u of a){const m=(0,session_1.getTasksDir)(t,u.conversationId);if(!fs_1.default.existsSync(m))continue;const g=utils_ok_1.fileUtil.dirWalker(m).filter(d=>path_1.default.basename(d)==="task.json");for(const d of g)try{const f=utils_ok_1.fileUtil.getJSON(d);if(!f)continue;if(String(f.startTime)===r){s.push({file:d,task:f});continue}if(f.title&&f.title.includes(r)){s.push({file:d,task:f});continue}}catch{}}if(s.length===0)return`\u672A\u627E\u5230\u5339\u914D\u7684\u5F85\u529E\u4EFB\u52A1: ${r}`;let o=0;for(const{file:u,task:m}of s)try{fs_1.default.unlinkSync(u),o++,console.log(`[${(0,session_1.timestamp)()}] \u5DF2\u53D6\u6D88\u4EFB\u52A1: #${m.startTime} ${m.title||m.prompt}`)}catch(c){console.error(`[${(0,session_1.timestamp)()}] \u53D6\u6D88\u4EFB\u52A1\u5931\u8D25: ${u}`,c)}const l=s.slice(0,5).map(u=>`#${u.task.startTime} ${taskDisplayName(u.task)}`).join(`
17
+ `),n=o>5?`
18
+ ...\u5171\u53D6\u6D88 ${o} \u4E2A\u4EFB\u52A1`:"";return`\u5DF2\u53D6\u6D88 ${o} \u4E2A\u5F85\u529E\u4EFB\u52A1:
19
+ ${l}${n}`}function parseTaskCancelCommand(t){const i=t.trim().match(/^\/task\s+cancel\s+(.+)$/i);return i?i[1].trim():null}function updateCmdArgsSettings(t,e){const i=t.indexOf("--settings");i!==-1&&t.splice(i,2),e&&t.push("--settings",e)}async function handleTask(t){const e=await getOneTodoTask(t);if(!e){(0,session_1.debugLog)(t,"\u672A\u53D1\u73B0\u5F85\u529E\u4EFB\u52A1...");return}const i=(0,session_1.getConversationConfig)(t,e.conversationId),s=(0,session_1.getConversationDir)(t,e.conversationId),r=`${(0,session_1.getTasksDir)(t,e.conversationId)}/${e.startTimeStr}`;if(!fs_1.default.existsSync(r)){console.error(`\u4EFB\u52A1\u76EE\u5F55\u4E0D\u5B58\u5728: ${r}`);return}e.type!=="cron"&&await(0,messaging_1.sendDingMessage)(t,{conversationId:e.conversationId,sessionWebhook:e.sessionWebhook,atUserId:e.senderStaffId,content:`\u{1F504} \u5F00\u59CB\u5904\u7406\u4EFB\u52A1: ${taskDisplayName(e)}`});const a=`${r}/result.md`,o=`${r}/task.log`;console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u5904\u7406\u4E2D: ${e.title||e.prompt}`);const l=e.senderNickName&&e.senderStaffId?`${e.senderNickName}(${e.senderStaffId}), `:"unknown",n=t.config.apiKeyCfg,u=(0,api_key_manager_1.getForceEnabledSettingsPath)(s);let m=!1,c=null;if(u)console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 FORCE_ENABLE\uFF0C\u5F3A\u5236\u4F7F\u7528 settings-ding.json`);else if(n){if(c=(0,api_key_manager_1.pickValidApiKey)(t),!c){console.log(`[${(0,session_1.timestamp)()}] \u65E0\u53EF\u7528\u914D\u989D\uFF0C\u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E`),await resetTaskToTodo(t,r,"\u65E0\u53EF\u7528\u914D\u989D");return}m=!0,console.log(`[${(0,session_1.timestamp)()}] \u5207\u6362\u5230 API Key \u6A21\u5F0F`)}const g=i?.taskCfg?.skill,d=i?.agent,f=e.promptSimply||e.prompt,p=["--permission-mode","bypassPermissions","--print",`${g?`/${g}`:""} \u7528\u6237: ${l}, \u9700\u6C42: ${f}; \u6700\u540E\u5C06\u56DE\u590D\u5185\u5BB9\u4FDD\u5B58\u81F3: ${a}`.trim()];if(u)p.push("--settings",u);else if(m&&c){const $=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);p.push("--settings",$)}else if(!n){const $=path_1.default.join(s,".claude","settings.json");fs_1.default.existsSync($)&&(p.push("--settings",$),console.log(`[${(0,session_1.timestamp)()}] \u81EA\u52A8\u68C0\u6D4B\u5230 settings.json: ${$}`))}d&&p.push("--agent",d),(0,session_1.debugLog)(t,`\u6267\u884C\u547D\u4EE4: claude ${p.join(" ")}`);const _=20,N=1e4,F=1e4,x=300*1e3,U=60*1e3,C="claude",b=$=>{const k=Date.now();return new Promise(S=>{const v=[];let O=!1,M=Date.now();const D=(0,child_process_1.spawn)(C,$,{cwd:s,stdio:["ignore","pipe","pipe"]}),A=setInterval(()=>{if(O){clearInterval(A);return}Date.now()-M>=x&&(console.warn(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1 Watchdog: ${x/1e3}s \u65E0\u65E5\u5FD7\u8F93\u51FA\uFF0C\u901A\u77E5\u7528\u6237`),clearInterval(A),(0,messaging_1.sendDingMessage)(t,{conversationId:e.conversationId,sessionWebhook:e.sessionWebhook,atUserId:e.senderStaffId,content:`\u23F0 \u4EFB\u52A1\u8D85\u8FC7 ${x/1e3}s \u65E0\u54CD\u5E94\uFF0C\u4ECD\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u5019`}).catch(j=>console.error("\u53D1\u9001\u4EFB\u52A1 Watchdog \u901A\u77E5\u5931\u8D25:",j)))},U),P=()=>{M=Date.now()};D.stdout.on("data",T=>{const j=T.toString();process.stdout.write(j),v.push(j),P()}),D.stderr.on("data",T=>{const j=T.toString();process.stderr.write(j),v.push(j),P()}),D.on("close",T=>{O=!0,clearInterval(A),S({exitCode:T??1,output:v.join(""),elapsed:Date.now()-k})}),D.on("error",T=>{console.error("\u8FDB\u7A0B\u6267\u884C\u9519\u8BEF:",T),v.push(`\u8FDB\u7A0B\u6267\u884C\u9519\u8BEF: ${T.message}`)})})};let h,w,y=0;for(;;){const $=await b(p);if(h=$.exitCode,w=$.output,h!==0){if((0,api_key_manager_1.isQuotaExhaustedError)(w)&&n){if(m){if(c){const S=(0,api_key_manager_1.rotateApiKey)(t,c.apiKey);if(S){c=S,y=0;const v=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(p,v),console.log(`[${(0,session_1.timestamp)()}] API Key \u914D\u989D\u8017\u5C3D(429)\uFF0C\u5207\u6362\u5230\u65B0 Key: ${(0,api_key_manager_1.settingLabel)(S)}`);continue}}}else if(c=(0,api_key_manager_1.pickValidApiKey)(t),c){m=!0,y=0;const S=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(p,S),console.log(`[${(0,session_1.timestamp)()}] \u5207\u6362\u5230 API Key \u6A21\u5F0F`);continue}console.log(`[${(0,session_1.timestamp)()}] \u65E0\u53EF\u7528\u914D\u989D\uFF0C\u4EFB\u52A1\u91CD\u7F6E\u4E3A\u5F85\u529E`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${C} ${p.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,w].join(`
20
+ `);fs_1.default.writeFileSync(o,k),await resetTaskToTodo(t,r,"\u65E0\u53EF\u7528\u914D\u989D(429)");return}if((0,api_key_manager_1.isAuthenticationError)(w)){console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230\u8BA4\u8BC1\u9519\u8BEF(401)\uFF0C\u6807\u8BB0\u4EFB\u52A1\u5931\u8D25`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${C} ${p.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,w].join(`
21
+ `);fs_1.default.writeFileSync(o,k),await failTask(t,r,"\u8BA4\u8BC1\u5931\u8D25(401)\uFF0CAPI Key \u65E0\u6548\u6216\u670D\u52A1\u672A\u6388\u6743");return}if((0,claude_process_1.isRetryableApiError)(w)){if($.elapsed<F&&m&&c&&n){if(y++,y>=_){const k=(0,api_key_manager_1.rotateApiKey)(t,c.apiKey);if(k){c=k,y=0;const S=(0,api_key_manager_1.ensureSettingsWithApiKey)(s,c);updateCmdArgsSettings(p,S),console.log(`[${(0,session_1.timestamp)()}] TPM \u9650\u6D41\u8FDE\u7EED\u5FEB\u901F\u5931\u8D25 ${_} \u6B21\uFF0C\u5207\u6362\u5230\u65B0 Key: ${(0,api_key_manager_1.settingLabel)(k)}`),await utils_ok_1.asyncUtil.sleep(N);continue}}}else if($.elapsed<F){if(y++,y>=_){console.log(`[${(0,session_1.timestamp)()}] TPM \u9650\u6D41\u5FEB\u901F\u5931\u8D25\u8FDE\u7EED${_}\u6B21\uFF0C\u91CD\u7F6E\u4EFB\u52A1\u4E3A\u5F85\u529E`);const k=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${C} ${p.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,w].join(`
22
+ `);fs_1.default.writeFileSync(o,k),await resetTaskToTodo(t,r,"TPM\u9650\u6D41\u5FEB\u901F\u5931\u8D25\u6B21\u6570\u8FC7\u591A");return}console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 TPM \u9650\u6D41(\u5FEB\u901F\u5931\u8D25)\uFF0C${N/1e3}s \u540E\u91CD\u8BD5 (${y}/${_})`)}else y=0,console.log(`[${(0,session_1.timestamp)()}] \u68C0\u6D4B\u5230 TPM \u9650\u6D41(\u8FDB\u7A0B\u5DF2\u8FD0\u884C\u4E00\u6BB5\u65F6\u95F4)\uFF0C\u91CD\u7F6E\u5FEB\u901F\u5931\u8D25\u8BA1\u6570\uFF0C${N/1e3}s \u540E\u91CD\u8BD5`);await utils_ok_1.asyncUtil.sleep(N);continue}}break}const W=[`[${(0,session_1.timestamp)()}] \u6267\u884C\u547D\u4EE4: ${C} ${p.join(" ")}`,`[${(0,session_1.timestamp)()}] \u9000\u51FA\u7801: ${h}`,w].join(`
23
+ `);if(fs_1.default.writeFileSync(o,W),h!==0){console.error(`\u547D\u4EE4\u6267\u884C\u5931\u8D25, \u9000\u51FA\u7801: ${h}`),await failTask(t,r,`\u6267\u884C\u5931\u8D25(\u9000\u51FA\u7801: ${h})`);return}if(fs_1.default.existsSync(a))console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u5904\u7406\u5B8C\u6210`);else{console.error("\u4EFB\u52A1\u672A\u6309\u9884\u671F\u5904\u7406"),await failTask(t,r,"\u672A\u751F\u6210\u7ED3\u679C\u6587\u4EF6");return}await finishTask(t,r)}async function runTaskHandlerLoop(t){for(;;)await handleTask(t).catch(e=>console.error(e)),await utils_ok_1.asyncUtil.sleep(1e4)}async function saveTask(t,e){const{conversationId:i,prompt:s,senderStaffId:r,senderNickName:a,sessionWebhook:o,type:l="normal"}=e,n=Date.now(),u=utils_ok_1.dateUtil.mm(n).format("YYYY-MM-DD-HH-mm-ss"),m=`${(0,session_1.getTasksDir)(t,i)}/${u}`,c=`${m}/task.json`,g={conversationId:i,startTime:n,startTimeStr:u,prompt:s,senderStaffId:r,senderNickName:a||"",sessionWebhook:o,type:l};await utils_ok_1.fileUtil.saveFileStr(JSON.stringify(g,null,2),c),(0,session_1.debugLog)(t,`\u4EFB\u52A1\u5DF2\u4FDD\u5B58: ${c}`),preprocessTask(t,i,s).then(d=>{if(d)try{const f=`${m}/task-doing.json`,I=fs_1.default.existsSync(f)?f:fs_1.default.existsSync(c)?c:null;if(!I){console.log(`[${(0,session_1.timestamp)()}] \u9884\u5904\u7406\u5B8C\u6210\u4F46\u4EFB\u52A1\u6587\u4EF6\u5DF2\u4E0D\u5B58\u5728: ${m}`);return}const p=utils_ok_1.fileUtil.getJSON(I);p.title=d.title,p.promptSimply=d.promptSimply,fs_1.default.writeFileSync(I,JSON.stringify(p,null,2),"utf-8"),console.log(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u7ED3\u679C\u5DF2\u66F4\u65B0: ${d.title}`)}catch(f){console.error(`[${(0,session_1.timestamp)()}] \u66F4\u65B0\u4EFB\u52A1\u9884\u5904\u7406\u7ED3\u679C\u5931\u8D25:`,f)}}).catch(d=>{console.error(`[${(0,session_1.timestamp)()}] \u4EFB\u52A1\u9884\u5904\u7406\u5F02\u5E38:`,d)})}
@@ -1,8 +1,8 @@
1
- "use strict";var __importDefault=this&&this.__importDefault||function(n){return n&&n.__esModule?n:{default:n}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.TodoEngine=void 0,exports.loadTodoData=loadTodoData,exports.getSortedTodoItems=getSortedTodoItems,exports.addTodoItem=addTodoItem,exports.doneTodoItem=doneTodoItem,exports.deleteTodoItem=deleteTodoItem,exports.clearAllTodoItems=clearAllTodoItems,exports.getReminderHour=getReminderHour,exports.setReminderHour=setReminderHour,exports.formatDate=formatDate,exports.getDefaultDeadline=getDefaultDeadline,exports.parseDeadline=parseDeadline,exports.formatDeadlineDisplay=formatDeadlineDisplay,exports.formatTodoList=formatTodoList,exports.formatTodoItemCreated=formatTodoItemCreated;const fs_1=__importDefault(require("fs")),utils_ok_1=require("utils-ok"),session_1=require("./session"),messaging_1=require("./messaging");function getTodoFile(n){return`${(0,session_1.getClientDir)(n)}/todo.json`}function loadTodoData(n){const e=getTodoFile(n);try{const o=fs_1.default.readFileSync(e,"utf-8"),t=JSON.parse(o);return{conversations:t.conversations&&typeof t.conversations=="object"?t.conversations:{},reminders:t.reminders&&typeof t.reminders=="object"?t.reminders:{}}}catch{return{conversations:{},reminders:{}}}}function saveTodoData(n,e){const o=getTodoFile(n);fs_1.default.writeFileSync(o,JSON.stringify(e,null,2),"utf-8")}function sortTodoItems(n){const e=n.filter(t=>!t.completed).sort(todoSortByDeadline),o=n.filter(t=>t.completed).sort((t,s)=>(s.completedAt||"").localeCompare(t.completedAt||""));return[...e,...o]}function getSortedTodoItems(n,e){const o=loadTodoData(n);return sortTodoItems(o.conversations[e]||[])}function todoSortByDeadline(n,e){return!n.deadline&&!e.deadline?0:n.deadline?e.deadline?n.deadline.localeCompare(e.deadline):-1:1}function addTodoItem(n,e,o){const t=loadTodoData(n);t.conversations[e]||(t.conversations[e]=[]);const s={content:o.content,assigneeStaffId:o.assigneeStaffId,assigneeNick:o.assigneeNick,deadline:o.deadline,createdAt:utils_ok_1.dateUtil.mm(Date.now()).format("YYYY-MM-DD HH:mm:ss"),completed:!1};return t.conversations[e].push(s),saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u6DFB\u52A0\u5F85\u529E in ${e}: ${o.content}`),s}function doneTodoItem(n,e,o){const t=loadTodoData(n),s=t.conversations[e]||[],r=sortTodoItems(s);if(r.length===0)return{success:!1,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};if(o<1||o>r.length)return{success:!1,error:`\u5E8F\u53F7\u65E0\u6548\uFF0C\u8303\u56F4 1-${r.length}`};const i=r[o-1];if(i.completed)return{success:!1,error:`#${o} \u5DF2\u5B8C\u6210`};const c=s.findIndex(l=>l.content===i.content&&l.createdAt===i.createdAt&&l.assigneeStaffId===i.assigneeStaffId);return c===-1?{success:!1,error:"\u672A\u627E\u5230\u5F85\u529E\u9879"}:(s[c].completed=!0,s[c].completedAt=(0,session_1.timestamp)(),saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u5B8C\u6210\u5F85\u529E in ${e}: ${i.content}`),{success:!0,item:i})}function deleteTodoItem(n,e,o){const t=loadTodoData(n),s=t.conversations[e]||[],r=sortTodoItems(s);if(r.length===0)return{success:!1,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};if(o<1||o>r.length)return{success:!1,error:`\u5E8F\u53F7\u65E0\u6548\uFF0C\u8303\u56F4 1-${r.length}`};const i=r[o-1],c=s.findIndex(u=>u.content===i.content&&u.createdAt===i.createdAt&&u.assigneeStaffId===i.assigneeStaffId);if(c===-1)return{success:!1,error:"\u672A\u627E\u5230\u5F85\u529E\u9879"};const[l]=s.splice(c,1);return s.length===0&&delete t.conversations[e],saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u5220\u9664\u5F85\u529E in ${e}: ${l.content}`),{success:!0,item:l}}function clearAllTodoItems(n,e){const o=loadTodoData(n),t=o.conversations[e]||[];if(t.length===0)return{success:!1,count:0,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};const s=t.length;return delete o.conversations[e],saveTodoData(n,o),console.log(`[${(0,session_1.timestamp)()}] [todo] \u6E05\u7A7A\u5F85\u529E in ${e}: ${s} \u6761`),{success:!0,count:s}}function getReminderHour(n,e){const t=loadTodoData(n).reminders?.[e];return t===!1?null:typeof t=="number"?t:10}function setReminderHour(n,e,o){const t=loadTodoData(n);t.reminders||(t.reminders={}),o===null?t.reminders[e]=!1:t.reminders[e]=o,saveTodoData(n,t)}function addDays(n,e){const o=new Date(n);return o.setDate(o.getDate()+e),o}function formatDate(n){const e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),t=String(n.getDate()).padStart(2,"0");return`${e}-${o}-${t}`}function getNextWeekday(n,e,o){const t=n.getDay()===0?7:n.getDay();let s=e-t;return o?s<=0&&(s+=7):(s<0&&(s+=7),s===0&&(s=7)),formatDate(addDays(n,s))}function getDefaultDeadline(){return formatDate(addDays(new Date,7))}function parseDeadline(n){const e=new Date,o=new Date(e.getFullYear(),e.getMonth(),e.getDate()),t=n.trim(),s=t.match(/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/);if(s)return`${s[1]}-${s[2].padStart(2,"0")}-${s[3].padStart(2,"0")}`;const r=t.match(/^(\d{1,2})[-/](\d{1,2})$/);if(r){const a=parseInt(r[1],10),f=parseInt(r[2],10);let m=new Date(e.getFullYear(),a-1,f);return m<o&&(m=new Date(e.getFullYear()+1,a-1,f)),formatDate(m)}const i=t.match(/^(\d{2})(\d{2})$/);if(i){const a=parseInt(i[1],10),f=parseInt(i[2],10);if(a>=1&&a<=12&&f>=1&&f<=31){let m=new Date(e.getFullYear(),a-1,f);return m<o&&(m=new Date(e.getFullYear()+1,a-1,f)),formatDate(m)}}const c={\u4E00:1,\u4E8C:2,\u4E09:3,\u56DB:4,\u4E94:5,\u516D:6,\u65E5:7,\u5929:7};if(t==="\u4ECA\u5929")return formatDate(o);if(t==="\u660E\u5929")return formatDate(addDays(o,1));if(t==="\u540E\u5929")return formatDate(addDays(o,2));if(t==="\u5927\u540E\u5929")return formatDate(addDays(o,3));const l=t.match(/^(这|下)周([一二三四五六日天])$/);if(l){const a=c[l[2]];if(a!==void 0)return getNextWeekday(o,a,l[1]==="\u4E0B")}const u=t.match(/^(?:周|星期)([一二三四五六日天])$/);if(u){const a=c[u[1]];if(a!==void 0)return getNextWeekday(o,a,!1)}return""}function getDeadlineDiffDays(n){const e=new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()),o=new Date(n+"T00:00:00");return Math.floor((o.getTime()-e.getTime())/(1440*60*1e3))}function formatDeadlineDisplay(n){if(!n)return"";const e=getDeadlineDiffDays(n);return e<0?`${n} \u{1F534}\u5DF2\u903E\u671F${Math.abs(e)}\u5929`:e===0?`${n} \u26A1\u4ECA\u5929`:e===1?`${n} \u{1F7E1}\u660E\u5929`:e<=3?`${n} \u{1F7E1}${e}\u5929\u540E`:e<=7?`${n} ${e}\u5929\u540E`:n}function formatTodoList(n,e){if(n.length===0)return`\u{1F4ED} \u6682\u65E0\u5F85\u529E\u4E8B\u9879${e===null?"":`
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(n){return n&&n.__esModule?n:{default:n}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.TodoEngine=void 0,exports.loadTodoData=loadTodoData,exports.getSortedTodoItems=getSortedTodoItems,exports.addTodoItem=addTodoItem,exports.doneTodoItem=doneTodoItem,exports.deleteTodoItem=deleteTodoItem,exports.clearAllTodoItems=clearAllTodoItems,exports.getReminderHour=getReminderHour,exports.setReminderHour=setReminderHour,exports.getIdMode=getIdMode,exports.setIdMode=setIdMode,exports.formatDate=formatDate,exports.getDefaultDeadline=getDefaultDeadline,exports.parseDeadline=parseDeadline,exports.formatDeadlineDisplay=formatDeadlineDisplay,exports.formatTodoList=formatTodoList,exports.formatTodoItemCreated=formatTodoItemCreated;const fs_1=__importDefault(require("fs")),utils_ok_1=require("utils-ok"),session_1=require("./session"),messaging_1=require("./messaging");function getTodoFile(n){return`${(0,session_1.getClientDir)(n)}/todo.json`}function loadTodoData(n){const e=getTodoFile(n);try{const o=fs_1.default.readFileSync(e,"utf-8"),t=JSON.parse(o);return{conversations:t.conversations&&typeof t.conversations=="object"?t.conversations:{},reminders:t.reminders&&typeof t.reminders=="object"?t.reminders:{},idModes:t.idModes&&typeof t.idModes=="object"?t.idModes:{}}}catch{return{conversations:{},reminders:{},idModes:{}}}}function saveTodoData(n,e){const o=getTodoFile(n);fs_1.default.writeFileSync(o,JSON.stringify(e,null,2),"utf-8")}function sortTodoItems(n){const e=n.filter(t=>!t.completed).sort(todoSortByDeadline),o=n.filter(t=>t.completed).sort((t,s)=>(s.completedAt||"").localeCompare(t.completedAt||""));return[...e,...o]}function getSortedTodoItems(n,e){const o=loadTodoData(n);return sortTodoItems(o.conversations[e]||[])}function todoSortByDeadline(n,e){return!n.deadline&&!e.deadline?0:n.deadline?e.deadline?n.deadline.localeCompare(e.deadline):-1:1}function addTodoItem(n,e,o){const t=loadTodoData(n);t.conversations[e]||(t.conversations[e]=[]);const s={content:o.content,assigneeStaffId:o.assigneeStaffId,assigneeNick:o.assigneeNick,deadline:o.deadline,createdAt:utils_ok_1.dateUtil.mm(Date.now()).format("YYYY-MM-DD HH:mm:ss"),completed:!1,assigneeIdType:o.assigneeIdType||"staffId"};return t.conversations[e].push(s),saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u6DFB\u52A0\u5F85\u529E in ${e}: ${o.content}`),s}function doneTodoItem(n,e,o){const t=loadTodoData(n),s=t.conversations[e]||[],r=sortTodoItems(s);if(r.length===0)return{success:!1,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};if(o<1||o>r.length)return{success:!1,error:`\u5E8F\u53F7\u65E0\u6548\uFF0C\u8303\u56F4 1-${r.length}`};const i=r[o-1];if(i.completed)return{success:!1,error:`#${o} \u5DF2\u5B8C\u6210`};const a=s.findIndex(l=>l.content===i.content&&l.createdAt===i.createdAt&&l.assigneeStaffId===i.assigneeStaffId);return a===-1?{success:!1,error:"\u672A\u627E\u5230\u5F85\u529E\u9879"}:(s[a].completed=!0,s[a].completedAt=(0,session_1.timestamp)(),saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u5B8C\u6210\u5F85\u529E in ${e}: ${i.content}`),{success:!0,item:i})}function deleteTodoItem(n,e,o){const t=loadTodoData(n),s=t.conversations[e]||[],r=sortTodoItems(s);if(r.length===0)return{success:!1,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};if(o<1||o>r.length)return{success:!1,error:`\u5E8F\u53F7\u65E0\u6548\uFF0C\u8303\u56F4 1-${r.length}`};const i=r[o-1],a=s.findIndex(u=>u.content===i.content&&u.createdAt===i.createdAt&&u.assigneeStaffId===i.assigneeStaffId);if(a===-1)return{success:!1,error:"\u672A\u627E\u5230\u5F85\u529E\u9879"};const[l]=s.splice(a,1);return s.length===0&&delete t.conversations[e],saveTodoData(n,t),console.log(`[${(0,session_1.timestamp)()}] [todo] \u5220\u9664\u5F85\u529E in ${e}: ${l.content}`),{success:!0,item:l}}function clearAllTodoItems(n,e){const o=loadTodoData(n),t=o.conversations[e]||[];if(t.length===0)return{success:!1,count:0,error:"\u5F53\u524D\u65E0\u5F85\u529E\u4E8B\u9879"};const s=t.length;return delete o.conversations[e],saveTodoData(n,o),console.log(`[${(0,session_1.timestamp)()}] [todo] \u6E05\u7A7A\u5F85\u529E in ${e}: ${s} \u6761`),{success:!0,count:s}}function getReminderHour(n,e){const t=loadTodoData(n).reminders?.[e];return t===!1?null:typeof t=="number"?t:10}function setReminderHour(n,e,o){const t=loadTodoData(n);t.reminders||(t.reminders={}),o===null?t.reminders[e]=!1:t.reminders[e]=o,saveTodoData(n,t)}function getIdMode(n,e){return loadTodoData(n).idModes?.[e]||"staffId"}function setIdMode(n,e,o){const t=loadTodoData(n);t.idModes||(t.idModes={}),t.idModes[e]=o,saveTodoData(n,t)}function addDays(n,e){const o=new Date(n);return o.setDate(o.getDate()+e),o}function formatDate(n){const e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),t=String(n.getDate()).padStart(2,"0");return`${e}-${o}-${t}`}function getNextWeekday(n,e,o){const t=n.getDay()===0?7:n.getDay();let s=e-t;return o?s<=0&&(s+=7):(s<0&&(s+=7),s===0&&(s=7)),formatDate(addDays(n,s))}function getDefaultDeadline(){return formatDate(addDays(new Date,7))}function parseDeadline(n){const e=new Date,o=new Date(e.getFullYear(),e.getMonth(),e.getDate()),t=n.trim(),s=t.match(/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/);if(s)return`${s[1]}-${s[2].padStart(2,"0")}-${s[3].padStart(2,"0")}`;const r=t.match(/^(\d{1,2})[-/](\d{1,2})$/);if(r){const c=parseInt(r[1],10),f=parseInt(r[2],10);let m=new Date(e.getFullYear(),c-1,f);return m<o&&(m=new Date(e.getFullYear()+1,c-1,f)),formatDate(m)}const i=t.match(/^(\d{2})(\d{2})$/);if(i){const c=parseInt(i[1],10),f=parseInt(i[2],10);if(c>=1&&c<=12&&f>=1&&f<=31){let m=new Date(e.getFullYear(),c-1,f);return m<o&&(m=new Date(e.getFullYear()+1,c-1,f)),formatDate(m)}}const a={\u4E00:1,\u4E8C:2,\u4E09:3,\u56DB:4,\u4E94:5,\u516D:6,\u65E5:7,\u5929:7};if(t==="\u4ECA\u5929")return formatDate(o);if(t==="\u660E\u5929")return formatDate(addDays(o,1));if(t==="\u540E\u5929")return formatDate(addDays(o,2));if(t==="\u5927\u540E\u5929")return formatDate(addDays(o,3));const l=t.match(/^(这|下)周([一二三四五六日天])$/);if(l){const c=a[l[2]];if(c!==void 0)return getNextWeekday(o,c,l[1]==="\u4E0B")}const u=t.match(/^(?:周|星期)([一二三四五六日天])$/);if(u){const c=a[u[1]];if(c!==void 0)return getNextWeekday(o,c,!1)}return""}function getDeadlineDiffDays(n){const e=new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()),o=new Date(n+"T00:00:00");return Math.floor((o.getTime()-e.getTime())/(1440*60*1e3))}function formatDeadlineDisplay(n){if(!n)return"";const e=getDeadlineDiffDays(n);return e<0?`${n} \u{1F534}\u5DF2\u903E\u671F${Math.abs(e)}\u5929`:e===0?`${n} \u26A1\u4ECA\u5929`:e===1?`${n} \u{1F7E1}\u660E\u5929`:e<=3?`${n} \u{1F7E1}${e}\u5929\u540E`:e<=7?`${n} ${e}\u5929\u540E`:n}function formatTodoList(n,e){if(n.length===0)return`\u{1F4ED} \u6682\u65E0\u5F85\u529E\u4E8B\u9879${e===null?"":`
2
2
  \u23F0 \u6BCF\u65E5\u63D0\u9192: ${e}:00`}
3
3
 
4
- \u{1F4A1} \`/todo <\u5185\u5BB9> ddl \u660E\u5929\` \u6DFB\u52A0\uFF08\u9ED8\u8BA47\u5929\u5230\u671F\uFF09`;const o=n.filter(r=>!r.completed),t=n.filter(r=>r.completed),s=[];if(o.length>0){s.push("### \u{1F4CB} \u8FDB\u884C\u4E2D","");for(let r=0;r<o.length;r++){const i=o[r],c=i.deadline?` \u{1F4C5}${formatDeadlineDisplay(i.deadline)}`:"";s.push(`${r+1}. ${i.content} _@${i.assigneeNick}_${c}`)}}if(t.length>0){o.length>0&&s.push(""),s.push("### \u2705 \u5DF2\u5B8C\u6210","");for(let r=0;r<t.length;r++){const i=t[r],c=o.length+r+1;s.push(`${c}. ~~${i.content}~~ _@${i.assigneeNick}_`)}}if(s.push("","---","\u{1F4A1} `/todo done <\u5E8F\u53F7>` \u5B8C\u6210 | `/todo rm <\u5E8F\u53F7>` \u5220\u9664 | `/todo <\u5185\u5BB9> ddl \u660E\u5929`"),e!==void 0){const r=e===null?"\u23F0 \u6BCF\u65E5\u63D0\u9192: \u5DF2\u5173\u95ED":`\u23F0 \u6BCF\u65E5\u63D0\u9192: ${e}:00`;s.push(r)}return s.join(`
4
+ \u{1F4A1} \`/todo <\u5185\u5BB9> ddl \u660E\u5929\` \u6DFB\u52A0\uFF08\u9ED8\u8BA47\u5929\u5230\u671F\uFF09`;const o=n.filter(r=>!r.completed),t=n.filter(r=>r.completed),s=[];if(o.length>0){s.push("### \u{1F4CB} \u8FDB\u884C\u4E2D","");for(let r=0;r<o.length;r++){const i=o[r],a=i.deadline?` \u{1F4C5}${formatDeadlineDisplay(i.deadline)}`:"";s.push(`${r+1}. ${i.content} _@${i.assigneeNick}_${a}`)}}if(t.length>0){o.length>0&&s.push(""),s.push("### \u2705 \u5DF2\u5B8C\u6210","");for(let r=0;r<t.length;r++){const i=t[r],a=o.length+r+1;s.push(`${a}. ~~${i.content}~~ _@${i.assigneeNick}_`)}}if(s.push("","---","\u{1F4A1} `/todo done <\u5E8F\u53F7>` \u5B8C\u6210 | `/todo rm <\u5E8F\u53F7>` \u5220\u9664 | `/todo <\u5185\u5BB9> ddl \u660E\u5929`"),e!==void 0){const r=e===null?"\u23F0 \u6BCF\u65E5\u63D0\u9192: \u5DF2\u5173\u95ED":`\u23F0 \u6BCF\u65E5\u63D0\u9192: ${e}:00`;s.push(r)}return s.join(`
5
5
  `)}function formatTodoItemCreated(n,e){const o=n.deadline?`
6
6
  - **\u622A\u6B62:** ${formatDeadlineDisplay(n.deadline)}`:"";return[`\u2705 \u5DF2\u6DFB\u52A0\u5F85\u529E #${e}`,"",`- **\u5185\u5BB9:** ${n.content}`,`- **\u8D1F\u8D23\u4EBA:** @${n.assigneeNick}${o}`].join(`
7
- `)}const AUTO_CLEAN_DAYS=1;class TodoEngine{constructor(e){this.timer=null,this.dc=e}start(){this.scheduleNext(),console.log(`[${(0,session_1.timestamp)()}] Todo\u5F15\u64CE\u5DF2\u542F\u52A8`)}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}scheduleNext(){const e=new Date,o=this.findNextReminderHour(e),t=new Date(e.getFullYear(),e.getMonth(),e.getDate(),o,0,0,0);t.getTime()<=e.getTime()&&t.setDate(t.getDate()+1);const s=t.getTime()-e.getTime();this.timer=setTimeout(()=>{console.log(`[${(0,session_1.timestamp)()}] [todo] \u5B9A\u65F6\u89E6\u53D1 (${o}:00)`),this.cleanExpiredItems(),this.sendReminders(o),this.scheduleNext()},s),console.log(`[${(0,session_1.timestamp)()}] [todo] \u4E0B\u6B21\u89E6\u53D1: ${t.toISOString()}`)}findNextReminderHour(e){const o=e.getHours(),t=loadTodoData(this.dc),s=new Set;for(const i of Object.keys(t.reminders)){const c=t.reminders[i];if(c!==!1){if(typeof c=="number"){s.add(c);continue}s.add(10)}}s.size===0&&s.add(10);const r=Array.from(s).sort((i,c)=>i-c);for(const i of r)if(i>o)return i;return r[0]}cleanExpiredItems(){const e=loadTodoData(this.dc),o=Date.now();let t=0;for(const s of Object.keys(e.conversations)){const r=e.conversations[s],i=r.length,c=r.filter(l=>{if(!l.completed||!l.completedAt)return!0;const u=new Date(l.completedAt).getTime();return isNaN(u)?!0:(o-u)/(1440*60*1e3)<AUTO_CLEAN_DAYS});c.length<i&&(e.conversations[s]=c,t+=i-c.length,c.length===0&&delete e.conversations[s])}t>0&&(saveTodoData(this.dc,e),console.log(`[${(0,session_1.timestamp)()}] [todo] \u81EA\u52A8\u6E05\u7406 ${t} \u6761\u5DF2\u5B8C\u6210\u5F85\u529E`))}async sendReminders(e){const o=loadTodoData(this.dc),t=Object.keys(o.conversations);for(const s of t){const r=o.reminders?.[s];if((r===!1?null:typeof r=="number"?r:10)!==e)continue;const c=(o.conversations[s]||[]).filter(d=>!d.completed);if(c.length===0)continue;const l=this.dc.getConversationConfig(s);if(!l||!(l.dingToken||this.dc.config.defaultDingToken||this.dc.config.ownerConversationId))continue;const u=[],a=[];for(const d of c){if(!d.deadline)continue;const g=getDeadlineDiffDays(d.deadline);g<0?u.push(d):g<=3&&a.push(d)}if(u.length===0&&a.length===0)continue;const f=["### \u23F0 \u6BCF\u65E5\u5F85\u529E\u63D0\u9192",""],m=new Set;if(u.length>0){f.push("\u{1F534} **\u5DF2\u903E\u671F:**");for(const d of u)f.push(`- ${d.content} _@${d.assigneeNick}_ \u{1F4C5}${formatDeadlineDisplay(d.deadline)}`),m.add(d.assigneeStaffId);f.push("")}if(a.length>0){f.push("\u{1F7E1} **\u5373\u5C06\u5230\u671F (3\u5929\u5185):**");for(const d of a)f.push(`- ${d.content} _@${d.assigneeNick}_ \u{1F4C5}${formatDeadlineDisplay(d.deadline)}`),m.add(d.assigneeStaffId);f.push("")}f.push("---"),f.push("\u{1F4A1} `/todo done <\u5E8F\u53F7>` \u5B8C\u6210 | `/todo` \u67E5\u770B\u5168\u90E8");try{await(0,messaging_1.sendDingMessage)(this.dc,{conversationId:s,sessionWebhook:"",content:f.join(`
8
- `),msgType:"markdown"}),console.log(`[${(0,session_1.timestamp)()}] [todo] \u5DF2\u53D1\u9001\u63D0\u9192\u5230 ${s}, \u6D89\u53CA ${m.size} \u4EBA`)}catch(d){console.error(`[${(0,session_1.timestamp)()}] [todo] \u53D1\u9001\u63D0\u9192\u5931\u8D25 ${s}:`,d)}}}}exports.TodoEngine=TodoEngine;
7
+ `)}const AUTO_CLEAN_DAYS=1;class TodoEngine{constructor(e){this.timer=null,this.dc=e}start(){this.scheduleNext(),console.log(`[${(0,session_1.timestamp)()}] Todo\u5F15\u64CE\u5DF2\u542F\u52A8`)}destroy(){this.timer&&(clearTimeout(this.timer),this.timer=null)}scheduleNext(){const e=new Date,o=this.findNextReminderHour(e),t=new Date(e.getFullYear(),e.getMonth(),e.getDate(),o,0,0,0);t.getTime()<=e.getTime()&&t.setDate(t.getDate()+1);const s=t.getTime()-e.getTime();this.timer=setTimeout(()=>{console.log(`[${(0,session_1.timestamp)()}] [todo] \u5B9A\u65F6\u89E6\u53D1 (${o}:00)`),this.cleanExpiredItems(),this.sendReminders(o),this.scheduleNext()},s),console.log(`[${(0,session_1.timestamp)()}] [todo] \u4E0B\u6B21\u89E6\u53D1: ${t.toISOString()}`)}findNextReminderHour(e){const o=e.getHours(),t=loadTodoData(this.dc),s=new Set;for(const i of Object.keys(t.reminders)){const a=t.reminders[i];if(a!==!1){if(typeof a=="number"){s.add(a);continue}s.add(10)}}s.size===0&&s.add(10);const r=Array.from(s).sort((i,a)=>i-a);for(const i of r)if(i>o)return i;return r[0]}cleanExpiredItems(){const e=loadTodoData(this.dc),o=Date.now();let t=0;for(const s of Object.keys(e.conversations)){const r=e.conversations[s],i=r.length,a=r.filter(l=>{if(!l.completed||!l.completedAt)return!0;const u=new Date(l.completedAt).getTime();return isNaN(u)?!0:(o-u)/(1440*60*1e3)<AUTO_CLEAN_DAYS});a.length<i&&(e.conversations[s]=a,t+=i-a.length,a.length===0&&delete e.conversations[s])}t>0&&(saveTodoData(this.dc,e),console.log(`[${(0,session_1.timestamp)()}] [todo] \u81EA\u52A8\u6E05\u7406 ${t} \u6761\u5DF2\u5B8C\u6210\u5F85\u529E`))}async sendReminders(e){const o=loadTodoData(this.dc),t=Object.keys(o.conversations);for(const s of t){const r=o.reminders?.[s];if((r===!1?null:typeof r=="number"?r:10)!==e)continue;const a=(o.conversations[s]||[]).filter(d=>!d.completed);if(a.length===0)continue;const l=this.dc.getConversationConfig(s);if(!l||!(l.dingToken||this.dc.config.defaultDingToken||this.dc.config.ownerConversationId))continue;const u=[],c=[];for(const d of a){if(!d.deadline)continue;const g=getDeadlineDiffDays(d.deadline);g<0?u.push(d):g<=3&&c.push(d)}if(u.length===0&&c.length===0)continue;const f=["### \u23F0 \u6BCF\u65E5\u5F85\u529E\u63D0\u9192",""],m=[];let p=!1;if(u.length>0){f.push("\u{1F534} **\u5DF2\u903E\u671F:**");for(const d of u)f.push(`- ${d.content} _@${d.assigneeNick}_ \u{1F4C5}${formatDeadlineDisplay(d.deadline)}`),d.assigneeIdType==="dingtalkId"?p=!0:m.push(d.assigneeStaffId);f.push("")}if(c.length>0){f.push("\u{1F7E1} **\u5373\u5C06\u5230\u671F (3\u5929\u5185):**");for(const d of c)f.push(`- ${d.content} _@${d.assigneeNick}_ \u{1F4C5}${formatDeadlineDisplay(d.deadline)}`),d.assigneeIdType==="dingtalkId"?p=!0:m.push(d.assigneeStaffId);f.push("")}if(p){const d=u.concat(c).filter(g=>g.assigneeIdType==="dingtalkId").map(g=>`@${g.assigneeStaffId}`);f.push(d.join(" ")),f.push("")}f.push("---"),f.push("\u{1F4A1} `/todo done <\u5E8F\u53F7>` \u5B8C\u6210 | `/todo` \u67E5\u770B\u5168\u90E8");try{await(0,messaging_1.sendDingMessage)(this.dc,{conversationId:s,sessionWebhook:"",content:f.join(`
8
+ `),msgType:"markdown",atUserId:m.length>0?m[0]:""})}catch(d){console.error(`[${(0,session_1.timestamp)()}] [todo] \u53D1\u9001\u63D0\u9192\u5931\u8D25 ${s}:`,d)}}}}exports.TodoEngine=TodoEngine;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-ding",
3
- "version": "0.3.0-beta.1",
3
+ "version": "0.3.1",
4
4
  "description": "本地Claude对接钉钉机器人工具套件",
5
5
  "keywords": [
6
6
  "cli",
@@ -13,7 +13,7 @@
13
13
  "dotenv": "^16.6.1",
14
14
  "shelljs": "^0.10.0",
15
15
  "urllib": "^4.9.0",
16
- "utils-ok": "^1.1.2"
16
+ "utils-ok": "^2.0.0"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/chai": "^5.2.3",
@@ -42,7 +42,7 @@
42
42
  "scripts": {
43
43
  "lint": "eslint . && tsc && npm run blacklint",
44
44
  "lint:fix": "eslint . --fix",
45
- "blacklint": "utils-ok blacklint -bd 'src bin'",
45
+ "blacklint": "utils-ok blacklint --blacklintDir 'src bin'",
46
46
  "test": "mocha 'test/**/*.test.ts'",
47
47
  "build": "npm run lint && sh build.sh",
48
48
  "prepublishOnly": "npm run build"