opencode-chat-channel 1.2.12 → 1.2.13

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/feishu/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAiC,MAAM,gBAAgB,CAAC;AAmOjG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAuBlC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/feishu/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAiC,MAAM,gBAAgB,CAAC;AAoSjG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAuBlC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAuPlD,eAAO,MAAM,iBAAiB,EAAE,MA6G/B,CAAC;AAEF,eAAe,iBAAiB,CAAC;AAMjC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiUlD,eAAO,MAAM,iBAAiB,EAAE,MA8K/B,CAAC;AAEF,eAAe,iBAAiB,CAAC;AAMjC,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -11,7 +11,10 @@ function fileLog(level, message) {
11
11
  const ts = new Date().toISOString();
12
12
  appendFileSync(LOG_FILE, `${ts} [${level.toUpperCase()}] ${message}
13
13
  `, "utf8");
14
- } catch {}
14
+ } catch (err) {
15
+ process.stderr.write(`[chat-channel] fileLog 写入失败: ${String(err)}
16
+ `);
17
+ }
15
18
  }
16
19
  var SESSION_TTL_MS = 2 * 60 * 60 * 1000;
17
20
 
@@ -59,11 +62,6 @@ class SessionManager {
59
62
  return setInterval(() => this.cleanup(), intervalMs);
60
63
  }
61
64
  }
62
- function extractResponseText(parts) {
63
- if (!Array.isArray(parts))
64
- return "";
65
- return parts.filter((p) => p?.type === "text").map((p) => p?.text ?? "").join("").trim();
66
- }
67
65
  function loadDotEnv(envPath) {
68
66
  try {
69
67
  const content = readFileSync(envPath, "utf8");
@@ -160,7 +158,7 @@ class FeishuChannel {
160
158
  }
161
159
  }
162
160
  async sendThinkingCard(chatId) {
163
- const card = buildThinkingCard("⏳ 正在思考...");
161
+ const card = buildCard("⏳ 正在思考...", "", "thinking");
164
162
  try {
165
163
  const res = await this.larkClient.im.message.create({
166
164
  params: { receive_id_type: "chat_id" },
@@ -170,26 +168,63 @@ class FeishuChannel {
170
168
  msg_type: "interactive"
171
169
  }
172
170
  });
173
- return res.data?.message_id ?? null;
171
+ const msgId = res.data?.message_id ?? null;
172
+ fileLog("info", `[feishu] sendThinkingCard 成功: msgId=${msgId}`);
173
+ return msgId;
174
174
  } catch (err) {
175
+ const errStr = err?.response?.data ? JSON.stringify(err.response.data) : String(err);
175
176
  this.client.app.log({
176
177
  body: {
177
178
  service: "chat-channel",
178
179
  level: "warn",
179
- message: `[feishu] 发送思考卡片失败: ${String(err)}`
180
+ message: `[feishu] sendThinkingCard 失败: ${errStr}`
180
181
  }
181
182
  });
183
+ fileLog("warn", `[feishu] sendThinkingCard 失败: ${errStr}`);
182
184
  return null;
183
185
  }
184
186
  }
185
187
  async updateThinkingCard(messageId, statusText) {
186
- const card = buildThinkingCard(statusText);
188
+ const card = buildCard(statusText, "", "thinking");
187
189
  try {
188
190
  await this.larkClient.im.message.patch({
189
191
  data: { content: JSON.stringify(card) },
190
192
  path: { message_id: messageId }
191
193
  });
192
- } catch {}
194
+ fileLog("info", `[feishu] updateThinkingCard 成功: msgId=${messageId}`);
195
+ } catch (err) {
196
+ const errStr = err?.response?.data ? JSON.stringify(err.response.data) : String(err);
197
+ this.client.app.log({ body: { service: "chat-channel", level: "warn", message: `[feishu] updateThinkingCard patch 失败: ${errStr}` } });
198
+ fileLog("warn", `[feishu] updateThinkingCard patch 失败: ${errStr}`);
199
+ }
200
+ }
201
+ async patchProgress(messageId, summary, detail, stage) {
202
+ const card = buildCard(summary, detail, stage);
203
+ try {
204
+ await this.larkClient.im.message.patch({
205
+ data: { content: JSON.stringify(card) },
206
+ path: { message_id: messageId }
207
+ });
208
+ fileLog("info", `[feishu] patchProgress 成功: msgId=${messageId} stage=${stage}`);
209
+ } catch (err) {
210
+ const errStr = err?.response?.data ? JSON.stringify(err.response.data) : String(err);
211
+ this.client.app.log({ body: { service: "chat-channel", level: "warn", message: `[feishu] patchProgress 失败: ${errStr}` } });
212
+ fileLog("warn", `[feishu] patchProgress 失败: ${errStr}`);
213
+ }
214
+ }
215
+ async patchDone(messageId, detail) {
216
+ const card = buildCard("✅ 已完成", detail, "done");
217
+ try {
218
+ await this.larkClient.im.message.patch({
219
+ data: { content: JSON.stringify(card) },
220
+ path: { message_id: messageId }
221
+ });
222
+ fileLog("info", `[feishu] patchDone 成功: msgId=${messageId}`);
223
+ } catch (err) {
224
+ const errStr = err?.response?.data ? JSON.stringify(err.response.data) : String(err);
225
+ this.client.app.log({ body: { service: "chat-channel", level: "warn", message: `[feishu] patchDone 失败: ${errStr}` } });
226
+ fileLog("warn", `[feishu] patchDone 失败: ${errStr}`);
227
+ }
193
228
  }
