@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,162 @@
1
+ import { LarkClient } from "../../core/lark-client";
2
+ import { normalizeFeishuTarget, resolveReceiveIdType } from "../../core/targets";
3
+ import { optimizeMarkdownStyle } from "../../card/markdown-style";
4
+ import { uploadAndSendMediaLark } from "./media";
5
+ import { formatLarkError } from "../../core/api-error";
6
+ import { larkLogger } from "../../core/lark-logger";
7
+ const log = larkLogger("outbound/deliver");
8
+ function buildPostContent(text) {
9
+ return JSON.stringify({
10
+ zh_cn: {
11
+ content: [[{ tag: "md", text }]]
12
+ }
13
+ });
14
+ }
15
+ function normalizeAtMentions(text) {
16
+ return text.replace(/<at\s+(?:id|open_id|user_id)\s*=\s*"?([^">\s]+)"?\s*>/gi, '<at user_id="$1">');
17
+ }
18
+ function prepareTextForLark(text) {
19
+ let processed = normalizeAtMentions(text);
20
+ try {
21
+ const runtime = LarkClient.runtime;
22
+ if (runtime?.channel?.text?.convertMarkdownTables) {
23
+ processed = runtime.channel.text.convertMarkdownTables(processed, "bullets");
24
+ }
25
+ } catch {
26
+ }
27
+ return optimizeMarkdownStyle(processed, 1);
28
+ }
29
+ async function sendImMessage(params) {
30
+ const { client, to, content, msgType, replyToMessageId, replyInThread } = params;
31
+ if (replyToMessageId) {
32
+ log.info(`replying to message ${replyToMessageId} (msg_type=${msgType}, thread=${replyInThread ?? false})`);
33
+ const response2 = await client.im.message.reply({
34
+ path: { message_id: replyToMessageId },
35
+ data: { content, msg_type: msgType, reply_in_thread: replyInThread }
36
+ });
37
+ const result2 = {
38
+ messageId: response2?.data?.message_id ?? "",
39
+ chatId: response2?.data?.chat_id ?? ""
40
+ };
41
+ log.debug(`reply sent: messageId=${result2.messageId}`);
42
+ return result2;
43
+ }
44
+ const target = normalizeFeishuTarget(to);
45
+ if (!target) {
46
+ throw new Error(
47
+ `Cannot send message: "${to}" is not a valid target. Expected a chat_id (oc_*), open_id (ou_*), or user_id.`
48
+ );
49
+ }
50
+ const receiveIdType = resolveReceiveIdType(target);
51
+ log.info(`creating message to ${target} (msg_type=${msgType})`);
52
+ const response = await client.im.message.create({
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ params: { receive_id_type: receiveIdType },
55
+ data: { receive_id: target, msg_type: msgType, content }
56
+ });
57
+ const result = {
58
+ messageId: response?.data?.message_id ?? "",
59
+ chatId: response?.data?.chat_id ?? ""
60
+ };
61
+ log.debug(`message created: messageId=${result.messageId}`);
62
+ return result;
63
+ }
64
+ function detectCardJson(text) {
65
+ const trimmed = text.trim();
66
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return void 0;
67
+ try {
68
+ const parsed = JSON.parse(trimmed);
69
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
70
+ return void 0;
71
+ }
72
+ const obj = parsed;
73
+ if (obj.schema === "2.0") return obj;
74
+ if (Array.isArray(obj.elements) && (obj.config !== void 0 || obj.header !== void 0)) {
75
+ return obj;
76
+ }
77
+ if (obj.type === "template" && typeof obj.data === "object" && obj.data !== null && typeof obj.data.template_id === "string") {
78
+ return obj;
79
+ }
80
+ if ((obj.msg_type === "interactive" || obj.type === "interactive") && typeof obj.card === "object" && obj.card !== null) {
81
+ return obj.card;
82
+ }
83
+ return void 0;
84
+ } catch {
85
+ return void 0;
86
+ }
87
+ }
88
+ async function sendTextLark(params) {
89
+ const { cfg, to, text, replyToMessageId, replyInThread, accountId } = params;
90
+ const card = detectCardJson(text);
91
+ if (card) {
92
+ const version = card.schema === "2.0" ? "v2" : "v1";
93
+ log.info(`detected ${version} card JSON in text (target=${to}), routing to sendCardLark`);
94
+ return sendCardLark({ cfg, to, card, replyToMessageId, replyInThread, accountId });
95
+ }
96
+ log.info(`sendTextLark: target=${to}, textLength=${text.length}`);
97
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
98
+ const processedText = prepareTextForLark(text);
99
+ const content = buildPostContent(processedText);
100
+ return sendImMessage({ client, to, content, msgType: "post", replyToMessageId, replyInThread });
101
+ }
102
+ async function sendCardLark(params) {
103
+ const { cfg, to, card, replyToMessageId, replyInThread, accountId } = params;
104
+ const version = card.schema === "2.0" ? "v2" : "v1";
105
+ log.info(`sendCardLark: target=${to}, cardVersion=${version}`);
106
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
107
+ const content = JSON.stringify(card);
108
+ try {
109
+ return await sendImMessage({ client, to, content, msgType: "interactive", replyToMessageId, replyInThread });
110
+ } catch (err) {
111
+ const detail = formatLarkError(err);
112
+ log.error(`sendCardLark failed: ${detail}`);
113
+ throw new Error(
114
+ `Card send failed: ${detail}
115
+
116
+ Troubleshooting:
117
+ - Do NOT use img/image elements with fabricated img_key values \u2014 Feishu rejects invalid keys.
118
+ - Do NOT put URLs in img_key \u2014 it must be a real image_key from uploadImage.
119
+ - Prefer text-only cards (markdown elements) which have 100% success rate.
120
+ - If you need images, send them as separate media messages, not inside cards.`
121
+ );
122
+ }
123
+ }
124
+ async function sendMediaLark(params) {
125
+ const { cfg, to, mediaUrl, replyToMessageId, replyInThread, accountId, mediaLocalRoots } = params;
126
+ log.info(`sendMediaLark: target=${to}, mediaUrl=${mediaUrl}`);
127
+ try {
128
+ const result = await uploadAndSendMediaLark({
129
+ cfg,
130
+ to,
131
+ mediaUrl,
132
+ replyToMessageId,
133
+ replyInThread,
134
+ accountId,
135
+ mediaLocalRoots
136
+ });
137
+ log.info(`media sent: messageId=${result.messageId}`);
138
+ return { messageId: result.messageId, chatId: result.chatId };
139
+ } catch (err) {
140
+ const errMsg = err instanceof Error ? err.message : String(err);
141
+ log.error(`sendMediaLark failed for "${mediaUrl}": ${errMsg}`);
142
+ log.info(`falling back to text link for "${mediaUrl}"`);
143
+ const fallbackResult = await sendTextLark({
144
+ cfg,
145
+ to,
146
+ text: `\u{1F4CE} ${mediaUrl}`,
147
+ replyToMessageId,
148
+ replyInThread,
149
+ accountId
150
+ });
151
+ return {
152
+ ...fallbackResult,
153
+ warning: `Media upload failed for "${mediaUrl}" (${errMsg}). A text link was sent instead. The user may need to open the link manually.`
154
+ };
155
+ }
156
+ }
157
+ export {
158
+ sendCardLark,
159
+ sendMediaLark,
160
+ sendTextLark
161
+ };
162
+ //# sourceMappingURL=deliver.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/deliver.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n\n/**\n * Standalone text and media delivery functions for the Lark/Feishu channel.\n *\n * These functions operate directly on the Lark SDK without depending on\n * {@link sendMessageFeishu} from `send.ts`. The outbound adapter delegates\n * to these for its `sendText` and `sendMedia` implementations.\n */\n\nimport type { ClawdbotConfig } from 'openclaw/plugin-sdk';\nimport type { FeishuSendResult } from '../types';\nimport { LarkClient } from '../../core/lark-client';\nimport { normalizeFeishuTarget, resolveReceiveIdType } from '../../core/targets';\nimport { optimizeMarkdownStyle } from '../../card/markdown-style';\nimport { uploadAndSendMediaLark } from './media';\nimport { formatLarkError } from '../../core/api-error';\nimport { larkLogger } from '../../core/lark-logger';\n\nconst log = larkLogger('outbound/deliver');\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Build a Feishu post-format content envelope from processed text.\n */\nfunction buildPostContent(text: string): string {\n return JSON.stringify({\n zh_cn: {\n content: [[{ tag: 'md', text }]],\n },\n });\n}\n\n/**\n * Normalise `<at>` mention tags that the AI frequently writes incorrectly.\n *\n * Correct Feishu syntax:\n * `<at user_id=\"ou_xxx\">name</at>` \u2014 mention a user\n * `<at user_id=\"all\"></at>` \u2014 mention everyone\n *\n * Common AI mistakes this function fixes:\n * `<at id=all></at>` \u2192 `<at user_id=\"all\"></at>`\n * `<at id=\"ou_xxx\"></at>` \u2192 `<at user_id=\"ou_xxx\"></at>`\n * `<at open_id=\"ou_xxx\"></at>` \u2192 `<at user_id=\"ou_xxx\"></at>`\n * `<at user_id=ou_xxx></at>` \u2192 `<at user_id=\"ou_xxx\"></at>`\n */\nfunction normalizeAtMentions(text: string): string {\n return text.replace(/<at\\s+(?:id|open_id|user_id)\\s*=\\s*\"?([^\">\\s]+)\"?\\s*>/gi, '<at user_id=\"$1\">');\n}\n\n/**\n * Pre-process text for Lark rendering:\n * mention normalisation + table conversion + style optimization.\n */\nfunction prepareTextForLark(text: string): string {\n let processed = normalizeAtMentions(text);\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 processed = runtime.channel.text.convertMarkdownTables(processed, 'bullets');\n }\n } catch {\n // Runtime not available -- use the text as-is.\n }\n\n return optimizeMarkdownStyle(processed, 1);\n}\n\n/**\n * Unified IM message sender \u2014 handles both reply and create paths for any\n * `msg_type`. Replaces the former `replyPostMessage`, `createPostMessage`,\n * `replyInteractiveMessage` and `createInteractiveMessage` helpers.\n */\nasync function sendImMessage(params: {\n client: ReturnType<typeof LarkClient.fromCfg>['sdk'];\n to: string;\n content: string;\n msgType: 'post' | 'interactive';\n replyToMessageId?: string;\n replyInThread?: boolean;\n}): Promise<FeishuSendResult> {\n const { client, to, content, msgType, replyToMessageId, replyInThread } = params;\n\n // --- Reply path ---\n if (replyToMessageId) {\n log.info(`replying to message ${replyToMessageId} ` + `(msg_type=${msgType}, thread=${replyInThread ?? false})`);\n const response = await client.im.message.reply({\n path: { message_id: replyToMessageId },\n data: { content, msg_type: msgType, reply_in_thread: replyInThread },\n });\n\n const result: FeishuSendResult = {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n log.debug(`reply sent: messageId=${result.messageId}`);\n return result;\n }\n\n // --- Create path ---\n const target = normalizeFeishuTarget(to);\n if (!target) {\n throw new Error(\n `Cannot send message: \"${to}\" is not a valid target. ` + `Expected a chat_id (oc_*), open_id (ou_*), or user_id.`,\n );\n }\n\n const receiveIdType = resolveReceiveIdType(target);\n log.info(`creating message to ${target} (msg_type=${msgType})`);\n\n const response = await client.im.message.create({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: { receive_id_type: receiveIdType as any },\n data: { receive_id: target, msg_type: msgType, content },\n });\n\n const result: FeishuSendResult = {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n log.debug(`message created: messageId=${result.messageId}`);\n return result;\n}\n\n/**\n * Detect whether a text string is a complete Feishu card JSON (v1, v2, or template).\n *\n * Returns the parsed card object if the text is valid card JSON, or\n * `undefined` if it is plain text. Detection is conservative \u2014 only\n * triggers when the **entire** trimmed text is a JSON object with\n * recognisable card structure markers.\n *\n * - **v2**: top-level `schema` equals `\"2.0\"`\n * - **v1**: has an `elements` array AND at least `config` or `header`\n * - **template**: `type` equals `\"template\"` with `data.template_id`\n * - **wrapped**: `msg_type` or `type` equals `\"interactive\"` with a nested `card` object\n */\nfunction detectCardJson(text: string): Record<string, unknown> | undefined {\n const trimmed = text.trim();\n if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) return undefined;\n\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return undefined;\n }\n\n const obj = parsed as Record<string, unknown>;\n\n // v2 CardKit \u2014 must declare schema \"2.0\"\n if (obj.schema === '2.0') return obj;\n\n // v1 Message Card \u2014 must have elements[] AND (config OR header)\n if (Array.isArray(obj.elements) && (obj.config !== undefined || obj.header !== undefined)) {\n return obj;\n }\n\n // Template card \u2014 type: \"template\" with data.template_id\n if (\n obj.type === 'template' &&\n typeof obj.data === 'object' &&\n obj.data !== null &&\n typeof (obj.data as Record<string, unknown>).template_id === 'string'\n ) {\n return obj;\n }\n\n // Wrapped card \u2014 AI sometimes wraps card JSON with msg_type/type: \"interactive\"\n if (\n (obj.msg_type === 'interactive' || obj.type === 'interactive') &&\n typeof obj.card === 'object' &&\n obj.card !== null\n ) {\n return obj.card as Record<string, unknown>;\n }\n\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// sendTextLark\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for sending a text message via Feishu.\n */\nexport interface SendTextLarkParams {\n /** Plugin configuration. */\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 /** When true, the reply appears in the thread instead of main chat. */\n replyInThread?: boolean;\n /** Optional account identifier for multi-account setups. */\n accountId?: string;\n}\n\n/**\n * Send a text message to a Feishu chat or user.\n *\n * Standalone implementation that directly operates the Lark SDK.\n * The text is pre-processed (table conversion, style optimization)\n * and sent as a Feishu \"post\" message with markdown rendering.\n *\n * If the entire text is a valid Feishu card JSON string (v1 or v2),\n * it is automatically detected and routed to {@link sendCardLark}\n * instead of being sent as plain text.\n *\n * @param params - See {@link SendTextLarkParams}.\n * @returns The message ID and chat ID.\n * @throws {Error} When the target is invalid or the API call fails.\n *\n * @example\n * ```ts\n * const result = await sendTextLark({\n * cfg,\n * to: \"oc_xxx\",\n * text: \"Hello from Feishu\",\n * });\n * ```\n */\nexport async function sendTextLark(params: SendTextLarkParams): Promise<FeishuSendResult> {\n const { cfg, to, text, replyToMessageId, replyInThread, accountId } = params;\n\n // Detect card JSON in text \u2014 route to card sending before text preprocessing.\n const card = detectCardJson(text);\n if (card) {\n const version = card.schema === '2.0' ? 'v2' : 'v1';\n log.info(`detected ${version} card JSON in text (target=${to}), routing to sendCardLark`);\n return sendCardLark({ cfg, to, card, replyToMessageId, replyInThread, accountId });\n }\n\n log.info(`sendTextLark: target=${to}, textLength=${text.length}`);\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n const processedText = prepareTextForLark(text);\n const content = buildPostContent(processedText);\n\n return sendImMessage({ client, to, content, msgType: 'post', replyToMessageId, replyInThread });\n}\n\n// ---------------------------------------------------------------------------\n// sendCardLark\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for sending an interactive card message via Feishu.\n */\nexport interface SendCardLarkParams {\n /** Plugin configuration. */\n cfg: ClawdbotConfig;\n /** Target identifier (chat_id, open_id, or user_id). */\n to: string;\n /**\n * Complete card JSON object (v1 Message Card or v2 CardKit).\n *\n * - **v1**: top-level `config`, `header`, `elements`.\n * - **v2**: `schema: \"2.0\"`, `config`, `header`, `body.elements`.\n *\n * The Feishu server determines the version by the presence of\n * `schema: \"2.0\"`.\n */\n card: Record<string, unknown>;\n /** When set, the card is sent as a threaded reply. */\n replyToMessageId?: string;\n /** When true, the reply appears in the thread instead of main chat. */\n replyInThread?: boolean;\n /** Optional account identifier for multi-account setups. */\n accountId?: string;\n}\n\n/**\n * Send an interactive card message to a Feishu chat or user.\n *\n * Supports both v1 (Message Card) and v2 (CardKit) card formats.\n * The card JSON is serialised and sent as `msg_type: \"interactive\"`.\n *\n * @param params - See {@link SendCardLarkParams}.\n * @returns The message ID and chat ID.\n * @throws {Error} When the target is invalid or the API call fails.\n *\n * @example\n * ```ts\n * // v1 card\n * const result = await sendCardLark({\n * cfg,\n * to: \"oc_xxx\",\n * card: {\n * config: { wide_screen_mode: true },\n * header: { title: { tag: \"plain_text\", content: \"Hello\" }, template: \"blue\" },\n * elements: [{ tag: \"div\", text: { tag: \"lark_md\", content: \"world\" } }],\n * },\n * });\n *\n * // v2 card\n * const result2 = await sendCardLark({\n * cfg,\n * to: \"oc_xxx\",\n * card: {\n * schema: \"2.0\",\n * config: { wide_screen_mode: true },\n * body: { elements: [{ tag: \"markdown\", content: \"Hello **world**\" }] },\n * },\n * });\n * ```\n */\nexport async function sendCardLark(params: SendCardLarkParams): Promise<FeishuSendResult> {\n const { cfg, to, card, replyToMessageId, replyInThread, accountId } = params;\n\n const version = card.schema === '2.0' ? 'v2' : 'v1';\n log.info(`sendCardLark: target=${to}, cardVersion=${version}`);\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n const content = JSON.stringify(card);\n\n try {\n return await sendImMessage({ client, to, content, msgType: 'interactive', replyToMessageId, replyInThread });\n } catch (err) {\n const detail = formatLarkError(err);\n log.error(`sendCardLark failed: ${detail}`);\n\n throw new Error(\n `Card send failed: ${detail}\\n\\n` +\n `Troubleshooting:\\n` +\n `- Do NOT use img/image elements with fabricated img_key values \u2014 Feishu rejects invalid keys.\\n` +\n `- Do NOT put URLs in img_key \u2014 it must be a real image_key from uploadImage.\\n` +\n `- Prefer text-only cards (markdown elements) which have 100% success rate.\\n` +\n `- If you need images, send them as separate media messages, not inside cards.`,\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// sendMediaLark\n// ---------------------------------------------------------------------------\n\n/**\n * Parameters for sending a single media message via Feishu.\n */\nexport interface SendMediaLarkParams {\n /** Plugin configuration. */\n cfg: ClawdbotConfig;\n /** Target identifier (chat_id, open_id, or user_id). */\n to: string;\n /** Media URL to upload and send. */\n mediaUrl: string;\n /** When set, the message is sent as a threaded reply. */\n replyToMessageId?: string;\n /** When true, the reply appears in the thread instead of main chat. */\n replyInThread?: boolean;\n /** Optional account identifier for multi-account setups. */\n accountId?: string;\n /** Allowed root directories for local file access (SSRF prevention). */\n mediaLocalRoots?: readonly string[];\n}\n\n/**\n * Send a single media message to a Feishu chat or user.\n *\n * Pure atomic operation \u2014 uploads the media and sends it. On upload\n * failure, falls back to sending the URL as a clickable text link.\n *\n * This function does **not** handle leading text or multi-media\n * orchestration; those concerns belong to the adapter's `sendMedia`\n * and `sendPayload` methods.\n *\n * @param params - See {@link SendMediaLarkParams}.\n * @returns The message ID and chat ID of the sent message.\n * @throws {Error} When the target is invalid or all send attempts fail.\n *\n * @example\n * ```ts\n * const result = await sendMediaLark({\n * cfg,\n * to: \"oc_xxx\",\n * mediaUrl: \"https://example.com/image.png\",\n * });\n * ```\n */\nexport async function sendMediaLark(params: SendMediaLarkParams): Promise<FeishuSendResult> {\n const { cfg, to, mediaUrl, replyToMessageId, replyInThread, accountId, mediaLocalRoots } = params;\n\n log.info(`sendMediaLark: target=${to}, mediaUrl=${mediaUrl}`);\n\n try {\n const result = await uploadAndSendMediaLark({\n cfg,\n to,\n mediaUrl,\n replyToMessageId,\n replyInThread,\n accountId,\n mediaLocalRoots,\n });\n log.info(`media sent: messageId=${result.messageId}`);\n return { messageId: result.messageId, chatId: result.chatId };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n log.error(`sendMediaLark failed for \"${mediaUrl}\": ${errMsg}`);\n\n // Fallback: send the URL as a clickable text link.\n log.info(`falling back to text link for \"${mediaUrl}\"`);\n const fallbackResult = await sendTextLark({\n cfg,\n to,\n text: `\\u{1F4CE} ${mediaUrl}`,\n replyToMessageId,\n replyInThread,\n accountId,\n });\n\n return {\n ...fallbackResult,\n warning:\n `Media upload failed for \"${mediaUrl}\" (${errMsg}). ` +\n `A text link was sent instead. The user may need to open the link manually.`,\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["response", "result"]
7
+ }
@@ -0,0 +1,7 @@
1
+ import { getMessageFeishu } from "../shared/message-lookup";
2
+ import { getChatTypeFeishu } from "../../core/chat-info-cache";
3
+ export {
4
+ getChatTypeFeishu,
5
+ getMessageFeishu
6
+ };
7
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/fetch.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Message fetching re-exports for backward compatibility.\n *\n * The actual implementations have been moved to:\n * - `getMessageFeishu` / `FeishuMessageInfo` \u2192 `../shared/message-lookup.ts`\n * - `getChatTypeFeishu` \u2192 `../../core/chat-info-cache.ts`\n */\n\nexport { getMessageFeishu, type FeishuMessageInfo } from '../shared/message-lookup';\nexport { getChatTypeFeishu } from '../../core/chat-info-cache';\n"],
5
+ "mappings": "AAWA,SAAS,wBAAgD;AACzD,SAAS,yBAAyB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,31 @@
1
+ import { LarkClient } from "../../core/lark-client";
2
+ import { normalizeFeishuTarget, resolveReceiveIdType } from "../../core/targets";
3
+ async function forwardMessageFeishu(params) {
4
+ const { cfg, messageId, to, accountId } = params;
5
+ const client = LarkClient.fromCfg(cfg, accountId).sdk;
6
+ const target = normalizeFeishuTarget(to);
7
+ if (!target) {
8
+ throw new Error(`[feishu-forward] Invalid target: "${to}"`);
9
+ }
10
+ const receiveIdType = resolveReceiveIdType(target);
11
+ const response = await client.im.message.forward({
12
+ path: {
13
+ message_id: messageId
14
+ },
15
+ params: {
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ receive_id_type: receiveIdType
18
+ },
19
+ data: {
20
+ receive_id: target
21
+ }
22
+ });
23
+ return {
24
+ messageId: response?.data?.message_id ?? "",
25
+ chatId: response?.data?.chat_id ?? ""
26
+ };
27
+ }
28
+ export {
29
+ forwardMessageFeishu
30
+ };
31
+ //# sourceMappingURL=forward.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/forward.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Message forwarding for the Lark/Feishu channel plugin.\n *\n * Provides a function to forward an existing message to another chat\n * or user using the IM Message Forward API.\n */\n\nimport type { OpenClawConfig } from 'openclaw/plugin-sdk';\nimport type { FeishuSendResult } from '../types';\nimport { LarkClient } from '../../core/lark-client';\nimport { normalizeFeishuTarget, resolveReceiveIdType } from '../../core/targets';\n\n// ---------------------------------------------------------------------------\n// forwardMessageFeishu\n// ---------------------------------------------------------------------------\n\n/**\n * Forward an existing message to another chat or user.\n *\n * @param params.cfg - Plugin configuration with Feishu credentials.\n * @param params.messageId - The message ID to forward.\n * @param params.to - Target identifier (chat_id, open_id, or user_id).\n * @param params.accountId - Optional account identifier for multi-account setups.\n * @returns The send result containing the new forwarded message ID.\n */\nexport async function forwardMessageFeishu(params: {\n cfg: OpenClawConfig;\n messageId: string;\n to: string;\n accountId?: string;\n}): Promise<FeishuSendResult> {\n const { cfg, messageId, to, accountId } = params;\n\n const client = LarkClient.fromCfg(cfg, accountId).sdk;\n\n const target = normalizeFeishuTarget(to);\n if (!target) {\n throw new Error(`[feishu-forward] Invalid target: \"${to}\"`);\n }\n\n const receiveIdType = resolveReceiveIdType(target);\n\n const response = await client.im.message.forward({\n path: {\n message_id: messageId,\n },\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 },\n });\n\n return {\n messageId: response?.data?.message_id ?? '',\n chatId: response?.data?.chat_id ?? '',\n };\n}\n"],
5
+ "mappings": "AAYA,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB,4BAA4B;AAe5D,eAAsB,qBAAqB,QAKb;AAC5B,QAAM,EAAE,KAAK,WAAW,IAAI,UAAU,IAAI;AAE1C,QAAM,SAAS,WAAW,QAAQ,KAAK,SAAS,EAAE;AAElD,QAAM,SAAS,sBAAsB,EAAE;AACvC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,qCAAqC,EAAE,GAAG;AAAA,EAC5D;AAEA,QAAM,gBAAgB,qBAAqB,MAAM;AAEjD,QAAM,WAAW,MAAM,OAAO,GAAG,QAAQ,QAAQ;AAAA,IAC/C,MAAM;AAAA,MACJ,YAAY;AAAA,IACd;AAAA,IACA,QAAQ;AAAA;AAAA,MAEN,iBAAiB;AAAA,IACnB;AAAA,IACA,MAAM;AAAA,MACJ,YAAY;AAAA,IACd;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,WAAW,UAAU,MAAM,cAAc;AAAA,IACzC,QAAQ,UAAU,MAAM,WAAW;AAAA,EACrC;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,101 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ function normalizeMediaUrlInput(value) {
5
+ let raw = value.trim();
6
+ if (raw.startsWith("<") && raw.endsWith(">") && raw.length >= 2) {
7
+ raw = raw.slice(1, -1).trim();
8
+ }
9
+ const first = raw[0];
10
+ const last = raw[raw.length - 1];
11
+ if (raw.length >= 2 && (first === '"' && last === '"' || first === "'" && last === "'" || first === "`" && last === "`")) {
12
+ raw = raw.slice(1, -1).trim();
13
+ }
14
+ return raw;
15
+ }
16
+ function stripQueryAndHash(value) {
17
+ return value.split(/[?#]/, 1)[0] ?? value;
18
+ }
19
+ function isWindowsAbsolutePath(value) {
20
+ return /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\");
21
+ }
22
+ function isLocalMediaPath(value) {
23
+ const raw = normalizeMediaUrlInput(value);
24
+ return raw.startsWith("file://") || path.isAbsolute(raw) || isWindowsAbsolutePath(raw);
25
+ }
26
+ function safeFileUrlToPath(fileUrl) {
27
+ const raw = normalizeMediaUrlInput(fileUrl);
28
+ try {
29
+ return fileURLToPath(raw);
30
+ } catch {
31
+ return new URL(raw).pathname;
32
+ }
33
+ }
34
+ function validateLocalMediaRoots(filePath, localRoots) {
35
+ if (localRoots === void 0) return;
36
+ if (localRoots.length === 0) {
37
+ throw new Error(
38
+ `[feishu-media] Local file access denied for "${filePath}": mediaLocalRoots is configured as an empty array, which blocks all local access. Add allowed directories to mediaLocalRoots or use a remote URL instead.`
39
+ );
40
+ }
41
+ let resolved;
42
+ try {
43
+ resolved = fs.realpathSync(path.resolve(filePath));
44
+ } catch {
45
+ resolved = path.resolve(filePath);
46
+ }
47
+ const isAllowed = localRoots.some((root) => {
48
+ let resolvedRoot;
49
+ try {
50
+ resolvedRoot = fs.realpathSync(path.resolve(root));
51
+ } catch {
52
+ resolvedRoot = path.resolve(root);
53
+ }
54
+ return resolved === resolvedRoot || resolved.startsWith(resolvedRoot + path.sep);
55
+ });
56
+ if (!isAllowed) {
57
+ throw new Error(
58
+ `[feishu-media] Local file access denied for "${filePath}": path is not under any allowed mediaLocalRoots (${localRoots.join(", ")}). Move the file to an allowed directory or use a remote URL instead.`
59
+ );
60
+ }
61
+ }
62
+ function resolveBaseNameFromPath(value) {
63
+ const raw = normalizeMediaUrlInput(value);
64
+ const cleanPath = stripQueryAndHash(raw);
65
+ const fileName = isWindowsAbsolutePath(cleanPath) ? path.win32.basename(cleanPath) : path.basename(cleanPath);
66
+ if (fileName && fileName !== "/" && fileName !== "." && fileName !== "\\") {
67
+ return fileName;
68
+ }
69
+ return void 0;
70
+ }
71
+ function resolveFileNameFromMediaUrl(mediaUrl) {
72
+ const raw = normalizeMediaUrlInput(mediaUrl);
73
+ if (!raw) return void 0;
74
+ if (isLocalMediaPath(raw)) {
75
+ if (raw.startsWith("file://")) {
76
+ const fromFileUrlPath = safeFileUrlToPath(raw);
77
+ const fromFileUrlName = resolveBaseNameFromPath(fromFileUrlPath);
78
+ if (fromFileUrlName) return fromFileUrlName;
79
+ }
80
+ return resolveBaseNameFromPath(raw);
81
+ }
82
+ try {
83
+ const parsed = new URL(raw);
84
+ if (parsed.protocol === "http:" || parsed.protocol === "https:") {
85
+ const fromUrlPath = path.posix.basename(parsed.pathname);
86
+ if (fromUrlPath && fromUrlPath !== "/") return fromUrlPath;
87
+ }
88
+ } catch {
89
+ }
90
+ return resolveBaseNameFromPath(raw);
91
+ }
92
+ export {
93
+ isLocalMediaPath,
94
+ isWindowsAbsolutePath,
95
+ normalizeMediaUrlInput,
96
+ resolveBaseNameFromPath,
97
+ resolveFileNameFromMediaUrl,
98
+ safeFileUrlToPath,
99
+ validateLocalMediaRoots
100
+ };
101
+ //# sourceMappingURL=media-url-utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/outbound/media-url-utils.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function normalizeMediaUrlInput(value: string): string {\n let raw = value.trim();\n\n // Common wrappers from markdown/chat payloads.\n if (raw.startsWith('<') && raw.endsWith('>') && raw.length >= 2) {\n raw = raw.slice(1, -1).trim();\n }\n\n // Strip matching surrounding quotes/backticks.\n const first = raw[0];\n const last = raw[raw.length - 1];\n if (\n raw.length >= 2 &&\n ((first === '\"' && last === '\"') || (first === \"'\" && last === \"'\") || (first === '`' && last === '`'))\n ) {\n raw = raw.slice(1, -1).trim();\n }\n\n return raw;\n}\n\nfunction stripQueryAndHash(value: string): string {\n return value.split(/[?#]/, 1)[0] ?? value;\n}\n\nexport function isWindowsAbsolutePath(value: string): boolean {\n return /^[A-Za-z]:[\\\\/]/.test(value) || value.startsWith('\\\\\\\\');\n}\n\nexport function isLocalMediaPath(value: string): boolean {\n const raw = normalizeMediaUrlInput(value);\n return raw.startsWith('file://') || path.isAbsolute(raw) || isWindowsAbsolutePath(raw);\n}\n\nexport function safeFileUrlToPath(fileUrl: string): string {\n const raw = normalizeMediaUrlInput(fileUrl);\n try {\n return fileURLToPath(raw);\n } catch {\n return new URL(raw).pathname;\n }\n}\n\n/**\n * Validate that a resolved local file path falls under one of the\n * allowed root directories. Prevents path-traversal attacks when\n * the AI or an external payload supplies a local media path.\n *\n * Semantics:\n * - **`undefined`** \u2014 caller has not opted in to restriction; the\n * function is a no-op so existing behaviour is preserved. The\n * caller should log a warning independently.\n * - **`[]` (empty array)** \u2014 explicitly configured with no allowed\n * roots \u2192 all local access is denied.\n * - **Non-empty array** \u2014 standard allowlist check.\n *\n * @param filePath - Resolved absolute path to validate.\n * @param localRoots - Allowed root directories.\n * @throws {Error} When the path is not under any allowed root, or\n * when `localRoots` is an empty array.\n */\nexport function validateLocalMediaRoots(filePath: string, localRoots: readonly string[] | undefined): void {\n // Not configured \u2014 skip validation (backwards-compatible).\n if (localRoots === undefined) return;\n\n if (localRoots.length === 0) {\n throw new Error(\n `[feishu-media] Local file access denied for \"${filePath}\": ` +\n `mediaLocalRoots is configured as an empty array, which blocks all local access. ` +\n `Add allowed directories to mediaLocalRoots or use a remote URL instead.`,\n );\n }\n\n // Resolve symlinks to prevent traversal via symlinked paths.\n // Fall back to path.resolve when the file does not exist yet \u2014 the\n // subsequent readFileSync will report a clear \"file not found\" error.\n let resolved: string;\n try {\n resolved = fs.realpathSync(path.resolve(filePath));\n } catch {\n resolved = path.resolve(filePath);\n }\n\n const isAllowed = localRoots.some((root) => {\n let resolvedRoot: string;\n try {\n resolvedRoot = fs.realpathSync(path.resolve(root));\n } catch {\n resolvedRoot = path.resolve(root);\n }\n // Must be exactly the root or strictly inside it (with separator).\n return resolved === resolvedRoot || resolved.startsWith(resolvedRoot + path.sep);\n });\n\n if (!isAllowed) {\n throw new Error(\n `[feishu-media] Local file access denied for \"${filePath}\": ` +\n `path is not under any allowed mediaLocalRoots (${localRoots.join(', ')}). ` +\n `Move the file to an allowed directory or use a remote URL instead.`,\n );\n }\n}\n\nexport function resolveBaseNameFromPath(value: string): string | undefined {\n const raw = normalizeMediaUrlInput(value);\n const cleanPath = stripQueryAndHash(raw);\n const fileName = isWindowsAbsolutePath(cleanPath) ? path.win32.basename(cleanPath) : path.basename(cleanPath);\n if (fileName && fileName !== '/' && fileName !== '.' && fileName !== '\\\\') {\n return fileName;\n }\n return undefined;\n}\n\nexport function resolveFileNameFromMediaUrl(mediaUrl: string): string | undefined {\n const raw = normalizeMediaUrlInput(mediaUrl);\n if (!raw) return undefined;\n\n if (isLocalMediaPath(raw)) {\n if (raw.startsWith('file://')) {\n const fromFileUrlPath = safeFileUrlToPath(raw);\n const fromFileUrlName = resolveBaseNameFromPath(fromFileUrlPath);\n if (fromFileUrlName) return fromFileUrlName;\n }\n return resolveBaseNameFromPath(raw);\n }\n\n try {\n const parsed = new URL(raw);\n if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {\n const fromUrlPath = path.posix.basename(parsed.pathname);\n if (fromUrlPath && fromUrlPath !== '/') return fromUrlPath;\n }\n } catch {\n // Not a valid URL. Continue with file path fallback.\n }\n\n return resolveBaseNameFromPath(raw);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }