@m1heng-clawd/feishu 0.1.10 → 0.1.12

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 (47) hide show
  1. package/README.md +280 -7
  2. package/index.ts +6 -6
  3. package/package.json +13 -3
  4. package/skills/feishu-doc/SKILL.md +64 -2
  5. package/skills/feishu-task/SKILL.md +210 -0
  6. package/src/bitable-tools/index.ts +1 -0
  7. package/src/bot.ts +182 -71
  8. package/src/channel.ts +2 -0
  9. package/src/config-schema.ts +4 -0
  10. package/src/doc-tools/actions.ts +341 -0
  11. package/src/doc-tools/common.ts +33 -0
  12. package/src/doc-tools/index.ts +2 -0
  13. package/src/doc-tools/register.ts +90 -0
  14. package/src/{doc-schema.ts → doc-tools/schemas.ts} +39 -1
  15. package/src/{docx.ts → doc-write-service.ts} +204 -351
  16. package/src/drive-tools/actions.ts +182 -0
  17. package/src/drive-tools/common.ts +18 -0
  18. package/src/drive-tools/index.ts +2 -0
  19. package/src/drive-tools/register.ts +71 -0
  20. package/src/{drive-schema.ts → drive-tools/schemas.ts} +2 -1
  21. package/src/media.ts +5 -3
  22. package/src/onboarding.ts +14 -4
  23. package/src/perm-tools/actions.ts +111 -0
  24. package/src/perm-tools/common.ts +18 -0
  25. package/src/perm-tools/index.ts +2 -0
  26. package/src/perm-tools/register.ts +65 -0
  27. package/src/policy.ts +13 -0
  28. package/src/reply-dispatcher.ts +6 -4
  29. package/src/send.ts +33 -2
  30. package/src/task-tools/actions.ts +466 -13
  31. package/src/task-tools/constants.ts +13 -0
  32. package/src/task-tools/index.ts +1 -0
  33. package/src/task-tools/register.ts +175 -13
  34. package/src/task-tools/schemas.ts +433 -4
  35. package/src/text/markdown-links.ts +104 -0
  36. package/src/types.ts +1 -0
  37. package/src/wiki-tools/actions.ts +166 -0
  38. package/src/wiki-tools/common.ts +18 -0
  39. package/src/wiki-tools/index.ts +2 -0
  40. package/src/wiki-tools/register.ts +66 -0
  41. package/src/bitable.ts +0 -1
  42. package/src/drive.ts +0 -264
  43. package/src/perm.ts +0 -165
  44. package/src/task.ts +0 -1
  45. package/src/wiki.ts +0 -223
  46. /package/src/{perm-schema.ts → perm-tools/schemas.ts} +0 -0
  47. /package/src/{wiki-schema.ts → wiki-tools/schemas.ts} +0 -0
