opencode-lark 0.1.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.
Files changed (138) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/LICENSE +21 -0
  3. package/README.md +322 -0
  4. package/README.zh-CN.md +324 -0
  5. package/bin/opencode-lark.js +2 -0
  6. package/dist/channel/base-plugin.d.ts +31 -0
  7. package/dist/channel/base-plugin.d.ts.map +1 -0
  8. package/dist/channel/base-plugin.js +42 -0
  9. package/dist/channel/base-plugin.js.map +1 -0
  10. package/dist/channel/feishu/feishu-plugin.d.ts +36 -0
  11. package/dist/channel/feishu/feishu-plugin.d.ts.map +1 -0
  12. package/dist/channel/feishu/feishu-plugin.js +149 -0
  13. package/dist/channel/feishu/feishu-plugin.js.map +1 -0
  14. package/dist/channel/feishu/index.d.ts +2 -0
  15. package/dist/channel/feishu/index.d.ts.map +1 -0
  16. package/dist/channel/feishu/index.js +2 -0
  17. package/dist/channel/feishu/index.js.map +1 -0
  18. package/dist/channel/index.d.ts +4 -0
  19. package/dist/channel/index.d.ts.map +1 -0
  20. package/dist/channel/index.js +4 -0
  21. package/dist/channel/index.js.map +1 -0
  22. package/dist/channel/manager.d.ts +37 -0
  23. package/dist/channel/manager.d.ts.map +1 -0
  24. package/dist/channel/manager.js +68 -0
  25. package/dist/channel/manager.js.map +1 -0
  26. package/dist/channel/mock/mock-plugin.d.ts +24 -0
  27. package/dist/channel/mock/mock-plugin.d.ts.map +1 -0
  28. package/dist/channel/mock/mock-plugin.js +42 -0
  29. package/dist/channel/mock/mock-plugin.js.map +1 -0
  30. package/dist/channel/types.d.ts +226 -0
  31. package/dist/channel/types.d.ts.map +1 -0
  32. package/dist/channel/types.js +7 -0
  33. package/dist/channel/types.js.map +1 -0
  34. package/dist/cron/cron-service.d.ts +40 -0
  35. package/dist/cron/cron-service.d.ts.map +1 -0
  36. package/dist/cron/cron-service.js +140 -0
  37. package/dist/cron/cron-service.js.map +1 -0
  38. package/dist/cron/heartbeat.d.ts +30 -0
  39. package/dist/cron/heartbeat.d.ts.map +1 -0
  40. package/dist/cron/heartbeat.js +76 -0
  41. package/dist/cron/heartbeat.js.map +1 -0
  42. package/dist/feishu/api-client.d.ts +19 -0
  43. package/dist/feishu/api-client.d.ts.map +1 -0
  44. package/dist/feishu/api-client.js +98 -0
  45. package/dist/feishu/api-client.js.map +1 -0
  46. package/dist/feishu/card-builder.d.ts +10 -0
  47. package/dist/feishu/card-builder.d.ts.map +1 -0
  48. package/dist/feishu/card-builder.js +74 -0
  49. package/dist/feishu/card-builder.js.map +1 -0
  50. package/dist/feishu/cardkit-client.d.ts +48 -0
  51. package/dist/feishu/cardkit-client.d.ts.map +1 -0
  52. package/dist/feishu/cardkit-client.js +97 -0
  53. package/dist/feishu/cardkit-client.js.map +1 -0
  54. package/dist/feishu/message-dedup.d.ts +28 -0
  55. package/dist/feishu/message-dedup.d.ts.map +1 -0
  56. package/dist/feishu/message-dedup.js +58 -0
  57. package/dist/feishu/message-dedup.js.map +1 -0
  58. package/dist/feishu/webhook-server.d.ts +20 -0
  59. package/dist/feishu/webhook-server.d.ts.map +1 -0
  60. package/dist/feishu/webhook-server.js +111 -0
  61. package/dist/feishu/webhook-server.js.map +1 -0
  62. package/dist/feishu/ws-client.d.ts +17 -0
  63. package/dist/feishu/ws-client.d.ts.map +1 -0
  64. package/dist/feishu/ws-client.js +158 -0
  65. package/dist/feishu/ws-client.js.map +1 -0
  66. package/dist/handler/interactive-handler.d.ts +16 -0
  67. package/dist/handler/interactive-handler.d.ts.map +1 -0
  68. package/dist/handler/interactive-handler.js +86 -0
  69. package/dist/handler/interactive-handler.js.map +1 -0
  70. package/dist/handler/interactive-poller.d.ts +16 -0
  71. package/dist/handler/interactive-poller.d.ts.map +1 -0
  72. package/dist/handler/interactive-poller.js +147 -0
  73. package/dist/handler/interactive-poller.js.map +1 -0
  74. package/dist/handler/message-handler.d.ts +34 -0
  75. package/dist/handler/message-handler.d.ts.map +1 -0
  76. package/dist/handler/message-handler.js +305 -0
  77. package/dist/handler/message-handler.js.map +1 -0
  78. package/dist/handler/streaming-integration.d.ts +21 -0
  79. package/dist/handler/streaming-integration.d.ts.map +1 -0
  80. package/dist/handler/streaming-integration.js +325 -0
  81. package/dist/handler/streaming-integration.js.map +1 -0
  82. package/dist/index.d.ts +16 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +281 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/memory/memory-manager.d.ts +16 -0
  87. package/dist/memory/memory-manager.d.ts.map +1 -0
  88. package/dist/memory/memory-manager.js +58 -0
  89. package/dist/memory/memory-manager.js.map +1 -0
  90. package/dist/session/progress-tracker.d.ts +12 -0
  91. package/dist/session/progress-tracker.d.ts.map +1 -0
  92. package/dist/session/progress-tracker.js +46 -0
  93. package/dist/session/progress-tracker.js.map +1 -0
  94. package/dist/session/session-manager.d.ts +15 -0
  95. package/dist/session/session-manager.d.ts.map +1 -0
  96. package/dist/session/session-manager.js +91 -0
  97. package/dist/session/session-manager.js.map +1 -0
  98. package/dist/streaming/event-processor.d.ts +74 -0
  99. package/dist/streaming/event-processor.d.ts.map +1 -0
  100. package/dist/streaming/event-processor.js +240 -0
  101. package/dist/streaming/event-processor.js.map +1 -0
  102. package/dist/streaming/session-observer.d.ts +19 -0
  103. package/dist/streaming/session-observer.d.ts.map +1 -0
  104. package/dist/streaming/session-observer.js +140 -0
  105. package/dist/streaming/session-observer.js.map +1 -0
  106. package/dist/streaming/streaming-card.d.ts +37 -0
  107. package/dist/streaming/streaming-card.d.ts.map +1 -0
  108. package/dist/streaming/streaming-card.js +139 -0
  109. package/dist/streaming/streaming-card.js.map +1 -0
  110. package/dist/streaming/subagent-card.d.ts +32 -0
  111. package/dist/streaming/subagent-card.d.ts.map +1 -0
  112. package/dist/streaming/subagent-card.js +103 -0
  113. package/dist/streaming/subagent-card.js.map +1 -0
  114. package/dist/streaming/subagent-tracker.d.ts +45 -0
  115. package/dist/streaming/subagent-tracker.d.ts.map +1 -0
  116. package/dist/streaming/subagent-tracker.js +118 -0
  117. package/dist/streaming/subagent-tracker.js.map +1 -0
  118. package/dist/types.d.ts +55 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +5 -0
  121. package/dist/types.js.map +1 -0
  122. package/dist/utils/config.d.ts +197 -0
  123. package/dist/utils/config.d.ts.map +1 -0
  124. package/dist/utils/config.js +87 -0
  125. package/dist/utils/config.js.map +1 -0
  126. package/dist/utils/db.d.ts +12 -0
  127. package/dist/utils/db.d.ts.map +1 -0
  128. package/dist/utils/db.js +35 -0
  129. package/dist/utils/db.js.map +1 -0
  130. package/dist/utils/event-listeners.d.ts +12 -0
  131. package/dist/utils/event-listeners.d.ts.map +1 -0
  132. package/dist/utils/event-listeners.js +21 -0
  133. package/dist/utils/event-listeners.js.map +1 -0
  134. package/dist/utils/logger.d.ts +11 -0
  135. package/dist/utils/logger.d.ts.map +1 -0
  136. package/dist/utils/logger.js +38 -0
  137. package/dist/utils/logger.js.map +1 -0
  138. package/package.json +41 -0