194
229
  parseEvent(data) {
195
230
  const { message, sender } = data ?? {};
@@ -228,16 +263,25 @@ class FeishuChannel {
228
263
  };
229
264
  }
230
265
  }
231
- function buildThinkingCard(text) {
232
- return {
266
+ function buildCard(summary, detail, stage) {
267
+ const templates = {
268
+ thinking: "blue",
269
+ reasoning: "wathet",
270
+ replying: "turquoise",
271
+ done: "green"
272
+ };
273
+ const card = {
274
+ schema: "2.0",
233
275
  config: { update_multi: true },
234
- elements: [
235
- {
236
- tag: "markdown",
237
- content: text
238
- }
239
- ]
276
+ header: {
277
+ title: { tag: "plain_text", content: summary },
278
+ template: templates[stage]
279
+ }
280
+ };
281
+ card["body"] = {
282
+ elements: detail ? [{ tag: "markdown", content: detail }] : [{ tag: "markdown", content: " " }]
240
283
  };
284
+ return card;
241
285
  }
242
286
  var feishuChannelFactory = async (client) => {
243
287
  const appId = process.env["FEISHU_APP_ID"];
@@ -330,6 +374,59 @@ function resolveEnabledChannels(client) {
330
374
  }
331
375
  return enabled;
332
376
  }
377
+ var PATCH_THROTTLE_MS = 2000;
378
+ function buildDetailContent(entry) {
379
+ const parts = [];
380
+ if (entry.reasoning) {
381
+ parts.push(`**\uD83D\uDCAD 推理过程**
382
+ ${entry.reasoning}`);
383
+ }
384
+ for (const callId of entry.toolPartOrder) {
385
+ const t = entry.toolParts.get(callId);
386
+ if (!t)
387
+ continue;
388
+ const statusIcon = t.status === "completed" ? "✓" : t.status === "running" ? "..." : "⏳";
389
+ const inputStr = t.input !== undefined ? `
390
+ input: \`${JSON.stringify(t.input)}\`` : "";
391
+ const outputStr = t.output ? `
392
+ output: ${t.output.length > 200 ? t.output.slice(0, 200) + "..." : t.output}` : "";
393
+ parts.push(`\uD83D\uDD27 **${t.tool}** (${statusIcon})${inputStr}${outputStr}`);
394
+ }
395
+ const allText = entry.textPartOrder.map((id) => entry.textParts.get(id) ?? "").filter(Boolean).join(`
396
+
397
+ `);
398
+ if (allText) {
399
+ parts.push(`**✍️ 回复内容**
400
+ ${allText}`);
401
+ }
402
+ return parts.join(`
403
+
404
+ ---
405
+
406
+ `) || "(暂无内容)";
407
+ }
408
+ function doPatch(entry) {
409
+ if (!entry.thinkingMsgId)
410
+ return;
411
+ entry.lastPatchTime = Date.now();
412
+ const hasText = entry.textPartOrder.some((id) => (entry.textParts.get(id) ?? "").length > 0);
413
+ const stage = hasText ? "replying" : "reasoning";
414
+ const summaryText = hasText ? "✍️ 正在输出回复..." : "\uD83E\uDD14 正在推理...";
415
+ const detail = buildDetailContent(entry);
416
+ entry.channel.patchProgress?.(entry.thinkingMsgId, summaryText, detail, stage);
417
+ }
418
+ function scheduleThrottledPatch(entry) {
419
+ const now = Date.now();
420
+ if (now - entry.lastPatchTime >= PATCH_THROTTLE_MS) {
421
+ doPatch(entry);
422
+ } else if (!entry.pendingPatchTimer) {
423
+ const delay = PATCH_THROTTLE_MS - (now - entry.lastPatchTime);
424
+ entry.pendingPatchTimer = setTimeout(() => {
425
+ entry.pendingPatchTimer = null;
426
+ doPatch(entry);
427
+ }, delay);
428
+ }
429
+ }
333
430
  function createMessageHandler(channel, sessionManager, client, pendingMap) {
334
431
  return async (msg) => {
335
432
  const { userId, replyTarget, text } = msg;
@@ -346,6 +443,7 @@ function createMessageHandler(channel, sessionManager, client, pendingMap) {
346
443
  let thinkingMsgId = null;
347
444
  if (channel.sendThinkingCard) {
348
445
  thinkingMsgId = await channel.sendThinkingCard(replyTarget);
446
+ fileLog("info", `[${channel.name}] sendThinkingCard 完成: thinkingMsgId=${thinkingMsgId}`);
349
447
  }
350
448
  let sessionId;
351
449
  try {
@@ -367,8 +465,10 @@ function createMessageHandler(channel, sessionManager, client, pendingMap) {
367
465
  parts: [{ type: "text", text }]
368
466
  }
369
467
  });
468
+ fileLog("info", `[${channel.name}] promptAsync 成功: sessionId=${sessionId}`);
370
469
  } catch (err) {
371
470
  const errorMsg = err?.data?.message ?? err?.message ?? String(err);
471
+ fileLog("error", `[${channel.name}] promptAsync 失败: ${errorMsg}`);
372
472
  await client.app.log({
373
473
  body: { service: "chat-channel", level: "error", message: `[${channel.name}] promptAsync 失败: ${errorMsg}`, extra: { userId } }
374
474
  });
@@ -404,28 +504,22 @@ async function waitForSessionAndReply(client, channel, sessionId, replyTarget, t
404
504
  clearTimeout(timeoutId);
405
505
  pendingMap.delete(sessionId);
406
506
  reject(err);
407
- }
507
+ },
508
+ thinkingMsgId,
509
+ channel,
510
+ replyTarget,
511
+ lastPatchTime: 0,
512
+ pendingPatchTimer: null,
513
+ reasoning: "",
514
+ textParts: new Map,
515
+ textPartOrder: [],
516
+ toolParts: new Map,
517
+ toolPartOrder: []
408
518
  });
409
519
  }).catch((err) => {
410
520
  log("error", `[${channel.name}] session 出错: ${err.message}`);
411
521
  });
