chattercatcher 0.2.1 → 0.2.3

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/cli.js CHANGED
@@ -8,7 +8,7 @@ import fs15 from "fs/promises";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "chattercatcher",
11
- version: "0.2.1",
11
+ version: "0.2.3",
12
12
  description: "\u672C\u5730\u4F18\u5148\u7684\u98DE\u4E66/Lark \u5BB6\u5EAD\u7FA4\u77E5\u8BC6\u5E93\u673A\u5668\u4EBA",
13
13
  type: "module",
14
14
  main: "dist/index.js",
@@ -2714,6 +2714,28 @@ async function restoreLocalData(input2) {
2714
2714
  };
2715
2715
  }
2716
2716
 
2717
+ // src/time/beijing.ts
2718
+ var BEIJING_TIME_ZONE = "Asia/Shanghai";
2719
+ var BEIJING_DATE_TIME_FORMATTER = new Intl.DateTimeFormat("zh-CN", {
2720
+ timeZone: BEIJING_TIME_ZONE,
2721
+ year: "numeric",
2722
+ month: "2-digit",
2723
+ day: "2-digit",
2724
+ hour: "2-digit",
2725
+ minute: "2-digit",
2726
+ second: "2-digit",
2727
+ hour12: false
2728
+ });
2729
+ function formatOffsetTimeZone(date) {
2730
+ const parts = Object.fromEntries(
2731
+ BEIJING_DATE_TIME_FORMATTER.formatToParts(date).map((part) => [part.type, part.value])
2732
+ );
2733
+ return `${parts.year}-${parts.month}-${parts.day}T${parts.hour}:${parts.minute}:${parts.second}+08:00`;
2734
+ }
2735
+ function formatBeijingTimeForPrompt(date) {
2736
+ return `${formatOffsetTimeZone(date)}\uFF08\u5317\u4EAC\u65F6\u95F4\uFF0CUTC+8\uFF0CAsia/Shanghai\uFF09`;
2737
+ }
2738
+
2717
2739
  // src/episodes/summarizer.ts
