@lark-project/openclaw-lark-project 2026.3.131

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 (368) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/README.zh.md +80 -0
  4. package/dist/index.js +172 -0
  5. package/dist/index.js.map +7 -0
  6. package/dist/skills/feishu-bitable/SKILL.md +248 -0
  7. package/dist/skills/feishu-bitable/references/examples.md +813 -0
  8. package/dist/skills/feishu-bitable/references/field-properties.md +763 -0
  9. package/dist/skills/feishu-bitable/references/record-values.md +911 -0
  10. package/dist/skills/feishu-calendar/SKILL.md +244 -0
  11. package/dist/skills/feishu-channel-rules/SKILL.md +18 -0
  12. package/dist/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  13. package/dist/skills/feishu-create-doc/SKILL.md +719 -0
  14. package/dist/skills/feishu-fetch-doc/SKILL.md +93 -0
  15. package/dist/skills/feishu-im-read/SKILL.md +163 -0
  16. package/dist/skills/feishu-project/SKILL.md +122 -0
  17. package/dist/skills/feishu-task/SKILL.md +293 -0
  18. package/dist/skills/feishu-troubleshoot/SKILL.md +70 -0
  19. package/dist/skills/feishu-update-doc/SKILL.md +285 -0
  20. package/dist/src/card/builder.js +293 -0
  21. package/dist/src/card/builder.js.map +7 -0
  22. package/dist/src/card/cardkit.js +126 -0
  23. package/dist/src/card/cardkit.js.map +7 -0
  24. package/dist/src/card/flush-controller.js +107 -0
  25. package/dist/src/card/flush-controller.js.map +7 -0
  26. package/dist/src/card/markdown-style.js +57 -0
  27. package/dist/src/card/markdown-style.js.map +7 -0
  28. package/dist/src/card/reply-dispatcher-types.js +39 -0
  29. package/dist/src/card/reply-dispatcher-types.js.map +7 -0
  30. package/dist/src/card/reply-dispatcher.js +245 -0
  31. package/dist/src/card/reply-dispatcher.js.map +7 -0
  32. package/dist/src/card/reply-mode.js +29 -0
  33. package/dist/src/card/reply-mode.js.map +7 -0
  34. package/dist/src/card/streaming-card-controller.js +653 -0
  35. package/dist/src/card/streaming-card-controller.js.map +7 -0
  36. package/dist/src/card/unavailable-guard.js +76 -0
  37. package/dist/src/card/unavailable-guard.js.map +7 -0
  38. package/dist/src/channel/abort-detect.js +79 -0
  39. package/dist/src/channel/abort-detect.js.map +7 -0
  40. package/dist/src/channel/chat-queue.js +50 -0
  41. package/dist/src/channel/chat-queue.js.map +7 -0
  42. package/dist/src/channel/config-adapter.js +89 -0
  43. package/dist/src/channel/config-adapter.js.map +7 -0
  44. package/dist/src/channel/directory.js +133 -0
  45. package/dist/src/channel/directory.js.map +7 -0
  46. package/dist/src/channel/event-handlers.js +175 -0
  47. package/dist/src/channel/event-handlers.js.map +7 -0
  48. package/dist/src/channel/monitor.js +108 -0
  49. package/dist/src/channel/monitor.js.map +7 -0
  50. package/dist/src/channel/onboarding-config.js +76 -0
  51. package/dist/src/channel/onboarding-config.js.map +7 -0
  52. package/dist/src/channel/onboarding-migrate.js +55 -0
  53. package/dist/src/channel/onboarding-migrate.js.map +7 -0
  54. package/dist/src/channel/onboarding.js +285 -0
  55. package/dist/src/channel/onboarding.js.map +7 -0
  56. package/dist/src/channel/plugin.js +260 -0
  57. package/dist/src/channel/plugin.js.map +7 -0
  58. package/dist/src/channel/probe.js +14 -0
  59. package/dist/src/channel/probe.js.map +7 -0
  60. package/dist/src/channel/types.js +1 -0
  61. package/dist/src/channel/types.js.map +7 -0
  62. package/dist/src/commands/auth.js +73 -0
  63. package/dist/src/commands/auth.js.map +7 -0
  64. package/dist/src/commands/diagnose.js +658 -0
  65. package/dist/src/commands/diagnose.js.map +7 -0
  66. package/dist/src/commands/doctor.js +327 -0
  67. package/dist/src/commands/doctor.js.map +7 -0
  68. package/dist/src/commands/index.js +124 -0
  69. package/dist/src/commands/index.js.map +7 -0
  70. package/dist/src/core/accounts.js +129 -0
  71. package/dist/src/core/accounts.js.map +7 -0
  72. package/dist/src/core/agent-config.js +60 -0
  73. package/dist/src/core/agent-config.js.map +7 -0
  74. package/dist/src/core/api-error.js +55 -0
  75. package/dist/src/core/api-error.js.map +7 -0
  76. package/dist/src/core/app-owner-fallback.js +17 -0
  77. package/dist/src/core/app-owner-fallback.js.map +7 -0
  78. package/dist/src/core/app-scope-checker.js +95 -0
  79. package/dist/src/core/app-scope-checker.js.map +7 -0
  80. package/dist/src/core/auth-errors.js +120 -0
  81. package/dist/src/core/auth-errors.js.map +7 -0
  82. package/dist/src/core/chat-info-cache.js +102 -0
  83. package/dist/src/core/chat-info-cache.js.map +7 -0
  84. package/dist/src/core/config-schema.js +150 -0
  85. package/dist/src/core/config-schema.js.map +7 -0
  86. package/dist/src/core/device-flow.js +174 -0
  87. package/dist/src/core/device-flow.js.map +7 -0
  88. package/dist/src/core/feishu-fetch.js +12 -0
  89. package/dist/src/core/feishu-fetch.js.map +7 -0
  90. package/dist/src/core/footer-config.js +16 -0
  91. package/dist/src/core/footer-config.js.map +7 -0
  92. package/dist/src/core/lark-client.js +322 -0
  93. package/dist/src/core/lark-client.js.map +7 -0
  94. package/dist/src/core/lark-logger.js +92 -0
  95. package/dist/src/core/lark-logger.js.map +7 -0
  96. package/dist/src/core/lark-ticket.js +18 -0
  97. package/dist/src/core/lark-ticket.js.map +7 -0
  98. package/dist/src/core/message-unavailable.js +119 -0
  99. package/dist/src/core/message-unavailable.js.map +7 -0
  100. package/dist/src/core/owner-policy.js +25 -0
  101. package/dist/src/core/owner-policy.js.map +7 -0
  102. package/dist/src/core/permission-url.js +37 -0
  103. package/dist/src/core/permission-url.js.map +7 -0
  104. package/dist/src/core/project-auth.js +177 -0
  105. package/dist/src/core/project-auth.js.map +7 -0
  106. package/dist/src/core/project-oauth-flow.js +124 -0
  107. package/dist/src/core/project-oauth-flow.js.map +7 -0
  108. package/dist/src/core/project-token-store.js +172 -0
  109. package/dist/src/core/project-token-store.js.map +7 -0
  110. package/dist/src/core/raw-request.js +45 -0
  111. package/dist/src/core/raw-request.js.map +7 -0
  112. package/dist/src/core/scope-manager.js +62 -0
  113. package/dist/src/core/scope-manager.js.map +7 -0
  114. package/dist/src/core/security-check.js +118 -0
  115. package/dist/src/core/security-check.js.map +7 -0
  116. package/dist/src/core/shutdown-hooks.js +37 -0
  117. package/dist/src/core/shutdown-hooks.js.map +7 -0
  118. package/dist/src/core/targets.js +55 -0
  119. package/dist/src/core/targets.js.map +7 -0
  120. package/dist/src/core/token-store.js +215 -0
  121. package/dist/src/core/token-store.js.map +7 -0
  122. package/dist/src/core/tool-client.js +335 -0
  123. package/dist/src/core/tool-client.js.map +7 -0
  124. package/dist/src/core/tool-scopes.js +207 -0
  125. package/dist/src/core/tool-scopes.js.map +7 -0
  126. package/dist/src/core/tools-config.js +57 -0
  127. package/dist/src/core/tools-config.js.map +7 -0
  128. package/dist/src/core/types.js +1 -0
  129. package/dist/src/core/types.js.map +7 -0
  130. package/dist/src/core/uat-client.js +124 -0
  131. package/dist/src/core/uat-client.js.map +7 -0
  132. package/dist/src/core/version.js +27 -0
  133. package/dist/src/core/version.js.map +7 -0
  134. package/dist/src/messaging/converters/audio.js +19 -0
  135. package/dist/src/messaging/converters/audio.js.map +7 -0
  136. package/dist/src/messaging/converters/calendar.js +46 -0
  137. package/dist/src/messaging/converters/calendar.js.map +7 -0
  138. package/dist/src/messaging/converters/content-converter.js +61 -0
  139. package/dist/src/messaging/converters/content-converter.js.map +7 -0
  140. package/dist/src/messaging/converters/file.js +18 -0
  141. package/dist/src/messaging/converters/file.js.map +7 -0
  142. package/dist/src/messaging/converters/folder.js +18 -0
  143. package/dist/src/messaging/converters/folder.js.map +7 -0
  144. package/dist/src/messaging/converters/hongbao.js +14 -0
  145. package/dist/src/messaging/converters/hongbao.js.map +7 -0
  146. package/dist/src/messaging/converters/image.js +16 -0
  147. package/dist/src/messaging/converters/image.js.map +7 -0
  148. package/dist/src/messaging/converters/index.js +48 -0
  149. package/dist/src/messaging/converters/index.js.map +7 -0
  150. package/dist/src/messaging/converters/interactive/card-converter.js +1040 -0
  151. package/dist/src/messaging/converters/interactive/card-converter.js.map +7 -0
  152. package/dist/src/messaging/converters/interactive/card-utils.js +36 -0
  153. package/dist/src/messaging/converters/interactive/card-utils.js.map +7 -0
  154. package/dist/src/messaging/converters/interactive/index.js +19 -0
  155. package/dist/src/messaging/converters/interactive/index.js.map +7 -0
  156. package/dist/src/messaging/converters/interactive/legacy.js +53 -0
  157. package/dist/src/messaging/converters/interactive/legacy.js.map +7 -0
  158. package/dist/src/messaging/converters/interactive/types.js +23 -0
  159. package/dist/src/messaging/converters/interactive/types.js.map +7 -0
  160. package/dist/src/messaging/converters/location.js +17 -0
  161. package/dist/src/messaging/converters/location.js.map +7 -0
  162. package/dist/src/messaging/converters/merge-forward.js +143 -0
  163. package/dist/src/messaging/converters/merge-forward.js.map +7 -0
  164. package/dist/src/messaging/converters/post.js +113 -0
  165. package/dist/src/messaging/converters/post.js.map +7 -0
  166. package/dist/src/messaging/converters/share.js +22 -0
  167. package/dist/src/messaging/converters/share.js.map +7 -0
  168. package/dist/src/messaging/converters/sticker.js +16 -0
  169. package/dist/src/messaging/converters/sticker.js.map +7 -0
  170. package/dist/src/messaging/converters/system.js +25 -0
  171. package/dist/src/messaging/converters/system.js.map +7 -0
  172. package/dist/src/messaging/converters/text.js +12 -0
  173. package/dist/src/messaging/converters/text.js.map +7 -0
  174. package/dist/src/messaging/converters/todo.js +37 -0
  175. package/dist/src/messaging/converters/todo.js.map +7 -0
  176. package/dist/src/messaging/converters/types.js +1 -0
  177. package/dist/src/messaging/converters/types.js.map +7 -0
  178. package/dist/src/messaging/converters/unknown.js +13 -0
  179. package/dist/src/messaging/converters/unknown.js.map +7 -0
  180. package/dist/src/messaging/converters/utils.js +35 -0
  181. package/dist/src/messaging/converters/utils.js.map +7 -0
  182. package/dist/src/messaging/converters/video-chat.js +21 -0
  183. package/dist/src/messaging/converters/video-chat.js.map +7 -0
  184. package/dist/src/messaging/converters/video.js +30 -0
  185. package/dist/src/messaging/converters/video.js.map +7 -0
  186. package/dist/src/messaging/converters/vote.js +24 -0
  187. package/dist/src/messaging/converters/vote.js.map +7 -0
  188. package/dist/src/messaging/inbound/dedup.js +82 -0
  189. package/dist/src/messaging/inbound/dedup.js.map +7 -0
  190. package/dist/src/messaging/inbound/dispatch-builders.js +98 -0
  191. package/dist/src/messaging/inbound/dispatch-builders.js.map +7 -0
  192. package/dist/src/messaging/inbound/dispatch-commands.js +94 -0
  193. package/dist/src/messaging/inbound/dispatch-commands.js.map +7 -0
  194. package/dist/src/messaging/inbound/dispatch-context.js +96 -0
  195. package/dist/src/messaging/inbound/dispatch-context.js.map +7 -0
  196. package/dist/src/messaging/inbound/dispatch.js +150 -0
  197. package/dist/src/messaging/inbound/dispatch.js.map +7 -0
  198. package/dist/src/messaging/inbound/enrich.js +137 -0
  199. package/dist/src/messaging/inbound/enrich.js.map +7 -0
  200. package/dist/src/messaging/inbound/gate-effects.js +28 -0
  201. package/dist/src/messaging/inbound/gate-effects.js.map +7 -0
  202. package/dist/src/messaging/inbound/gate.js +163 -0
  203. package/dist/src/messaging/inbound/gate.js.map +7 -0
  204. package/dist/src/messaging/inbound/handler.js +132 -0
  205. package/dist/src/messaging/inbound/handler.js.map +7 -0
  206. package/dist/src/messaging/inbound/media-resolver.js +70 -0
  207. package/dist/src/messaging/inbound/media-resolver.js.map +7 -0
  208. package/dist/src/messaging/inbound/mention.js +50 -0
  209. package/dist/src/messaging/inbound/mention.js.map +7 -0
  210. package/dist/src/messaging/inbound/parse-io.js +41 -0
  211. package/dist/src/messaging/inbound/parse-io.js.map +7 -0
  212. package/dist/src/messaging/inbound/parse.js +79 -0
  213. package/dist/src/messaging/inbound/parse.js.map +7 -0
  214. package/dist/src/messaging/inbound/permission.js +30 -0
  215. package/dist/src/messaging/inbound/permission.js.map +7 -0
  216. package/dist/src/messaging/inbound/policy.js +83 -0
  217. package/dist/src/messaging/inbound/policy.js.map +7 -0
  218. package/dist/src/messaging/inbound/reaction-handler.js +162 -0
  219. package/dist/src/messaging/inbound/reaction-handler.js.map +7 -0
  220. package/dist/src/messaging/inbound/user-name-cache.js +172 -0
  221. package/dist/src/messaging/inbound/user-name-cache.js.map +7 -0
  222. package/dist/src/messaging/outbound/actions.js +239 -0
  223. package/dist/src/messaging/outbound/actions.js.map +7 -0
  224. package/dist/src/messaging/outbound/chat-manage.js +74 -0
  225. package/dist/src/messaging/outbound/chat-manage.js.map +7 -0
  226. package/dist/src/messaging/outbound/deliver.js +162 -0
  227. package/dist/src/messaging/outbound/deliver.js.map +7 -0
  228. package/dist/src/messaging/outbound/fetch.js +7 -0
  229. package/dist/src/messaging/outbound/fetch.js.map +7 -0
  230. package/dist/src/messaging/outbound/forward.js +31 -0
  231. package/dist/src/messaging/outbound/forward.js.map +7 -0
  232. package/dist/src/messaging/outbound/media-url-utils.js +101 -0
  233. package/dist/src/messaging/outbound/media-url-utils.js.map +7 -0
  234. package/dist/src/messaging/outbound/media.js +463 -0
  235. package/dist/src/messaging/outbound/media.js.map +7 -0
  236. package/dist/src/messaging/outbound/outbound.js +95 -0
  237. package/dist/src/messaging/outbound/outbound.js.map +7 -0
  238. package/dist/src/messaging/outbound/reactions.js +312 -0
  239. package/dist/src/messaging/outbound/reactions.js.map +7 -0
  240. package/dist/src/messaging/outbound/send.js +194 -0
  241. package/dist/src/messaging/outbound/send.js.map +7 -0
  242. package/dist/src/messaging/outbound/typing.js +77 -0
  243. package/dist/src/messaging/outbound/typing.js.map +7 -0
  244. package/dist/src/messaging/shared/message-lookup.js +84 -0
  245. package/dist/src/messaging/shared/message-lookup.js.map +7 -0
  246. package/dist/src/messaging/types.js +1 -0
  247. package/dist/src/messaging/types.js.map +7 -0
  248. package/dist/src/tools/auto-auth.js +714 -0
  249. package/dist/src/tools/auto-auth.js.map +7 -0
  250. package/dist/src/tools/helpers.js +133 -0
  251. package/dist/src/tools/helpers.js.map +7 -0
  252. package/dist/src/tools/mcp/doc/create.js +35 -0
  253. package/dist/src/tools/mcp/doc/create.js.map +7 -0
  254. package/dist/src/tools/mcp/doc/fetch.js +33 -0
  255. package/dist/src/tools/mcp/doc/fetch.js.map +7 -0
  256. package/dist/src/tools/mcp/doc/index.js +32 -0
  257. package/dist/src/tools/mcp/doc/index.js.map +7 -0
  258. package/dist/src/tools/mcp/doc/update.js +61 -0
  259. package/dist/src/tools/mcp/doc/update.js.map +7 -0
  260. package/dist/src/tools/mcp/project/endpoint.js +25 -0
  261. package/dist/src/tools/mcp/project/endpoint.js.map +7 -0
  262. package/dist/src/tools/mcp/project/index.js +27 -0
  263. package/dist/src/tools/mcp/project/index.js.map +7 -0
  264. package/dist/src/tools/mcp/project/tools.js +579 -0
  265. package/dist/src/tools/mcp/project/tools.js.map +7 -0
  266. package/dist/src/tools/mcp/shared.js +170 -0
  267. package/dist/src/tools/mcp/shared.js.map +7 -0
  268. package/dist/src/tools/oapi/bitable/app-table-field.js +244 -0
  269. package/dist/src/tools/oapi/bitable/app-table-field.js.map +7 -0
  270. package/dist/src/tools/oapi/bitable/app-table-record.js +501 -0
  271. package/dist/src/tools/oapi/bitable/app-table-record.js.map +7 -0
  272. package/dist/src/tools/oapi/bitable/app-table-view.js +226 -0
  273. package/dist/src/tools/oapi/bitable/app-table-view.js.map +7 -0
  274. package/dist/src/tools/oapi/bitable/app-table.js +278 -0
  275. package/dist/src/tools/oapi/bitable/app-table.js.map +7 -0
  276. package/dist/src/tools/oapi/bitable/app.js +200 -0
  277. package/dist/src/tools/oapi/bitable/app.js.map +7 -0
  278. package/dist/src/tools/oapi/bitable/index.js +13 -0
  279. package/dist/src/tools/oapi/bitable/index.js.map +7 -0
  280. package/dist/src/tools/oapi/calendar/calendar.js +131 -0
  281. package/dist/src/tools/oapi/calendar/calendar.js.map +7 -0
  282. package/dist/src/tools/oapi/calendar/event-attendee.js +301 -0
  283. package/dist/src/tools/oapi/calendar/event-attendee.js.map +7 -0
  284. package/dist/src/tools/oapi/calendar/event.js +834 -0
  285. package/dist/src/tools/oapi/calendar/event.js.map +7 -0
  286. package/dist/src/tools/oapi/calendar/freebusy.js +111 -0
  287. package/dist/src/tools/oapi/calendar/freebusy.js.map +7 -0
  288. package/dist/src/tools/oapi/calendar/index.js +11 -0
  289. package/dist/src/tools/oapi/calendar/index.js.map +7 -0
  290. package/dist/src/tools/oapi/chat/chat.js +132 -0
  291. package/dist/src/tools/oapi/chat/chat.js.map +7 -0
  292. package/dist/src/tools/oapi/chat/index.js +11 -0
  293. package/dist/src/tools/oapi/chat/index.js.map +7 -0
  294. package/dist/src/tools/oapi/chat/members.js +83 -0
  295. package/dist/src/tools/oapi/chat/members.js.map +7 -0
  296. package/dist/src/tools/oapi/common/get-user.js +95 -0
  297. package/dist/src/tools/oapi/common/get-user.js.map +7 -0
  298. package/dist/src/tools/oapi/common/index.js +7 -0
  299. package/dist/src/tools/oapi/common/index.js.map +7 -0
  300. package/dist/src/tools/oapi/common/search-user.js +67 -0
  301. package/dist/src/tools/oapi/common/search-user.js.map +7 -0
  302. package/dist/src/tools/oapi/drive/doc-comments.js +310 -0
  303. package/dist/src/tools/oapi/drive/doc-comments.js.map +7 -0
  304. package/dist/src/tools/oapi/drive/doc-media.js +314 -0
  305. package/dist/src/tools/oapi/drive/doc-media.js.map +7 -0
  306. package/dist/src/tools/oapi/drive/file.js +548 -0
  307. package/dist/src/tools/oapi/drive/file.js.map +7 -0
  308. package/dist/src/tools/oapi/drive/index.js +29 -0
  309. package/dist/src/tools/oapi/drive/index.js.map +7 -0
  310. package/dist/src/tools/oapi/helpers.js +199 -0
  311. package/dist/src/tools/oapi/helpers.js.map +7 -0
  312. package/dist/src/tools/oapi/im/format-messages.js +128 -0
  313. package/dist/src/tools/oapi/im/format-messages.js.map +7 -0
  314. package/dist/src/tools/oapi/im/index.js +15 -0
  315. package/dist/src/tools/oapi/im/index.js.map +7 -0
  316. package/dist/src/tools/oapi/im/message-read.js +404 -0
  317. package/dist/src/tools/oapi/im/message-read.js.map +7 -0
  318. package/dist/src/tools/oapi/im/message.js +179 -0
  319. package/dist/src/tools/oapi/im/message.js.map +7 -0
  320. package/dist/src/tools/oapi/im/resource.js +126 -0
  321. package/dist/src/tools/oapi/im/resource.js.map +7 -0
  322. package/dist/src/tools/oapi/im/time-utils.js +169 -0
  323. package/dist/src/tools/oapi/im/time-utils.js.map +7 -0
  324. package/dist/src/tools/oapi/im/user-name-uat.js +103 -0
  325. package/dist/src/tools/oapi/im/user-name-uat.js.map +7 -0
  326. package/dist/src/tools/oapi/index.js +56 -0
  327. package/dist/src/tools/oapi/index.js.map +7 -0
  328. package/dist/src/tools/oapi/sdk-types.js +1 -0
  329. package/dist/src/tools/oapi/sdk-types.js.map +7 -0
  330. package/dist/src/tools/oapi/search/doc-search.js +215 -0
  331. package/dist/src/tools/oapi/search/doc-search.js.map +7 -0
  332. package/dist/src/tools/oapi/search/index.js +25 -0
  333. package/dist/src/tools/oapi/search/index.js.map +7 -0
  334. package/dist/src/tools/oapi/sheets/index.js +25 -0
  335. package/dist/src/tools/oapi/sheets/index.js.map +7 -0
  336. package/dist/src/tools/oapi/sheets/sheet.js +652 -0
  337. package/dist/src/tools/oapi/sheets/sheet.js.map +7 -0
  338. package/dist/src/tools/oapi/task/comment.js +151 -0
  339. package/dist/src/tools/oapi/task/comment.js.map +7 -0
  340. package/dist/src/tools/oapi/task/index.js +11 -0
  341. package/dist/src/tools/oapi/task/index.js.map +7 -0
  342. package/dist/src/tools/oapi/task/subtask.js +175 -0
  343. package/dist/src/tools/oapi/task/subtask.js.map +7 -0
  344. package/dist/src/tools/oapi/task/task.js +405 -0
  345. package/dist/src/tools/oapi/task/task.js.map +7 -0
  346. package/dist/src/tools/oapi/task/tasklist.js +366 -0
  347. package/dist/src/tools/oapi/task/tasklist.js.map +7 -0
  348. package/dist/src/tools/oapi/wiki/index.js +27 -0
  349. package/dist/src/tools/oapi/wiki/index.js.map +7 -0
  350. package/dist/src/tools/oapi/wiki/space-node.js +311 -0
  351. package/dist/src/tools/oapi/wiki/space-node.js.map +7 -0
  352. package/dist/src/tools/oapi/wiki/space.js +148 -0
  353. package/dist/src/tools/oapi/wiki/space.js.map +7 -0
  354. package/dist/src/tools/oauth-batch-auth.js +125 -0
  355. package/dist/src/tools/oauth-batch-auth.js.map +7 -0
  356. package/dist/src/tools/oauth-cards.js +269 -0
  357. package/dist/src/tools/oauth-cards.js.map +7 -0
  358. package/dist/src/tools/oauth.js +538 -0
  359. package/dist/src/tools/oauth.js.map +7 -0
  360. package/dist/src/tools/onboarding-auth.js +101 -0
  361. package/dist/src/tools/onboarding-auth.js.map +7 -0
  362. package/dist/src/tools/project-oauth.js +305 -0
  363. package/dist/src/tools/project-oauth.js.map +7 -0
  364. package/dist/src/tools/tat/im/index.js +9 -0
  365. package/dist/src/tools/tat/im/index.js.map +7 -0
  366. package/dist/src/tools/tat/im/resource.js +123 -0
  367. package/dist/src/tools/tat/im/resource.js.map +7 -0
  368. package/package.json +64 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/outbound.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n\n/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Outbound message adapter for the Lark/Feishu channel plugin.\n *\n * Exposes a `ChannelOutboundAdapter` that the OpenClaw core uses to deliver\n * agent-generated replies back to Feishu chats. The adapter translates SDK\n * parameters and delegates to standalone sending functions.\n */\n\nimport type { ChannelOutboundAdapter, ClawdbotConfig } from 'openclaw/plugin-sdk';\nimport type { FeishuSendResult } from '../types';\nimport { LarkClient } from '../../core/lark-client';\nimport { sendTextLark, sendMediaLark, sendCardLark } from './deliver';\nimport { larkLogger } from '../../core/lark-logger';\n\nconst log = larkLogger('outbound/outbound');\n\n// ---------------------------------------------------------------------------\n// channelData.feishu contract\n// ---------------------------------------------------------------------------\n\n/**\n * Channel-specific payload for Feishu, carried in `ReplyPayload.channelData.feishu`.\n *\n * Callers (skills, tools, programmatic code) populate this structure to send\n * Feishu-native content that the standard text/media path cannot express.\n *\n * Both card v1 (Message Card) and v2 (CardKit) formats are supported.\n * The Feishu server distinguishes the version by the presence of `schema: \"2.0\"`.\n *\n * @example\n * ```ts\n * // --- v1 Message Card (default) ---\n * const v1Reply: ReplyPayload = {\n * channelData: {\n * feishu: {\n * card: {\n * config: { wide_screen_mode: true },\n * header: {\n * title: { tag: \"plain_text\", content: \"Task Created\" },\n * template: \"green\",\n * },\n * elements: [\n * { tag: \"div\", text: { tag: \"lark_md\", content: \"**Title:** Fix login bug\" } },\n * { tag: \"action\", actions: [\n * { tag: \"button\", text: { tag: \"plain_text\", content: \"View\" }, type: \"primary\", url: \"https://...\" },\n * ]},\n * ],\n * },\n * },\n * },\n * };\n *\n * // --- v2 CardKit ---\n * const v2Reply: ReplyPayload = {\n * channelData: {\n * feishu: {\n * card: {\n * schema: \"2.0\",\n * config: { wide_screen_mode: true },\n * header: {\n * title: { tag: \"plain_text\", content: \"Task Created\" },\n * template: \"green\",\n * },\n * body: {\n * elements: [\n * { tag: \"markdown\", content: \"**Title:** Fix login bug\" },\n * ],\n * },\n * },\n * },\n * },\n * };\n * ```\n */\nexport interface FeishuChannelData {\n /**\n * A complete Feishu interactive card JSON object (v1 or v2).\n *\n * The card is sent as-is via `msg_type: \"interactive\"`. The Feishu server\n * uses the presence of `schema: \"2.0\"` to determine the card version.\n *\n * **v1 (Message Card)** \u2014 default when no `schema` field is present.\n * Top-level fields: `config`, `header`, `elements`.\n * Element tags: `div`, `action`, `button`, `button_group`, `note`,\n * `img`, `hr`, `column_set`, `markdown` (limited), `lark_md` (in div.text).\n *\n * **v2 (CardKit)** \u2014 activated by `schema: \"2.0\"`.\n * Top-level fields: `schema`, `config`, `header`, `body.elements`.\n * Element tags: `markdown`, `plain_text`, `hr`, `collapsible_panel`,\n * `column_set`, `table`, `image`, `button`, `select_static`, `overflow`.\n * Not supported in v2: `action`, `button_group`, `note`, `div` + `lark_md`.\n *\n * @see https://open.larkoffice.com/document/feishu-cards/card-json-v2-structure (v2)\n * @see https://open.feishu.cn/document/uAjLw4CM/ukzMukzMukzM/feishu-cards/card-components (v1)\n */\n card?: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Shared context resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Common send context extracted from outbound adapter parameters.\n */\ninterface FeishuSendContext {\n cfg: ClawdbotConfig;\n replyToMessageId?: string;\n replyInThread: boolean;\n accountId?: string;\n}\n\n/**\n * Map adapter-level parameters to internal send context.\n *\n * Mirrors the pattern used by Telegram (`resolveTelegramSendContext`) and\n * Slack (`sendSlackOutboundMessage`) to centralise parameter mapping.\n */\nfunction resolveFeishuSendContext(params: {\n cfg: ClawdbotConfig;\n accountId?: string | null;\n replyToId?: string | null;\n threadId?: string | number | null;\n}): FeishuSendContext {\n return {\n cfg: params.cfg,\n replyToMessageId: params.replyToId ?? undefined,\n replyInThread: Boolean(params.threadId),\n accountId: params.accountId ?? undefined,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport const feishuOutbound: ChannelOutboundAdapter = {\n deliveryMode: 'direct',\n\n chunker: (text, limit) => LarkClient.runtime.channel.text.chunkMarkdownText(text, limit),\n\n chunkerMode: 'markdown',\n\n textChunkLimit: 15000,\n\n sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {\n log.info(`sendText: target=${to}, textLength=${text.length}`);\n const ctx = resolveFeishuSendContext({ cfg, accountId, replyToId, threadId });\n const result = await sendTextLark({ ...ctx, to, text });\n return { channel: 'feishu', ...result };\n },\n\n sendMedia: async ({ cfg, to, text, mediaUrl, mediaLocalRoots, accountId, replyToId, threadId }) => {\n log.info(`sendMedia: target=${to}, ` + `hasText=${Boolean(text?.trim())}, mediaUrl=${mediaUrl ?? '(none)'}`);\n const ctx = resolveFeishuSendContext({ cfg, accountId, replyToId, threadId });\n\n // Feishu media messages do not support inline captions \u2014 send text first.\n if (text?.trim()) {\n await sendTextLark({ ...ctx, to, text });\n }\n\n // No mediaUrl \u2014 text-only fallback.\n if (!mediaUrl) {\n log.info('sendMedia: no mediaUrl provided, falling back to text-only');\n const result = await sendTextLark({ ...ctx, to, text: text ?? '' });\n return { channel: 'feishu', ...result };\n }\n\n const result = await sendMediaLark({ ...ctx, to, mediaUrl, mediaLocalRoots });\n return {\n channel: 'feishu',\n messageId: result.messageId,\n chatId: result.chatId,\n ...(result.warning ? { meta: { warnings: [result.warning] } } : {}),\n };\n },\n\n sendPayload: async ({ cfg, to, payload, mediaLocalRoots, accountId, replyToId, threadId }) => {\n const ctx = resolveFeishuSendContext({ cfg, accountId, replyToId, threadId });\n\n // --- channelData.feishu: card message support ---\n const feishuData = payload.channelData?.feishu as FeishuChannelData | undefined;\n\n // --- Resolve text + media from payload ---\n const text = payload.text ?? '';\n const mediaUrls = payload.mediaUrls?.length ? payload.mediaUrls : payload.mediaUrl ? [payload.mediaUrl] : [];\n\n log.info(\n `sendPayload: target=${to}, ` +\n `textLength=${text.length}, mediaCount=${mediaUrls.length}, ` +\n `hasCard=${Boolean(feishuData?.card)}`,\n );\n\n // --- channelData.feishu.card: card message path ---\n // Feishu card messages are standalone (msg_type=\"interactive\"), so\n // text and media must be sent as separate messages around the card.\n if (feishuData?.card) {\n if (text.trim()) {\n await sendTextLark({ ...ctx, to, text });\n }\n\n const cardResult = await sendCardLark({ ...ctx, to, card: feishuData.card });\n\n const warnings: string[] = [];\n for (const mediaUrl of mediaUrls) {\n const mediaResult = await sendMediaLark({ ...ctx, to, mediaUrl, mediaLocalRoots });\n if (mediaResult.warning) {\n warnings.push(mediaResult.warning);\n }\n }\n\n return {\n channel: 'feishu',\n messageId: cardResult.messageId,\n chatId: cardResult.chatId,\n ...(warnings.length > 0 ? { meta: { warnings } } : {}),\n };\n }\n\n // --- Standard text + media orchestration (no card) ---\n\n // No media: text-only\n if (mediaUrls.length === 0) {\n const result = await sendTextLark({ ...ctx, to, text });\n return { channel: 'feishu', ...result };\n }\n\n // Has media: send leading text, then loop media URLs\n if (text.trim()) {\n await sendTextLark({ ...ctx, to, text });\n }\n\n const warnings: string[] = [];\n let lastResult: FeishuSendResult | undefined;\n for (const mediaUrl of mediaUrls) {\n lastResult = await sendMediaLark({ ...ctx, to, mediaUrl, mediaLocalRoots });\n if (lastResult.warning) {\n warnings.push(lastResult.warning);\n }\n }\n\n return {\n channel: 'feishu',\n ...(lastResult ?? { messageId: '', chatId: '' }),\n ...(warnings.length > 0 ? { meta: { warnings } } : {}),\n };\n },\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["result", "warnings"]
7
+ }
@@ -0,0 +1,312 @@
1
+ import { LarkClient } from "../../core/lark-client";
2
+ const FeishuEmoji = {
3
+ THUMBSUP: "THUMBSUP",
4
+ THUMBSDOWN: "THUMBSDOWN",
5
+ HEART: "HEART",
6
+ SMILE: "SMILE",
7
+ JOYFUL: "JOYFUL",
8
+ FROWN: "FROWN",
9
+ BLUSH: "BLUSH",
10
+ OK: "OK",
11
+ CLAP: "CLAP",
12
+ FIREWORKS: "FIREWORKS",
13
+ PARTY: "PARTY",
14
+ MUSCLE: "MUSCLE",
15
+ FIRE: "FIRE",
16
+ EYES: "EYES",
17
+ THINKING: "THINKING",
18
+ PRAISE: "PRAISE",
19
+ PRAY: "PRAY",
20
+ ROCKET: "ROCKET",
21
+ DONE: "DONE",
22
+ SKULL: "SKULL",
23
+ HUNDREDPOINTS: "HUNDREDPOINTS",
24
+ FACEPALM: "FACEPALM",
25
+ CHECK: "CHECK",
26
+ CROSSMARK: "CrossMark",
27
+ COOL: "COOL",
28
+ TYPING: "Typing",
29
+ SPEECHLESS: "SPEECHLESS"
30
+ };
31
+ const VALID_FEISHU_EMOJI_TYPES = /* @__PURE__ */ new Set([
32
+ // Gestures / actions
33
+ "OK",
34
+ "THUMBSUP",
35
+ "THANKS",
36
+ "MUSCLE",
37
+ "FINGERHEART",
38
+ "APPLAUSE",
39
+ "FISTBUMP",
40
+ "JIAYI",
41
+ "DONE",
42
+ // Faces / expressions
43
+ "SMILE",
44
+ "BLUSH",
45
+ "LAUGH",
46
+ "SMIRK",
47
+ "LOL",
48
+ "FACEPALM",
49
+ "LOVE",
50
+ "WINK",
51
+ "PROUD",
52
+ "WITTY",
53
+ "SMART",
54
+ "SCOWL",
55
+ "THINKING",
56
+ "SOB",
57
+ "CRY",
58
+ "ERROR",
59
+ "NOSEPICK",
60
+ "HAUGHTY",
61
+ "SLAP",
62
+ "SPITBLOOD",
63
+ "TOASTED",
64
+ "GLANCE",
65
+ "DULL",
66
+ "INNOCENTSMILE",
67
+ "JOYFUL",
68
+ "WOW",
69
+ "TRICK",
70
+ "YEAH",
71
+ "ENOUGH",
72
+ "TEARS",
73
+ "EMBARRASSED",
74
+ "KISS",
75
+ "SMOOCH",
76
+ "DROOL",
77
+ "OBSESSED",
78
+ "MONEY",
79
+ "TEASE",
80
+ "SHOWOFF",
81
+ "COMFORT",
82
+ "CLAP",
83
+ "PRAISE",
84
+ "STRIVE",
85
+ "XBLUSH",
86
+ "SILENT",
87
+ "WAVE",
88
+ "WHAT",
89
+ "FROWN",
90
+ "SHY",
91
+ "DIZZY",
92
+ "LOOKDOWN",
93
+ "CHUCKLE",
94
+ "WAIL",
95
+ "CRAZY",
96
+ "WHIMPER",
97
+ "HUG",
98
+ "BLUBBER",
99
+ "WRONGED",
100
+ "HUSKY",
101
+ "SHHH",
102
+ "SMUG",
103
+ "ANGRY",
104
+ "HAMMER",
105
+ "SHOCKED",
106
+ "TERROR",
107
+ "PETRIFIED",
108
+ "SKULL",
109
+ "SWEAT",
110
+ "SPEECHLESS",
111
+ "SLEEP",
112
+ "DROWSY",
113
+ "YAWN",
114
+ "SICK",
115
+ "PUKE",
116
+ "BETRAYED",
117
+ "HEADSET",
118
+ "EatingFood",
119
+ "MeMeMe",
120
+ "Sigh",
121
+ "Typing",
122
+ "SLIGHT",
123
+ "TONGUE",
124
+ "EYESCLOSED",
125
+ "RoarForYou",
126
+ "CALF",
127
+ "BEAR",
128
+ "BULL",
129
+ "RAINBOWPUKE",
130
+ // Objects / food / drinks
131
+ "Lemon",
132
+ "ROSE",
133
+ "HEART",
134
+ "PARTY",
135
+ "LIPS",
136
+ "BEER",
137
+ "CAKE",
138
+ "GIFT",
139
+ "CUCUMBER",
140
+ "Drumstick",
141
+ "Pepper",
142
+ "CANDIEDHAWS",
143
+ "BubbleTea",
144
+ "Coffee",
145
+ // Symbols / marks
146
+ "Get",
147
+ "LGTM",
148
+ "OnIt",
149
+ "OneSecond",
150
+ "VRHeadset",
151
+ "YouAreTheBest",
152
+ "SALUTE",
153
+ "SHAKE",
154
+ "HIGHFIVE",
155
+ "UPPERLEFT",
156
+ "ThumbsDown",
157
+ "Yes",
158
+ "No",
159
+ "OKR",
160
+ "CheckMark",
161
+ "CrossMark",
162
+ "MinusOne",
163
+ "Hundred",
164
+ "AWESOMEN",
165
+ "Pin",
166
+ "Alarm",
167
+ "Loudspeaker",
168
+ "Trophy",
169
+ "Fire",
170
+ "BOMB",
171
+ "Music",
172
+ // Holidays / seasons
173
+ "XmasTree",
174
+ "Snowman",
175
+ "XmasHat",
176
+ "FIREWORKS",
177
+ "2022",
178
+ "REDPACKET",
179
+ "FORTUNE",
180
+ "LUCK",
181
+ "FIRECRACKER",
182
+ "StickyRiceBalls",
183
+ // Miscellaneous
184
+ "HEARTBROKEN",
185
+ "POOP",
186
+ "StatusFlashOfInspiration",
187
+ "18X",
188
+ "CLEAVER",
189
+ "Soccer",
190
+ "Basketball",
191
+ // Status
192
+ "GeneralDoNotDisturb",
193
+ "Status_PrivateMessage",
194
+ "GeneralInMeetingBusy",
195
+ "StatusReading",
196
+ "StatusInFlight",
197
+ "GeneralBusinessTrip",
198
+ "GeneralWorkFromHome",
199
+ "StatusEnjoyLife",
200
+ "GeneralTravellingCar",
201
+ "StatusBus",
202
+ "GeneralSun",
203
+ "GeneralMoonRest",
204
+ // Holiday extras
205
+ "MoonRabbit",
206
+ "Mooncake",
207
+ "JubilantRabbit",
208
+ "TV",
209
+ "Movie",
210
+ "Pumpkin",
211
+ // Newer additions
212
+ "BeamingFace",
213
+ "Delighted",
214
+ "ColdSweat",
215
+ "FullMoonFace",
216
+ "Partying",
217
+ "GoGoGo",
218
+ "ThanksFace",
219
+ "SaluteFace",
220
+ "Shrug",
221
+ "ClownFace",
222
+ "HappyDragon"
223
+ ]);
224
+ async function addReactionFeishu(params) {
225
+ const { cfg, messageId, emojiType, accountId } = params;
226
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
227
+ let response;
228
+ try {
229
+ response = await client.im.messageReaction.create({
230
+ path: {
231
+ message_id: messageId
232
+ },
233
+ data: {
234
+ reaction_type: {
235
+ emoji_type: emojiType
236
+ }
237
+ }
238
+ });
239
+ } catch (err) {
240
+ const e = err;
241
+ const errCode = e.code ?? e.response?.data?.code;
242
+ if (errCode === 231001) {
243
+ const validTypes = Array.from(VALID_FEISHU_EMOJI_TYPES).join(", ");
244
+ throw new Error(`Emoji type "${emojiType}" is not a valid Feishu reaction. Valid types: ${validTypes}`);
245
+ }
246
+ throw err;
247
+ }
248
+ const reactionId = response?.data?.reaction_id;
249
+ if (!reactionId) {
250
+ throw new Error(
251
+ `[feishu-reactions] Failed to add reaction "${emojiType}" to message ${messageId}: no reaction_id returned`
252
+ );
253
+ }
254
+ return { reactionId };
255
+ }
256
+ async function removeReactionFeishu(params) {
257
+ const { cfg, messageId, reactionId, accountId } = params;
258
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
259
+ await client.im.messageReaction.delete({
260
+ path: {
261
+ message_id: messageId,
262
+ reaction_id: reactionId
263
+ }
264
+ });
265
+ }
266
+ async function listReactionsFeishu(params) {
267
+ const { cfg, messageId, emojiType, accountId } = params;
268
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
269
+ const reactions = [];
270
+ let pageToken;
271
+ let hasMore = true;
272
+ while (hasMore) {
273
+ const requestParams = {
274
+ page_size: 50
275
+ };
276
+ if (emojiType) {
277
+ requestParams.reaction_type = emojiType;
278
+ }
279
+ if (pageToken) {
280
+ requestParams.page_token = pageToken;
281
+ }
282
+ const response = await client.im.messageReaction.list({
283
+ path: {
284
+ message_id: messageId
285
+ },
286
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
287
+ params: requestParams
288
+ });
289
+ const items = response?.data?.items;
290
+ if (items && items.length > 0) {
291
+ for (const item of items) {
292
+ reactions.push({
293
+ reactionId: item.reaction_id ?? "",
294
+ emojiType: item.reaction_type?.emoji_type ?? "",
295
+ operatorType: item.operator?.operator_type === "app" ? "app" : "user",
296
+ operatorId: item.operator?.operator_id ?? ""
297
+ });
298
+ }
299
+ }
300
+ pageToken = response?.data?.page_token ?? void 0;
301
+ hasMore = response?.data?.has_more === true && !!pageToken;
302
+ }
303
+ return reactions;
304
+ }
305
+ export {
306
+ FeishuEmoji,
307
+ VALID_FEISHU_EMOJI_TYPES,
308
+ addReactionFeishu,
309
+ listReactionsFeishu,
310
+ removeReactionFeishu
311
+ };
312
+ //# sourceMappingURL=reactions.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/reactions.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Reaction management for the Lark/Feishu channel plugin.\n *\n * Provides functions to add, remove, and list emoji reactions on Feishu\n * messages using the IM Message Reaction API.\n */\n\nimport type { OpenClawConfig } from 'openclaw/plugin-sdk';\nimport { LarkClient } from '../../core/lark-client';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Represents a single reaction on a Feishu message.\n */\nexport interface FeishuReaction {\n /** Unique reaction ID assigned by the platform. */\n reactionId: string;\n /** The emoji type string (e.g. \"THUMBSUP\", \"HEART\"). */\n emojiType: string;\n /** Whether the reaction was added by an app or a human user. */\n operatorType: 'app' | 'user';\n /** Open ID of the operator who added the reaction. */\n operatorId: string;\n}\n\n// ---------------------------------------------------------------------------\n// Feishu emoji constants\n// ---------------------------------------------------------------------------\n\n/**\n * Well-known Feishu emoji type strings.\n *\n * This is a convenience map so consumers do not need to memorise the\n * exact string identifiers. It is intentionally non-exhaustive --\n * Feishu supports many more emoji types. Any valid emoji type string\n * can be passed directly to the API functions.\n */\nexport const FeishuEmoji = {\n THUMBSUP: 'THUMBSUP',\n THUMBSDOWN: 'THUMBSDOWN',\n HEART: 'HEART',\n SMILE: 'SMILE',\n JOYFUL: 'JOYFUL',\n FROWN: 'FROWN',\n BLUSH: 'BLUSH',\n OK: 'OK',\n CLAP: 'CLAP',\n FIREWORKS: 'FIREWORKS',\n PARTY: 'PARTY',\n MUSCLE: 'MUSCLE',\n FIRE: 'FIRE',\n EYES: 'EYES',\n THINKING: 'THINKING',\n PRAISE: 'PRAISE',\n PRAY: 'PRAY',\n ROCKET: 'ROCKET',\n DONE: 'DONE',\n SKULL: 'SKULL',\n HUNDREDPOINTS: 'HUNDREDPOINTS',\n FACEPALM: 'FACEPALM',\n CHECK: 'CHECK',\n CROSSMARK: 'CrossMark',\n COOL: 'COOL',\n TYPING: 'Typing',\n SPEECHLESS: 'SPEECHLESS',\n} as const;\n\n// ---------------------------------------------------------------------------\n// Valid Feishu emoji types (complete set)\n// ---------------------------------------------------------------------------\n\n/**\n * Complete set of valid Feishu emoji type strings for reactions.\n *\n * Sourced from the official Feishu emoji documentation.\n * Unlike `FeishuEmoji` (a convenience subset), this set is exhaustive\n * and can be used for validation and error reporting.\n *\n * @see https://go.feishu.cn/s/670vFWbA804\n */\nexport const VALID_FEISHU_EMOJI_TYPES: ReadonlySet<string> = new Set([\n // Gestures / actions\n 'OK',\n 'THUMBSUP',\n 'THANKS',\n 'MUSCLE',\n 'FINGERHEART',\n 'APPLAUSE',\n 'FISTBUMP',\n 'JIAYI',\n 'DONE',\n // Faces / expressions\n 'SMILE',\n 'BLUSH',\n 'LAUGH',\n 'SMIRK',\n 'LOL',\n 'FACEPALM',\n 'LOVE',\n 'WINK',\n 'PROUD',\n 'WITTY',\n 'SMART',\n 'SCOWL',\n 'THINKING',\n 'SOB',\n 'CRY',\n 'ERROR',\n 'NOSEPICK',\n 'HAUGHTY',\n 'SLAP',\n 'SPITBLOOD',\n 'TOASTED',\n 'GLANCE',\n 'DULL',\n 'INNOCENTSMILE',\n 'JOYFUL',\n 'WOW',\n 'TRICK',\n 'YEAH',\n 'ENOUGH',\n 'TEARS',\n 'EMBARRASSED',\n 'KISS',\n 'SMOOCH',\n 'DROOL',\n 'OBSESSED',\n 'MONEY',\n 'TEASE',\n 'SHOWOFF',\n 'COMFORT',\n 'CLAP',\n 'PRAISE',\n 'STRIVE',\n 'XBLUSH',\n 'SILENT',\n 'WAVE',\n 'WHAT',\n 'FROWN',\n 'SHY',\n 'DIZZY',\n 'LOOKDOWN',\n 'CHUCKLE',\n 'WAIL',\n 'CRAZY',\n 'WHIMPER',\n 'HUG',\n 'BLUBBER',\n 'WRONGED',\n 'HUSKY',\n 'SHHH',\n 'SMUG',\n 'ANGRY',\n 'HAMMER',\n 'SHOCKED',\n 'TERROR',\n 'PETRIFIED',\n 'SKULL',\n 'SWEAT',\n 'SPEECHLESS',\n 'SLEEP',\n 'DROWSY',\n 'YAWN',\n 'SICK',\n 'PUKE',\n 'BETRAYED',\n 'HEADSET',\n 'EatingFood',\n 'MeMeMe',\n 'Sigh',\n 'Typing',\n 'SLIGHT',\n 'TONGUE',\n 'EYESCLOSED',\n 'RoarForYou',\n 'CALF',\n 'BEAR',\n 'BULL',\n 'RAINBOWPUKE',\n // Objects / food / drinks\n 'Lemon',\n 'ROSE',\n 'HEART',\n 'PARTY',\n 'LIPS',\n 'BEER',\n 'CAKE',\n 'GIFT',\n 'CUCUMBER',\n 'Drumstick',\n 'Pepper',\n 'CANDIEDHAWS',\n 'BubbleTea',\n 'Coffee',\n // Symbols / marks\n 'Get',\n 'LGTM',\n 'OnIt',\n 'OneSecond',\n 'VRHeadset',\n 'YouAreTheBest',\n 'SALUTE',\n 'SHAKE',\n 'HIGHFIVE',\n 'UPPERLEFT',\n 'ThumbsDown',\n 'Yes',\n 'No',\n 'OKR',\n 'CheckMark',\n 'CrossMark',\n 'MinusOne',\n 'Hundred',\n 'AWESOMEN',\n 'Pin',\n 'Alarm',\n 'Loudspeaker',\n 'Trophy',\n 'Fire',\n 'BOMB',\n 'Music',\n // Holidays / seasons\n 'XmasTree',\n 'Snowman',\n 'XmasHat',\n 'FIREWORKS',\n '2022',\n 'REDPACKET',\n 'FORTUNE',\n 'LUCK',\n 'FIRECRACKER',\n 'StickyRiceBalls',\n // Miscellaneous\n 'HEARTBROKEN',\n 'POOP',\n 'StatusFlashOfInspiration',\n '18X',\n 'CLEAVER',\n 'Soccer',\n 'Basketball',\n // Status\n 'GeneralDoNotDisturb',\n 'Status_PrivateMessage',\n 'GeneralInMeetingBusy',\n 'StatusReading',\n 'StatusInFlight',\n 'GeneralBusinessTrip',\n 'GeneralWorkFromHome',\n 'StatusEnjoyLife',\n 'GeneralTravellingCar',\n 'StatusBus',\n 'GeneralSun',\n 'GeneralMoonRest',\n // Holiday extras\n 'MoonRabbit',\n 'Mooncake',\n 'JubilantRabbit',\n 'TV',\n 'Movie',\n 'Pumpkin',\n // Newer additions\n 'BeamingFace',\n 'Delighted',\n 'ColdSweat',\n 'FullMoonFace',\n 'Partying',\n 'GoGoGo',\n 'ThanksFace',\n 'SaluteFace',\n 'Shrug',\n 'ClownFace',\n 'HappyDragon',\n]);\n\n// ---------------------------------------------------------------------------\n// addReactionFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Add an emoji reaction to a Feishu message.\n *\n * @param params.cfg - Plugin configuration with Feishu credentials.\n * @param params.messageId - The message to react to.\n * @param params.emojiType - The emoji type string (e.g. \"THUMBSUP\").\n * @param params.accountId - Optional account identifier for multi-account setups.\n * @returns An object containing the platform-assigned reaction ID.\n */\nexport async function addReactionFeishu(params: {\n cfg: OpenClawConfig;\n messageId: string;\n emojiType: string;\n accountId?: string;\n}): Promise<{ reactionId: string }> {\n const { cfg, messageId, emojiType, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n let response;\n try {\n response = await client.im.messageReaction.create({\n path: {\n message_id: messageId,\n },\n data: {\n reaction_type: {\n emoji_type: emojiType,\n },\n },\n });\n } catch (err) {\n const e = err as { code?: number; msg?: string; response?: { data?: { code?: number } } };\n const errCode = e.code ?? e.response?.data?.code;\n if (errCode === 231001) {\n const validTypes = Array.from(VALID_FEISHU_EMOJI_TYPES).join(', ');\n throw new Error(`Emoji type \"${emojiType}\" is not a valid Feishu reaction. Valid types: ${validTypes}`);\n }\n throw err;\n }\n\n const reactionId = response?.data?.reaction_id;\n if (!reactionId) {\n throw new Error(\n `[feishu-reactions] Failed to add reaction \"${emojiType}\" to message ${messageId}: no reaction_id returned`,\n );\n }\n\n return { reactionId };\n}\n\n// ---------------------------------------------------------------------------\n// removeReactionFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Remove a specific reaction from a Feishu message by its reaction ID.\n *\n * Unlike the outbound module's `removeReaction` (which looks up the\n * reaction by emoji type), this function takes the exact reaction ID\n * for direct deletion.\n *\n * @param params.cfg - Plugin configuration with Feishu credentials.\n * @param params.messageId - The message the reaction belongs to.\n * @param params.reactionId - The platform-assigned reaction ID to delete.\n * @param params.accountId - Optional account identifier for multi-account setups.\n */\nexport async function removeReactionFeishu(params: {\n cfg: OpenClawConfig;\n messageId: string;\n reactionId: string;\n accountId?: string;\n}): Promise<void> {\n const { cfg, messageId, reactionId, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n await client.im.messageReaction.delete({\n path: {\n message_id: messageId,\n reaction_id: reactionId,\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// listReactionsFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * List reactions on a Feishu message, optionally filtered by emoji type.\n *\n * Paginates through all results and returns a flat array of\n * {@link FeishuReaction} objects.\n *\n * @param params.cfg - Plugin configuration with Feishu credentials.\n * @param params.messageId - The message whose reactions to list.\n * @param params.emojiType - Optional emoji type filter (e.g. \"THUMBSUP\").\n * When omitted, all reaction types are returned.\n * @param params.accountId - Optional account identifier for multi-account setups.\n * @returns An array of reactions matching the criteria.\n */\nexport async function listReactionsFeishu(params: {\n cfg: OpenClawConfig;\n messageId: string;\n emojiType?: string;\n accountId?: string;\n}): Promise<FeishuReaction[]> {\n const { cfg, messageId, emojiType, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n const reactions: FeishuReaction[] = [];\n let pageToken: string | undefined;\n let hasMore = true;\n\n while (hasMore) {\n const requestParams: Record<string, unknown> = {\n page_size: 50,\n };\n\n if (emojiType) {\n requestParams.reaction_type = emojiType;\n }\n\n if (pageToken) {\n requestParams.page_token = pageToken;\n }\n\n const response = await client.im.messageReaction.list({\n path: {\n message_id: messageId,\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: requestParams as any,\n });\n\n const items = response?.data?.items;\n if (items && items.length > 0) {\n for (const item of items) {\n reactions.push({\n reactionId: item.reaction_id ?? '',\n emojiType: item.reaction_type?.emoji_type ?? '',\n operatorType: item.operator?.operator_type === 'app' ? 'app' : 'user',\n operatorId: item.operator?.operator_id ?? '',\n });\n }\n }\n\n pageToken = response?.data?.page_token ?? undefined;\n hasMore = response?.data?.has_more === true && !!pageToken;\n }\n\n return reactions;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,194 @@
1
+ import { LarkClient } from "../../core/lark-client";
2
+ import { normalizeFeishuTarget, normalizeMessageId, resolveReceiveIdType } from "../../core/targets";
3
+ import { runWithMessageUnavailableGuard } from "../../core/message-unavailable";
4
+ import { optimizeMarkdownStyle } from "../../card/markdown-style";
5
+ import { buildMentionedMessage, buildMentionedCardContent } from "../inbound/mention";
6
+ async function sendMessageFeishu(params) {
7
+ const { cfg, to, text, replyToMessageId, mentions, accountId, replyInThread } = params;
8
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
9
+ let messageText = text;
10
+ if (mentions && mentions.length > 0) {
11
+ messageText = buildMentionedMessage(mentions, messageText);
12
+ }
13
+ try {
14
+ const runtime = LarkClient.runtime;
15
+ if (runtime?.channel?.text?.convertMarkdownTables) {
16
+ messageText = runtime.channel.text.convertMarkdownTables(messageText, "bullets");
17
+ }
18
+ } catch {
19
+ }
20
+ messageText = optimizeMarkdownStyle(messageText, 1);
21
+ const contentPayload = JSON.stringify({
22
+ zh_cn: {
23
+ content: [[{ tag: "md", text: messageText }]]
24
+ }
25
+ });
26
+ if (replyToMessageId) {
27
+ const normalizedId = normalizeMessageId(replyToMessageId);
28
+ const response2 = await runWithMessageUnavailableGuard({
29
+ messageId: normalizedId,
30
+ operation: "im.message.reply(post)",
31
+ fn: () => client.im.message.reply({
32
+ path: {
33
+ message_id: normalizedId
34
+ },
35
+ data: {
36
+ content: contentPayload,
37
+ msg_type: "post",
38
+ reply_in_thread: replyInThread
39
+ }
40
+ })
41
+ });
42
+ return {
43
+ messageId: response2?.data?.message_id ?? "",
44
+ chatId: response2?.data?.chat_id ?? ""
45
+ };
46
+ }
47
+ const target = normalizeFeishuTarget(to);
48
+ if (!target) {
49
+ throw new Error(`[feishu-send] Invalid target: "${to}"`);
50
+ }
51
+ const receiveIdType = resolveReceiveIdType(target);
52
+ const response = await client.im.message.create({
53
+ params: {
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ receive_id_type: receiveIdType
56
+ },
57
+ data: {
58
+ receive_id: target,
59
+ msg_type: "post",
60
+ content: contentPayload
61
+ }
62
+ });
63
+ return {
64
+ messageId: response?.data?.message_id ?? "",
65
+ chatId: response?.data?.chat_id ?? ""
66
+ };
67
+ }
68
+ async function sendCardFeishu(params) {
69
+ const { cfg, to, card, replyToMessageId, accountId, replyInThread } = params;
70
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
71
+ const contentPayload = JSON.stringify(card);
72
+ if (replyToMessageId) {
73
+ const normalizedId = normalizeMessageId(replyToMessageId);
74
+ const response2 = await runWithMessageUnavailableGuard({
75
+ messageId: normalizedId,
76
+ operation: "im.message.reply(interactive)",
77
+ fn: () => client.im.message.reply({
78
+ path: {
79
+ message_id: normalizedId
80
+ },
81
+ data: {
82
+ content: contentPayload,
83
+ msg_type: "interactive",
84
+ reply_in_thread: replyInThread
85
+ }
86
+ })
87
+ });
88
+ return {
89
+ messageId: response2?.data?.message_id ?? "",
90
+ chatId: response2?.data?.chat_id ?? ""
91
+ };
92
+ }
93
+ const target = normalizeFeishuTarget(to);
94
+ if (!target) {
95
+ throw new Error(`[feishu-send] Invalid target: "${to}"`);
96
+ }
97
+ const receiveIdType = resolveReceiveIdType(target);
98
+ const response = await client.im.message.create({
99
+ params: {
100
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
101
+ receive_id_type: receiveIdType
102
+ },
103
+ data: {
104
+ receive_id: target,
105
+ msg_type: "interactive",
106
+ content: contentPayload
107
+ }
108
+ });
109
+ return {
110
+ messageId: response?.data?.message_id ?? "",
111
+ chatId: response?.data?.chat_id ?? ""
112
+ };
113
+ }
114
+ async function updateCardFeishu(params) {
115
+ const { cfg, messageId, card, accountId } = params;
116
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
117
+ await runWithMessageUnavailableGuard({
118
+ messageId,
119
+ operation: "im.message.patch(interactive)",
120
+ fn: () => client.im.message.patch({
121
+ path: {
122
+ message_id: messageId
123
+ },
124
+ data: {
125
+ content: JSON.stringify(card)
126
+ }
127
+ })
128
+ });
129
+ }
130
+ function buildMarkdownCard(text) {
131
+ const optimizedText = optimizeMarkdownStyle(text);
132
+ return {
133
+ schema: "2.0",
134
+ config: {
135
+ wide_screen_mode: true
136
+ },
137
+ body: {
138
+ elements: [
139
+ {
140
+ tag: "markdown",
141
+ content: optimizedText
142
+ }
143
+ ]
144
+ }
145
+ };
146
+ }
147
+ async function sendMarkdownCardFeishu(params) {
148
+ const { cfg, to, text, replyToMessageId, mentions, accountId, replyInThread } = params;
149
+ let cardText = text;
150
+ if (mentions && mentions.length > 0) {
151
+ cardText = buildMentionedCardContent(mentions, cardText);
152
+ }
153
+ const card = buildMarkdownCard(cardText);
154
+ return sendCardFeishu({
155
+ cfg,
156
+ to,
157
+ card,
158
+ replyToMessageId,
159
+ replyInThread,
160
+ accountId
161
+ });
162
+ }
163
+ async function editMessageFeishu(params) {
164
+ const { cfg, messageId, text, accountId } = params;
165
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
166
+ const optimizedText = optimizeMarkdownStyle(text);
167
+ const contentPayload = JSON.stringify({
168
+ zh_cn: {
169
+ content: [[{ tag: "md", text: optimizedText }]]
170
+ }
171
+ });
172
+ await runWithMessageUnavailableGuard({
173
+ messageId,
174
+ operation: "im.message.update(post)",
175
+ fn: () => client.im.message.update({
176
+ path: {
177
+ message_id: messageId
178
+ },
179
+ data: {
180
+ content: contentPayload,
181
+ msg_type: "post"
182
+ }
183
+ })
184
+ });
185
+ }
186
+ export {
187
+ buildMarkdownCard,
188
+ editMessageFeishu,
189
+ sendCardFeishu,
190
+ sendMarkdownCardFeishu,
191
+ sendMessageFeishu,
192
+ updateCardFeishu
193
+ };
194
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/send.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Message sending for the Lark/Feishu channel plugin.\n */\n\nimport type { ClawdbotConfig } from 'openclaw/plugin-sdk';\nimport type { FeishuSendResult } from '../types';\nimport { LarkClient } from '../../core/lark-client';\nimport { normalizeFeishuTarget, normalizeMessageId, resolveReceiveIdType } from '../../core/targets';\nimport { runWithMessageUnavailableGuard } from '../../core/message-unavailable';\nimport type { MentionInfo } from '../types';\nimport { optimizeMarkdownStyle } from '../../card/markdown-style';\nimport { buildMentionedMessage, buildMentionedCardContent } from '../inbound/mention';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for sending a text / post message.\n */\nexport interface SendFeishuMessageParams {\n cfg: ClawdbotConfig;\n /** Target identifier (chat_id, open_id, or user_id). */\n to: string;\n /** Message text content (supports Feishu markdown subset). */\n text: string;\n /** When set, the message is sent as a threaded reply. */\n replyToMessageId?: string;\n /** Optional mention targets to prepend to the message. */\n mentions?: MentionInfo[];\n /** Optional account identifier for multi-account setups. */\n accountId?: string;\n /** When true, the reply appears in the thread instead of main chat. */\n replyInThread?: boolean;\n}\n\n/**\n * Parameters for sending an interactive card message.\n */\nexport interface SendFeishuCardParams {\n cfg: ClawdbotConfig;\n /** Target identifier (chat_id, open_id, or user_id). */\n to: string;\n /** The full interactive card JSON payload. */\n card: Record<string, unknown>;\n /** When set, the card is sent as a threaded reply. */\n replyToMessageId?: string;\n /** Optional account identifier for multi-account setups. */\n accountId?: string;\n /** When true, the reply appears in the thread instead of main chat. */\n replyInThread?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// sendMessageFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Send a text message (rendered as a Feishu \"post\" with markdown support)\n * to a chat or user.\n *\n * The message text is wrapped in Feishu's post format using the `md` tag\n * for rich rendering. If `replyToMessageId` is provided, the message is\n * sent as a threaded reply; otherwise it is sent as a new message using\n * the appropriate `receive_id_type`.\n *\n * Markdown tables in the text are automatically converted to the format\n * supported by Feishu via the runtime's table converter when available.\n *\n * @param params - See {@link SendFeishuMessageParams}.\n * @returns The send result containing the new message ID.\n */\nexport async function sendMessageFeishu(params: SendFeishuMessageParams): Promise<FeishuSendResult> {\n const { cfg, to, text, replyToMessageId, mentions, accountId, replyInThread } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n // Apply mention prefix if targets are provided.\n let messageText = text;\n if (mentions && mentions.length > 0) {\n messageText = buildMentionedMessage(mentions, messageText);\n }\n\n // Convert markdown tables to Feishu-compatible format if the runtime\n // provides a converter.\n try {\n const runtime = LarkClient.runtime;\n if (runtime?.channel?.text?.convertMarkdownTables) {\n messageText = runtime.channel.text.convertMarkdownTables(messageText, 'bullets');\n }\n } catch {\n // Runtime not available -- use the text as-is.\n }\n\n // Apply Markdown style optimization.\n messageText = optimizeMarkdownStyle(messageText, 1);\n\n // Build the post-format content envelope.\n const contentPayload = JSON.stringify({\n zh_cn: {\n content: [[{ tag: 'md', text: messageText }]],\n },\n });\n\n if (replyToMessageId) {\n // Send as a threaded reply.\n // \u89C4\u8303\u5316 message_id\uFF0C\u5904\u7406\u5408\u6210 ID\uFF08\u5982 \"om_xxx:auth-complete\"\uFF09\n const normalizedId = normalizeMessageId(replyToMessageId);\n const response = await runWithMessageUnavailableGuard({\n messageId: normalizedId,\n operation: 'im.message.reply(post)',\n fn: () =>\n client.im.message.reply({\n path: {\n message_id: normalizedId!,\n },\n data: {\n content: contentPayload,\n msg_type: 'post',\n reply_in_thread: replyInThread,\n },\n }),\n });\n\n return {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n }\n\n // Send as a new message.\n const target = normalizeFeishuTarget(to);\n if (!target) {\n throw new Error(`[feishu-send] Invalid target: \"${to}\"`);\n }\n\n const receiveIdType = resolveReceiveIdType(target);\n\n const response = await client.im.message.create({\n params: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n receive_id_type: receiveIdType as any,\n },\n data: {\n receive_id: target,\n msg_type: 'post',\n content: contentPayload,\n },\n });\n\n return {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n}\n\n// ---------------------------------------------------------------------------\n// sendCardFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Send an interactive card message to a chat or user.\n *\n * @param params - See {@link SendFeishuCardParams}.\n * @returns The send result containing the new message ID.\n */\nexport async function sendCardFeishu(params: SendFeishuCardParams): Promise<FeishuSendResult> {\n const { cfg, to, card, replyToMessageId, accountId, replyInThread } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n const contentPayload = JSON.stringify(card);\n\n if (replyToMessageId) {\n // \u89C4\u8303\u5316 message_id\uFF0C\u5904\u7406\u5408\u6210 ID\uFF08\u5982 \"om_xxx:auth-complete\"\uFF09\n const normalizedId = normalizeMessageId(replyToMessageId);\n const response = await runWithMessageUnavailableGuard({\n messageId: normalizedId,\n operation: 'im.message.reply(interactive)',\n fn: () =>\n client.im.message.reply({\n path: {\n message_id: normalizedId!,\n },\n data: {\n content: contentPayload,\n msg_type: 'interactive',\n reply_in_thread: replyInThread,\n },\n }),\n });\n\n return {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n }\n\n const target = normalizeFeishuTarget(to);\n if (!target) {\n throw new Error(`[feishu-send] Invalid target: \"${to}\"`);\n }\n\n const receiveIdType = resolveReceiveIdType(target);\n\n const response = await client.im.message.create({\n params: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n receive_id_type: receiveIdType as any,\n },\n data: {\n receive_id: target,\n msg_type: 'interactive',\n content: contentPayload,\n },\n });\n\n return {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n}\n\n// ---------------------------------------------------------------------------\n// updateCardFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Update (PATCH) the content of an existing interactive card message.\n *\n * Only messages originally sent by the bot can be updated. The card\n * must have been created with `\"update_multi\": true` in its config if\n * all recipients should see the update.\n *\n * @param params.cfg - Plugin configuration.\n * @param params.messageId - The card message ID to update.\n * @param params.card - The new card content.\n * @param params.accountId - Optional account identifier.\n */\nexport async function updateCardFeishu(params: {\n cfg: ClawdbotConfig;\n messageId: string;\n card: Record<string, unknown>;\n accountId?: string;\n}): Promise<void> {\n const { cfg, messageId, card, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n await runWithMessageUnavailableGuard({\n messageId,\n operation: 'im.message.patch(interactive)',\n fn: () =>\n client.im.message.patch({\n path: {\n message_id: messageId,\n },\n data: {\n content: JSON.stringify(card),\n },\n }),\n });\n}\n\n// ---------------------------------------------------------------------------\n// buildMarkdownCard\n// ---------------------------------------------------------------------------\n\n/**\n * Build a simple Feishu Interactive Message Card containing a single\n * markdown element.\n *\n * This is a convenience wrapper for the most common card layout: a\n * wide-screen card with one markdown block.\n *\n * @param text - The markdown text to render in the card.\n * @returns A card JSON object ready to be sent via {@link sendCardFeishu}.\n */\nexport function buildMarkdownCard(text: string): Record<string, unknown> {\n const optimizedText = optimizeMarkdownStyle(text);\n\n return {\n schema: '2.0',\n config: {\n wide_screen_mode: true,\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: optimizedText,\n },\n ],\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// sendMarkdownCardFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Build a markdown card and send it in one step.\n *\n * If mention targets are provided, they are prepended to the markdown\n * content using the card mention syntax.\n *\n * @param params.cfg - Plugin configuration.\n * @param params.to - Target identifier.\n * @param params.text - Markdown content for the card.\n * @param params.replyToMessageId - Optional message ID for threaded reply.\n * @param params.mentions - Optional mention targets.\n * @param params.accountId - Optional account identifier.\n * @returns The send result containing the new message ID.\n */\nexport async function sendMarkdownCardFeishu(params: {\n cfg: ClawdbotConfig;\n to: string;\n text: string;\n replyToMessageId?: string;\n mentions?: MentionInfo[];\n accountId?: string;\n replyInThread?: boolean;\n}): Promise<FeishuSendResult> {\n const { cfg, to, text, replyToMessageId, mentions, accountId, replyInThread } = params;\n\n let cardText = text;\n if (mentions && mentions.length > 0) {\n cardText = buildMentionedCardContent(mentions, cardText);\n }\n\n const card = buildMarkdownCard(cardText);\n\n return sendCardFeishu({\n cfg,\n to,\n card,\n replyToMessageId,\n replyInThread,\n accountId,\n });\n}\n\n// ---------------------------------------------------------------------------\n// editMessageFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Edit the content of an existing message.\n *\n * Updates the message body via the IM message update API. Only\n * messages sent by the bot can be edited.\n *\n * @param params.cfg - Plugin configuration.\n * @param params.messageId - The message ID to edit.\n * @param params.text - The new message text.\n * @param params.accountId - Optional account identifier.\n */\nexport async function editMessageFeishu(params: {\n cfg: ClawdbotConfig;\n messageId: string;\n text: string;\n accountId?: string;\n}): Promise<void> {\n const { cfg, messageId, text, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n const optimizedText = optimizeMarkdownStyle(text);\n\n const contentPayload = JSON.stringify({\n zh_cn: {\n content: [[{ tag: 'md', text: optimizedText }]],\n },\n });\n\n await runWithMessageUnavailableGuard({\n messageId,\n operation: 'im.message.update(post)',\n fn: () =>\n client.im.message.update({\n path: {\n message_id: messageId,\n },\n data: {\n content: contentPayload,\n msg_type: 'post',\n },\n }),\n });\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["response"]
7
+ }