package/README.md CHANGED
@@ -5,6 +5,12 @@ Feishu/Lark (飞书) channel plugin for [OpenClaw](https://github.com/openclaw/o
5
5
  > **中文社区资料** - 配置教程、常见问题、使用技巧:[Wiki](https://github.com/m1heng/clawdbot-feishu/wiki)
6
6
  >
7
7
  > **Contributing / 贡献指南**: [CONTRIBUTING.md](./CONTRIBUTING.md)
8
+ >
9
+ > **Issue Reporting / 问题反馈**: Please check [Discussions](https://github.com/m1heng/clawdbot-feishu/discussions) first for common solutions, then open a structured Issue Form if needed.
10
+ > 问题反馈前请先查看 [Discussions](https://github.com/m1heng/clawdbot-feishu/discussions) 是否已有常见解答;如仍未解决,再提交结构化 Issue 模板。
11
+ >
12
+ > **Questions / 使用咨询**: Use `Question` issue for troubleshooting; use [Discussions](https://github.com/m1heng/clawdbot-feishu/discussions) for open-ended Q&A.
13
+ > 排查型咨询请提交 `Question` Issue;开放式交流请使用 [Discussions](https://github.com/m1heng/clawdbot-feishu/discussions)。
8
14
 
9
15
  [English](#english) | [中文](#中文)
10
16
 
@@ -77,19 +83,57 @@ openclaw plugins update feishu
77
83
  | `wiki:wiki:readonly` | `feishu_wiki` | List spaces, list nodes, get node info, search |
78
84
  | `bitable:app:readonly` | `feishu_bitable` | Read bitable records and fields |
79
85
  | `task:task:read` | `feishu_task_get` | Get task details |
86
+ | `task:tasklist:read` | `feishu_tasklist_get`, `feishu_tasklist_list` | Get/list tasklists |
87
+ | `task:comment:read` | `feishu_task_comment_list`, `feishu_task_comment_get` | List/get task comments |
88
+ | `task:attachment:read` | `feishu_task_attachment_list`, `feishu_task_attachment_get` | List/get task attachments |
80
89
 
81
90
  **Read-write** (optional, for create/edit/delete operations):
82
91
 
83
92
  | Permission | Tool | Description |
84
93
  |------------|------|-------------|
85
94
  | `docx:document` | `feishu_doc` | Create/edit documents |
86
- | `docx:document.block:convert` | `feishu_doc` | Markdown to blocks conversion (required for write/append) |
95
+ | `docx:document.block:convert` | `feishu_doc` | Markdown to blocks conversion (required for write/append/create_and_write; also used by `feishu_drive.import_document`) |
87
96
  | `drive:drive` | `feishu_doc`, `feishu_drive` | Upload images to documents, create folders, move/delete files |
88
97
  | `wiki:wiki` | `feishu_wiki` | Create/move/rename wiki nodes |
89
98
  | `bitable:app` | `feishu_bitable` | Create/update/delete bitable records and manage fields |
90
- | `task:task:write` | `feishu_task_create`, `feishu_task_update`, `feishu_task_delete` | Create/update/delete tasks |
99
+ | `task:task:write` | `feishu_task_create`, `feishu_task_subtask_create`, `feishu_task_update`, `feishu_task_delete` | Create/update/delete tasks |
100
+ | `task:tasklist:write` | `feishu_tasklist_create`, `feishu_tasklist_update`, `feishu_tasklist_delete`, `feishu_tasklist_add_members`, `feishu_tasklist_remove_members`, `feishu_task_add_tasklist`, `feishu_task_remove_tasklist` | Create/update/delete tasklists and manage membership |
101
+ | `task:comment:write` | `feishu_task_comment_create`, `feishu_task_comment_update`, `feishu_task_comment_delete` | Create/update/delete task comments |
102
+ | `task:attachment:write` | `feishu_task_attachment_upload`, `feishu_task_attachment_delete` | Upload/delete task attachments |
103
+
104
+ > Task scope names may vary slightly in Feishu console UI. If needed, search for Task / Tasklist / Comment / Attachment-related permissions and grant read/write accordingly.
105
+
106
+ #### Task Comment Scopes ⚠️
107
+
108
+ Task comments require dedicated scopes:
109
+ 1. Read comments: grant `task:comment:read`.
110
+ 2. Create/update/delete comments: grant `task:comment:write`.
111
+
112
+ If these scopes are missing, comment APIs will return permission-denied errors.
113
+
114
+ #### Task Attachment Upload ⚠️
115
+
116
+ Task attachments support upload/get/list/delete. Upload sources:
117
+ 1. Local files on the OpenClaw/Node host (`file_path`)
118
+ 2. Remote links (`file_url`, public or presigned)
119
+
120
+ For `file_url`, OpenClaw runtime media loader is used with safety checks and size limit (`mediaMaxMb`), then the downloaded file is uploaded via a temporary local file.
121
+
122
+ #### Tasklist Ownership ⚠️
123
+
124
+ > **Important:** Keep tasklist owner as the bot. Add users as members instead.
125
+
126
+ Tasklist access is granted based on owner + member roles. If you change the owner to a user and the bot is not a member, the bot may lose permission to read/edit/manage that tasklist (and subsequent operations will fail).
127
+
128
+ #### Task Visibility & Subtasks ⚠️
129
+
130
+ > **Important:** A user can only view a task when they are included as an assignee.
131
+ >
132
+ > **Limitation:** The bot can currently only create subtasks for tasks created by itself.
91
133
 
92
- > Task scope names may vary slightly in Feishu console UI. If needed, search for Task-related permissions and grant read/write accordingly.
134
+ To avoid “task created but not visible” issues:
135
+ 1. When creating a task, set the requesting user as an assignee.
136
+ 2. If you need more flexible subtask organization/visibility, consider using tasklists.
93
137
 
94
138
  #### Drive Access ⚠️
95
139
 
@@ -168,16 +212,112 @@ channels:
168
212
  connectionMode: "websocket"
169
213
  # DM policy: "pairing" | "open" | "allowlist"
170
214
  dmPolicy: "pairing"
215
+ # DM allowlist (open_id/user_id). Include "*" when dmPolicy="open"
216
+ allowFrom: []
171
217
  # Group policy: "open" | "allowlist" | "disabled"
172
218
  groupPolicy: "allowlist"
173
219
  # Require @mention in groups
174
220
  requireMention: true
221
+ # Group command mention bypass: "never" | "single_bot" | "always"
222
+ # Default "single_bot": allow authorized command-only messages without @
223
+ # only when the group has a single bot.
224
+ groupCommandMentionBypass: "single_bot"
175
225
  # Max media size in MB (default: 30)
176
226
  mediaMaxMb: 30
177
227
  # Render mode for bot replies: "auto" | "raw" | "card"
178
228
  renderMode: "auto"
179
229
  ```
180
230
 
231
+ #### DM Policy & Access Control
232
+
233
+ `dmPolicy` controls who can interact with the bot in direct messages (DM).
234
+ In multi-account mode, this is resolved per account (`channels.feishu.accounts.<accountId>`).
235
+
236
+ | `dmPolicy` | Who can send DM | How to grant access to a user |
237
+ |------------|------------------|--------------------------------|
238
+ | `pairing` | Users in `allowFrom`, or users approved through pairing | User sends a DM and gets a pairing code; bot owner runs `openclaw pairing approve feishu <code>`. |
239
+ | `open` | Everyone | Set `allowFrom: ["*"]` so all users are treated as allowed. |
240
+ | `allowlist` | Only users in `allowFrom` | Add the user's `open_id`/`user_id` to `allowFrom`, then reload config. |
241
+
242
+ Notes:
243
+ - `allowFrom` accepts Feishu user IDs (`open_id` recommended, `user_id` also supported).
244
+ - If `dmPolicy: "open"`, use `allowFrom: ["*"]`. This is required by top-level schema validation and keeps access behavior explicit.
245
+ - `pairing` and `allowlist` can both pre-authorize users with `allowFrom`.
246
+
247
+ Pairing flow (owner approval):
248
+ 1. User sends any DM to the bot.
249
+ 2. Bot replies with a pairing code (for example `H9ZEHY8R`).
250
+ 3. Bot owner approves:
251
+
252
+ ```bash
253
+ openclaw pairing approve feishu H9ZEHY8R
254
+ ```
255
+
256
+ 4. The user is added to the allow store and can chat immediately.
257
+
258
+ Example: open to everyone
259
+
260
+ ```yaml
261
+ channels:
262
+ feishu:
263
+ dmPolicy: "open"
264
+ allowFrom: ["*"]
265
+ ```
266
+
267
+ Example: controlled rollout (pairing + pre-approved users)
268
+
269
+ ```yaml
270
+ channels:
271
+ feishu:
272
+ dmPolicy: "pairing"
273
+ allowFrom:
274
+ - "ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
275
+ ```
276
+
277
+ Example: strict allowlist
278
+
279
+ ```yaml
280
+ channels:
281
+ feishu:
282
+ dmPolicy: "allowlist"
283
+ allowFrom:
284
+ - "ou_alice"
285
+ - "ou_bob"
286
+ ```
287
+
288
+ Example: account-level isolation
289
+
290
+ ```yaml
291
+ channels:
292
+ feishu:
293
+ accounts:
294
+ lobster-1:
295
+ dmPolicy: "open"
296
+ allowFrom: ["*"]
297
+ lobster-5:
298
+ dmPolicy: "pairing"
299
+ ```
300
+
301
+ Top-level `channels.feishu.dmPolicy` / `channels.feishu.allowFrom` are fallback defaults for accounts that do not override them.
302
+
303
+ > `dmPolicy` only controls who can trigger the bot.
304
+ > To actually read/write docs or files, you still need: (1) correct Feishu app scopes, and (2) sharing the target resources (Drive/Wiki/Bitable) with the bot.
305
+
306
+ #### Group Command Mention Bypass
307
+
308
+ When `requireMention: true`, Feishu can still allow authorized control commands (such as `/new`) without `@bot`.
309
+
310
+ | `groupCommandMentionBypass` | Behavior |
311
+ |----------------------------|----------|
312
+ | `never` | Never bypass `@` requirement for group commands. |
313
+ | `single_bot` | Bypass only when the group contains at most one bot (default). |
314
+ | `always` | Always allow authorized control commands to bypass mention gating. |
315
+
316
+ Notes:
317
+ - Bypass only applies to authorized control commands in group chats.
318
+ - If any user is explicitly `@`-mentioned in the same message, bypass is disabled.
319
+ - In DMs, this setting does not apply.
320
+
181
321
  #### Connection Mode
182
322
 
183
323
  Two connection modes are available for receiving events from Feishu:
@@ -276,7 +416,7 @@ session:
276
416
  - Pairing flow for DM approval
277
417
  - User and group directory lookup
278
418
  - **Card render mode**: Optional markdown rendering with syntax highlighting
279
- - **Document tools**: Read, create, and write Feishu documents with markdown (tables not supported due to API limitations)
419
+ - **Document tools**: Read, create, and write Feishu documents with markdown, including atomic `create_and_write` / `import_document` flows for reliable create+content write
280
420
  - **Wiki tools**: Navigate knowledge bases, list spaces, get node details, search, create/move/rename nodes
281
421
  - **Drive tools**: List folders, get file info, create folders, move/delete files
282
422
  - **Bitable tools**: Manage bitable (多维表格) fields and records (read/create/update/delete), supports both `/base/` and `/wiki/` URLs
@@ -394,19 +534,57 @@ openclaw plugins update feishu
394
534
  | `wiki:wiki:readonly` | `feishu_wiki` | 列出空间、列出节点、获取节点详情、搜索 |
395
535
  | `bitable:app:readonly` | `feishu_bitable` | 读取多维表格记录和字段 |
396
536
  | `task:task:read` | `feishu_task_get` | 获取任务详情 |
537
+ | `task:tasklist:read` | `feishu_tasklist_get`, `feishu_tasklist_list` | 获取/列出任务清单(tasklists) |
538
+ | `task:comment:read` | `feishu_task_comment_list`, `feishu_task_comment_get` | 列出/获取任务评论 |
539
+ | `task:attachment:read` | `feishu_task_attachment_list`, `feishu_task_attachment_get` | 列出/获取任务附件 |
397
540
 
398
541
  **读写权限**(可选,用于创建/编辑/删除操作):
399
542
 
400
543
  | 权限 | 工具 | 说明 |
401
544
  |------|------|------|
402
545
  | `docx:document` | `feishu_doc` | 创建/编辑文档 |
403
- | `docx:document.block:convert` | `feishu_doc` | Markdown 转 blocks(write/append 必需) |
546
+ | `docx:document.block:convert` | `feishu_doc` | Markdown 转 blocks(write/append/create_and_write 必需,`feishu_drive.import_document` 也会用到) |
404
547
  | `drive:drive` | `feishu_doc`, `feishu_drive` | 上传图片到文档、创建文件夹、移动/删除文件 |
405
548
  | `wiki:wiki` | `feishu_wiki` | 创建/移动/重命名知识库节点 |
406
549
  | `bitable:app` | `feishu_bitable` | 创建/更新/删除多维表格记录并管理字段 |
407
- | `task:task:write` | `feishu_task_create`, `feishu_task_update`, `feishu_task_delete` | 创建/更新/删除任务 |
550
+ | `task:task:write` | `feishu_task_create`, `feishu_task_subtask_create`, `feishu_task_update`, `feishu_task_delete` | 创建/更新/删除任务 |
551
+ | `task:tasklist:write` | `feishu_tasklist_create`, `feishu_tasklist_update`, `feishu_tasklist_delete`, `feishu_tasklist_add_members`, `feishu_tasklist_remove_members`, `feishu_task_add_tasklist`, `feishu_task_remove_tasklist` | 创建/更新/删除任务清单并管理成员/关联任务 |
552
+ | `task:comment:write` | `feishu_task_comment_create`, `feishu_task_comment_update`, `feishu_task_comment_delete` | 创建/更新/删除任务评论 |
553
+ | `task:attachment:write` | `feishu_task_attachment_upload`, `feishu_task_attachment_delete` | 上传/删除任务附件 |
554
+
555
+ > 飞书控制台中任务权限的显示名称可能略有差异,必要时可按关键字 `task` / `tasklist` / `comment` / `attachment` 搜索并授予对应读写权限。
556
+
557
+ #### 任务评论权限 ⚠️
558
+
559
+ 任务评论需要单独授权:
560
+ 1. 读取评论:授予 `task:comment:read`。
561
+ 2. 创建/更新/删除评论:授予 `task:comment:write`。
562
+
563
+ 缺少上述权限时,评论相关接口会返回权限不足错误。
564
+
565
+ #### 任务附件上传 ⚠️
566
+
567
+ 任务附件支持上传/获取/列表/删除。上传来源:
568
+ 1. OpenClaw/Node 所在机器的本地文件路径(`file_path`)
569
+ 2. 可直接下载的远程链接(`file_url`,公开/预签名 URL)
570
+
571
+ `file_url` 上传路径会使用 OpenClaw 运行时的媒体下载安全校验与大小限制(`mediaMaxMb`),随后经临时本地文件上传到任务附件。
572
+
573
+ #### 任务清单所有者限制 ⚠️
574
+
575
+ > **重要:** 创建/修改任务清单时,请保持清单所有者为机器人本身,只把用户作为协作人添加。
576
+
577
+ 任务清单权限基于“所有者 + 协作成员角色”授予。如果把清单所有者改成用户、且机器人不在协作成员中,机器人可能会失去对该清单的读取/编辑/管理权限,导致后续对清单的操作失败。
578
+
579
+ #### 任务限制 ⚠️
580
+
581
+ > **重要:** 只有当任务责任人包含用户时,用户才能查看到该任务。
582
+ >
583
+ > **限制:** 机器人目前只能给自己创建出来的任务创建子任务。
408
584
 
409
- > 飞书控制台中任务权限的显示名称可能略有差异,必要时可按关键字 `task` 搜索并授予对应读写权限。
585
+ 为避免“任务创建了但用户看不到”的问题:
586
+ 1. 创建任务时,请把发起用户设为任务负责人(`assignee`)。
587
+ 2. 如需更灵活的子任务创建/组织/可见性管理,建议使用任务清单(tasklists)。
410
588
 
411
589
  #### 云空间访问权限 ⚠️
412
590
 
@@ -485,16 +663,111 @@ channels:
485
663
  connectionMode: "websocket"
486
664
  # 私聊策略: "pairing" | "open" | "allowlist"
487
665
  dmPolicy: "pairing"
666
+ # 私聊白名单(open_id/user_id);当 dmPolicy="open" 时请包含 "*"
667
+ allowFrom: []
488
668
  # 群聊策略: "open" | "allowlist" | "disabled"
489
669
  groupPolicy: "allowlist"
490
670
  # 群聊是否需要 @机器人
491
671
  requireMention: true
672
+ # 群聊命令绕过 @ 策略: "never" | "single_bot" | "always"
673
+ # 默认 "single_bot":仅当群内机器人数量 <= 1 时,允许已授权命令免 @
674
+ groupCommandMentionBypass: "single_bot"
492
675
  # 媒体文件最大大小 (MB, 默认 30)
493
676
  mediaMaxMb: 30
494
677
  # 回复渲染模式: "auto" | "raw" | "card"
495
678
  renderMode: "auto"
496
679
  ```
497
680
 
681
+ #### 私聊策略(dmPolicy)与访问授权
682
+
683
+ `dmPolicy` 控制的是“谁可以在私聊里触发机器人”。
684
+ 在多账号模式下,它按账号生效(`channels.feishu.accounts.<accountId>`)。
685
+
686
+ | `dmPolicy` | 谁能私聊触发机器人 | 如何给用户开通 |
687
+ |------------|------------------|----------------|
688
+ | `pairing` | `allowFrom` 中的用户,或已通过配对审批的用户 | 用户先私聊机器人拿到配对码;管理员执行 `openclaw pairing approve feishu <code>`。 |
689
+ | `open` | 所有人 | 配置 `allowFrom: ["*"]`,表示全部放开。 |
690
+ | `allowlist` | 仅 `allowFrom` 中的用户 | 将用户 `open_id`/`user_id` 加入 `allowFrom`,然后重载配置。 |
691
+
692
+ 说明:
693
+ - `allowFrom` 支持飞书用户 ID(推荐 `open_id`,也支持 `user_id`)。
694
+ - 当 `dmPolicy: "open"` 时,建议固定写 `allowFrom: ["*"]`,语义最清晰,也满足顶层配置校验要求。
695
+ - `pairing` 和 `allowlist` 都可以先通过 `allowFrom` 预授权部分用户。
696
+
697
+ 配对审批流程(pairing):
698
+ 1. 用户先给机器人发一条私聊消息。
699
+ 2. 机器人返回配对码(例如 `H9ZEHY8R`)。
700
+ 3. 管理员执行审批命令:
701
+
702
+ ```bash
703
+ openclaw pairing approve feishu H9ZEHY8R
704
+ ```
705
+
706
+ 4. 审批后该用户立即可用。
707
+
708
+ 示例:全部放开
709
+
710
+ ```yaml
711
+ channels:
712
+ feishu:
713
+ dmPolicy: "open"
714
+ allowFrom: ["*"]
715
+ ```
716
+
717
+ 示例:灰度放开(pairing + 预授权)
718
+
719
+ ```yaml
720
+ channels:
721
+ feishu:
722
+ dmPolicy: "pairing"
723
+ allowFrom:
724
+ - "ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
725
+ ```
726
+
727
+ 示例:严格白名单
728
+
729
+ ```yaml
730
+ channels:
731
+ feishu:
732
+ dmPolicy: "allowlist"
733
+ allowFrom:
734
+ - "ou_alice"
735
+ - "ou_bob"
736
+ ```
737
+
738
+ 示例:按账号隔离配置
739
+
740
+ ```yaml
741
+ channels:
742
+ feishu:
743
+ accounts:
744
+ lobster-1:
745
+ dmPolicy: "open"
746
+ allowFrom: ["*"]
747
+ lobster-5:
748
+ dmPolicy: "pairing"
749
+ ```
750
+
751
+ `channels.feishu.dmPolicy` / `channels.feishu.allowFrom` 是“默认值”;账号下未覆盖时才会继承。
752
+
753
+ > `dmPolicy` 只控制“是否允许触发机器人”。
754
+ > 真正执行文档/云盘/知识库/多维表格操作,还需要两层权限:1)应用 API 权限(scopes);2)把目标资源分享给机器人。
755
+
756
+ #### 群聊命令免 @ 策略
757
+
758
+ 当 `requireMention: true` 时,Feishu 仍可让“已授权控制命令(如 `/new`)”在不 `@bot` 的情况下通过。
759
+
760
+ | `groupCommandMentionBypass` | 行为 |
761
+ |----------------------------|------|
762
+ | `never` | 群聊命令永不绕过 `@` 校验。 |
763
+ | `single_bot` | 仅当群内机器人数量不超过 1 个时才允许绕过(默认)。 |
764
+ | `always` | 已授权控制命令始终可绕过 `@` 校验。 |
765
+
766
+ 说明:
767
+ - 仅对群聊中的“已授权控制命令”生效。
768
+ - 同一条消息里如果显式 `@` 了任意用户,则不会触发命令免 `@`。
769
+ - 私聊场景不受该配置影响。
770
+
498
771
  #### 连接模式
499
772
 
500
773
  支持两种从飞书接收事件的连接模式:
package/index.ts CHANGED
@@ -2,12 +2,12 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
2
  import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
3
3
  import { feishuPlugin } from "./src/channel.js";
4
4
  import { setFeishuRuntime } from "./src/runtime.js";
5
- import { registerFeishuDocTools } from "./src/docx.js";
6
- import { registerFeishuWikiTools } from "./src/wiki.js";
7
- import { registerFeishuDriveTools } from "./src/drive.js";
8
- import { registerFeishuPermTools } from "./src/perm.js";
9
- import { registerFeishuBitableTools } from "./src/bitable.js";
10
- import { registerFeishuTaskTools } from "./src/task.js";
5
+ import { registerFeishuDocTools } from "./src/doc-tools/index.js";
6
+ import { registerFeishuWikiTools } from "./src/wiki-tools/index.js";
7
+ import { registerFeishuDriveTools } from "./src/drive-tools/index.js";
8
+ import { registerFeishuPermTools } from "./src/perm-tools/index.js";
9
+ import { registerFeishuBitableTools } from "./src/bitable-tools/index.js";
10
+ import { registerFeishuTaskTools } from "./src/task-tools/index.js";
11
11
 
12
12
  export { monitorFeishuProvider } from "./src/monitor.js";
13
13
  export {
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "@m1heng-clawd/feishu",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Feishu/Lark channel plugin",
6
+ "scripts": {
7
+ "test:unit": "vitest run",
8
+ "test:unit:watch": "vitest",
9
+ "test:coverage": "vitest run --coverage",
10
+ "ci:check": "npx tsc --noEmit && npm run test:coverage"
11
+ },
6
12
  "license": "MIT",
7
13
  "files": [
8
14
  "index.ts",
9
- "src",
15
+ "src/**/*.ts",
16
+ "!src/**/__tests__/**",
17
+ "!src/**/*.test.ts",
10
18
  "skills",
11
19
  "openclaw.plugin.json"
12
20
  ],
@@ -51,10 +59,12 @@
51
59
  "zod": "^4.3.6"
52
60
  },
53
61
  "devDependencies": {
62
+ "@vitest/coverage-v8": "^2.1.8",
54
63
  "@types/node": "^25.0.10",
55
64
  "openclaw": "2026.2.13",
56
65
  "tsx": "^4.21.0",
57
- "typescript": "^5.7.0"
66
+ "typescript": "^5.7.0",
67
+ "vitest": "^2.1.8"
58
68
  },
59
69
  "peerDependencies": {
60
70
  "openclaw": ">=2026.2.13"
@@ -1,16 +1,17 @@
1
1
  ---
2
2
  name: feishu-doc
3
3
  description: |
4
- Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.
4
+ Feishu document read/write operations + comment management. Activate when user mentions Feishu docs, cloud docs, docx links, or document comments.
5
5
  ---
6
6
 
7
7
  # Feishu Document Tool
8
8
 
9
- Single tool `feishu_doc` with action parameter for all document operations.
9
+ Single tool `feishu_doc` with action parameter for all document operations including comment management.
10
10
 
11
11
  ## Token Extraction
12
12
 
13
13
  From URL `https://xxx.feishu.cn/docx/ABC123def` → `doc_token` = `ABC123def`
14
+ From URL `https://xxx.feishu.cn/docs/doccn123c` → `doc_token` = `doccn123c`
14
15
 
15
16
  ## Actions
16
17
 
@@ -32,6 +33,28 @@ Replaces entire document with markdown content. Supports: headings, lists, code
32
33
 
33
34
  **Limitation:** Markdown tables are NOT supported.
34
35
 
36
+ ### Create + Write (Atomic, Recommended)
37
+
38
+ ```json
39
+ {
40
+ "action": "create_and_write",
41
+ "title": "New Document",
42
+ "content": "# Title\n\nMarkdown content..."
43
+ }
44
+ ```
45
+
46
+ With folder:
47
+ ```json
48
+ {
49
+ "action": "create_and_write",
50
+ "title": "New Document",
51
+ "content": "# Title\n\nMarkdown content...",
52
+ "folder_token": "fldcnXXX"
53
+ }
54
+ ```
55
+
56
+ Creates the document and writes content in one call. Prefer this over separate `create` + `write`.
57
+
35
58
  ### Append Content
36
59
 
37
60
  ```json
@@ -51,6 +74,8 @@ With folder:
51
74
  { "action": "create", "title": "New Document", "folder_token": "fldcnXXX" }
52
75
  ```
53
76
 
77
+ Creates an empty document (title only).
78
+
54
79
  ### List Blocks
55
80
 
56
81
  ```json
@@ -77,6 +102,39 @@ Returns full block data including tables, images. Use this to read structured co
77
102
  { "action": "delete_block", "doc_token": "ABC123def", "block_id": "doxcnXXX" }
78
103
  ```
79
104
 
105
+ ### List Comments
106
+
107
+ ```json
108
+ { "action": "list_comments", "doc_token": "ABC123def", "page_size": 50 }
109
+ ```
110
+
111
+ Returns all comments for the document. Use `page_token` for pagination. Comments include `is_whole` field to distinguish between whole-document comments (true) and block-level comments (false).
112
+
113
+ ### Get Single Comment
114
+
115
+ ```json
116
+ { "action": "get_comment", "doc_token": "ABC123def", "comment_id": "comment_xxx" }
117
+ ```
118
+
119
+ ### Create Comment
120
+
121
+ ```json
122
+ { "action": "create_comment", "doc_token": "ABC123def", "content": "Comment text" }
123
+ ```
124
+
125
+ ### List Comment Replies
126
+
127
+ ```json
128
+ { "action": "list_comment_replies", "doc_token": "ABC123def", "comment_id": "comment_xxx", "page_size": 50 }
129
+ ```
130
+
131
+ `page_size` should be a positive integer. If omitted, tool defaults to `50`.
132
+
133
+ ### Comment Write Scope
134
+
135
+ Current tool provides documented comment write action `create_comment` (global comment creation).
136
+ For replies, use `list_comment_replies` for retrieval; the reply creation endpoint is not exposed in current SDK surface.
137
+
80
138
  ## Reading Workflow
81
139
 
82
140
  1. Start with `action: "read"` - get plain text + statistics
@@ -97,3 +155,7 @@ channels:
97
155
  ## Permissions
98
156
 
99
157
  Required: `docx:document`, `docx:document:readonly`, `docx:document.block:convert`, `drive:drive`
158
+
159
+ For comment operations:
160
+ - Read comments: `docx:document.comment:read`
161
+ - Write comments: `docx:document.comment` (optional, for create_comment)