cc-ding 0.1.0 → 0.3.0-beta

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.
@@ -0,0 +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?"":`
2
+ \u23F0 \u6BCF\u65E5\u63D0\u9192: ${e}:00`}
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(`
5
+ `)}function formatTodoItemCreated(n,e){const o=n.deadline?`
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-ding",
3
- "version": "0.1.0",
3
+ "version": "0.3.0-beta",
4
4
  "description": "本地Claude对接钉钉机器人工具套件",
5
5
  "keywords": [
6
6
  "cli",