@modelzen/feishu-codex-bridge 0.6.4 → 0.6.5

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.
Files changed (2) hide show
  1. package/dist/cli.js +118 -31
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -1106,7 +1106,7 @@ ${lines || "\uFF08\u65E0\uFF09"}`));
1106
1106
  return card(elements, { forward: false });
1107
1107
  }
1108
1108
  function buildCliBridgeTaskCompletionCard(input2) {
1109
- const verb = input2.replyDoneAt ? "\u2705 \u5DF2\u786E\u8BA4\u5B8C\u6210" : input2.status === "failed" ? "\u274C \u4EFB\u52A1\u5931\u8D25" : pickCopy(COPY.completion, input2.id || input2.cwd);
1109
+ const verb = input2.replyDoneAt ? "\u2705 \u5DF2\u6536\u5DE5" : input2.status === "failed" ? "\u274C \u4EFB\u52A1\u5931\u8D25" : pickCopy(COPY.completion, input2.id || input2.cwd);
1110
1110
  const elements = [
1111
1111
  titleEl(verb),
1112
1112
  metaLine(input2.source, input2.cwd)
@@ -1123,7 +1123,7 @@ ${codeBlock(chunk, "text")}`));
1123
1123
  }
1124
1124
  if (input2.replyEnabled) {
1125
1125
  const expiresAt = input2.replyExpiresAt ? `\uFF08\u6709\u6548\u671F\u81F3 ${new Date(input2.replyExpiresAt).toLocaleString("zh-CN")}\uFF09` : "";
1126
- elements.push(actions([button("\u23F3 \u7B49\u5F85\u786E\u8BA4", { a: CLI.taskCompletionDone, id: input2.id }, "primary")]));
1126
+ elements.push(actions([button("\u2705 \u6536\u5DE5", { a: CLI.taskCompletionDone, id: input2.id }, "primary")]));
1127
1127
  elements.push(note(pickCopy(COPY.footerReply, input2.id || input2.cwd) + expiresAt));
1128
1128
  } else if (input2.replyDoneAt) {
1129
1129
  elements.push(actions([disabledButton("\u2705 \u5DF2\u5B8C\u6210", "primary")]));
@@ -1190,8 +1190,8 @@ var init_cards2 = __esm({
1190
1190
  "\u4EBA\u5728\u684C\u524D\u6211\u5C31\u95ED\u5634,\u4E00\u5207\u56DE\u5F52\u7EC8\u7AEF\u3002"
1191
1191
  ],
1192
1192
  footerReply: [
1193
- "\u{1F4AC} \u76F4\u63A5\u56DE\u590D\u8FD9\u6761\u6D88\u606F,\u5C31\u80FD\u63A5\u7740\u652F\u4F7F\u5B83\u5E72\u6D3B;\u6216\u70B9\u300C\u7B49\u5F85\u786E\u8BA4\u300D\u8BA9\u5B83\u6536\u5DE5\u3002",
1194
- "\u{1F4AC} \u56DE\u6211\u4E00\u53E5\u8BDD,\u5B83\u7ACB\u523B\u63A5\u7740\u8DD1;\u4E0D\u60F3\u7EE7\u7EED\u5C31\u70B9\u300C\u7B49\u5F85\u786E\u8BA4\u300D\u3002"
1193
+ "\u{1F4AC} \u76F4\u63A5\u56DE\u590D\u8FD9\u6761\u6D88\u606F,\u5C31\u80FD\u63A5\u7740\u652F\u4F7F\u5B83\u5E72\u6D3B;\u6216\u70B9\u300C\u6536\u5DE5\u300D\u8BA9\u5B83\u9000\u51FA\u3002",
1194
+ "\u{1F4AC} \u56DE\u6211\u4E00\u53E5\u8BDD,\u5B83\u7ACB\u523B\u63A5\u7740\u8DD1;\u4E0D\u60F3\u7EE7\u7EED\u5C31\u70B9\u300C\u6536\u5DE5\u300D\u3002"
1195
1195
  ]
1196
1196
  };
1197
1197
  }