@@ -0,0 +1,324 @@
1
+ [English](README.md)
2
+
3
+ # opencode-lark
4
+
5
+ > 将飞书群聊与 opencode TUI session 打通,实现双向实时消息转发。
6
+
7
+ ![CI](https://github.com/guazi04/opencode-lark/actions/workflows/ci.yml/badge.svg)
8
+ ![npm](https://img.shields.io/npm/v/opencode-lark.svg)
9
+ ![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
10
+
11
+ ---
12
+
13
+ ## 功能特性
14
+
15
+ - **实时桥接** — 飞书消息即时出现在 opencode TUI,agent 回复以动态卡片形式推送回飞书。
16
+ - **WebSocket 长连接** — 采用飞书 WebSocket 长连接模式,无需公网 IP,无需轮询。
17
+ - **SSE 流式输出** — 订阅 opencode SSE 事件流,防抖处理卡片更新,避免触发频率限制。
18
+ - **对话记忆** — SQLite 存储每个会话的对话历史,每次消息自动携带上下文。
19
+ - **Session 自动发现** — 自动发现并绑定当前目录的最新 TUI session,重启后映射关系持久保存。
20
+ - **优雅重连** — 启动时指数退避重连 opencode server,最多重试 10 次,无需手动等待 server 就绪。
21
+ - **可扩展渠道层** — `ChannelPlugin` 接口设计,可扩展接入 Slack、Discord 等其他平台,无需修改核心逻辑。
22
+
23
+ ---
24
+
25
+ ## 架构概览
26
+
27
+ ```
28
+ Feishu client
29
+ ↕ WebSocket
30
+ Feishu Open Platform
31
+ ↕ WebSocket
32
+ opencode-lark (本项目)
33
+ ↕ HTTP API + SSE
34
+ opencode server (localhost:4096)
35
+ ↕ stdin/stdout
36
+ opencode TUI
37
+ ```
38
+
39
+ > `opencode serve` 运行 HTTP server,在另一个终端用 `opencode attach` 查看 TUI 会话。
40
+
41
+ **入站(飞书 → TUI):** 飞书通过 WebSocket 发送消息,opencode-lark 标准化处理后找到绑定的 session,拼接对话历史,POST 到 opencode API。TUI 即时收到消息。
42
+
43
+ **出站(TUI → 飞书):** opencode-lark 订阅 opencode SSE 流。agent 输出文字时,`TextDelta` 事件累积并触发防抖卡片更新。`SessionIdle` 到达后,最终卡片推送到飞书。
44
+
45
+ ---
46
+
47
+ ## 安装
48
+
49
+ ```bash
50
+ # 全局安装
51
+ npm install -g opencode-lark
52
+ # 或
53
+ bun add -g opencode-lark
54
+ ```
55
+
56
+ 或从源码运行:
57
+
58
+ ```bash
59
+ git clone https://github.com/guazi04/opencode-lark.git
60
+ cd opencode-lark
61
+ bun install
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 飞书应用配置
67
+
68
+ 本节介绍如何创建飞书企业自建应用并配置所需权限。
69
+
70
+ ### 1. 创建企业自建应用
71
+
72
+ 1. 打开[飞书开放平台](https://open.feishu.cn/app)
73
+ 2. 点击**创建应用** → **创建企业自建应用**
74
+ 3. 填写应用名称和描述后确认
75
+
76
+ ### 2. 开启机器人能力
77
+
78
+ 进入**应用功能 → 机器人**,开启机器人功能。
79
+
80
+ ### 3. 获取凭证
81
+
82
+ 进入**凭证与基础信息**找到:
83
+
84
+ - **App ID** → 设为 `FEISHU_APP_ID`
85
+ - **App Secret** → 设为 `FEISHU_APP_SECRET`
86
+
87
+ 步骤 6 配置 opencode-lark 时需要这些凭证。
88
+
89
+ ### 4. 配置权限
90
+
91
+ 进入**开发配置 → 权限管理**,开通以下权限:
92
+
93
+ | 权限 | 权限标识 | 用途 | 必需 |
94
+ |---|---|---|---|
95
+ | 获取与发送单聊、群组消息 | `im:message` | 发送消息、更新卡片 | ✅ |
96
+ | 获取用户发给机器人的单聊消息 | `im:message.p2p_msg:readonly` | 接收私聊消息 | ✅ |
97
+ | 获取群组中所有消息 | `im:message.group_msg` | 接收群聊中的所有消息 | ✅ |
98
+ | 获取群组中 @机器人的消息 | `im:message.group_at_msg:readonly` | 接收群聊中 @机器人的消息 | ✅ |
99
+ | 获取与上传图片或文件资源 | `im:resource` | 处理消息附件 | ✅ |
100
+ | 创建并发布卡片 | `cardkit:card:write` | 渲染交互式卡片(提问、权限审批) | ✅ |
101
+
102
+ ### 5. 发布应用
103
+
104
+ 进入**应用发布 → 版本管理与发布**,创建版本并提交审核。审核通过后,将机器人添加到工作区。
105
+
106
+ > **注意**:测试阶段,应用管理员可直接使用,无需等待审核通过。
107
+
108
+ ### 6. 配置并启动 opencode-lark
109
+
110
+ 在配置事件订阅之前,需要先启动 opencode-lark,飞书才能检测到 WebSocket 连接。
111
+
112
+ 1. 克隆仓库并安装依赖:
113
+ ```bash
114
+ git clone https://github.com/guazi04/opencode-lark.git
115
+ cd opencode-lark
116
+ bun install
117
+ ```
118
+
119
+ 2. 配置凭证:
120
+ ```bash
121
+ cp .env.example .env
122
+ ```
123
+ 打开 `.env`,填入步骤 3 获取的 `FEISHU_APP_ID` 和 `FEISHU_APP_SECRET`。
124
+
125
+ 3. 在一个终端启动 opencode server:
126
+ ```bash
127
+ OPENCODE_SERVER_PORT=4096 opencode serve
128
+ ```
129
+
130
+ 4. 在另一个终端启动 opencode-lark:
131
+ ```bash
132
+ bun run dev
133
+ ```
134
+ 保持运行,然后继续下一步配置事件订阅。
135
+
136
+ > **提示**:要在 TUI 中实时查看消息,打开第三个终端并 attach 到 session:
137
+ > ```bash
138
+ > opencode attach http://127.0.0.1:4096 --session {session_id}
139
+ > ```
140
+ > `session_id` 会在 opencode-lark 启动日志中显示(如 `Bound to TUI session: ... → ses_xxxxx`)。
141
+
142
+ ### 7. 订阅事件
143
+
144
+ 进入**开发配置 → 事件订阅**,操作如下:
145
+
146
+ 1. 选择**长连接**模式 — 无需公网 IP
147
+ 2. 添加以下事件:
148
+
149
+ | 事件名称 | 事件标识 | 用途 | 必需 |
150
+ |---|---|---|---|
151
+ | 接收消息 | `im.message.receive_v1` | 接收用户消息 | ✅ |
152
+
153
+ > ⚠️ **重要**:保存长连接模式前 opencode-lark 必须处于运行状态(步骤 6)。如果看到“应用未建立长连接”错误,请返回步骤 6 确认应用已启动。
154
+
155
+ ### 8. 订阅回调(交互式卡片)
156
+
157
+ 进入**开发配置 → 事件与回调 → 回调订阅** — 这是与上方“事件订阅”**独立的配置项**。
158
+
159
+ 1. 选择**长连接**模式
160
+ 2. 添加以下回调:
161
+
162
+ | 回调名称 | 回调标识 | 用途 | 必需 |
163
+ |---|---|---|---|
164
+ | 卡片回传交互 | `card.action.trigger` | 接收卡片按钮点击(提问回答、权限审批) | ✅ |
165
+
166
+ > ⚠️ **重要**:这是交互式卡片(提问和权限审批)正常工作的必要配置。未配置时,点击卡片按钮会报错 `200340`。
167
+ >
168
+ > 事件订阅和回调订阅是**两个独立的设置**,必须分别配置。
169
+
170
+ ### 故障排除
171
+
172
+ | 现象 | 可能原因 | 解决方案 |
173
+ |---|---|---|
174
+ | 机器人收不到消息 | 未开启长连接或事件未订阅 | 检查事件订阅,确认选择长连接模式 |
175
+ | 凭证错误 | `.env` 中凭证有误 | 从步骤 3 重新确认 App ID 和 App Secret |
176
+ | 收到消息但无回复 | opencode server 未启动 | 确保先启动 opencode server:`OPENCODE_SERVER_PORT=4096 opencode serve` |
177
+ | 卡片不实时更新 | 频率限制或防抖延迟 | 正常行为,防抖处理避免触发频率限制 |
178
+ | 点击卡片按钮报错 `200340` | 回调订阅未配置 | 进入**回调订阅** → 选择长连接 → 添加 `card.action.trigger` |
179
+ | 保存长连接模式时报“应用未建立长连接” | 应用未启动,飞书要求先建立连接 | 先完成步骤 6 启动 opencode-lark,再回飞书后台保存设置 |
180
+ ---
181
+
182
+ ## 快速开始
183
+
184
+ 如果已完成上述飞书应用配置,opencode-lark 应该已经在运行。直接跳到下方**发送测试消息**。
185
+
186
+ 否则按以下步骤操作:
187
+
188
+ ### 前置要求
189
+
190
+ - **[Bun](https://bun.sh)**(必需运行时,本项目使用 `bun:sqlite`,仅 Bun 支持)
191
+ - **[opencode](https://opencode.ai)** 已安装在本地
192
+ - 已配置凭证和事件订阅的飞书开放平台应用(参见[飞书应用配置](#飞书应用配置))
193
+
194
+ ### 步骤
195
+
196
+ **1. 克隆、安装并配置**
197
+
198
+ ```bash
199
+ git clone https://github.com/guazi04/opencode-lark.git
200
+ cd opencode-lark
201
+ bun install
202
+ cp .env.example .env
203
+ ```
204
+
205
+ 打开 `.env` 填写 `FEISHU_APP_ID` 和 `FEISHU_APP_SECRET`。
206
+
207
+ **2. 启动 opencode server**
208
+
209
+ ```bash
210
+ OPENCODE_SERVER_PORT=4096 opencode serve
211
+ ```
212
+
213
+ opencode server 在 4096 端口监听,端口被占用时自动递增。
214
+
215
+ **3. 启动 opencode-lark**
216
+
217
+ 在第二个终端:
218
+
219
+ ```bash
220
+ bun run dev
221
+ ```
222
+
223
+ 或通过全局安装运行:
224
+
225
+ ```bash
226
+ opencode-lark
227
+ ```
228
+
229
+ `dev` 模式带 `--watch`,代码修改后自动重启。
230
+
231
+ **4. 发送测试消息**
232
+
233
+ 向飞书机器人发送任意消息。首次联系时自动发现最新 TUI session 并回复:
234
+
235
+ > Connected to session: ses_xxxxx
236
+
237
+ 首次消息后飞书收到 session 绑定通知,之后双向消息互通。
238
+
239
+ ---
240
+
241
+ ## 配置说明
242
+
243
+ ### 环境变量
244
+
245
+ | 变量 | 必需 | 默认值 | 说明 |
246
+ |----------|----------|---------|-------------|
247
+ | `FEISHU_APP_ID` | 是 | | 飞书应用 App ID |
248
+ | `FEISHU_APP_SECRET` | 是 | | 飞书应用 App Secret |
249
+ | `OPENCODE_SERVER_URL` | 否 | `http://localhost:4096` | opencode server 地址 |
250
+ | `FEISHU_WEBHOOK_PORT` | 否 | `3001` | 卡片回调端口 |
251
+ | `OPENCODE_CWD` | 否 | `process.cwd()` | 覆盖 session 发现目录 |
252
+ | `FEISHU_VERIFICATION_TOKEN` | 否 | | 事件订阅验证 token |
253
+ | `FEISHU_ENCRYPT_KEY` | 否 | | 事件加密密钥 |
254
+
255
+ ### JSONC 配置文件
256
+
257
+ `opencode-lark.jsonc`(已加入 .gitignore,从 `opencode-lark.example.jsonc` 复制):
258
+ (同时支持 `opencode-feishu.jsonc` 以兼容旧版)
259
+
260
+ ```jsonc
261
+ // opencode-lark.jsonc
262
+ {
263
+ "feishu": {
264
+ "appId": "${FEISHU_APP_ID}",
265
+ "appSecret": "${FEISHU_APP_SECRET}",
266
+ "verificationToken": "${FEISHU_VERIFICATION_TOKEN}",
267
+ "webhookPort": 3001,
268
+ "encryptKey": "${FEISHU_ENCRYPT_KEY}"
269
+ },
270
+ // Default opencode agent name. This should match an agent configured in your opencode setup.
271
+ // Common values: "build", "claude", "code" — check your opencode config for available agents.
272
+ "defaultAgent": "build",
273
+ "dataDir": "./data",
274
+ "progress": {
275
+ "debounceMs": 500,
276
+ "maxDebounceMs": 3000
277
+ }
278
+ }
279
+ ```
280
+
281
+ 支持 `${ENV_VAR}` 环境变量插值和 JSONC 注释。无配置文件时自动从 `.env` 构建默认配置。
282
+
283
+ ---
284
+
285
+ ## 项目结构
286
+
287
+ ```
288
+ src/
289
+ ├── index.ts # Entry point, 9-phase startup + graceful shutdown
290
+ ├── types.ts # Shared type definitions
291
+ ├── channel/ # ChannelPlugin interface, ChannelManager, FeishuPlugin
292
+ ├── feishu/ # Feishu REST client, CardKit, WebSocket, message dedup
293
+ ├── handler/ # MessageHandler (inbound pipeline) + StreamingBridge (SSE → cards)
294
+ ├── session/ # TUI session discovery, thread→session mapping, progress cards
295
+ ├── streaming/ # EventProcessor (SSE parsing), SessionObserver, SubAgentTracker
296
+ ├── memory/ # SQLite-backed per-thread conversation history
297
+ ├── cron/ # CronService (scheduled jobs) + HeartbeatService
298
+ └── utils/ # Config loader, logger, SQLite init, EventListenerMap
299
+ ```
300
+
301
+ ---
302
+
303
+ ## 开发
304
+
305
+ ```bash
306
+ bun run dev # 开发模式,代码变更自动重启
307
+ bun run start # 生产模式
308
+ bun run test:run # 运行全部测试
309
+ bun run build # 编译到 dist/
310
+ ```
311
+
312
+ > 使用 `bun run test:run` 而非 `bun test`,后者会同时扫描 `src/` 和 `dist/` 下的测试文件。
313
+
314
+ ---
315
+
316
+ ## 参与贡献
317
+
318
+ 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解提 issue、提 PR 和代码风格的规范。
319
+
320
+ ---
321
+
322
+ ## License
323
+
324
+ [MIT](LICENSE) © 2026 opencode-lark contributors
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/index.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Abstract base class implementing common ChannelPlugin patterns.
3
+ * Provides default threading adapter and leaves required fields abstract.
4
+ */
5
+ import type { ChannelPlugin, ChannelId, ChannelMeta, ChannelConfigAdapter, ChannelGatewayAdapter, ChannelMessagingAdapter, ChannelOutboundAdapter, ChannelStreamingAdapter, ChannelThreadingAdapter } from "./types.js";
6
+ /**
7
+ * BaseChannelPlugin — abstract base for channel integrations.
8
+ *
9
+ * Subclasses MUST provide:
10
+ * - id: ChannelId
11
+ * - meta: ChannelMeta
12
+ * - config: ChannelConfigAdapter
13
+ *
14
+ * Provides default implementations for:
15
+ * - threading: resolveThread, mapSession, getSession
16
+ *
17
+ * Optional adapters (gateway, messaging, outbound, streaming)
18
+ * default to undefined — subclasses override as needed.
19
+ */
20
+ export declare abstract class BaseChannelPlugin implements ChannelPlugin {
21
+ abstract id: ChannelId;
22
+ abstract meta: ChannelMeta;
23
+ abstract config: ChannelConfigAdapter;
24
+ gateway?: ChannelGatewayAdapter;
25
+ messaging?: ChannelMessagingAdapter;
26
+ outbound?: ChannelOutboundAdapter;
27
+ streaming?: ChannelStreamingAdapter;
28
+ private readonly _threadSessionMap;
29
+ threading: ChannelThreadingAdapter;
30
+ }
31
+ //# sourceMappingURL=base-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-plugin.d.ts","sourceRoot":"","sources":["../../src/channel/base-plugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EAGxB,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;IAGrC,OAAO,CAAC,EAAE,qBAAqB,CAAA;IAC/B,SAAS,CAAC,EAAE,uBAAuB,CAAA;IACnC,QAAQ,CAAC,EAAE,sBAAsB,CAAA;IACjC,SAAS,CAAC,EAAE,uBAAuB,CAAA;IAGnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;IAEjE,SAAS,EAAE,uBAAuB,CAejC;CACF"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Abstract base class implementing common ChannelPlugin patterns.
3
+ * Provides default threading adapter and leaves required fields abstract.
4
+ */
5
+ /**
6
+ * BaseChannelPlugin — abstract base for channel integrations.
7
+ *
8
+ * Subclasses MUST provide:
9
+ * - id: ChannelId
10
+ * - meta: ChannelMeta
11
+ * - config: ChannelConfigAdapter
12
+ *
13
+ * Provides default implementations for:
14
+ * - threading: resolveThread, mapSession, getSession
15
+ *
16
+ * Optional adapters (gateway, messaging, outbound, streaming)
17
+ * default to undefined — subclasses override as needed.
18
+ */
19
+ export class BaseChannelPlugin {
20
+ // Optional adapters — subclasses override as needed
21
+ gateway;
22
+ messaging;
23
+ outbound;
24
+ streaming;
25
+ // Default threading adapter backed by an internal Map
26
+ _threadSessionMap = new Map();
27
+ threading = {
28
+ resolveThread: (inbound) => {
29
+ if (inbound.threadId) {
30
+ return `${inbound.chatId}:${inbound.threadId}`;
31
+ }
32
+ return inbound.chatId;
33
+ },
34
+ mapSession: (threadKey, sessionId) => {
35
+ this._threadSessionMap.set(threadKey, sessionId);
36
+ },
37
+ getSession: (threadKey) => {
38
+ return this._threadSessionMap.get(threadKey) ?? null;
39
+ },
40
+ };
41
+ }
42
+ //# sourceMappingURL=base-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-plugin.js","sourceRoot":"","sources":["../../src/channel/base-plugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAgB,iBAAiB;IAKrC,oDAAoD;IACpD,OAAO,CAAwB;IAC/B,SAAS,CAA0B;IACnC,QAAQ,CAAyB;IACjC,SAAS,CAA0B;IAEnC,sDAAsD;IACrC,iBAAiB,GAAG,IAAI,GAAG,EAAqB,CAAA;IAEjE,SAAS,GAA4B;QACnC,aAAa,EAAE,CAAC,OAA0B,EAAa,EAAE;YACvD,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrB,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAe,CAAA;YAC7D,CAAC;YACD,OAAO,OAAO,CAAC,MAAmB,CAAA;QACpC,CAAC;QAED,UAAU,EAAE,CAAC,SAAoB,EAAE,SAAiB,EAAQ,EAAE;YAC5D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAClD,CAAC;QAED,UAAU,EAAE,CAAC,SAAoB,EAAiB,EAAE;YAClD,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAA;QACtD,CAAC;KACF,CAAA;CACF"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * FeishuPlugin — channel adapter wrapping existing Feishu modules.
3
+ * Extends BaseChannelPlugin and implements all 6 adapters.
4
+ */
5
+ import { BaseChannelPlugin } from "../base-plugin.js";
6
+ import type { ChannelId, ChannelMeta, ChannelConfigAdapter, ChannelGatewayAdapter, ChannelMessagingAdapter, ChannelOutboundAdapter, ChannelStreamingAdapter, ChannelThreadingAdapter } from "../types.js";
7
+ import type { AppConfig } from "../../utils/config.js";
8
+ import type { FeishuApiClient } from "../../feishu/api-client.js";
9
+ import type { CardKitClient } from "../../feishu/cardkit-client.js";
10
+ import type { Logger } from "../../utils/logger.js";
11
+ import type { FeishuMessageEvent, FeishuCardAction } from "../../types.js";
12
+ export interface FeishuPluginDeps {
13
+ appConfig: AppConfig;
14
+ feishuClient: FeishuApiClient;
15
+ cardkitClient: CardKitClient;
16
+ logger: Logger;
17
+ onMessage?: (event: FeishuMessageEvent) => Promise<void>;
18
+ onCardAction?: (action: FeishuCardAction) => Promise<void>;
19
+ }
20
+ export declare class FeishuPlugin extends BaseChannelPlugin {
21
+ id: ChannelId;
22
+ meta: ChannelMeta;
23
+ private readonly appConfig;
24
+ private readonly feishuClient;
25
+ private readonly cardkitClient;
26
+ private readonly logger;
27
+ config: ChannelConfigAdapter;
28
+ gateway: ChannelGatewayAdapter;
29
+ messaging: ChannelMessagingAdapter;
30
+ outbound: ChannelOutboundAdapter;
31
+ streaming: ChannelStreamingAdapter;
32
+ threading: ChannelThreadingAdapter;
33
+ private readonly _feishuThreadMap;
34
+ constructor(deps: FeishuPluginDeps);
35
+ }
36
+ //# sourceMappingURL=feishu-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-plugin.d.ts","sourceRoot":"","sources":["../../../src/channel/feishu/feishu-plugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EAOxB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAO1E,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,SAAS,CAAA;IACpB,YAAY,EAAE,eAAe,CAAA;IAC7B,aAAa,EAAE,aAAa,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxD,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3D;AAID,qBAAa,YAAa,SAAQ,iBAAiB;IACxC,EAAE,EAAe,SAAS,CAAA;IAC1B,IAAI,EAAE,WAAW,CAIzB;IAED,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAItB,MAAM,EAAE,oBAAoB,CAAA;IAC5B,OAAO,EAAE,qBAAqB,CAAA;IAC9B,SAAS,EAAE,uBAAuB,CAAA;IAClC,QAAQ,EAAE,sBAAsB,CAAA;IAChC,SAAS,EAAE,uBAAuB,CAAA;IAClC,SAAS,EAAE,uBAAuB,CAAA;IAE3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA+B;gBAEpD,IAAI,EAAE,gBAAgB;CAmInC"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * FeishuPlugin — channel adapter wrapping existing Feishu modules.
3
+ * Extends BaseChannelPlugin and implements all 6 adapters.
4
+ */
5
+ import { BaseChannelPlugin } from "../base-plugin.js";
6
+ import { buildResponseCard } from "../../feishu/card-builder.js";
7
+ import { StreamingCardSession } from "../../streaming/streaming-card.js";
8
+ import { createFeishuWSGateway } from "../../feishu/ws-client.js";
9
+ // ── Plugin ──
10
+ export class FeishuPlugin extends BaseChannelPlugin {
11
+ id = "feishu";
12
+ meta = {
13
+ id: "feishu",
14
+ label: "Feishu",
15
+ description: "\u98de\u4e66 channel integration",
16
+ };
17
+ appConfig;
18
+ feishuClient;
19
+ cardkitClient;
20
+ logger;
21
+ // ── Adapters ──
22
+ config;
23
+ gateway;
24
+ messaging;
25
+ outbound;
26
+ streaming;
27
+ threading;
28
+ _feishuThreadMap = new Map();
29
+ constructor(deps) {
30
+ super();
31
+ this.appConfig = deps.appConfig;
32
+ this.feishuClient = deps.feishuClient;
33
+ this.cardkitClient = deps.cardkitClient;
34
+ this.logger = deps.logger;
35
+ // 1. Config adapter
36
+ this.config = {
37
+ listAccountIds: () => ["default"],
38
+ resolveAccount: (_id) => this.appConfig,
39
+ };
40
+ // 2. Gateway adapter
41
+ this.gateway = {
42
+ startAccount: async (_accountId, _signal) => {
43
+ const gw = createFeishuWSGateway({
44
+ appId: this.appConfig.feishu.appId,
45
+ appSecret: this.appConfig.feishu.appSecret,
46
+ onMessage: async (event) => {
47
+ this.logger.info(`Gateway received message: ${event.message_id}`);
48
+ if (deps.onMessage) {
49
+ await deps.onMessage(event);
50
+ }
51
+ },
52
+ onCardAction: deps.onCardAction,
53
+ });
54
+ gw.start();
55
+ },
56
+ };
57
+ // 3. Messaging adapter
58
+ this.messaging = {
59
+ normalizeInbound: (raw) => {
60
+ const event = raw;
61
+ let text;
62
+ try {
63
+ const parsed = JSON.parse(event.message.content);
64
+ text = parsed.text ?? "";
65
+ }
66
+ catch {
67
+ text = event.message.content;
68
+ }
69
+ // Feishu-specific threadId logic:
70
+ // - p2p: no threadId
71
+ // - group with root_id: threadId = root_id
72
+ // - group without root_id: threadId = message_id
73
+ let threadId;
74
+ if (event.chat_type === "group") {
75
+ threadId = event.root_id ?? event.message_id;
76
+ }
77
+ return {
78
+ messageId: event.message_id,
79
+ senderId: event.sender.sender_id.open_id,
80
+ text,
81
+ chatId: event.chat_id,
82
+ threadId,
83
+ timestamp: Date.now(),
84
+ };
85
+ },
86
+ formatOutbound: (msg) => {
87
+ return buildResponseCard(msg.text);
88
+ },
89
+ };
90
+ // 4. Outbound adapter
91
+ this.outbound = {
92
+ sendText: async (target, text) => {
93
+ await this.feishuClient.sendMessage(target.address, {
94
+ msg_type: "text",
95
+ content: JSON.stringify({ text }),
96
+ });
97
+ },
98
+ sendCard: async (target, card) => {
99
+ await this.feishuClient.sendMessage(target.address, {
100
+ msg_type: "interactive",
101
+ content: JSON.stringify(card),
102
+ });
103
+ },
104
+ };
105
+ // 5. Streaming adapter
106
+ this.streaming = {
107
+ createStreamingSession: (target) => {
108
+ const cardSession = new StreamingCardSession({
109
+ cardkitClient: this.cardkitClient,
110
+ feishuClient: this.feishuClient,
111
+ chatId: target.address,
112
+ });
113
+ const sessionId = `feishu_stream_${Date.now()}`;
114
+ const session = {
115
+ sessionId,
116
+ target,
117
+ pendingUpdates: [],
118
+ createdAt: Date.now(),
119
+ flush: async () => {
120
+ // No-op: flush is handled by tool status cards
121
+ },
122
+ };
123
+ return session;
124
+ },
125
+ };
126
+ // 6. Threading adapter (Feishu-specific override)
127
+ // Matches feishu_key logic from index.ts:
128
+ // p2p → chatId
129
+ // group with root_id → chatId:rootId
130
+ // group without root_id → chatId:messageId
131
+ // The normalizeInbound above sets threadId for group chats,
132
+ // so resolveThread just uses the base pattern: chatId or chatId:threadId
133
+ this.threading = {
134
+ resolveThread: (inbound) => {
135
+ if (inbound.threadId) {
136
+ return `${inbound.chatId}:${inbound.threadId}`;
137
+ }
138
+ return inbound.chatId;
139
+ },
140
+ mapSession: (threadKey, sessionId) => {
141
+ this._feishuThreadMap.set(threadKey, sessionId);
142
+ },
143
+ getSession: (threadKey) => {
144
+ return this._feishuThreadMap.get(threadKey) ?? null;
145
+ },
146
+ };
147
+ }
148
+ }
149
+ //# sourceMappingURL=feishu-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-plugin.js","sourceRoot":"","sources":["../../../src/channel/feishu/feishu-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./feishu-plugin.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channel/feishu/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from "./feishu-plugin.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channel/feishu/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./base-plugin.js";
3
+ export * from "./manager.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channel/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA"}
@@ -0,0 +1,4 @@
1
+ export * from "./types.js";
2
+ export * from "./base-plugin.js";
3
+ export * from "./manager.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/channel/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA"}