@vui-design/openclaw-plugin-feishu-progress 0.2.0 → 0.2.1

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": "@vui-design/openclaw-plugin-feishu-progress",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "飞书任务进度卡片插件 — 在 AI 执行复杂多步骤任务时,实时更新飞书进度卡片",
5
5
  "keywords": [
6
6
  "openclaw-plugin",
package/src/index.ts CHANGED
@@ -47,16 +47,19 @@ export default {
47
47
  });
48
48
 
49
49
  // ── 1. 收到用户消息时,记录当前会话对应的飞书 chat_id ────────────────────
50
+ // ctx: PluginHookMessageContext → 有 channelId / accountId / conversationId,无 sessionKey
50
51
  api.on('message_received', async (_event: any, ctx: any) => {
51
52
  if (ctx.channelId !== 'feishu') return;
52
53
  if (!ctx.conversationId) return;
53
- const key = ctx.sessionKey ?? ctx.accountId ?? 'default';
54
+ const key = ctx.accountId ?? 'default';
54
55
  sessionChatMap.set(key, ctx.conversationId);
55
56
  });
56
57
 
57
58
  // ── 2. 每次工具调用前,自动推送进度到飞书 ──────────────────────────────
59
+ // ctx: PluginHookToolContext → 有 agentId / sessionKey / runId,无 conversationId
60
+ // agentId 与 message_received 的 accountId 通过 bindings 对应,用作关联 key
58
61
  api.on('before_tool_call', async (event: any, ctx: any) => {
59
- const key = ctx.sessionKey ?? 'default';
62
+ const key = ctx.agentId ?? ctx.sessionKey ?? 'default';
60
63
  const chatId = sessionChatMap.get(key);
61
64
  if (!chatId) return;
62
65
 
@@ -69,8 +72,9 @@ export default {
69
72
  });
70
73
 
71
74
  // ── 3. 任务结束后清理 session 映射 ───────────────────────────────────────
75
+ // ctx: PluginHookAgentContext → 有 agentId / sessionKey
72
76
  api.on('agent_end', async (_event: any, ctx: any) => {
73
- const key = ctx.sessionKey ?? 'default';
77
+ const key = ctx.agentId ?? ctx.sessionKey ?? 'default';
74
78
  sessionChatMap.delete(key);
75
79
  });
76
80
  },
@@ -1,58 +0,0 @@
1
- import type { StepEntry } from './session-store.js';
2
-
3
- export interface CardInput {
4
- stepIndex: number;
5
- totalSteps: number;
6
- done?: boolean;
7
- }
8
-
9
- export interface CardSession {
10
- steps: StepEntry[];
11
- startTime: number;
12
- }
13
-
14
- function formatElapsed(ms: number): string {
15
- const sec = Math.floor(ms / 1000);
16
- if (sec < 60) return `${sec}s`;
17
- return `${Math.floor(sec / 60)}m ${sec % 60}s`;
18
- }
19
-
20
- export function buildProgressCard(input: CardInput, session: CardSession): object {
21
- const elapsed = formatElapsed(Date.now() - session.startTime);
22
- const isDone = input.done === true;
23
-
24
- const headerText = isDone
25
- ? `任务完成 · 用时 ${elapsed}`
26
- : `正在执行任务 · 已用时 ${elapsed}`;
27
-
28
- const stepElements = session.steps.map((s) => {
29
- const icon =
30
- s.status === 'done' ? '✅' : s.status === 'active' ? '🔄' : '⬜';
31
- return {
32
- tag: 'div',
33
- text: { tag: 'lark_md', content: `${icon} ${s.label}` },
34
- };
35
- });
36
-
37
- return {
38
- config: { wide_screen_mode: true },
39
- header: {
40
- template: isDone ? 'green' : 'blue',
41
- title: {
42
- tag: 'plain_text',
43
- content: '🤖 OpenClaw 任务进度',
44
- },
45
- },
46
- elements: [
47
- {
48
- tag: 'div',
49
- text: {
50
- tag: 'lark_md',
51
- content: `**${isDone ? '✅' : '⏳'} ${headerText}**`,
52
- },
53
- },
54
- { tag: 'hr' },
55
- ...stepElements,
56
- ],
57
- };
58
- }
@@ -1,29 +0,0 @@
1
- export interface StepEntry {
2
- label: string;
3
- status: 'done' | 'active' | 'pending';
4
- }
5
-
6
- export interface SessionEntry {
7
- msgId: string;
8
- chatId: string;
9
- startTime: number;
10
- steps: StepEntry[];
11
- }
12
-
13
- class SessionStore {
14
- private store = new Map<string, SessionEntry>();
15
-
16
- get(key: string): SessionEntry | undefined {
17
- return this.store.get(key);
18
- }
19
-
20
- set(key: string, entry: SessionEntry): void {
21
- this.store.set(key, entry);
22
- }
23
-
24
- delete(key: string): void {
25
- this.store.delete(key);
26
- }
27
- }
28
-
29
- export const sessionStore = new SessionStore();