2718
2740
  async function summarizeEpisodeWindow(window, model, now) {
2719
2741
  const transcript = window.messages.map((message) => `[${message.sentAt}] ${message.senderName}\uFF1A${message.text}`).join("\n");
@@ -2724,7 +2746,7 @@ async function summarizeEpisodeWindow(window, model, now) {
2724
2746
  },
2725
2747
  {
2726
2748
  role: "user",
2727
- content: `\u5F53\u524D\u65F6\u95F4\uFF1A${now.toISOString()}
2749
+ content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(now)}
2728
2750
  \u7FA4\u804A\uFF1A${window.chatName}
2729
2751
  \u65F6\u95F4\uFF1A${window.startedAt} - ${window.endedAt}
2730
2752
 
@@ -3160,7 +3182,7 @@ ${input2.memberPrompt}
3160
3182
  \u751F\u6210\u6D88\u606F\u65F6\u9047\u5230\u4E0A\u8FF0 ID \u65F6\u4F18\u5148\u4F7F\u7528\u5BF9\u5E94\u7FA4\u6635\u79F0\uFF1B\u6CA1\u6709\u6620\u5C04\u65F6\u4FDD\u7559\u539F ID\uFF0C\u4E0D\u8981\u7F16\u9020\u6635\u79F0\u3002` : SYSTEM_PROMPT;
3161
3183
  const messages = [
3162
3184
  { role: "system", content: systemPrompt },
3163
- { role: "user", content: `\u5F53\u524D\u65F6\u95F4\uFF1A${input2.now.toISOString()}
3185
+ { role: "user", content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(input2.now)}
3164
3186
  \u4EFB\u52A1\u63D0\u793A\u8BCD\uFF1A${input2.prompt}` }
3165
3187
  ];
3166
3188
  const toolsByName = new Map(input2.tools.map((tool) => [tool.name, tool]));
@@ -3180,7 +3202,7 @@ ${input2.memberPrompt}
3180
3202
  { role: "system", content: systemPrompt },
3181
3203
  {
3182
3204
  role: "user",
3183
- content: `\u5F53\u524D\u65F6\u95F4\uFF1A${input2.now.toISOString()}
3205
+ content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(input2.now)}
3184
3206
  \u4EFB\u52A1\u63D0\u793A\u8BCD\uFF1A${input2.prompt}
3185
3207
 
3186
3208
  \u8BC1\u636E\uFF1A
@@ -3208,7 +3230,7 @@ ${evidenceToText(evidence)}`
3208
3230
  { role: "system", content: SYSTEM_PROMPT },
3209
3231
  {
3210
3232
  role: "user",
3211
- content: `\u5F53\u524D\u65F6\u95F4\uFF1A${input2.now.toISOString()}
3233
+ content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(input2.now)}
3212
3234
  \u4EFB\u52A1\u63D0\u793A\u8BCD\uFF1A${input2.prompt}
3213
3235
 
3214
3236
  \u8BC1\u636E\uFF1A
@@ -4217,7 +4239,7 @@ async function runFeishuToolLoop(input2) {
4217
4239
  const systemPrompt = systemPromptParts.join("\n\n");
4218
4240
  const messages = [
4219
4241
  { role: "system", content: systemPrompt },
4220
- { role: "user", content: `\u5F53\u524D\u65F6\u95F4\uFF1A${input2.now.toISOString()}
4242
+ { role: "user", content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(input2.now)}
4221
4243
  \u95EE\u9898\uFF1A${input2.question}` }
4222
4244
  ];
4223
4245
  const toolsByName = new Map(input2.tools.map((tool) => [tool.name, tool]));
@@ -4463,8 +4485,8 @@ function findMarkdownLinkEnd(text, start) {
4463
4485
  }
4464
4486
  return -1;
4465
4487
  }
4466
- function parseInline(text) {
4467
- const elements = [];
4488
+ function stripInlineMarkdown(text) {
4489
+ let output = "";
4468
4490
  let index2 = 0;
4469
4491
  while (index2 < text.length) {
4470
4492
  const linkStart = text.indexOf("[", index2);
@@ -4473,12 +4495,10 @@ function parseInline(text) {
4473
4495
  const candidates = [linkStart, boldStarStart, boldUnderscoreStart].filter((value) => value >= 0);
4474
4496
  const next = candidates.length ? Math.min(...candidates) : -1;
4475
4497
  if (next < 0) {
4476
- elements.push({ tag: "text", text: text.slice(index2) });
4498
+ output += text.slice(index2);
4477
4499
  break;
4478
4500
  }
4479
- if (next > index2) {
4480
- elements.push({ tag: "text", text: text.slice(index2, next) });
4481
- }
4501
+ output += text.slice(index2, next);
4482
4502
  if (next === linkStart) {
4483
4503
  const labelEnd = text.indexOf("](", next);
4484
4504
  if (labelEnd > next) {
@@ -4486,27 +4506,29 @@ function parseInline(text) {
4486
4506
  const hrefEnd = findMarkdownLinkEnd(text, hrefStart);
4487
4507
  const href = hrefEnd >= 0 ? text.slice(hrefStart, hrefEnd) : "";
4488
4508
  if (hrefEnd >= 0 && /^https?:\/\/\S+$/.test(href)) {
4489
- elements.push({ tag: "a", text: text.slice(next + 1, labelEnd), href });
4509
+ output += `${text.slice(next + 1, labelEnd)} ${href}`;
4490
4510
  index2 = hrefEnd + 1;
4491
4511
  continue;
4492
4512
  }
4493
4513
  }
4494
- elements.push({ tag: "text", text: text[next] });
4514
+ output += text[next];
4495
4515
  index2 = next + 1;
4496
4516
  continue;
4497
4517
  }
4498
4518
  const marker = next === boldStarStart ? "**" : "__";
4499
4519
  const close = text.indexOf(marker, next + marker.length);
4500
4520
  if (close > next + marker.length) {
4501
- elements.push({ tag: "text", text: text.slice(next + marker.length, close), style: ["bold"] });
4521
+ output += text.slice(next + marker.length, close);
4502
4522
  index2 = close + marker.length;
4503
4523
  continue;
4504
4524
  }
4505
- elements.push({ tag: "text", text: marker });
4525
+ output += marker;
4506
4526
  index2 = next + marker.length;
4507
4527
  }
4508
- const compacted = elements.filter((element) => element.tag !== "text" || element.text.length > 0);
4509
- return compacted.length ? compacted : [{ tag: "text", text: " " }];
4528
+ return output;
4529
+ }
4530
+ function parseInline(text) {
4531
+ return [{ tag: "text", text: stripInlineMarkdown(text) || " " }];
4510
4532
  }
4511
4533
  function pushParagraph(content, lines) {
4512
4534
  if (lines.length === 0) return;
@@ -4547,7 +4569,7 @@ ${code.join("\n")}
4547
4569
  const heading = line.match(/^#{1,6}\s+(.+)$/);
4548
4570
  if (heading) {
4549
4571
  pushParagraph(content, paragraph);
4550
- content.push([{ tag: "text", text: heading[1], style: ["bold"] }]);
4572
+ content.push([{ tag: "text", text: stripInlineMarkdown(heading[1]) || " " }]);
4551
4573
  continue;
4552
4574
  }
4553
4575
  const unordered = line.match(/^[-*]\s+(.+)$/);
@@ -4575,17 +4597,13 @@ function buildFeishuPostContent(markdown, options) {
4575
4597
  const content = parseMarkdownBlocks(markdown);
4576
4598
  const mentions = options?.mentions ?? [];
4577
4599
  if (mentions.length) {
4578
- const mentionElements = mentions.map((mention) => ({
4579
- tag: "at",
4580
- user_id: mention.openId,
4581
- user_name: mention.name
4582
- }));
4583
4600
  const firstLine = content[0] ?? [];
4584
4601
  const firstText = firstLine[0];
4602
+ const prefix = mentions.map((mention) => `@${mention.name}`).join(" ");
4585
4603
  if (firstText?.tag === "text") {
4586
- content[0] = [...mentionElements, { ...firstText, text: ` ${firstText.text}` }, ...firstLine.slice(1)];
4604
+ content[0] = [{ tag: "text", text: `${prefix} ${firstText.text}` }, ...firstLine.slice(1)];
4587
4605
  } else {
4588
- content[0] = [...mentionElements, { tag: "text", text: " " }, ...firstLine];
4606
+ content[0] = [{ tag: "text", text: `${prefix} ` }, ...firstLine];
4589
4607
  }
4590
4608
  }
4591
4609
  return {
@@ -5753,7 +5771,7 @@ function buildEvidencePrompt(input2, options = {}) {
5753
5771
  },
5754
5772
  {
5755
5773
  role: "user",
5756
- content: `\u5F53\u524D\u65F6\u95F4\uFF1A${now.toISOString()}
5774
+ content: `\u5F53\u524D\u65F6\u95F4\uFF1A${formatBeijingTimeForPrompt(now)}
5757
5775
  \u95EE\u9898\uFF1A${question}
5758
5776
 
5759
5777
  \u8BC1\u636E\u5904\u7406\u89C4\u5219\uFF1A