@@ -3126,14 +3126,19 @@ function mapNotification(n, ctx) {
3126
3126
  function mapItemStart(item, ctx) {
3127
3127
  switch (item.type) {
3128
3128
  case "commandExecution":
3129
- return { type: "tool_use", itemId: item.id, title: item.command, detail: String(item.cwd) };
3129
+ return { type: "tool_use", itemId: item.id, title: item.command, detail: String(item.cwd), kind: "command" };
3130
3130
  case "fileChange":
3131
- return { type: "tool_use", itemId: item.id, title: fileChangeTitle(item.changes, ctx?.cwd) };
3131
+ return { type: "tool_use", itemId: item.id, title: fileChangeTitle(item.changes, ctx?.cwd), kind: "file" };
3132
3132
  case "webSearch":
3133
- return { type: "tool_use", itemId: item.id, title: "\u8054\u7F51\u641C\u7D22" };
3133
+ return {
3134
+ type: "tool_use",
3135
+ itemId: item.id,
3136
+ title: item.query ? `\u8054\u7F51\u641C\u7D22\uFF1A${item.query}` : "\u8054\u7F51\u641C\u7D22",
3137
+ kind: "search"
3138
+ };
3134
3139
  case "mcpToolCall":
3135
3140
  case "dynamicToolCall":
3136
- return { type: "tool_use", itemId: item.id, title: "\u5DE5\u5177\u8C03\u7528" };
3141
+ return { type: "tool_use", itemId: item.id, title: "\u5DE5\u5177\u8C03\u7528", kind: "tool" };
3137
3142
  default:
3138
3143
  return null;
3139
3144
  }
@@ -3803,7 +3808,8 @@ function createTurnMapper(ctx = {}) {
3803
3808
  type: "tool_use",
3804
3809
  itemId: String(b.id ?? `tool${++blockSeq}`),
3805
3810
  title: toolTitle(b.name ?? "\u5DE5\u5177", b.input ?? {}, ctx.cwd),
3806
- detail: toolDetail(b.name ?? "", b.input ?? {})
3811
+ detail: toolDetail(b.name ?? "", b.input ?? {}),
3812
+ kind: toolKind(b.name ?? "")
3807
3813
  });
3808
3814
  }
3809
3815
  }
@@ -3922,6 +3928,26 @@ function toolTitle(name, input2, cwd) {
3922
3928
  return name || "\u5DE5\u5177\u8C03\u7528";
3923
3929
  }
3924
3930
  }
3931
+ function toolKind(name) {
3932
+ switch (name) {
3933
+ case "Bash":
3934
+ case "BashOutput":
3935
+ return "command";
3936
+ case "Read":
3937
+ case "Write":
3938
+ case "Edit":
3939
+ case "MultiEdit":
3940
+ case "NotebookEdit":
3941
+ return "file";
3942
+ case "Glob":
3943
+ case "Grep":
3944
+ case "WebFetch":
3945
+ case "WebSearch":
3946
+ return "search";
3947
+ default:
3948
+ return "tool";
3949
+ }
3950
+ }
3925
3951
  function toolDetail(name, input2) {
3926
3952
  if (name === "Bash" && typeof input2.description === "string" && input2.description) {
3927
3953
  return input2.description;
@@ -7007,6 +7033,7 @@ function reduce(state, evt) {
7007
7033
  id: evt.itemId,
7008
7034
  title: evt.title,
7009
7035
  detail: evt.detail,
7036
+ kind: evt.kind,
7010
7037
  status: "running"
7011
7038
  };
7012
7039
  return {
@@ -7349,25 +7376,61 @@ function renderCleanBody(bodyMarkdown, images) {
7349
7376
  }
7350
7377
 
7351
7378
  // src/card/tool-render.ts
7352
- var HEADER_TITLE_MAX = 80;
7379
+ var HEADER_TITLE_MAX = 120;
7353
7380
  var OUTPUT_MAX = 1200;
7381
+ var CMD_BLOCK_MAX = 1e3;
7382
+ var SUMMARY_LINE_MAX = 400;
7354
7383
  var BODY_TOTAL_MAX = 2500;
7384
+ function statusIcon(status) {
7385
+ return status === "done" ? "\u2705" : status === "error" ? "\u274C" : "\u23F3";
7386
+ }
7387
+ function kindGlyph(kind) {
7388
+ switch (kind) {
7389
+ case "command":
7390
+ return "\u{1F527}";
7391
+ case "file":
7392
+ return "\u{1F4C4}";
7393
+ case "search":
7394
+ return "\u{1F50D}";
7395
+ default:
7396
+ return "";
7397
+ }
7398
+ }
7399
+ function leadGlyphs(tool) {
7400
+ const glyph = kindGlyph(tool.kind);
7401
+ return glyph ? `${statusIcon(tool.status)} ${glyph}` : statusIcon(tool.status);
7402
+ }
7355
7403
  function toolHeaderText(tool) {
7356
- const icon = tool.status === "done" ? "\u2705" : tool.status === "error" ? "\u274C" : "\u23F3";
7357
- return `${icon} **${escapeInline2(truncate3(tool.title, HEADER_TITLE_MAX))}**`;
7404
+ return `${leadGlyphs(tool)} **${escapeInline2(truncate3(tool.title, HEADER_TITLE_MAX))}**`;
7405
+ }
7406
+ function toolSummaryLine(tool) {
7407
+ return `- ${leadGlyphs(tool)} **${escapeInline2(truncate3(tool.title, SUMMARY_LINE_MAX))}**`;
7358
7408
  }
7359
7409
  function toolBodyMd(tool) {
7360
- if (!tool.output) {
7361
- return tool.status === "running" ? "_\u8FD0\u884C\u4E2D\u2026_" : "";
7362
- }
7363
- const label = tool.status === "error" ? "Error" : "Output";
7364
- const block = tool.output.startsWith("```") ? tool.output : bashBlock(tool.output);
7365
- const body = `**${label}**
7366
- ${block}`;
7410
+ const lead = invocationMd(tool);
7411
+ const outputPart = tool.output ? outputBlock(tool) : tool.status === "running" ? "_\u8FD0\u884C\u4E2D\u2026_" : tool.kind === "search" ? "_\uFF08\u641C\u7D22\u7ED3\u679C\u5DF2\u7528\u4E8E\u4F5C\u7B54\uFF0C\u4E0D\u5355\u72EC\u56DE\u4F20\uFF09_" : "";
7412
+ const body = [lead, outputPart].filter(Boolean).join("\n\n");
7367
7413
  if (body.length <= BODY_TOTAL_MAX) return body;
7368
7414
  return `${body.slice(0, BODY_TOTAL_MAX)}\u2026
7369
7415
 
7370
- _\uFF08\u5DF2\u622A\u65AD\uFF0C\u5B8C\u6574\u8F93\u51FA ${tool.output.length} \u5B57\u7B26\uFF09_`;
7416
+ _\uFF08\u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09_`;
7417
+ }
7418
+ function invocationMd(tool) {
7419
+ if (tool.kind !== "command") return "";
7420
+ const cmd = tool.title.trim();
7421
+ if (!cmd) return "";
7422
+ const detail = tool.detail ? `
7423
+ \`${escapeInline2(tool.detail)}\`` : "";
7424
+ return `**\u547D\u4EE4**
7425
+ \`\`\`bash
7426
+ ${truncate3(cmd, CMD_BLOCK_MAX)}
7427
+ \`\`\`${detail}`;
7428
+ }
7429
+ function outputBlock(tool) {
7430
+ const label = tool.status === "error" ? "Error" : "Output";
7431
+ const block = tool.output.startsWith("```") ? tool.output : bashBlock(tool.output);
7432
+ return `**${label}**
7433
+ ${block}`;
7371
7434
  }
7372
7435
  function bashBlock(output) {
7373
7436
  const note2 = output.length > OUTPUT_MAX ? `
@@ -7468,6 +7531,8 @@ var CONTROLS_EID = "controls";
7468
7531
  var REASONING_MAX = 1500;
7469
7532
  var COLLAPSE_TOOL_THRESHOLD = 3;
7470
7533
  var PROCESS_BODY_BUDGET = 22e3;
7534
+ var PROCESS_COMPONENT_BUDGET = 120;
7535
+ var SUMMARY_BODY_MAX = 6e3;
7471
7536
  function buildRunCard(rc) {
7472
7537
  const state = rc.rs;
7473
7538
  const running = state.terminal === "running";
@@ -7529,7 +7594,7 @@ function renderTerminal(state, rc) {
7529
7594
  const toolCount = blocks.reduce((n, b) => b.kind === "tool" ? n + 1 : n, 0);
7530
7595
  elements.push(
7531
7596
  collapsiblePanelEl({
7532
- title: processTitle(Boolean(reasoning), toolCount),
7597
+ title: processTitle(Boolean(reasoning), toolCount, state.terminal),
7533
7598
  expanded: false,
7534
7599
  border: "grey",
7535
7600
  elements: processEls
@@ -7577,7 +7642,9 @@ function lastTextIndex(blocks) {
7577
7642
  }
7578
7643
  function buildProcessBody(reasoning, blocks) {
7579
7644
  const rich = processElements(reasoning, blocks, false);
7580
- if (estimateSize2(rich) <= PROCESS_BODY_BUDGET) return rich;
7645
+ if (estimateSize2(rich) <= PROCESS_BODY_BUDGET && estimateComponents(rich) <= PROCESS_COMPONENT_BUDGET) {
7646
+ return rich;
7647
+ }
7581
7648
  return processElements(reasoning, blocks, true);
7582
7649
  }
7583
7650
  function processElements(reasoning, blocks, compactTools) {
@@ -7592,18 +7659,25 @@ function processElements(reasoning, blocks, compactTools) {
7592
7659
  }
7593
7660
  return out;
7594
7661
  }
7595
- function processTitle(hasReasoning, toolCount) {
7662
+ function processTitle(hasReasoning, toolCount, terminal) {
7663
+ const icon = terminal === "interrupted" ? "\u23F9" : terminal === "idle_timeout" ? "\u23F1" : terminal === "error" ? "\u26A0\uFE0F" : "\u2705";
7664
+ const noun = terminal === "interrupted" ? "\u4E2D\u65AD\u524D\u7684\u8FC7\u7A0B" : terminal === "idle_timeout" ? "\u8D85\u65F6\u524D\u7684\u8FC7\u7A0B" : terminal === "error" ? "\u51FA\u9519\u524D\u7684\u8FC7\u7A0B" : "\u672C\u8F6E\u8FC7\u7A0B";
7596
7665
  const parts = [];
7597
7666
  if (hasReasoning) parts.push("\u{1F9E0} \u601D\u8003");
7598
- if (toolCount > 0) parts.push(`\u{1F9F0} ${toolCount} \u4E2A\u5DE5\u5177\u8C03\u7528`);
7599
- const detail = parts.length > 0 ? `\uFF1A${parts.join(" \xB7 ")}` : "";
7600
- return `\u{1F5C2} **\u8FC7\u7A0B${detail}**\uFF08\u70B9\u51FB\u5C55\u5F00\uFF09`;
7667
+ if (toolCount > 0) parts.push(`\u{1F9F0} ${toolCount} \u4E2A\u5DE5\u5177`);
7668
+ const detail = parts.length > 0 ? ` \xB7 ${parts.join(" \xB7 ")}` : "";
7669
+ return `${icon} **${noun}**${detail}\uFF08\u70B9\u51FB\u5C55\u5F00\uFF09`;
7601
7670
  }
7602
7671
  function estimateSize2(els) {
7603
7672
  let n = 0;
7604
7673
  for (const el of els) n += JSON.stringify(el).length;
7605
7674
  return n;
7606
7675
  }
7676
+ function estimateComponents(els) {
7677
+ let n = 0;
7678
+ for (const el of els) n += el.tag === "collapsible_panel" ? 3 : 1;
7679
+ return n;
7680
+ }
7607
7681
  function buildRunCardPlain(rc) {
7608
7682
  return buildRunCard({ ...rc, cardKey: void 0 });
7609
7683
  }
@@ -7638,11 +7712,11 @@ function* groupBlocks(blocks) {
7638
7712
  }
7639
7713
  function renderToolGroup(tools, finalized, compact = false) {
7640
7714
  if (tools.length === 0) return [];
7641
- if (compact) return [collapsedToolSummary(tools, true)];
7715
+ if (compact) return [collapsedToolSummary(tools, finalized)];
7716
+ if (finalized) return tools.map((t) => toolPanel(t, false));
7642
7717
  if (tools.length < COLLAPSE_TOOL_THRESHOLD) {
7643
7718
  return tools.map((t) => toolPanel(t, false));
7644
7719
  }
7645
- if (finalized) return [collapsedToolSummary(tools, true)];
7646
7720
  const prior = tools.slice(0, -1);
7647
7721
  const latest = tools[tools.length - 1];
7648
7722
  const out = [];
@@ -7652,7 +7726,7 @@ function renderToolGroup(tools, finalized, compact = false) {
7652
7726
  }
7653
7727
  function reasoningPanel(content, active) {
7654
7728
  return collapsiblePanel({
7655
- title: active ? "\u{1F9E0} **\u601D\u8003\u4E2D**" : "\u{1F9E0} **\u601D\u8003\u5B8C\u6210\uFF0C\u70B9\u51FB\u67E5\u770B**",
7729
+ title: active ? "\u{1F9E0} **\u6B63\u5728\u601D\u8003\u2026**" : "\u{1F9E0} **\u601D\u8003\u8FC7\u7A0B**\uFF08\u70B9\u51FB\u5C55\u5F00\uFF09",
7656
7730
  expanded: active,
7657
7731
  border: "grey",
7658
7732
  body: truncate4(content, REASONING_MAX)
@@ -7668,11 +7742,24 @@ function toolPanel(tool, expanded) {
7668
7742
  }
7669
7743
  function collapsedToolSummary(tools, finalized) {
7670
7744
  const suffix = finalized ? "\uFF08\u5DF2\u7ED3\u675F\uFF09" : "";
7745
+ const lines = tools.map(toolSummaryLine);
7746
+ let body = lines.join("\n");
7747
+ if (body.length > SUMMARY_BODY_MAX) {
7748
+ let kept = 0;
7749
+ let acc = 0;
7750
+ for (const line of lines) {
7751
+ if (acc + line.length + 1 > SUMMARY_BODY_MAX) break;
7752
+ acc += line.length + 1;
7753
+ kept++;
7754
+ }
7755
+ body = `${lines.slice(0, kept).join("\n")}
7756
+ - _\u2026\u8FD8\u6709 ${tools.length - kept} \u4E2A\u547D\u4EE4\u672A\u663E\u793A_`;
7757
+ }
7671
7758
  return collapsiblePanel({
7672
- title: `\u2615 **${tools.length} \u4E2A\u5DE5\u5177\u8C03\u7528${suffix}**`,
7759
+ title: `\u{1F9F0} **${tools.length} \u4E2A\u5DE5\u5177\u8C03\u7528${suffix}**`,
7673
7760
  expanded: false,
7674
7761
  border: "blue",
7675
- body: tools.map((t) => `- ${toolHeaderText(t)}`).join("\n")
7762
+ body
7676
7763
  });
7677
7764
  }
7678
7765
  function footerStatusText(status) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelzen/feishu-codex-bridge",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Bridge Feishu/Lark messenger with local Codex via app-server (project=group, thread=session)",
5
5
  "type": "module",
6
6
  "bin": {