412
- let responseText = null;
413
- try {
414
- const messagesRes = await client.session.messages({ path: { id: sessionId } });
415
- const messages = messagesRes.data ?? [];
416
- const lastAssistant = [...messages].reverse().find((m) => m.info?.role === "assistant");
417
- log("info", `[${channel.name}] [diag] messages count=${messages.length}, lastAssistant=${lastAssistant ? `id=${lastAssistant.info?.id} parts=${JSON.stringify((lastAssistant.parts ?? []).map((p) => ({ type: p.type, textLen: p.text?.length ?? 0 })))}` : "null"}`);
418
- if (lastAssistant) {
419
- responseText = extractResponseText(lastAssistant.parts ?? []);
420
- }
421
- } catch (err) {
422
- log("error", `[${channel.name}] 获取最终回复失败: ${String(err)}`);
423
- }
424
- log("info", `[${channel.name}] [diag] responseText length=${responseText?.length ?? 0} preview="${responseText?.slice(0, 80)}"`);
425
- if (!responseText) {
426
- responseText = "(AI 没有返回文字回复)";
427
- }
428
- await channel.send(replyTarget, responseText);
522
+ log("info", `[${channel.name}] session 完成,卡片已更新,跳过文本回复`);
429
523
  }
430
524
  var ChatChannelPlugin = async ({ client }) => {
431
525
  const configDir = join(process.env["HOME"] ?? `/Users/${process.env["USER"] ?? "unknown"}`, ".config", "opencode");
@@ -477,11 +571,61 @@ var ChatChannelPlugin = async ({ client }) => {
477
571
  return {
478
572
  event: async ({ event }) => {
479
573
  const props = event.properties;
574
+ if (event.type === "message.part.updated") {
575
+ const part = props?.["part"];
576
+ fileLog("info", `[diag] part.updated raw: ${JSON.stringify(part).slice(0, 300)}`);
577
+ const sessionId = part?.["sessionID"] ?? part?.["session_id"];
578
+ if (sessionId) {
579
+ const entry = pendingMap.get(sessionId);
580
+ if (entry) {
581
+ const partType = part?.["type"];
582
+ const partId = part?.["id"];
583
+ if (partType === "reasoning") {
584
+ entry.reasoning = part?.["text"] ?? "";
585
+ scheduleThrottledPatch(entry);
586
+ } else if (partType === "text") {
587
+ if (partId) {
588
+ if (!entry.textParts.has(partId)) {
589
+ entry.textPartOrder.push(partId);
590
+ }
591
+ entry.textParts.set(partId, part?.["text"] ?? "");
592
+ }
593
+ scheduleThrottledPatch(entry);
594
+ } else if (partType === "tool") {
595
+ const callId = part?.["callID"];
596
+ const toolName = part?.["tool"];
597
+ const toolState = part?.["state"];
598
+ const status = toolState?.["status"];
599
+ const toolInput = toolState?.["input"];
600
+ const toolOutput = toolState?.["output"];
601
+ if (callId && toolName && status) {
602
+ if (!entry.toolParts.has(callId)) {
603
+ entry.toolPartOrder.push(callId);
604
+ }
605
+ entry.toolParts.set(callId, { tool: toolName, status, input: toolInput, output: toolOutput });
606
+ scheduleThrottledPatch(entry);
607
+ }
608
+ }
609
+ }
610
+ }
611
+ }
480
612
  if (event.type === "session.idle") {
481
613
  const sessionId = props?.["sessionID"] ?? props?.["id"];
482
614
  if (sessionId) {
483
615
  fileLog("info", `[diag] event hook: session.idle sessionId=${sessionId}`);
484
- pendingMap.get(sessionId)?.resolve();
616
+ const entry = pendingMap.get(sessionId);
617
+ if (entry) {
618
+ if (entry.pendingPatchTimer) {
619
+ clearTimeout(entry.pendingPatchTimer);
620
+ entry.pendingPatchTimer = null;
621
+ }
622
+ fileLog("info", `[diag] session.idle: thinkingMsgId=${entry.thinkingMsgId}, hasPatchDone=${!!entry.channel.patchDone}, reasoning.len=${entry.reasoning.length}, textParts.count=${entry.textPartOrder.length}, toolParts.count=${entry.toolPartOrder.length}`);
623
+ if (entry.thinkingMsgId && entry.channel.patchDone) {
624
+ const detail = buildDetailContent(entry);
625
+ await entry.channel.patchDone(entry.thinkingMsgId, detail);
626
+ }
627
+ entry.resolve();
628
+ }
485
629
  }
486
630
  }
487
631
  if (event.type === "session.error") {
@@ -497,7 +641,14 @@ var ChatChannelPlugin = async ({ client }) => {
497
641
  });
498
642
  if (sessionId) {
499
643
  fileLog("info", `[diag] event hook: session.error sessionId=${sessionId} err=${errMsg}`);
500
- pendingMap.get(sessionId)?.reject(new Error(errMsg));
644
+ const entry = pendingMap.get(sessionId);
645
+ if (entry) {
646
+ if (entry.pendingPatchTimer) {
647
+ clearTimeout(entry.pendingPatchTimer);
648
+ entry.pendingPatchTimer = null;
649
+ }
650
+ entry.reject(new Error(errMsg));
651
+ }
501
652
  }
502
653
  }
503
654
  }
package/dist/types.d.ts CHANGED
@@ -25,7 +25,9 @@ export interface IncomingMessage {
25
25
  * - start(): 启动监听,收到消息时调用 onMessage 回调
26
26
  * - send(): 向指定 target 发送文本回复
27
27
  * - sendThinkingCard(): 发送占位卡片,返回可更新的 ID(可选)
28
- * - updateThinkingCard(): 更新占位卡片内容(可选)
28
+ * - updateThinkingCard(): 更新占位卡片内容(可选,旧接口向下兼容)
29
+ * - patchProgress(): 更新卡片为进度状态,外部摘要+内部详情折叠面板(可选)
30
+ * - patchDone(): 更新卡片为完成状态(可选)
29
31
  * - stop(): 优雅关闭(可选)
30
32
  */
31
33
  export interface ChatChannel {
@@ -48,11 +50,26 @@ export interface ChatChannel {
48
50
  */
49
51
  sendThinkingCard?(replyTarget: string): Promise<string | null>;
50
52
  /**
51
- * 更新占位消息的内容。
53
+ * 更新占位消息的内容(旧接口,向下兼容)。
52
54
  * @param placeholderId sendThinkingCard 返回的 ID
53
55
  * @param statusText 新状态文本
54
56
  */
55
57
  updateThinkingCard?(placeholderId: string, statusText: string): Promise<void>;
58
+ /**
59
+ * 更新思考卡片为进度状态(节流调用)。
60
+ * 卡片外部显示 summary 摘要,折叠面板内部展示 detail 详细内容。
61
+ * @param placeholderId sendThinkingCard 返回的 ID
62
+ * @param summary 外部摘要文字(如"🤔 正在推理...")
63
+ * @param detail 折叠面板内部展开后的详细内容(reasoning / text 累积)
64
+ * @param stage 当前阶段,用于选择卡片图标和样式
65
+ */
66
+ patchProgress?(placeholderId: string, summary: string, detail: string, stage: "reasoning" | "replying"): Promise<void>;
67
+ /**
68
+ * 更新思考卡片为完成状态。
69
+ * @param placeholderId sendThinkingCard 返回的 ID
70
+ * @param detail 展开后显示的完整内容(reasoning + text 摘要)
71
+ */
72
+ patchDone?(placeholderId: string, detail: string): Promise<void>;
56
73
  /** 优雅停止渠道(可选)。 */
57
74
  stop?(): Promise<void>;
58
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAI3D,kBAAkB;AAClB,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAID;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;OAGG;IACH,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;OAIG;IACH,gBAAgB,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE/D;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E,kBAAkB;IAClB,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,YAAY,KACjB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAIjC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,8CAA8C;AAC9C,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAI3D,kBAAkB;AAClB,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAID;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;OAGG;IACH,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;OAIG;IACH,gBAAgB,CAAC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE/D;;;;OAIG;IACH,kBAAkB,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9E;;;;;;;OAOG;IACH,aAAa,CAAC,CACZ,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,GAAG,UAAU,GAC9B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,kBAAkB;IAClB,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,YAAY,KACjB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAIjC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-chat-channel",
3
- "version": "1.2.12",
3
+ "version": "1.2.13",
4
4
  "description": "opencode plugin — multi-channel bot (Feishu/Lark, WeCom) with extensible ChatChannel interface",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",