@larksuite/openclaw-lark 2025.7.15-beta.0

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 (426) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/bin/openclaw-lark.js +39 -0
  4. package/index.d.ts +36 -0
  5. package/index.js +188 -0
  6. package/openclaw.plugin.json +64 -0
  7. package/package.json +63 -0
  8. package/secret-contract-api.d.ts +15 -0
  9. package/secret-contract-api.js +78 -0
  10. package/skills/feishu-bitable/SKILL.md +248 -0
  11. package/skills/feishu-bitable/references/examples.md +813 -0
  12. package/skills/feishu-bitable/references/field-properties.md +763 -0
  13. package/skills/feishu-bitable/references/record-values.md +911 -0
  14. package/skills/feishu-calendar/SKILL.md +242 -0
  15. package/skills/feishu-channel-rules/SKILL.md +18 -0
  16. package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  17. package/skills/feishu-create-doc/SKILL.md +719 -0
  18. package/skills/feishu-fetch-doc/SKILL.md +93 -0
  19. package/skills/feishu-im-read/SKILL.md +163 -0
  20. package/skills/feishu-task/SKILL.md +340 -0
  21. package/skills/feishu-troubleshoot/SKILL.md +70 -0
  22. package/skills/feishu-update-doc/SKILL.md +285 -0
  23. package/src/card/builder.d.ts +152 -0
  24. package/src/card/builder.js +794 -0
  25. package/src/card/card-error.d.ts +91 -0
  26. package/src/card/card-error.js +206 -0
  27. package/src/card/cardkit.d.ts +90 -0
  28. package/src/card/cardkit.js +203 -0
  29. package/src/card/flush-controller.d.ts +45 -0
  30. package/src/card/flush-controller.js +138 -0
  31. package/src/card/image-resolver.d.ts +45 -0
  32. package/src/card/image-resolver.js +116 -0
  33. package/src/card/markdown-style.d.ts +16 -0
  34. package/src/card/markdown-style.js +106 -0
  35. package/src/card/reasoning-utils.d.ts +14 -0
  36. package/src/card/reasoning-utils.js +64 -0
  37. package/src/card/reply-dispatcher-types.d.ts +132 -0
  38. package/src/card/reply-dispatcher-types.js +61 -0
  39. package/src/card/reply-dispatcher.d.ts +15 -0
  40. package/src/card/reply-dispatcher.js +447 -0
  41. package/src/card/reply-mode.d.ts +41 -0
  42. package/src/card/reply-mode.js +70 -0
  43. package/src/card/streaming-card-controller.d.ts +118 -0
  44. package/src/card/streaming-card-controller.js +1045 -0
  45. package/src/card/tool-use-config.d.ts +26 -0
  46. package/src/card/tool-use-config.js +76 -0
  47. package/src/card/tool-use-display.d.ts +37 -0
  48. package/src/card/tool-use-display.js +476 -0
  49. package/src/card/tool-use-trace-store.d.ts +51 -0
  50. package/src/card/tool-use-trace-store.js +271 -0
  51. package/src/card/unavailable-guard.d.ts +35 -0
  52. package/src/card/unavailable-guard.js +87 -0
  53. package/src/channel/abort-detect.d.ts +47 -0
  54. package/src/channel/abort-detect.js +219 -0
  55. package/src/channel/chat-queue.d.ts +41 -0
  56. package/src/channel/chat-queue.js +68 -0
  57. package/src/channel/config-adapter.d.ts +23 -0
  58. package/src/channel/config-adapter.js +107 -0
  59. package/src/channel/directory.d.ts +57 -0
  60. package/src/channel/directory.js +197 -0
  61. package/src/channel/event-handlers.d.ts +17 -0
  62. package/src/channel/event-handlers.js +380 -0
  63. package/src/channel/interactive-dispatch.d.ts +59 -0
  64. package/src/channel/interactive-dispatch.js +195 -0
  65. package/src/channel/monitor.d.ts +17 -0
  66. package/src/channel/monitor.js +140 -0
  67. package/src/channel/onboarding-config.d.ts +18 -0
  68. package/src/channel/onboarding-config.js +96 -0
  69. package/src/channel/onboarding-migrate.d.ts +25 -0
  70. package/src/channel/onboarding-migrate.js +70 -0
  71. package/src/channel/onboarding.d.ts +12 -0
  72. package/src/channel/onboarding.js +300 -0
  73. package/src/channel/plugin.d.ts +13 -0
  74. package/src/channel/plugin.js +310 -0
  75. package/src/channel/probe.d.ts +14 -0
  76. package/src/channel/probe.js +24 -0
  77. package/src/channel/types.d.ts +37 -0
  78. package/src/channel/types.js +8 -0
  79. package/src/commands/auth.d.ts +21 -0
  80. package/src/commands/auth.js +165 -0
  81. package/src/commands/diagnose.d.ts +69 -0
  82. package/src/commands/diagnose.js +848 -0
  83. package/src/commands/doctor.d.ts +27 -0
  84. package/src/commands/doctor.js +588 -0
  85. package/src/commands/index.d.ts +25 -0
  86. package/src/commands/index.js +219 -0
  87. package/src/commands/locale.d.ts +7 -0
  88. package/src/commands/locale.js +8 -0
  89. package/src/core/accounts.d.ts +51 -0
  90. package/src/core/accounts.js +219 -0
  91. package/src/core/agent-config.d.ts +100 -0
  92. package/src/core/agent-config.js +148 -0
  93. package/src/core/api-error.d.ts +48 -0
  94. package/src/core/api-error.js +117 -0
  95. package/src/core/app-owner-fallback.d.ts +22 -0
  96. package/src/core/app-owner-fallback.js +39 -0
  97. package/src/core/app-scope-checker.d.ts +87 -0
  98. package/src/core/app-scope-checker.js +198 -0
  99. package/src/core/auth-errors.d.ts +144 -0
  100. package/src/core/auth-errors.js +160 -0
  101. package/src/core/card-action-operator.d.ts +33 -0
  102. package/src/core/card-action-operator.js +30 -0
  103. package/src/core/chat-info-cache.d.ts +67 -0
  104. package/src/core/chat-info-cache.js +165 -0
  105. package/src/core/comment-target.d.ts +65 -0
  106. package/src/core/comment-target.js +100 -0
  107. package/src/core/config-schema.d.ts +490 -0
  108. package/src/core/config-schema.js +223 -0
  109. package/src/core/device-flow.d.ts +77 -0
  110. package/src/core/device-flow.js +217 -0
  111. package/src/core/domains.d.ts +18 -0
  112. package/src/core/domains.js +34 -0
  113. package/src/core/feishu-fetch.d.ts +18 -0
  114. package/src/core/feishu-fetch.js +28 -0
  115. package/src/core/footer-config.d.ts +24 -0
  116. package/src/core/footer-config.js +51 -0
  117. package/src/core/lark-client.d.ts +125 -0
  118. package/src/core/lark-client.js +468 -0
  119. package/src/core/lark-logger.d.ts +23 -0
  120. package/src/core/lark-logger.js +160 -0
  121. package/src/core/lark-ticket.d.ts +29 -0
  122. package/src/core/lark-ticket.js +40 -0
  123. package/src/core/message-unavailable.d.ts +53 -0
  124. package/src/core/message-unavailable.js +142 -0
  125. package/src/core/owner-policy.d.ts +32 -0
  126. package/src/core/owner-policy.js +55 -0
  127. package/src/core/permission-url.d.ts +22 -0
  128. package/src/core/permission-url.js +76 -0
  129. package/src/core/raw-request.d.ts +27 -0
  130. package/src/core/raw-request.js +90 -0
  131. package/src/core/runtime-store.d.ts +13 -0
  132. package/src/core/runtime-store.js +29 -0
  133. package/src/core/scope-manager.d.ts +168 -0
  134. package/src/core/scope-manager.js +224 -0
  135. package/src/core/sdk-compat.d.ts +20 -0
  136. package/src/core/sdk-compat.js +28 -0
  137. package/src/core/security-check.d.ts +72 -0
  138. package/src/core/security-check.js +184 -0
  139. package/src/core/shutdown-hooks.d.ts +22 -0
  140. package/src/core/shutdown-hooks.js +61 -0
  141. package/src/core/synthetic-target.d.ts +33 -0
  142. package/src/core/synthetic-target.js +40 -0
  143. package/src/core/targets.d.ts +60 -0
  144. package/src/core/targets.js +173 -0
  145. package/src/core/token-store.d.ts +54 -0
  146. package/src/core/token-store.js +326 -0
  147. package/src/core/tool-client.d.ts +176 -0
  148. package/src/core/tool-client.js +426 -0
  149. package/src/core/tool-scopes.d.ts +156 -0
  150. package/src/core/tool-scopes.js +344 -0
  151. package/src/core/tools-config.d.ts +55 -0
  152. package/src/core/tools-config.js +143 -0
  153. package/src/core/types.d.ts +91 -0
  154. package/src/core/types.js +12 -0
  155. package/src/core/uat-client.d.ts +46 -0
  156. package/src/core/uat-client.js +192 -0
  157. package/src/core/version.d.ts +31 -0
  158. package/src/core/version.js +69 -0
  159. package/src/messaging/converters/audio.d.ts +8 -0
  160. package/src/messaging/converters/audio.js +24 -0
  161. package/src/messaging/converters/calendar.d.ts +13 -0
  162. package/src/messaging/converters/calendar.js +56 -0
  163. package/src/messaging/converters/content-converter-helpers.d.ts +30 -0
  164. package/src/messaging/converters/content-converter-helpers.js +82 -0
  165. package/src/messaging/converters/content-converter.d.ts +24 -0
  166. package/src/messaging/converters/content-converter.js +40 -0
  167. package/src/messaging/converters/file.d.ts +8 -0
  168. package/src/messaging/converters/file.js +24 -0
  169. package/src/messaging/converters/folder.d.ts +8 -0
  170. package/src/messaging/converters/folder.js +24 -0
  171. package/src/messaging/converters/hongbao.d.ts +8 -0
  172. package/src/messaging/converters/hongbao.js +20 -0
  173. package/src/messaging/converters/image.d.ts +8 -0
  174. package/src/messaging/converters/image.js +22 -0
  175. package/src/messaging/converters/index.d.ts +8 -0
  176. package/src/messaging/converters/index.js +53 -0
  177. package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
  178. package/src/messaging/converters/interactive/card-converter.js +1177 -0
  179. package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
  180. package/src/messaging/converters/interactive/card-utils.js +47 -0
  181. package/src/messaging/converters/interactive/index.d.ts +8 -0
  182. package/src/messaging/converters/interactive/index.js +25 -0
  183. package/src/messaging/converters/interactive/legacy.d.ts +11 -0
  184. package/src/messaging/converters/interactive/legacy.js +60 -0
  185. package/src/messaging/converters/interactive/types.d.ts +23 -0
  186. package/src/messaging/converters/interactive/types.js +27 -0
  187. package/src/messaging/converters/location.d.ts +8 -0
  188. package/src/messaging/converters/location.js +23 -0
  189. package/src/messaging/converters/merge-forward.d.ts +32 -0
  190. package/src/messaging/converters/merge-forward.js +235 -0
  191. package/src/messaging/converters/post.d.ts +11 -0
  192. package/src/messaging/converters/post.js +235 -0
  193. package/src/messaging/converters/share.d.ts +9 -0
  194. package/src/messaging/converters/share.js +28 -0
  195. package/src/messaging/converters/sticker.d.ts +8 -0
  196. package/src/messaging/converters/sticker.js +22 -0
  197. package/src/messaging/converters/system.d.ts +12 -0
  198. package/src/messaging/converters/system.js +36 -0
  199. package/src/messaging/converters/text.d.ts +8 -0
  200. package/src/messaging/converters/text.js +18 -0
  201. package/src/messaging/converters/todo.d.ts +8 -0
  202. package/src/messaging/converters/todo.js +45 -0
  203. package/src/messaging/converters/types.d.ts +114 -0
  204. package/src/messaging/converters/types.js +8 -0
  205. package/src/messaging/converters/unknown.d.ts +8 -0
  206. package/src/messaging/converters/unknown.js +20 -0
  207. package/src/messaging/converters/utils.d.ts +22 -0
  208. package/src/messaging/converters/utils.js +57 -0
  209. package/src/messaging/converters/video-chat.d.ts +8 -0
  210. package/src/messaging/converters/video-chat.js +31 -0
  211. package/src/messaging/converters/video.d.ts +8 -0
  212. package/src/messaging/converters/video.js +35 -0
  213. package/src/messaging/converters/vote.d.ts +8 -0
  214. package/src/messaging/converters/vote.js +28 -0
  215. package/src/messaging/inbound/bot-content.d.ts +84 -0
  216. package/src/messaging/inbound/bot-content.js +117 -0
  217. package/src/messaging/inbound/bot-loop-guard.d.ts +48 -0
  218. package/src/messaging/inbound/bot-loop-guard.js +89 -0
  219. package/src/messaging/inbound/comment-context.d.ts +82 -0
  220. package/src/messaging/inbound/comment-context.js +353 -0
  221. package/src/messaging/inbound/comment-handler.d.ts +30 -0
  222. package/src/messaging/inbound/comment-handler.js +269 -0
  223. package/src/messaging/inbound/dedup.d.ts +59 -0
  224. package/src/messaging/inbound/dedup.js +121 -0
  225. package/src/messaging/inbound/dispatch-builders.d.ts +104 -0
  226. package/src/messaging/inbound/dispatch-builders.js +241 -0
  227. package/src/messaging/inbound/dispatch-commands.d.ts +22 -0
  228. package/src/messaging/inbound/dispatch-commands.js +131 -0
  229. package/src/messaging/inbound/dispatch-context.d.ts +67 -0
  230. package/src/messaging/inbound/dispatch-context.js +153 -0
  231. package/src/messaging/inbound/dispatch.d.ts +50 -0
  232. package/src/messaging/inbound/dispatch.js +477 -0
  233. package/src/messaging/inbound/enrich.d.ts +102 -0
  234. package/src/messaging/inbound/enrich.js +236 -0
  235. package/src/messaging/inbound/gate-effects.d.ts +23 -0
  236. package/src/messaging/inbound/gate-effects.js +46 -0
  237. package/src/messaging/inbound/gate.d.ts +91 -0
  238. package/src/messaging/inbound/gate.js +342 -0
  239. package/src/messaging/inbound/handler-registry.d.ts +25 -0
  240. package/src/messaging/inbound/handler-registry.js +23 -0
  241. package/src/messaging/inbound/handler.d.ts +37 -0
  242. package/src/messaging/inbound/handler.js +286 -0
  243. package/src/messaging/inbound/media-resolver.d.ts +32 -0
  244. package/src/messaging/inbound/media-resolver.js +91 -0
  245. package/src/messaging/inbound/mention-registry.d.ts +59 -0
  246. package/src/messaging/inbound/mention-registry.js +115 -0
  247. package/src/messaging/inbound/mention.d.ts +48 -0
  248. package/src/messaging/inbound/mention.js +102 -0
  249. package/src/messaging/inbound/parse-io.d.ts +50 -0
  250. package/src/messaging/inbound/parse-io.js +86 -0
  251. package/src/messaging/inbound/parse.d.ts +28 -0
  252. package/src/messaging/inbound/parse.js +128 -0
  253. package/src/messaging/inbound/permission.d.ts +17 -0
  254. package/src/messaging/inbound/permission.js +44 -0
  255. package/src/messaging/inbound/policy.d.ts +95 -0
  256. package/src/messaging/inbound/policy.js +168 -0
  257. package/src/messaging/inbound/reaction-handler.d.ts +62 -0
  258. package/src/messaging/inbound/reaction-handler.js +259 -0
  259. package/src/messaging/inbound/sentinel-store.d.ts +37 -0
  260. package/src/messaging/inbound/sentinel-store.js +98 -0
  261. package/src/messaging/inbound/synthetic-message.d.ts +26 -0
  262. package/src/messaging/inbound/synthetic-message.js +59 -0
  263. package/src/messaging/inbound/user-name-cache-store.d.ts +62 -0
  264. package/src/messaging/inbound/user-name-cache-store.js +236 -0
  265. package/src/messaging/inbound/user-name-cache.d.ts +78 -0
  266. package/src/messaging/inbound/user-name-cache.js +306 -0
  267. package/src/messaging/inbound/vc-meeting-invited-handler.d.ts +20 -0
  268. package/src/messaging/inbound/vc-meeting-invited-handler.js +236 -0
  269. package/src/messaging/inbound/vc-sender.d.ts +41 -0
  270. package/src/messaging/inbound/vc-sender.js +53 -0
  271. package/src/messaging/outbound/actions.d.ts +16 -0
  272. package/src/messaging/outbound/actions.js +329 -0
  273. package/src/messaging/outbound/bot-peer-context.d.ts +42 -0
  274. package/src/messaging/outbound/bot-peer-context.js +40 -0
  275. package/src/messaging/outbound/chat-manage.d.ts +64 -0
  276. package/src/messaging/outbound/chat-manage.js +117 -0
  277. package/src/messaging/outbound/deliver.d.ts +186 -0
  278. package/src/messaging/outbound/deliver.js +410 -0
  279. package/src/messaging/outbound/fetch.d.ts +12 -0
  280. package/src/messaging/outbound/fetch.js +17 -0
  281. package/src/messaging/outbound/forward.d.ts +26 -0
  282. package/src/messaging/outbound/forward.js +51 -0
  283. package/src/messaging/outbound/media-url-utils.d.ts +29 -0
  284. package/src/messaging/outbound/media-url-utils.js +172 -0
  285. package/src/messaging/outbound/media.d.ts +260 -0
  286. package/src/messaging/outbound/media.js +865 -0
  287. package/src/messaging/outbound/normalize-mentions.d.ts +50 -0
  288. package/src/messaging/outbound/normalize-mentions.js +166 -0
  289. package/src/messaging/outbound/outbound-mention.d.ts +41 -0
  290. package/src/messaging/outbound/outbound-mention.js +112 -0
  291. package/src/messaging/outbound/outbound.d.ts +79 -0
  292. package/src/messaging/outbound/outbound.js +195 -0
  293. package/src/messaging/outbound/reactions.d.ts +124 -0
  294. package/src/messaging/outbound/reactions.js +384 -0
  295. package/src/messaging/outbound/send.d.ts +153 -0
  296. package/src/messaging/outbound/send.js +417 -0
  297. package/src/messaging/outbound/typing.d.ts +60 -0
  298. package/src/messaging/outbound/typing.js +139 -0
  299. package/src/messaging/shared/message-lookup.d.ts +54 -0
  300. package/src/messaging/shared/message-lookup.js +120 -0
  301. package/src/messaging/types.d.ts +316 -0
  302. package/src/messaging/types.js +11 -0
  303. package/src/tools/ask-user-question.d.ts +32 -0
  304. package/src/tools/ask-user-question.js +922 -0
  305. package/src/tools/auto-auth.d.ts +57 -0
  306. package/src/tools/auto-auth.js +904 -0
  307. package/src/tools/helpers.d.ts +264 -0
  308. package/src/tools/helpers.js +389 -0
  309. package/src/tools/mcp/doc/create.d.ts +12 -0
  310. package/src/tools/mcp/doc/create.js +47 -0
  311. package/src/tools/mcp/doc/fetch.d.ts +12 -0
  312. package/src/tools/mcp/doc/fetch.js +39 -0
  313. package/src/tools/mcp/doc/index.d.ts +12 -0
  314. package/src/tools/mcp/doc/index.js +50 -0
  315. package/src/tools/mcp/doc/update.d.ts +12 -0
  316. package/src/tools/mcp/doc/update.js +64 -0
  317. package/src/tools/mcp/shared.d.ts +59 -0
  318. package/src/tools/mcp/shared.js +239 -0
  319. package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
  320. package/src/tools/oapi/bitable/app-table-field.js +225 -0
  321. package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
  322. package/src/tools/oapi/bitable/app-table-record.js +439 -0
  323. package/src/tools/oapi/bitable/app-table-view.d.ts +16 -0
  324. package/src/tools/oapi/bitable/app-table-view.js +172 -0
  325. package/src/tools/oapi/bitable/app-table.d.ts +17 -0
  326. package/src/tools/oapi/bitable/app-table.js +195 -0
  327. package/src/tools/oapi/bitable/app.d.ts +18 -0
  328. package/src/tools/oapi/bitable/app.js +189 -0
  329. package/src/tools/oapi/bitable/index.d.ts +9 -0
  330. package/src/tools/oapi/bitable/index.js +17 -0
  331. package/src/tools/oapi/calendar/calendar.d.ts +15 -0
  332. package/src/tools/oapi/calendar/calendar.js +125 -0
  333. package/src/tools/oapi/calendar/event-attendee.d.ts +14 -0
  334. package/src/tools/oapi/calendar/event-attendee.js +161 -0
  335. package/src/tools/oapi/calendar/event.d.ts +16 -0
  336. package/src/tools/oapi/calendar/event.js +712 -0
  337. package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
  338. package/src/tools/oapi/calendar/freebusy.js +114 -0
  339. package/src/tools/oapi/calendar/index.d.ts +8 -0
  340. package/src/tools/oapi/calendar/index.js +15 -0
  341. package/src/tools/oapi/chat/chat.d.ts +16 -0
  342. package/src/tools/oapi/chat/chat.js +127 -0
  343. package/src/tools/oapi/chat/index.d.ts +10 -0
  344. package/src/tools/oapi/chat/index.js +23 -0
  345. package/src/tools/oapi/chat/members.d.ts +11 -0
  346. package/src/tools/oapi/chat/members.js +84 -0
  347. package/src/tools/oapi/common/get-user.d.ts +12 -0
  348. package/src/tools/oapi/common/get-user.js +109 -0
  349. package/src/tools/oapi/common/index.d.ts +6 -0
  350. package/src/tools/oapi/common/index.js +11 -0
  351. package/src/tools/oapi/common/search-user.d.ts +11 -0
  352. package/src/tools/oapi/common/search-user.js +76 -0
  353. package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
  354. package/src/tools/oapi/drive/doc-comments.js +351 -0
  355. package/src/tools/oapi/drive/doc-media.d.ts +19 -0
  356. package/src/tools/oapi/drive/doc-media.js +371 -0
  357. package/src/tools/oapi/drive/file.d.ts +19 -0
  358. package/src/tools/oapi/drive/file.js +519 -0
  359. package/src/tools/oapi/drive/index.d.ts +12 -0
  360. package/src/tools/oapi/drive/index.js +45 -0
  361. package/src/tools/oapi/helpers.d.ts +183 -0
  362. package/src/tools/oapi/helpers.js +385 -0
  363. package/src/tools/oapi/im/format-messages.d.ts +50 -0
  364. package/src/tools/oapi/im/format-messages.js +169 -0
  365. package/src/tools/oapi/im/index.d.ts +10 -0
  366. package/src/tools/oapi/im/index.js +25 -0
  367. package/src/tools/oapi/im/message-read.d.ts +13 -0
  368. package/src/tools/oapi/im/message-read.js +419 -0
  369. package/src/tools/oapi/im/message.d.ts +16 -0
  370. package/src/tools/oapi/im/message.js +152 -0
  371. package/src/tools/oapi/im/resource.d.ts +13 -0
  372. package/src/tools/oapi/im/resource.js +186 -0
  373. package/src/tools/oapi/im/time-utils.d.ts +46 -0
  374. package/src/tools/oapi/im/time-utils.js +212 -0
  375. package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
  376. package/src/tools/oapi/im/user-name-uat.js +143 -0
  377. package/src/tools/oapi/index.d.ts +11 -0
  378. package/src/tools/oapi/index.js +64 -0
  379. package/src/tools/oapi/sdk-types.d.ts +96 -0
  380. package/src/tools/oapi/sdk-types.js +13 -0
  381. package/src/tools/oapi/search/doc-search.d.ts +13 -0
  382. package/src/tools/oapi/search/doc-search.js +194 -0
  383. package/src/tools/oapi/search/index.d.ts +12 -0
  384. package/src/tools/oapi/search/index.js +37 -0
  385. package/src/tools/oapi/sheets/index.d.ts +12 -0
  386. package/src/tools/oapi/sheets/index.js +35 -0
  387. package/src/tools/oapi/sheets/sheet.d.ts +16 -0
  388. package/src/tools/oapi/sheets/sheet.js +688 -0
  389. package/src/tools/oapi/task/attachment.d.ts +18 -0
  390. package/src/tools/oapi/task/attachment.js +107 -0
  391. package/src/tools/oapi/task/comment.d.ts +15 -0
  392. package/src/tools/oapi/task/comment.js +149 -0
  393. package/src/tools/oapi/task/index.d.ts +11 -0
  394. package/src/tools/oapi/task/index.js +21 -0
  395. package/src/tools/oapi/task/section.d.ts +17 -0
  396. package/src/tools/oapi/task/section.js +293 -0
  397. package/src/tools/oapi/task/subtask.d.ts +14 -0
  398. package/src/tools/oapi/task/subtask.js +171 -0
  399. package/src/tools/oapi/task/task.d.ts +19 -0
  400. package/src/tools/oapi/task/task.js +512 -0
  401. package/src/tools/oapi/task/task_agent.d.ts +14 -0
  402. package/src/tools/oapi/task/task_agent.js +108 -0
  403. package/src/tools/oapi/task/tasklist.d.ts +19 -0
  404. package/src/tools/oapi/task/tasklist.js +276 -0
  405. package/src/tools/oapi/wiki/index.d.ts +12 -0
  406. package/src/tools/oapi/wiki/index.js +42 -0
  407. package/src/tools/oapi/wiki/space-node.d.ts +17 -0
  408. package/src/tools/oapi/wiki/space-node.js +233 -0
  409. package/src/tools/oapi/wiki/space.d.ts +15 -0
  410. package/src/tools/oapi/wiki/space.js +133 -0
  411. package/src/tools/oauth-batch-auth.d.ts +11 -0
  412. package/src/tools/oauth-batch-auth.js +150 -0
  413. package/src/tools/oauth-cards.d.ts +39 -0
  414. package/src/tools/oauth-cards.js +324 -0
  415. package/src/tools/oauth.d.ts +47 -0
  416. package/src/tools/oauth.js +592 -0
  417. package/src/tools/onboarding-auth.d.ts +27 -0
  418. package/src/tools/onboarding-auth.js +133 -0
  419. package/src/tools/tat/im/index.d.ts +15 -0
  420. package/src/tools/tat/im/index.js +22 -0
  421. package/src/tools/tat/im/resource.d.ts +15 -0
  422. package/src/tools/tat/im/resource.js +192 -0
  423. package/tsdown.config.d.ts +2 -0
  424. package/tsdown.config.js +25 -0
  425. package/vitest.config.d.ts +2 -0
  426. package/vitest.config.js +12 -0
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * WebSocket monitoring for the Lark/Feishu channel plugin.
7
+ *
8
+ * Manages per-account WSClient connections and routes inbound Feishu
9
+ * events (messages, bot membership changes, read receipts) to the
10
+ * appropriate handlers.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.monitorFeishuProvider = monitorFeishuProvider;
14
+ const accounts_1 = require("../core/accounts.js");
15
+ const lark_client_1 = require("../core/lark-client.js");
16
+ const lark_logger_1 = require("../core/lark-logger.js");
17
+ const shutdown_hooks_1 = require("../core/shutdown-hooks.js");
18
+ const dedup_1 = require("../messaging/inbound/dedup.js");
19
+ const event_handlers_1 = require("./event-handlers.js");
20
+ const mlog = (0, lark_logger_1.larkLogger)('channel/monitor');
21
+ // ---------------------------------------------------------------------------
22
+ // Single-account monitor
23
+ // ---------------------------------------------------------------------------
24
+ /**
25
+ * Start monitoring a single Feishu account.
26
+ *
27
+ * Creates a LarkClient, probes bot identity, registers event handlers,
28
+ * and starts a WebSocket connection. Returns a Promise that resolves
29
+ * when the abort signal fires (or immediately if already aborted).
30
+ */
31
+ async function monitorSingleAccount(params) {
32
+ const { account, runtime, abortSignal } = params;
33
+ const { accountId } = account;
34
+ const log = runtime?.log ?? ((...args) => mlog.info(args.map(String).join(' ')));
35
+ const error = runtime?.error ?? ((...args) => mlog.error(args.map(String).join(' ')));
36
+ // Only websocket mode is supported in the monitor path.
37
+ const connectionMode = account.config.connectionMode ?? 'websocket';
38
+ if (connectionMode !== 'websocket') {
39
+ log(`feishu[${accountId}]: webhook mode not implemented in monitor`);
40
+ return;
41
+ }
42
+ // Message dedup — filters duplicate deliveries from WebSocket reconnects.
43
+ const dedupCfg = account.config.dedup;
44
+ const messageDedup = new dedup_1.MessageDedup({
45
+ ttlMs: dedupCfg?.ttlMs,
46
+ maxEntries: dedupCfg?.maxEntries,
47
+ });
48
+ log(`feishu[${accountId}]: message dedup enabled (ttl=${messageDedup['ttlMs']}ms, max=${messageDedup['maxEntries']})`);
49
+ log(`feishu[${accountId}]: starting WebSocket connection...`);
50
+ // Create LarkClient instance — manages SDK client, WS, and bot identity.
51
+ const lark = lark_client_1.LarkClient.fromAccount(account);
52
+ // Attach dedup instance so it is disposed together with the client.
53
+ lark.messageDedup = messageDedup;
54
+ /** Per-chat history maps (used for group-chat context window). */
55
+ const chatHistories = new Map();
56
+ const ctx = {
57
+ get cfg() {
58
+ return lark_client_1.LarkClient.runtime.config.loadConfig();
59
+ },
60
+ lark,
61
+ accountId,
62
+ chatHistories,
63
+ messageDedup,
64
+ runtime,
65
+ log,
66
+ error,
67
+ };
68
+ await lark.startWS({
69
+ handlers: {
70
+ 'im.message.receive_v1': (data) => (0, event_handlers_1.handleMessageEvent)(ctx, data),
71
+ 'im.message.message_read_v1': async () => { },
72
+ 'im.message.reaction.created_v1': (data) => (0, event_handlers_1.handleReactionEvent)(ctx, data),
73
+ // These events are expected in normal usage but do not affect the
74
+ // plugin's current behavior. Register no-op handlers to avoid SDK
75
+ // warnings about missing handlers.
76
+ 'im.message.reaction.deleted_v1': async () => { },
77
+ 'im.chat.access_event.bot_p2p_chat_entered_v1': async () => { },
78
+ 'im.chat.member.bot.added_v1': (data) => (0, event_handlers_1.handleBotMembershipEvent)(ctx, data, 'added'),
79
+ 'im.chat.member.bot.deleted_v1': (data) => (0, event_handlers_1.handleBotMembershipEvent)(ctx, data, 'removed'),
80
+ 'vc.bot.meeting_invited_v1': (data) => (0, event_handlers_1.handleVcMeetingInvitedEvent)(ctx, data),
81
+ // Drive comment event — fires when a user adds a comment or reply on a document.
82
+ 'drive.notice.comment_add_v1': (data) => (0, event_handlers_1.handleCommentEvent)(ctx, data),
83
+ // 飞书 SDK EventDispatcher.register 不支持带返回值的处理器,此处 as any 是 SDK 类型限制的变通
84
+ 'card.action.trigger': ((data) =>
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ (0, event_handlers_1.handleCardActionEvent)(ctx, data)),
87
+ },
88
+ abortSignal,
89
+ });
90
+ // startWS resolves when abortSignal fires — probe result is logged inside startWS.
91
+ log(`feishu[${accountId}]: bot open_id resolved: ${lark.botOpenId ?? 'unknown'}`);
92
+ log(`feishu[${accountId}]: WebSocket client started`);
93
+ mlog.info(`websocket started for account ${accountId}`);
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Public API
97
+ // ---------------------------------------------------------------------------
98
+ /**
99
+ * Start monitoring for all enabled Feishu accounts (or a single
100
+ * account when `opts.accountId` is specified).
101
+ */
102
+ async function monitorFeishuProvider(opts = {}) {
103
+ const cfg = opts.config;
104
+ if (!cfg) {
105
+ throw new Error('Config is required for Feishu monitor');
106
+ }
107
+ // Store the original global config so plugin commands (doctor, diagnose)
108
+ // can access cross-account information even when running inside an
109
+ // account-scoped config context.
110
+ lark_client_1.LarkClient.setGlobalConfig(cfg);
111
+ const log = opts.runtime?.log ?? ((...args) => mlog.info(args.map(String).join(' ')));
112
+ // Single-account mode.
113
+ if (opts.accountId) {
114
+ const account = (0, accounts_1.getLarkAccount)(cfg, opts.accountId);
115
+ if (!account.enabled || !account.configured) {
116
+ throw new Error(`Feishu account "${opts.accountId}" not configured or disabled`);
117
+ }
118
+ await monitorSingleAccount({
119
+ cfg,
120
+ account,
121
+ runtime: opts.runtime,
122
+ abortSignal: opts.abortSignal,
123
+ });
124
+ await (0, shutdown_hooks_1.drainShutdownHooks)({ log });
125
+ return;
126
+ }
127
+ // Multi-account mode: start all enabled accounts in parallel.
128
+ const accounts = (0, accounts_1.getEnabledLarkAccounts)(cfg);
129
+ if (accounts.length === 0) {
130
+ throw new Error('No enabled Feishu accounts configured');
131
+ }
132
+ log(`feishu: starting ${accounts.length} account(s): ${accounts.map((a) => a.accountId).join(', ')}`);
133
+ await Promise.all(accounts.map((account) => monitorSingleAccount({
134
+ cfg,
135
+ account,
136
+ runtime: opts.runtime,
137
+ abortSignal: opts.abortSignal,
138
+ })));
139
+ await (0, shutdown_hooks_1.drainShutdownHooks)({ log });
140
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Onboarding configuration mutation helpers.
6
+ *
7
+ * Pure functions that apply Feishu channel configuration changes
8
+ * to a ClawdbotConfig. Extracted from onboarding.ts for reuse
9
+ * in CLI commands and other configuration flows.
10
+ */
11
+ import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
12
+ import type { DmPolicy } from 'openclaw/plugin-sdk/setup';
13
+ export declare function setFeishuDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy): ClawdbotConfig;
14
+ export declare function setFeishuAllowFrom(cfg: ClawdbotConfig, allowFrom: string[]): ClawdbotConfig;
15
+ export declare function setFeishuGroupPolicy(cfg: ClawdbotConfig, groupPolicy: 'open' | 'allowlist' | 'disabled'): ClawdbotConfig;
16
+ export declare function setFeishuGroupAllowFrom(cfg: ClawdbotConfig, groupAllowFrom: string[]): ClawdbotConfig;
17
+ export declare function setFeishuGroups(cfg: ClawdbotConfig, groups: Record<string, object>): ClawdbotConfig;
18
+ export declare function parseAllowFromInput(raw: string): string[];
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Onboarding configuration mutation helpers.
7
+ *
8
+ * Pure functions that apply Feishu channel configuration changes
9
+ * to a ClawdbotConfig. Extracted from onboarding.ts for reuse
10
+ * in CLI commands and other configuration flows.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.setFeishuDmPolicy = setFeishuDmPolicy;
14
+ exports.setFeishuAllowFrom = setFeishuAllowFrom;
15
+ exports.setFeishuGroupPolicy = setFeishuGroupPolicy;
16
+ exports.setFeishuGroupAllowFrom = setFeishuGroupAllowFrom;
17
+ exports.setFeishuGroups = setFeishuGroups;
18
+ exports.parseAllowFromInput = parseAllowFromInput;
19
+ const setup_1 = require("openclaw/plugin-sdk/setup");
20
+ // ---------------------------------------------------------------------------
21
+ // Config mutation helpers
22
+ // ---------------------------------------------------------------------------
23
+ function setFeishuDmPolicy(cfg, dmPolicy) {
24
+ const allowFrom = dmPolicy === 'open'
25
+ ? (0, setup_1.addWildcardAllowFrom)(cfg.channels?.feishu?.allowFrom)?.map((entry) => String(entry))
26
+ : undefined;
27
+ return {
28
+ ...cfg,
29
+ channels: {
30
+ ...cfg.channels,
31
+ feishu: {
32
+ ...cfg.channels?.feishu,
33
+ dmPolicy,
34
+ ...(allowFrom ? { allowFrom } : {}),
35
+ },
36
+ },
37
+ };
38
+ }
39
+ function setFeishuAllowFrom(cfg, allowFrom) {
40
+ return {
41
+ ...cfg,
42
+ channels: {
43
+ ...cfg.channels,
44
+ feishu: {
45
+ ...cfg.channels?.feishu,
46
+ allowFrom,
47
+ },
48
+ },
49
+ };
50
+ }
51
+ function setFeishuGroupPolicy(cfg, groupPolicy) {
52
+ return {
53
+ ...cfg,
54
+ channels: {
55
+ ...cfg.channels,
56
+ feishu: {
57
+ ...cfg.channels?.feishu,
58
+ enabled: true,
59
+ groupPolicy,
60
+ },
61
+ },
62
+ };
63
+ }
64
+ function setFeishuGroupAllowFrom(cfg, groupAllowFrom) {
65
+ return {
66
+ ...cfg,
67
+ channels: {
68
+ ...cfg.channels,
69
+ feishu: {
70
+ ...cfg.channels?.feishu,
71
+ groupAllowFrom,
72
+ },
73
+ },
74
+ };
75
+ }
76
+ function setFeishuGroups(cfg, groups) {
77
+ return {
78
+ ...cfg,
79
+ channels: {
80
+ ...cfg.channels,
81
+ feishu: {
82
+ ...cfg.channels?.feishu,
83
+ groups,
84
+ },
85
+ },
86
+ };
87
+ }
88
+ // ---------------------------------------------------------------------------
89
+ // Input helpers
90
+ // ---------------------------------------------------------------------------
91
+ function parseAllowFromInput(raw) {
92
+ return raw
93
+ .split(/[\n,;]+/g)
94
+ .map((entry) => entry.trim())
95
+ .filter(Boolean);
96
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Legacy groupAllowFrom migration for Feishu onboarding.
6
+ *
7
+ * Handles the migration of chat_id entries (oc_xxx) from
8
+ * groupAllowFrom to the groups config, preserving the original
9
+ * semantic of "allow this group for any sender".
10
+ */
11
+ import type { ClawdbotConfig, WizardPrompter } from 'openclaw/plugin-sdk';
12
+ /**
13
+ * Detect and migrate legacy chat_id entries in groupAllowFrom.
14
+ *
15
+ * Old semantic: groupAllowFrom contained chat_ids (oc_xxx) to control
16
+ * which groups could use the bot.
17
+ * New semantic: groupAllowFrom is for sender filtering (open_ids like ou_xxx).
18
+ *
19
+ * This function prompts the user and, if confirmed, moves chat_ids
20
+ * to the groups config and keeps only sender IDs in groupAllowFrom.
21
+ */
22
+ export declare function migrateLegacyGroupAllowFrom(params: {
23
+ cfg: ClawdbotConfig;
24
+ prompter: WizardPrompter;
25
+ }): Promise<ClawdbotConfig>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Legacy groupAllowFrom migration for Feishu onboarding.
7
+ *
8
+ * Handles the migration of chat_id entries (oc_xxx) from
9
+ * groupAllowFrom to the groups config, preserving the original
10
+ * semantic of "allow this group for any sender".
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.migrateLegacyGroupAllowFrom = migrateLegacyGroupAllowFrom;
14
+ const onboarding_config_1 = require("./onboarding-config.js");
15
+ /**
16
+ * Detect and migrate legacy chat_id entries in groupAllowFrom.
17
+ *
18
+ * Old semantic: groupAllowFrom contained chat_ids (oc_xxx) to control
19
+ * which groups could use the bot.
20
+ * New semantic: groupAllowFrom is for sender filtering (open_ids like ou_xxx).
21
+ *
22
+ * This function prompts the user and, if confirmed, moves chat_ids
23
+ * to the groups config and keeps only sender IDs in groupAllowFrom.
24
+ */
25
+ async function migrateLegacyGroupAllowFrom(params) {
26
+ let next = params.cfg;
27
+ const { prompter } = params;
28
+ const existingGroupAllowFrom = next.channels?.feishu?.groupAllowFrom ?? [];
29
+ const legacyChatIds = existingGroupAllowFrom.filter((e) => String(e).startsWith('oc_'));
30
+ const senderAllowFrom = existingGroupAllowFrom.filter((e) => !String(e).startsWith('oc_'));
31
+ if (legacyChatIds.length === 0) {
32
+ return next;
33
+ }
34
+ await prompter.note([
35
+ `⚠️ Detected legacy config: groupAllowFrom contains chat_ids (${legacyChatIds.join(', ')})`,
36
+ '',
37
+ 'Old semantic: groupAllowFrom controlled which groups could use the bot.',
38
+ 'New semantic: groupAllowFrom is for SENDER filtering (open_ids like ou_xxx).',
39
+ '',
40
+ 'Recommended migration:',
41
+ ` 1. Move chat_ids (oc_xxx) → channels.feishu.groups`,
42
+ ` 2. Keep sender IDs (ou_xxx) in groupAllowFrom`,
43
+ ].join('\n'), 'Legacy config detected');
44
+ const migrate = await prompter.confirm({
45
+ message: `Migrate ${legacyChatIds.length} chat_id(s) to groups config?`,
46
+ initialValue: true,
47
+ });
48
+ if (migrate) {
49
+ const existingGroups = next.channels?.feishu?.groups ?? {};
50
+ const migratedGroups = {
51
+ ...existingGroups,
52
+ };
53
+ for (const chatId of legacyChatIds) {
54
+ if (!migratedGroups[String(chatId)]) {
55
+ migratedGroups[String(chatId)] = {
56
+ enabled: true,
57
+ groupPolicy: 'open',
58
+ };
59
+ }
60
+ }
61
+ next = (0, onboarding_config_1.setFeishuGroups)(next, migratedGroups);
62
+ next = (0, onboarding_config_1.setFeishuGroupAllowFrom)(next, senderAllowFrom);
63
+ await prompter.note(`✅ Migrated: ${legacyChatIds.length} chat_id(s) moved to groups, ` +
64
+ `${senderAllowFrom.length} sender(s) kept in groupAllowFrom`, 'Migration complete');
65
+ }
66
+ else {
67
+ await prompter.note('Skipped migration. Please update config manually to avoid issues.', 'Migration skipped');
68
+ }
69
+ return next;
70
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Onboarding wizard adapter for the Lark/Feishu channel plugin.
6
+ *
7
+ * Implements the ChannelOnboardingAdapter interface so the `openclaw
8
+ * setup` wizard can configure Feishu credentials, domain, group
9
+ * policies, and DM allowlists interactively.
10
+ */
11
+ import type { ChannelSetupWizardAdapter } from 'openclaw/plugin-sdk/setup';
12
+ export declare const feishuOnboardingAdapter: ChannelSetupWizardAdapter;
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Onboarding wizard adapter for the Lark/Feishu channel plugin.
7
+ *
8
+ * Implements the ChannelOnboardingAdapter interface so the `openclaw
9
+ * setup` wizard can configure Feishu credentials, domain, group
10
+ * policies, and DM allowlists interactively.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.feishuOnboardingAdapter = void 0;
14
+ const account_id_1 = require("openclaw/plugin-sdk/account-id");
15
+ const setup_1 = require("openclaw/plugin-sdk/setup");
16
+ const accounts_1 = require("../core/accounts.js");
17
+ const probe_1 = require("./probe.js");
18
+ const onboarding_config_1 = require("./onboarding-config.js");
19
+ const onboarding_migrate_1 = require("./onboarding-migrate.js");
20
+ // ---------------------------------------------------------------------------
21
+ // Constants
22
+ // ---------------------------------------------------------------------------
23
+ const channel = 'feishu';
24
+ // ---------------------------------------------------------------------------
25
+ // Prompter helpers
26
+ // ---------------------------------------------------------------------------
27
+ async function noteFeishuCredentialHelp(prompter) {
28
+ await prompter.note([
29
+ '1) Go to Feishu Open Platform (open.feishu.cn)',
30
+ '2) Create a self-built app',
31
+ '3) Get App ID and App Secret from Credentials page',
32
+ '4) Enable required permissions: im:message, im:chat, contact:user.base:readonly',
33
+ '5) Publish the app or add it to a test group',
34
+ 'Tip: you can also set FEISHU_APP_ID / FEISHU_APP_SECRET env vars.',
35
+ `Docs: ${(0, setup_1.formatDocsLink)('/channels/feishu', 'feishu')}`,
36
+ ].join('\n'), 'Feishu credentials');
37
+ }
38
+ async function promptFeishuAllowFrom(params) {
39
+ const existing = params.cfg.channels?.feishu?.allowFrom ?? [];
40
+ await params.prompter.note([
41
+ 'Allowlist Feishu DMs by open_id or user_id.',
42
+ 'You can find user open_id in Feishu admin console or via API.',
43
+ 'Examples:',
44
+ '- ou_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
45
+ '- on_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
46
+ ].join('\n'), 'Feishu allowlist');
47
+ while (true) {
48
+ const entry = await params.prompter.text({
49
+ message: 'Feishu allowFrom (user open_ids)',
50
+ placeholder: 'ou_xxxxx, ou_yyyyy',
51
+ initialValue: existing[0] ? String(existing[0]) : undefined,
52
+ validate: (value) => (String(value ?? '').trim() ? undefined : 'Required'),
53
+ });
54
+ const parts = (0, onboarding_config_1.parseAllowFromInput)(String(entry));
55
+ if (parts.length === 0) {
56
+ await params.prompter.note('Enter at least one user.', 'Feishu allowlist');
57
+ continue;
58
+ }
59
+ const unique = [...new Set([...existing.map((v) => String(v).trim()).filter(Boolean), ...parts])];
60
+ return (0, onboarding_config_1.setFeishuAllowFrom)(params.cfg, unique);
61
+ }
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Credential acquisition
65
+ // ---------------------------------------------------------------------------
66
+ async function acquireCredentials(params) {
67
+ const { prompter, feishuCfg } = params;
68
+ let next = params.cfg;
69
+ const hasConfigCreds = Boolean(feishuCfg?.appId?.trim() && feishuCfg?.appSecret?.trim());
70
+ const canUseEnv = Boolean(!hasConfigCreds && process.env.FEISHU_APP_ID?.trim() && process.env.FEISHU_APP_SECRET?.trim());
71
+ let appId = null;
72
+ let appSecret = null;
73
+ if (canUseEnv) {
74
+ const keepEnv = await prompter.confirm({
75
+ message: 'FEISHU_APP_ID + FEISHU_APP_SECRET detected. Use env vars?',
76
+ initialValue: true,
77
+ });
78
+ if (keepEnv) {
79
+ next = {
80
+ ...next,
81
+ channels: {
82
+ ...next.channels,
83
+ feishu: { ...next.channels?.feishu, enabled: true },
84
+ },
85
+ };
86
+ }
87
+ else {
88
+ appId = String(await prompter.text({
89
+ message: 'Enter Feishu App ID',
90
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
91
+ })).trim();
92
+ appSecret = String(await prompter.text({
93
+ message: 'Enter Feishu App Secret',
94
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
95
+ })).trim();
96
+ }
97
+ }
98
+ else if (hasConfigCreds) {
99
+ const keep = await prompter.confirm({
100
+ message: 'Feishu credentials already configured. Keep them?',
101
+ initialValue: true,
102
+ });
103
+ if (!keep) {
104
+ appId = String(await prompter.text({
105
+ message: 'Enter Feishu App ID',
106
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
107
+ })).trim();
108
+ appSecret = String(await prompter.text({
109
+ message: 'Enter Feishu App Secret',
110
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
111
+ })).trim();
112
+ }
113
+ }
114
+ else {
115
+ appId = String(await prompter.text({
116
+ message: 'Enter Feishu App ID',
117
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
118
+ })).trim();
119
+ appSecret = String(await prompter.text({
120
+ message: 'Enter Feishu App Secret',
121
+ validate: (value) => (value?.trim() ? undefined : 'Required'),
122
+ })).trim();
123
+ }
124
+ return { cfg: next, appId, appSecret };
125
+ }
126
+ // ---------------------------------------------------------------------------
127
+ // DM policy
128
+ // ---------------------------------------------------------------------------
129
+ const dmPolicy = {
130
+ label: 'Feishu',
131
+ channel,
132
+ policyKey: 'channels.feishu.dmPolicy',
133
+ allowFromKey: 'channels.feishu.allowFrom',
134
+ getCurrent: (cfg) => cfg.channels?.feishu?.dmPolicy ?? 'pairing',
135
+ setPolicy: (cfg, policy) => (0, onboarding_config_1.setFeishuDmPolicy)(cfg, policy),
136
+ promptAllowFrom: promptFeishuAllowFrom,
137
+ };
138
+ // ---------------------------------------------------------------------------
139
+ // Adapter
140
+ // ---------------------------------------------------------------------------
141
+ exports.feishuOnboardingAdapter = {
142
+ channel,
143
+ // -----------------------------------------------------------------------
144
+ // getStatus
145
+ // -----------------------------------------------------------------------
146
+ getStatus: async ({ cfg }) => {
147
+ const feishuCfg = cfg.channels?.feishu;
148
+ const configured = Boolean((0, accounts_1.getLarkCredentials)(feishuCfg));
149
+ // Attempt a live probe when credentials are present.
150
+ let probeResult = null;
151
+ if (configured && feishuCfg) {
152
+ try {
153
+ probeResult = await (0, probe_1.probeFeishu)(feishuCfg);
154
+ }
155
+ catch {
156
+ // Ignore probe errors -- status degrades gracefully.
157
+ }
158
+ }
159
+ const statusLines = [];
160
+ if (!configured) {
161
+ statusLines.push('Feishu: needs app credentials');
162
+ }
163
+ else if (probeResult?.ok) {
164
+ statusLines.push(`Feishu: connected as ${probeResult.botName ?? probeResult.botOpenId ?? 'bot'}`);
165
+ }
166
+ else {
167
+ statusLines.push('Feishu: configured (connection not verified)');
168
+ }
169
+ return {
170
+ channel,
171
+ configured,
172
+ statusLines,
173
+ selectionHint: configured ? 'configured' : 'needs app creds',
174
+ quickstartScore: configured ? 2 : 0,
175
+ };
176
+ },
177
+ // -----------------------------------------------------------------------
178
+ // configure
179
+ // -----------------------------------------------------------------------
180
+ configure: async ({ cfg, prompter }) => {
181
+ const feishuCfg = cfg.channels?.feishu;
182
+ const resolved = (0, accounts_1.getLarkCredentials)(feishuCfg);
183
+ let next = cfg;
184
+ // Show credential help if nothing is configured yet.
185
+ if (!resolved) {
186
+ await noteFeishuCredentialHelp(prompter);
187
+ }
188
+ // --- Credential acquisition ---
189
+ const creds = await acquireCredentials({ cfg: next, prompter, feishuCfg });
190
+ next = creds.cfg;
191
+ // --- Persist and test credentials ---
192
+ if (creds.appId && creds.appSecret) {
193
+ next = {
194
+ ...next,
195
+ channels: {
196
+ ...next.channels,
197
+ feishu: {
198
+ ...next.channels?.feishu,
199
+ enabled: true,
200
+ appId: creds.appId,
201
+ appSecret: creds.appSecret,
202
+ },
203
+ },
204
+ };
205
+ const testCfg = next.channels?.feishu;
206
+ try {
207
+ const probe = await (0, probe_1.probeFeishu)(testCfg);
208
+ if (probe.ok) {
209
+ await prompter.note(`Connected as ${probe.botName ?? probe.botOpenId ?? 'bot'}`, 'Feishu connection test');
210
+ }
211
+ else {
212
+ await prompter.note(`Connection failed: ${probe.error ?? 'unknown error'}`, 'Feishu connection test');
213
+ }
214
+ }
215
+ catch (err) {
216
+ await prompter.note(`Connection test failed: ${String(err)}`, 'Feishu connection test');
217
+ }
218
+ }
219
+ // --- Domain selection ---
220
+ const currentDomain = next.channels?.feishu?.domain ?? 'feishu';
221
+ const domain = await prompter.select({
222
+ message: 'Which Feishu domain?',
223
+ options: [
224
+ { value: 'feishu', label: 'Feishu (feishu.cn) - China' },
225
+ { value: 'lark', label: 'Lark (larksuite.com) - International' },
226
+ ],
227
+ initialValue: currentDomain,
228
+ });
229
+ if (domain) {
230
+ next = {
231
+ ...next,
232
+ channels: {
233
+ ...next.channels,
234
+ feishu: {
235
+ ...next.channels?.feishu,
236
+ domain: domain,
237
+ },
238
+ },
239
+ };
240
+ }
241
+ // --- Legacy migration ---
242
+ next = await (0, onboarding_migrate_1.migrateLegacyGroupAllowFrom)({ cfg: next, prompter });
243
+ // --- Group policy ---
244
+ const groupPolicy = await prompter.select({
245
+ message: 'Group chat policy — which groups can interact with the bot?',
246
+ options: [
247
+ {
248
+ value: 'allowlist',
249
+ label: 'Allowlist — only groups listed in `groups` config (default)',
250
+ },
251
+ {
252
+ value: 'open',
253
+ label: 'Open — any group (requires @mention)',
254
+ },
255
+ {
256
+ value: 'disabled',
257
+ label: 'Disabled — no group interactions',
258
+ },
259
+ ],
260
+ initialValue: next.channels?.feishu?.groupPolicy ?? 'allowlist',
261
+ });
262
+ if (groupPolicy) {
263
+ next = (0, onboarding_config_1.setFeishuGroupPolicy)(next, groupPolicy);
264
+ }
265
+ // --- Group sender allowlist ---
266
+ if (groupPolicy !== 'disabled') {
267
+ const existing = next.channels?.feishu?.groupAllowFrom ?? [];
268
+ const entry = await prompter.text({
269
+ message: 'Group sender allowlist — which users can trigger the bot in allowed groups? (user open_ids)',
270
+ placeholder: 'ou_xxxxx, ou_yyyyy',
271
+ initialValue: existing.length > 0 ? existing.map(String).join(', ') : undefined,
272
+ });
273
+ if (entry) {
274
+ const parts = (0, onboarding_config_1.parseAllowFromInput)(String(entry));
275
+ if (parts.length > 0) {
276
+ next = (0, onboarding_config_1.setFeishuGroupAllowFrom)(next, parts);
277
+ }
278
+ }
279
+ else if (groupPolicy === 'allowlist') {
280
+ await prompter.note('Empty sender list + allowlist = nobody can trigger. ' +
281
+ "Use groupPolicy 'open' if you want anyone in allowed groups to trigger.", 'Note');
282
+ }
283
+ }
284
+ return { cfg: next, accountId: account_id_1.DEFAULT_ACCOUNT_ID };
285
+ },
286
+ // -----------------------------------------------------------------------
287
+ // dmPolicy
288
+ // -----------------------------------------------------------------------
289
+ dmPolicy,
290
+ // -----------------------------------------------------------------------
291
+ // disable
292
+ // -----------------------------------------------------------------------
293
+ disable: (cfg) => ({
294
+ ...cfg,
295
+ channels: {
296
+ ...cfg.channels,
297
+ feishu: { ...cfg.channels?.feishu, enabled: false },
298
+ },
299
+ }),
300
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * ChannelPlugin interface implementation for the Lark/Feishu channel.
6
+ *
7
+ * This is the top-level entry point that the OpenClaw plugin system uses to
8
+ * discover capabilities, resolve accounts, obtain outbound adapters, and
9
+ * start the inbound event gateway.
10
+ */
11
+ import type { ChannelPlugin } from 'openclaw/plugin-sdk';
12
+ import type { LarkAccount } from '../core/types';
13
+ export declare const feishuPlugin: ChannelPlugin<LarkAccount>;