@lih-x-x/kmr 1.0.19 → 1.0.21

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/index.js CHANGED
@@ -335,6 +335,19 @@ var Messenger = class {
335
335
  }
336
336
  await this.replyText(messageId, lines.join("\n"));
337
337
  }
338
+ /**
339
+ * 主动向指定用户发送消息(不需要先收到消息)
340
+ */
341
+ async sendToUser(openId, text) {
342
+ await this.client.im.message.create({
343
+ params: { receive_id_type: "open_id" },
344
+ data: {
345
+ receive_id: openId,
346
+ content: JSON.stringify({ text }),
347
+ msg_type: "text"
348
+ }
349
+ });
350
+ }
338
351
  };
339
352
 
340
353
  // src/lark/router.ts
@@ -1053,6 +1066,24 @@ var TaskCreator = class {
1053
1066
  console.log(`[task] \u4EFB\u52A1\u521B\u5EFA\u6210\u529F: taskId=${taskId}`);
1054
1067
  return { taskId, url };
1055
1068
  }
1069
+ /**
1070
+ * 查询飞书任务的最新状态
1071
+ */
1072
+ async getTaskStatus(taskId) {
1073
+ try {
1074
+ const response = await this.client.task.v2.task.get({
1075
+ path: { task_guid: taskId }
1076
+ });
1077
+ const task = response.data?.task;
1078
+ if (!task) return null;
1079
+ const completedAt = task.completed_at || "";
1080
+ const status = completedAt ? "completed" : "open";
1081
+ return { status, completedAt: completedAt || void 0 };
1082
+ } catch (err) {
1083
+ console.error(`[task-sync] \u67E5\u8BE2\u4EFB\u52A1\u72B6\u6001\u5931\u8D25: taskId=${taskId}`, err.message);
1084
+ return null;
1085
+ }
1086
+ }
1056
1087
  };
1057
1088
 
1058
1089
  // src/lark/userResolver.ts
@@ -1310,5 +1341,39 @@ async function main() {
1310
1341
  openBrowser(`http://localhost:${port}`);
1311
1342
  console.log(`KMR Web \u754C\u9762\u5DF2\u542F\u52A8: http://localhost:${port}`);
1312
1343
  console.log("KMR \u670D\u52A1\u5DF2\u542F\u52A8\uFF0C\u7B49\u5F85\u98DE\u4E66\u6D88\u606F...");
1344
+ if (config.lark.adminOpenId) {
1345
+ messenger.sendToUser(config.lark.adminOpenId, "\u2705 KMR \u670D\u52A1\u5DF2\u542F\u52A8").catch((err) => {
1346
+ console.error("[notify] \u5411\u7BA1\u7406\u5458\u63A8\u9001\u542F\u52A8\u901A\u77E5\u5931\u8D25:", err.message);
1347
+ });
1348
+ }
1349
+ async function syncTaskStatuses() {
1350
+ console.log("[task-sync] \u5F00\u59CB\u540C\u6B65\u98DE\u4E66\u4EFB\u52A1\u72B6\u6001...");
1351
+ try {
1352
+ const meetings = await store.list();
1353
+ let updatedCount = 0;
1354
+ for (const meeting of meetings) {
1355
+ if (!meeting.createdTasks || meeting.createdTasks.length === 0) continue;
1356
+ let changed = false;
1357
+ for (const task of meeting.createdTasks) {
1358
+ if (!task.taskId || task.status === "completed") continue;
1359
+ const result = await taskCreator.getTaskStatus(task.taskId);
1360
+ if (result && result.status !== (task.status || "open")) {
1361
+ task.status = result.status;
1362
+ task.completedAt = result.completedAt;
1363
+ changed = true;
1364
+ }
1365
+ }
1366
+ if (changed) {
1367
+ await store.save(meeting);
1368
+ updatedCount++;
1369
+ }
1370
+ }
1371
+ console.log(`[task-sync] \u540C\u6B65\u5B8C\u6210, \u66F4\u65B0\u4E86 ${updatedCount} \u6761\u4F1A\u8BAE\u8BB0\u5F55`);
1372
+ } catch (err) {
1373
+ console.error("[task-sync] \u540C\u6B65\u5931\u8D25:", err.message);
1374
+ }
1375
+ }
1376
+ syncTaskStatuses();
1377
+ setInterval(syncTaskStatuses, 60 * 60 * 1e3);
1313
1378
  }
1314
1379
  main().catch(console.error);
@@ -129,9 +129,11 @@ async function renderMeetings() {
129
129
  if (m.createdTasks && m.createdTasks.length > 0) {
130
130
  detail += '<div class="detail-section"><h4>📋 已创建任务</h4><ul>' +
131
131
  m.createdTasks.map(function (t) {
132
- return '<li>' + escapeHtml(t.summary) +
132
+ var statusIcon = t.status === 'completed' ? '✅' : '⏳';
133
+ return '<li>' + statusIcon + ' ' + escapeHtml(t.summary) +
133
134
  (t.url ? ' <a class="detail-link" href="' + escapeAttr(t.url) + '" target="_blank">查看 →</a>' : '') +
134
- '<br><span class="insight-source">创建于 ' + escapeHtml(t.createdAt) + '</span></li>';
135
+ '<br><span class="insight-source">创建于 ' + escapeHtml(t.createdAt) +
136
+ (t.completedAt ? ' | 完成于 ' + escapeHtml(t.completedAt) : '') + '</span></li>';
135
137
  }).join('') + '</ul></div>';
136
138
  }
137
139
 
@@ -278,6 +280,10 @@ async function renderSettings() {
278
280
  '<label class="form-label">App Secret</label>' +
279
281
  '<input class="form-input" id="cfg-appSecret" type="password" value="' + escapeAttr(config.lark.appSecret) + '">' +
280
282
  '</div>' +
283
+ '<div class="form-field">' +
284
+ '<label class="form-label">管理员 Open ID(可选,用于接收服务通知)</label>' +
285
+ '<input class="form-input" id="cfg-adminOpenId" type="text" value="' + escapeAttr(config.lark.adminOpenId || '') + '">' +
286
+ '</div>' +
281
287
  '</div>' +
282
288
  '<div class="settings-group">' +
283
289
  '<div class="settings-group-title">Agent 配置</div>' +
@@ -308,6 +314,7 @@ async function saveSettings() {
308
314
  lark: {
309
315
  appId: document.getElementById('cfg-appId').value,
310
316
  appSecret: document.getElementById('cfg-appSecret').value,
317
+ adminOpenId: document.getElementById('cfg-adminOpenId').value || undefined,
311
318
  },
312
319
  agent: {
313
320
  provider: document.getElementById('cfg-provider').value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lih-x-x/kmr",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {