chatccc 0.2.80 → 0.2.81

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatccc",
3
- "version": "0.2.80",
3
+ "version": "0.2.81",
4
4
  "description": "Feishu bot bridge for Claude Code",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -137,6 +137,8 @@ export interface DisplayCardState {
137
137
  lastSentAccLen?: number;
138
138
  /** WeChat delta: 上次发送时的 finalReply */
139
139
  lastSentFinalReply?: string;
140
+ /** 上次 loop 读取到的 turnCount,用于检测轮次切换 */
141
+ lastTurnCount?: number;
140
142
  }
141
143
 
142
144
  export const displayCards = new Map<string, DisplayCardState>();
package/src/session.ts CHANGED
@@ -898,9 +898,13 @@ export async function runAgentSession(
898
898
  setQueuePreservedChat(sessionId, preservedChat);
899
899
  }
900
900
  console.log(`[${ts()}] [QUEUE] Consuming queued message for session ${sessionId}: "${queued.text.slice(0, 50)}"`);
901
- setImmediate(() => {
901
+ // setTimeout 而非 setImmediate:给 display loop 的 setInterval
902
+ // 足够时间读到 "done" 状态并终结旧卡片,避免新轮更新旧卡片的 bug。
903
+ // setImmediate 在 check 阶段触发早于下一个 timers 阶段,
904
+ // display loop (setInterval) 还没机会读到 "done" 就被新 "running" 覆盖。
905
+ setTimeout(() => {
902
906
  consumeQueuedMessage(platform, queued);
903
- });
907
+ }, 200);
904
908
  }
905
909
  }
906
910
 
@@ -1103,11 +1107,44 @@ export function ensureDisplayLoop(sessionId: string): void {
1103
1107
  cardCreatedAt: Date.now(),
1104
1108
  lastSentContent: "",
1105
1109
  streamErrorNotified: false,
1110
+ lastTurnCount: state.turnCount,
1106
1111
  });
1107
1112
  }
1108
1113
  } else {
1109
1114
  if (display.cardBusy) return;
1110
1115
 
1116
+ // 检测轮次切换:turnCount 变化说明上一轮已完成、本 tick 是新轮,
1117
+ // 但上一轮的 display 卡片因 setImmediate/setTimeout 时序问题
1118
+ // 还没被终结分支清除。此处主动终结旧卡、创建新卡。
1119
+ if (display.lastTurnCount !== undefined && display.lastTurnCount !== state.turnCount) {
1120
+ display.cardBusy = true;
1121
+ try {
1122
+ const doneSeq = display.sequence + 1;
1123
+ const doneCard = buildProgressCard("", { showStop: false, headerTitle: "完成" });
1124
+ await p.cardUpdate(display.cardId, doneCard, doneSeq).catch(() => {});
1125
+ displayCards.delete(chatId);
1126
+ } catch (_) { /* ignore */ }
1127
+ display.cardBusy = false;
1128
+ // 新建卡片
1129
+ const cardId = await p.cardCreate(buildProgressCard("", { showStop: true, headerTitle: "生成中..." })).catch(() => null);
1130
+ if (cardId) {
1131
+ await p.cardSend(chatId, cardId).catch(() => null);
1132
+ displayCards.set(chatId, {
1133
+ cardId,
1134
+ sequence: 1,
1135
+ cardBusy: false,
1136
+ cardCreatedAt: Date.now(),
1137
+ lastSentContent: "",
1138
+ streamErrorNotified: false,
1139
+ lastTurnCount: state.turnCount,
1140
+ });
1141
+ }
1142
+ return;
1143
+ }
1144
+
1145
+ // 更新当前 turn 的 lastTurnCount
1146
+ display.lastTurnCount = state.turnCount;
1147
+
1111
1148
  // 卡片轮转
1112
1149
  if (Date.now() - display.cardCreatedAt > CARD_ROTATE_MS) {
1113
1150
  display.cardBusy = true;