@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,29 @@
1
+ import { getEnabledLarkAccounts } from "../../../core/accounts";
2
+ import { resolveAnyEnabledToolsConfig } from "../../../core/tools-config";
3
+ import { registerFeishuDriveFileTool } from "./file";
4
+ import { registerDocCommentsTool } from "./doc-comments";
5
+ import { registerDocMediaTool } from "./doc-media";
6
+ function registerFeishuDriveTools(api) {
7
+ if (!api.config) {
8
+ api.logger.debug?.("feishu_drive: No config available, skipping");
9
+ return;
10
+ }
11
+ const accounts = getEnabledLarkAccounts(api.config);
12
+ if (accounts.length === 0) {
13
+ api.logger.debug?.("feishu_drive: No Feishu accounts configured, skipping");
14
+ return;
15
+ }
16
+ const toolsCfg = resolveAnyEnabledToolsConfig(accounts);
17
+ if (!toolsCfg.drive) {
18
+ api.logger.debug?.("feishu_drive: drive tool disabled in all accounts");
19
+ return;
20
+ }
21
+ registerFeishuDriveFileTool(api);
22
+ registerDocCommentsTool(api);
23
+ registerDocMediaTool(api);
24
+ api.logger.info?.("feishu_drive: Registered feishu_drive_file, feishu_doc_comments, feishu_doc_media");
25
+ }
26
+ export {
27
+ registerFeishuDriveTools
28
+ };
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/drive/index.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Drive \u5DE5\u5177\u96C6\n * \u7EDF\u4E00\u5BFC\u51FA\u6240\u6709\u4E91\u7A7A\u95F4\u76F8\u5173\u5DE5\u5177\u7684\u6CE8\u518C\u51FD\u6570\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { getEnabledLarkAccounts } from '../../../core/accounts';\nimport { resolveAnyEnabledToolsConfig } from '../../../core/tools-config';\nimport { registerFeishuDriveFileTool } from './file';\nimport { registerDocCommentsTool } from './doc-comments';\nimport { registerDocMediaTool } from './doc-media';\n\n/**\n * \u6CE8\u518C\u6240\u6709 Drive \u5DE5\u5177\n */\nexport function registerFeishuDriveTools(api: OpenClawPluginApi) {\n if (!api.config) {\n api.logger.debug?.('feishu_drive: No config available, skipping');\n return;\n }\n\n const accounts = getEnabledLarkAccounts(api.config);\n if (accounts.length === 0) {\n api.logger.debug?.('feishu_drive: No Feishu accounts configured, skipping');\n return;\n }\n\n const toolsCfg = resolveAnyEnabledToolsConfig(accounts);\n if (!toolsCfg.drive) {\n api.logger.debug?.('feishu_drive: drive tool disabled in all accounts');\n return;\n }\n\n // \u6CE8\u518C\u6240\u6709\u5DE5\u5177\n registerFeishuDriveFileTool(api);\n registerDocCommentsTool(api);\n registerDocMediaTool(api);\n\n api.logger.info?.('feishu_drive: Registered feishu_drive_file, feishu_doc_comments, feishu_doc_media');\n}\n"],
5
+ "mappings": "AASA,SAAS,8BAA8B;AACvC,SAAS,oCAAoC;AAC7C,SAAS,mCAAmC;AAC5C,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AAK9B,SAAS,yBAAyB,KAAwB;AAC/D,MAAI,CAAC,IAAI,QAAQ;AACf,QAAI,OAAO,QAAQ,6CAA6C;AAChE;AAAA,EACF;AAEA,QAAM,WAAW,uBAAuB,IAAI,MAAM;AAClD,MAAI,SAAS,WAAW,GAAG;AACzB,QAAI,OAAO,QAAQ,uDAAuD;AAC1E;AAAA,EACF;AAEA,QAAM,WAAW,6BAA6B,QAAQ;AACtD,MAAI,CAAC,SAAS,OAAO;AACnB,QAAI,OAAO,QAAQ,mDAAmD;AACtE;AAAA,EACF;AAGA,8BAA4B,GAAG;AAC/B,0BAAwB,GAAG;AAC3B,uBAAqB,GAAG;AAExB,MAAI,OAAO,OAAO,mFAAmF;AACvG;",
6
+ "names": []
7
+ }
@@ -0,0 +1,199 @@
1
+ import {
2
+ formatToolResult,
3
+ formatToolError,
4
+ createToolLogger,
5
+ createClientGetter,
6
+ createToolContext,
7
+ getFirstAccount,
8
+ validateRequiredParams,
9
+ validateEnum
10
+ } from "../helpers";
11
+ import {
12
+ ToolClient,
13
+ createToolClient,
14
+ NeedAuthorizationError,
15
+ AppScopeMissingError,
16
+ UserAuthRequiredError,
17
+ UserScopeInsufficientError
18
+ } from "../../core/tool-client";
19
+ import { createClientGetter as createClientGetter2 } from "../helpers";
20
+ function createFeishuClientFromConfig(config) {
21
+ const getClient = createClientGetter2(config);
22
+ return getClient();
23
+ }
24
+ import { formatToolResult as formatToolResult2 } from "../helpers";
25
+ function json(data) {
26
+ return formatToolResult2(data);
27
+ }
28
+ function parseTimeToTimestamp(input) {
29
+ try {
30
+ const trimmed = input.trim();
31
+ const hasTimezone = /[Zz]$|[+-]\d{2}:\d{2}$/.test(trimmed);
32
+ if (hasTimezone) {
33
+ const date = new Date(trimmed);
34
+ if (isNaN(date.getTime())) return null;
35
+ return Math.floor(date.getTime() / 1e3).toString();
36
+ }
37
+ const normalized = trimmed.replace("T", " ");
38
+ const match = normalized.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})(?::(\d{2}))?$/);
39
+ if (!match) {
40
+ const date = new Date(trimmed);
41
+ if (isNaN(date.getTime())) return null;
42
+ return Math.floor(date.getTime() / 1e3).toString();
43
+ }
44
+ const [, year, month, day, hour, minute, second] = match;
45
+ const utcDate = new Date(
46
+ Date.UTC(
47
+ parseInt(year),
48
+ parseInt(month) - 1,
49
+ parseInt(day),
50
+ parseInt(hour) - 8,
51
+ // 北京时间减去 8 小时得到 UTC
52
+ parseInt(minute),
53
+ parseInt(second ?? "0")
54
+ )
55
+ );
56
+ return Math.floor(utcDate.getTime() / 1e3).toString();
57
+ } catch {
58
+ return null;
59
+ }
60
+ }
61
+ function parseTimeToTimestampMs(input) {
62
+ try {
63
+ const trimmed = input.trim();
64
+ const hasTimezone = /[Zz]$|[+-]\d{2}:\d{2}$/.test(trimmed);
65
+ if (hasTimezone) {
66
+ const date = new Date(trimmed);
67
+ if (isNaN(date.getTime())) return null;
68
+ return date.getTime().toString();
69
+ }
70
+ const normalized = trimmed.replace("T", " ");
71
+ const match = normalized.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})(?::(\d{2}))?$/);
72
+ if (!match) {
73
+ const date = new Date(trimmed);
74
+ if (isNaN(date.getTime())) return null;
75
+ return date.getTime().toString();
76
+ }
77
+ const [, year, month, day, hour, minute, second] = match;
78
+ const utcDate = new Date(
79
+ Date.UTC(
80
+ parseInt(year),
81
+ parseInt(month) - 1,
82
+ parseInt(day),
83
+ parseInt(hour) - 8,
84
+ // 北京时间减去 8 小时得到 UTC
85
+ parseInt(minute),
86
+ parseInt(second ?? "0")
87
+ )
88
+ );
89
+ return utcDate.getTime().toString();
90
+ } catch {
91
+ return null;
92
+ }
93
+ }
94
+ function parseTimeToRFC3339(input) {
95
+ try {
96
+ const trimmed = input.trim();
97
+ const hasTimezone = /[Zz]$|[+-]\d{2}:\d{2}$/.test(trimmed);
98
+ if (hasTimezone) {
99
+ const date = new Date(trimmed);
100
+ if (isNaN(date.getTime())) return null;
101
+ return trimmed;
102
+ }
103
+ const normalized = trimmed.replace("T", " ");
104
+ const match = normalized.match(/^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})(?::(\d{2}))?$/);
105
+ if (!match) {
106
+ const date = new Date(trimmed);
107
+ if (isNaN(date.getTime())) return null;
108
+ return trimmed.includes("T") ? `${trimmed}+08:00` : trimmed;
109
+ }
110
+ const [, year, month, day, hour, minute, second] = match;
111
+ const sec = second ?? "00";
112
+ return `${year}-${month}-${day}T${hour}:${minute}:${sec}+08:00`;
113
+ } catch {
114
+ return null;
115
+ }
116
+ }
117
+ function convertTimeRange(timeRange, unit = "s") {
118
+ if (!timeRange) return void 0;
119
+ const result = {};
120
+ const parseFn = unit === "ms" ? parseTimeToTimestampMs : parseTimeToTimestamp;
121
+ if (timeRange.start) {
122
+ const ts = parseFn(timeRange.start);
123
+ if (!ts) {
124
+ throw new Error(
125
+ `Invalid time format for start. Must use ISO 8601 / RFC 3339 with timezone, e.g. "2024-01-01T00:00:00+08:00". Received: ${timeRange.start}`
126
+ );
127
+ }
128
+ result.start = parseInt(ts, 10);
129
+ }
130
+ if (timeRange.end) {
131
+ const ts = parseFn(timeRange.end);
132
+ if (!ts) {
133
+ throw new Error(
134
+ `Invalid time format for end. Must use ISO 8601 / RFC 3339 with timezone, e.g. "2024-01-01T00:00:00+08:00". Received: ${timeRange.end}`
135
+ );
136
+ }
137
+ result.end = parseInt(ts, 10);
138
+ }
139
+ return Object.keys(result).length > 0 ? result : void 0;
140
+ }
141
+ const SHANGHAI_UTC_OFFSET_HOURS = 8;
142
+ const SHANGHAI_OFFSET_SUFFIX = "+08:00";
143
+ function pad2(value) {
144
+ return String(value).padStart(2, "0");
145
+ }
146
+ function unixTimestampToISO8601(raw) {
147
+ if (raw === void 0 || raw === null) return null;
148
+ const text = typeof raw === "number" ? String(raw) : String(raw).trim();
149
+ if (!/^-?\d+$/.test(text)) return null;
150
+ const num = Number(text);
151
+ if (!Number.isFinite(num)) return null;
152
+ const utcMs = Math.abs(num) >= 1e12 ? num : num * 1e3;
153
+ const beijingDate = new Date(utcMs + SHANGHAI_UTC_OFFSET_HOURS * 60 * 60 * 1e3);
154
+ if (Number.isNaN(beijingDate.getTime())) return null;
155
+ const year = beijingDate.getUTCFullYear();
156
+ const month = pad2(beijingDate.getUTCMonth() + 1);
157
+ const day = pad2(beijingDate.getUTCDate());
158
+ const hour = pad2(beijingDate.getUTCHours());
159
+ const minute = pad2(beijingDate.getUTCMinutes());
160
+ const second = pad2(beijingDate.getUTCSeconds());
161
+ return `${year}-${month}-${day}T${hour}:${minute}:${second}${SHANGHAI_OFFSET_SUFFIX}`;
162
+ }
163
+ import { assertLarkOk, formatLarkError } from "../../core/api-error";
164
+ import { AppScopeMissingError as AppScopeMissingError2, UserAuthRequiredError as UserAuthRequiredError2, UserScopeInsufficientError as UserScopeInsufficientError2 } from "../../core/tool-client";
165
+ function isInvokeError(err) {
166
+ return err instanceof UserAuthRequiredError2 || err instanceof AppScopeMissingError2 || err instanceof UserScopeInsufficientError2;
167
+ }
168
+ import { handleInvokeErrorWithAutoAuth } from "../auto-auth";
169
+ export {
170
+ AppScopeMissingError,
171
+ NeedAuthorizationError,
172
+ SHANGHAI_OFFSET_SUFFIX,
173
+ SHANGHAI_UTC_OFFSET_HOURS,
174
+ ToolClient,
175
+ UserAuthRequiredError,
176
+ UserScopeInsufficientError,
177
+ assertLarkOk,
178
+ convertTimeRange,
179
+ createClientGetter,
180
+ createFeishuClientFromConfig,
181
+ createToolClient,
182
+ createToolContext,
183
+ createToolLogger,
184
+ formatLarkError,
185
+ formatToolError,
186
+ formatToolResult,
187
+ getFirstAccount,
188
+ handleInvokeErrorWithAutoAuth,
189
+ isInvokeError,
190
+ json,
191
+ pad2,
192
+ parseTimeToRFC3339,
193
+ parseTimeToTimestamp,
194
+ parseTimeToTimestampMs,
195
+ unixTimestampToISO8601,
196
+ validateEnum,
197
+ validateRequiredParams
198
+ };
199
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/tools/oapi/helpers.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * OAPI \u5DE5\u5177\u4E13\u7528\u8F85\u52A9\u51FD\u6570\n *\n * \u63D0\u4F9B OAPI \u5DE5\u5177\u7279\u6709\u7684\u529F\u80FD\uFF08\u5982\u65F6\u95F4\u8F6C\u6362\uFF09\uFF0C\u5E76\u590D\u7528\u901A\u7528\u8F85\u52A9\u51FD\u6570\u3002\n */\n\nimport type { ClawdbotConfig } from 'openclaw/plugin-sdk';\nimport type { Client as LarkClient } from '@larksuiteoapi/node-sdk';\n\n// ---------------------------------------------------------------------------\n// \u901A\u7528\u529F\u80FD\uFF08\u4ECE tools/helpers.ts \u5BFC\u5165\uFF09\n// ---------------------------------------------------------------------------\n\nexport {\n formatToolResult,\n formatToolError,\n createToolLogger,\n createClientGetter,\n createToolContext,\n getFirstAccount,\n validateRequiredParams,\n validateEnum,\n} from '../helpers';\n\nexport type { ToolResult, ClientGetter, ToolContext } from '../helpers';\n\n// ---------------------------------------------------------------------------\n// ToolClient\uFF08\u5DE5\u5177\u5C42\u7EDF\u4E00\u5BA2\u6237\u7AEF\uFF09\n// ---------------------------------------------------------------------------\n\nexport {\n ToolClient,\n createToolClient,\n NeedAuthorizationError,\n AppScopeMissingError,\n UserAuthRequiredError,\n UserScopeInsufficientError,\n} from '../../core/tool-client';\nexport type {\n ApiFn,\n InvokeFn,\n InvokeOptions,\n InvokeByPathOptions,\n AuthHint,\n TryInvokeResult,\n} from '../../core/tool-client';\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1A\u5BA2\u6237\u7AEF\u4FBF\u6377\u521B\u5EFA\n// ---------------------------------------------------------------------------\n\nimport { createClientGetter } from '../helpers';\n\n/**\n * \u4ECE\u914D\u7F6E\u76F4\u63A5\u521B\u5EFA\u98DE\u4E66\u5BA2\u6237\u7AEF\uFF08OAPI \u5DE5\u5177\u5E38\u7528\u6A21\u5F0F\uFF09\n *\n * \u8FD9\u662F\u5BF9 createClientGetter \u7684\u7B80\u5316\u5C01\u88C5\uFF0C\u76F4\u63A5\u8FD4\u56DE\u5BA2\u6237\u7AEF\u5B9E\u4F8B\u800C\u975E getter \u51FD\u6570\u3002\n *\n * @param config - OpenClaw \u914D\u7F6E\u5BF9\u8C61\n * @returns \u98DE\u4E66 SDK \u5BA2\u6237\u7AEF\u5B9E\u4F8B\n * @throws \u5982\u679C\u6CA1\u6709\u542F\u7528\u7684\u8D26\u53F7\n *\n * @example\n * ```typescript\n * export function registerMyOapiTool(api: OpenClawPluginApi) {\n * api.registerTool({\n * name: \"my_oapi_tool\",\n * async execute(_toolCallId, params) {\n * const client = createFeishuClientFromConfig(api.config);\n * const res = await client.calendar.calendarEvent.list({ ... });\n * return json(res.data);\n * }\n * });\n * }\n * ```\n */\nexport function createFeishuClientFromConfig(config: ClawdbotConfig): LarkClient {\n const getClient = createClientGetter(config);\n return getClient();\n}\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1A\u8FD4\u56DE\u503C\u683C\u5F0F\u5316\uFF08\u7B80\u5316\u7248\uFF09\n// ---------------------------------------------------------------------------\n\nimport { formatToolResult } from '../helpers';\n\n/**\n * \u683C\u5F0F\u5316\u8FD4\u56DE\u503C\u4E3A JSON\uFF08OAPI \u5DE5\u5177\u5E38\u7528\u7B80\u5316\u63A5\u53E3\uFF09\n *\n * \u8FD9\u662F\u5BF9 formatToolResult \u7684\u7B80\u5316\u5C01\u88C5\uFF0C\u51FD\u6570\u540D\u66F4\u77ED\u4FBF\u4E8E\u9891\u7E41\u4F7F\u7528\u3002\n *\n * @param data - \u8981\u8FD4\u56DE\u7684\u6570\u636E\n * @returns \u683C\u5F0F\u5316\u7684\u5DE5\u5177\u8FD4\u56DE\u503C\n *\n * @example\n * ```typescript\n * return json({ task: taskData });\n * return json({ error: \"Invalid parameter\" });\n * ```\n */\nexport function json(data: unknown) {\n return formatToolResult(data);\n}\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1A\u65F6\u95F4\u8F6C\u6362\u5DE5\u5177\n// ---------------------------------------------------------------------------\n\n/**\n * \u89E3\u6790\u65F6\u95F4\u5B57\u7B26\u4E32\u4E3A Unix \u65F6\u95F4\u6233\uFF08\u79D2\uFF09\n *\n * \u652F\u6301\u591A\u79CD\u683C\u5F0F\uFF1A\n * 1. ISO 8601 / RFC 3339\uFF08\u5E26\u65F6\u533A\uFF09\uFF1A\"2024-01-01T00:00:00+08:00\"\n * 2. \u4E0D\u5E26\u65F6\u533A\u7684\u683C\u5F0F\uFF08\u9ED8\u8BA4\u4E3A\u5317\u4EAC\u65F6\u95F4 UTC+8\uFF09\uFF1A\n * - \"2026-02-25 14:30\"\n * - \"2026-02-25 14:30:00\"\n * - \"2026-02-25T14:30:00\"\n *\n * @param input - \u65F6\u95F4\u5B57\u7B26\u4E32\n * @returns Unix \u65F6\u95F4\u6233\u5B57\u7B26\u4E32\uFF08\u79D2\uFF09\uFF0C\u89E3\u6790\u5931\u8D25\u8FD4\u56DE null\n *\n * @example\n * ```typescript\n * parseTimeToTimestamp(\"2026-02-25T14:30:00+08:00\") // => \"1740459000\"\n * parseTimeToTimestamp(\"2026-02-25 14:30\") // => \"1740459000\" (\u9ED8\u8BA4\u5317\u4EAC\u65F6\u95F4)\n * parseTimeToTimestamp(\"2026-02-25T14:30:00\") // => \"1740459000\" (\u9ED8\u8BA4\u5317\u4EAC\u65F6\u95F4)\n * parseTimeToTimestamp(\"invalid\") // => null\n * ```\n */\nexport function parseTimeToTimestamp(input: string): string | null {\n try {\n const trimmed = input.trim();\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u65F6\u533A\u4FE1\u606F\uFF08Z \u6216 +/- \u504F\u79FB\uFF09\n const hasTimezone = /[Zz]$|[+-]\\d{2}:\\d{2}$/.test(trimmed);\n\n if (hasTimezone) {\n // \u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u76F4\u63A5\u89E3\u6790\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n return Math.floor(date.getTime() / 1000).toString();\n }\n\n // \u6CA1\u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u5F53\u4F5C\u5317\u4EAC\u65F6\u95F4\u5904\u7406\n // \u652F\u6301\u683C\u5F0F\uFF1AYYYY-MM-DD HH:mm \u6216 YYYY-MM-DD HH:mm:ss \u6216 YYYY-MM-DDTHH:mm:ss\n const normalized = trimmed.replace('T', ' ');\n const match = normalized.match(/^(\\d{4})-(\\d{2})-(\\d{2})\\s+(\\d{2}):(\\d{2})(?::(\\d{2}))?$/);\n\n if (!match) {\n // \u5C1D\u8BD5\u76F4\u63A5\u89E3\u6790\uFF08\u53EF\u80FD\u662F\u5176\u4ED6 ISO 8601 \u683C\u5F0F\uFF09\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n return Math.floor(date.getTime() / 1000).toString();\n }\n\n const [, year, month, day, hour, minute, second] = match;\n // \u5F53\u4F5C\u5317\u4EAC\u65F6\u95F4\uFF08UTC+8\uFF09\uFF0C\u8F6C\u6362\u4E3A UTC\n const utcDate = new Date(\n Date.UTC(\n parseInt(year),\n parseInt(month) - 1,\n parseInt(day),\n parseInt(hour) - 8, // \u5317\u4EAC\u65F6\u95F4\u51CF\u53BB 8 \u5C0F\u65F6\u5F97\u5230 UTC\n parseInt(minute),\n parseInt(second ?? '0'),\n ),\n );\n\n return Math.floor(utcDate.getTime() / 1000).toString();\n } catch {\n return null;\n }\n}\n\n/**\n * \u89E3\u6790\u65F6\u95F4\u5B57\u7B26\u4E32\u4E3A Unix \u65F6\u95F4\u6233\uFF08\u6BEB\u79D2\uFF09\n *\n * \u652F\u6301\u591A\u79CD\u683C\u5F0F\uFF1A\n * 1. ISO 8601 / RFC 3339\uFF08\u5E26\u65F6\u533A\uFF09\uFF1A\"2024-01-01T00:00:00+08:00\"\n * 2. \u4E0D\u5E26\u65F6\u533A\u7684\u683C\u5F0F\uFF08\u9ED8\u8BA4\u4E3A\u5317\u4EAC\u65F6\u95F4 UTC+8\uFF09\uFF1A\n * - \"2026-02-25 14:30\"\n * - \"2026-02-25 14:30:00\"\n * - \"2026-02-25T14:30:00\"\n *\n * @param input - \u65F6\u95F4\u5B57\u7B26\u4E32\n * @returns Unix \u65F6\u95F4\u6233\u5B57\u7B26\u4E32\uFF08\u6BEB\u79D2\uFF09\uFF0C\u89E3\u6790\u5931\u8D25\u8FD4\u56DE null\n *\n * @example\n * ```typescript\n * parseTimeToTimestampMs(\"2026-02-25T14:30:00+08:00\") // => \"1740459000000\"\n * parseTimeToTimestampMs(\"2026-02-25 14:30\") // => \"1740459000000\" (\u9ED8\u8BA4\u5317\u4EAC\u65F6\u95F4)\n * parseTimeToTimestampMs(\"2026-02-25T14:30:00\") // => \"1740459000000\" (\u9ED8\u8BA4\u5317\u4EAC\u65F6\u95F4)\n * parseTimeToTimestampMs(\"invalid\") // => null\n * ```\n */\nexport function parseTimeToTimestampMs(input: string): string | null {\n try {\n const trimmed = input.trim();\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u65F6\u533A\u4FE1\u606F\uFF08Z \u6216 +/- \u504F\u79FB\uFF09\n const hasTimezone = /[Zz]$|[+-]\\d{2}:\\d{2}$/.test(trimmed);\n\n if (hasTimezone) {\n // \u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u76F4\u63A5\u89E3\u6790\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n return date.getTime().toString();\n }\n\n // \u6CA1\u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u5F53\u4F5C\u5317\u4EAC\u65F6\u95F4\u5904\u7406\n // \u652F\u6301\u683C\u5F0F\uFF1AYYYY-MM-DD HH:mm \u6216 YYYY-MM-DD HH:mm:ss \u6216 YYYY-MM-DDTHH:mm:ss\n const normalized = trimmed.replace('T', ' ');\n const match = normalized.match(/^(\\d{4})-(\\d{2})-(\\d{2})\\s+(\\d{2}):(\\d{2})(?::(\\d{2}))?$/);\n\n if (!match) {\n // \u5C1D\u8BD5\u76F4\u63A5\u89E3\u6790\uFF08\u53EF\u80FD\u662F\u5176\u4ED6 ISO 8601 \u683C\u5F0F\uFF09\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n return date.getTime().toString();\n }\n\n const [, year, month, day, hour, minute, second] = match;\n // \u5F53\u4F5C\u5317\u4EAC\u65F6\u95F4\uFF08UTC+8\uFF09\uFF0C\u8F6C\u6362\u4E3A UTC\n const utcDate = new Date(\n Date.UTC(\n parseInt(year),\n parseInt(month) - 1,\n parseInt(day),\n parseInt(hour) - 8, // \u5317\u4EAC\u65F6\u95F4\u51CF\u53BB 8 \u5C0F\u65F6\u5F97\u5230 UTC\n parseInt(minute),\n parseInt(second ?? '0'),\n ),\n );\n\n return utcDate.getTime().toString();\n } catch {\n return null;\n }\n}\n\n/**\n * \u89E3\u6790\u65F6\u95F4\u5B57\u7B26\u4E32\u4E3A RFC 3339 \u683C\u5F0F\uFF08\u7528\u4E8E freebusy API\uFF09\n *\n * \u652F\u6301\u591A\u79CD\u683C\u5F0F\uFF1A\n * 1. ISO 8601 / RFC 3339\uFF08\u5E26\u65F6\u533A\uFF09\uFF1A\"2024-01-01T00:00:00+08:00\" - \u76F4\u63A5\u8FD4\u56DE\n * 2. \u4E0D\u5E26\u65F6\u533A\u7684\u683C\u5F0F\uFF08\u9ED8\u8BA4\u4E3A\u5317\u4EAC\u65F6\u95F4 UTC+8\uFF09\uFF1A\n * - \"2026-02-25 14:30\" - \u8F6C\u6362\u4E3A \"2026-02-25T14:30:00+08:00\"\n * - \"2026-02-25 14:30:00\" - \u8F6C\u6362\u4E3A \"2026-02-25T14:30:00+08:00\"\n * - \"2026-02-25T14:30:00\" - \u8F6C\u6362\u4E3A \"2026-02-25T14:30:00+08:00\"\n *\n * @param input - \u65F6\u95F4\u5B57\u7B26\u4E32\n * @returns RFC 3339 \u683C\u5F0F\u7684\u65F6\u95F4\u5B57\u7B26\u4E32\uFF0C\u89E3\u6790\u5931\u8D25\u8FD4\u56DE null\n *\n * @example\n * ```typescript\n * parseTimeToRFC3339(\"2026-02-25T14:30:00+08:00\") // => \"2026-02-25T14:30:00+08:00\"\n * parseTimeToRFC3339(\"2026-02-25 14:30\") // => \"2026-02-25T14:30:00+08:00\"\n * parseTimeToRFC3339(\"2026-02-25T14:30:00\") // => \"2026-02-25T14:30:00+08:00\"\n * ```\n */\nexport function parseTimeToRFC3339(input: string): string | null {\n try {\n const trimmed = input.trim();\n\n // \u68C0\u67E5\u662F\u5426\u5305\u542B\u65F6\u533A\u4FE1\u606F\uFF08Z \u6216 +/- \u504F\u79FB\uFF09\n const hasTimezone = /[Zz]$|[+-]\\d{2}:\\d{2}$/.test(trimmed);\n\n if (hasTimezone) {\n // \u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u9A8C\u8BC1\u540E\u76F4\u63A5\u8FD4\u56DE\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n return trimmed;\n }\n\n // \u6CA1\u6709\u65F6\u533A\u4FE1\u606F\uFF0C\u5F53\u4F5C\u5317\u4EAC\u65F6\u95F4\u5904\u7406\uFF0C\u8F6C\u6362\u4E3A RFC 3339 \u683C\u5F0F\n // \u652F\u6301\u683C\u5F0F\uFF1AYYYY-MM-DD HH:mm \u6216 YYYY-MM-DD HH:mm:ss \u6216 YYYY-MM-DDTHH:mm:ss\n const normalized = trimmed.replace('T', ' ');\n const match = normalized.match(/^(\\d{4})-(\\d{2})-(\\d{2})\\s+(\\d{2}):(\\d{2})(?::(\\d{2}))?$/);\n\n if (!match) {\n // \u5C1D\u8BD5\u76F4\u63A5\u89E3\u6790\uFF08\u53EF\u80FD\u662F\u5176\u4ED6 ISO 8601 \u683C\u5F0F\uFF09\n const date = new Date(trimmed);\n if (isNaN(date.getTime())) return null;\n // \u5982\u679C\u80FD\u89E3\u6790\u4F46\u6CA1\u6709\u65F6\u533A\uFF0C\u6DFB\u52A0 +08:00\n return trimmed.includes('T') ? `${trimmed}+08:00` : trimmed;\n }\n\n const [, year, month, day, hour, minute, second] = match;\n const sec = second ?? '00';\n\n // \u76F4\u63A5\u6784\u9020 RFC 3339 \u683C\u5F0F\uFF08\u5317\u4EAC\u65F6\u95F4 UTC+8\uFF09\n return `${year}-${month}-${day}T${hour}:${minute}:${sec}+08:00`;\n } catch {\n return null;\n }\n}\n\n/**\n * \u8F6C\u6362\u65F6\u95F4\u8303\u56F4\u5BF9\u8C61\uFF08\u7528\u4E8E search \u7B49 API\uFF09\n *\n * \u5C06\u5305\u542B ISO 8601 \u683C\u5F0F\u65F6\u95F4\u5B57\u7B26\u4E32\u7684\u65F6\u95F4\u8303\u56F4\u8F6C\u6362\u4E3A\u65F6\u95F4\u6233\u3002\n *\n * @param timeRange - \u65F6\u95F4\u8303\u56F4\u5BF9\u8C61\uFF0C\u5305\u542B\u53EF\u9009\u7684 start \u548C end \u5B57\u6BB5\n * @param unit - \u65F6\u95F4\u6233\u5355\u4F4D\uFF0C's' \u4E3A\u79D2\uFF0C'ms' \u4E3A\u6BEB\u79D2\uFF0C\u9ED8\u8BA4\u4E3A 's'\n * @returns \u8F6C\u6362\u540E\u7684\u65F6\u95F4\u8303\u56F4\u5BF9\u8C61\uFF0C\u5305\u542B\u6570\u5B57\u7C7B\u578B\u7684\u65F6\u95F4\u6233\n * @throws \u5982\u679C\u65F6\u95F4\u683C\u5F0F\u9519\u8BEF\n *\n * @example\n * ```typescript\n * convertTimeRange({ start: \"2026-02-25T14:00:00+08:00\", end: \"2026-02-25T18:00:00+08:00\" })\n * // => { start: 1740459000, end: 1740473400 }\n *\n * convertTimeRange({ start: \"2026-02-25T14:00:00+08:00\" }, 'ms')\n * // => { start: 1740459000000 }\n * ```\n */\nexport function convertTimeRange(\n timeRange: { start?: string; end?: string } | undefined,\n unit: 's' | 'ms' = 's',\n): { start?: number; end?: number } | undefined {\n if (!timeRange) return undefined;\n\n const result: { start?: number; end?: number } = {};\n const parseFn = unit === 'ms' ? parseTimeToTimestampMs : parseTimeToTimestamp;\n\n if (timeRange.start) {\n const ts = parseFn(timeRange.start);\n if (!ts) {\n throw new Error(\n `Invalid time format for start. Must use ISO 8601 / RFC 3339 with timezone, e.g. \"2024-01-01T00:00:00+08:00\". Received: ${timeRange.start}`,\n );\n }\n result.start = parseInt(ts, 10);\n }\n\n if (timeRange.end) {\n const ts = parseFn(timeRange.end);\n if (!ts) {\n throw new Error(\n `Invalid time format for end. Must use ISO 8601 / RFC 3339 with timezone, e.g. \"2024-01-01T00:00:00+08:00\". Received: ${timeRange.end}`,\n );\n }\n result.end = parseInt(ts, 10);\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1AUnix \u65F6\u95F4\u6233 \u2192 ISO 8601 (\u4E0A\u6D77\u65F6\u533A)\n// ---------------------------------------------------------------------------\n\nexport const SHANGHAI_UTC_OFFSET_HOURS = 8;\nexport const SHANGHAI_OFFSET_SUFFIX = '+08:00';\n\nexport function pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n\n/**\n * Convert a Unix timestamp (seconds or milliseconds) to ISO 8601 string\n * in the Asia/Shanghai timezone.\n *\n * Auto-detects seconds vs milliseconds based on magnitude.\n *\n * @returns e.g. `\"2026-02-25T14:30:00+08:00\"`, or `null` on invalid input\n */\nexport function unixTimestampToISO8601(raw: string | number | undefined): string | null {\n if (raw === undefined || raw === null) return null;\n\n const text = typeof raw === 'number' ? String(raw) : String(raw).trim();\n if (!/^-?\\d+$/.test(text)) return null;\n\n const num = Number(text);\n if (!Number.isFinite(num)) return null;\n\n const utcMs = Math.abs(num) >= 1e12 ? num : num * 1000;\n const beijingDate = new Date(utcMs + SHANGHAI_UTC_OFFSET_HOURS * 60 * 60 * 1000);\n if (Number.isNaN(beijingDate.getTime())) return null;\n\n const year = beijingDate.getUTCFullYear();\n const month = pad2(beijingDate.getUTCMonth() + 1);\n const day = pad2(beijingDate.getUTCDate());\n const hour = pad2(beijingDate.getUTCHours());\n const minute = pad2(beijingDate.getUTCMinutes());\n const second = pad2(beijingDate.getUTCSeconds());\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}${SHANGHAI_OFFSET_SUFFIX}`;\n}\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1A\u98DE\u4E66 API \u9519\u8BEF\u5904\u7406\n// ---------------------------------------------------------------------------\n\n/**\n * Re-export \u98DE\u4E66 API \u9519\u8BEF\u5904\u7406\u51FD\u6570\n *\n * \u8FD9\u4E9B\u51FD\u6570\u4E13\u95E8\u7528\u4E8E\u5904\u7406\u98DE\u4E66 Open API \u7684\u54CD\u5E94\u548C\u9519\u8BEF\u3002\n */\nexport { assertLarkOk, formatLarkError } from '../../core/api-error';\n\n// ---------------------------------------------------------------------------\n// OAPI \u4E13\u7528\uFF1Ainvoke() \u9519\u8BEF\u5224\u65AD\n// ---------------------------------------------------------------------------\n\nimport { AppScopeMissingError, UserAuthRequiredError, UserScopeInsufficientError } from '../../core/tool-client';\n\n/**\n * Check whether an error is a structured invoke-level auth/permission error.\n *\n * Useful in intermediate catch blocks that need to let auth errors bubble up\n * to the outer `handleInvokeErrorWithAutoAuth`.\n *\n * For \"allow-to-fail\" sub-operations, prefer `client.tryInvoke()` over\n * manual `isInvokeError` + throw.\n */\nexport function isInvokeError(err: unknown): boolean {\n return (\n err instanceof UserAuthRequiredError ||\n err instanceof AppScopeMissingError ||\n err instanceof UserScopeInsufficientError\n );\n}\n\n// ---------------------------------------------------------------------------\n// \u81EA\u52A8\u6388\u6743\uFF1AhandleInvokeErrorWithAutoAuth\n// ---------------------------------------------------------------------------\n\nexport { handleInvokeErrorWithAutoAuth } from '../auto-auth';\n"],
5
+ "mappings": "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",
6
+ "names": ["createClientGetter", "formatToolResult", "AppScopeMissingError", "UserAuthRequiredError", "UserScopeInsufficientError"]
7
+ }
@@ -0,0 +1,128 @@
1
+ import { larkLogger } from "../../../core/lark-logger";
2
+ import {
3
+ convertMessageContent,
4
+ buildConvertContextFromItem,
5
+ extractMentionOpenId
6
+ } from "../../../messaging/converters/content-converter";
7
+ import { getUATUserName, setUATUserNames, batchResolveUserNamesAsUser } from "./user-name-uat";
8
+ import { millisStringToDateTime } from "./time-utils";
9
+ const log = larkLogger("oapi/im/format-messages");
10
+ function createUATFetchSubMessages(client) {
11
+ return async (messageId) => {
12
+ const res = await client.invokeByPath("feishu_im_user_get_messages.default", `/open-apis/im/v1/messages/${messageId}`, {
13
+ method: "GET",
14
+ query: { user_id_type: "open_id", card_msg_content_type: "raw_card_content" },
15
+ as: "user"
16
+ });
17
+ if (res.code !== 0) {
18
+ throw new Error(`API error: code=${res.code} msg=${res.msg}`);
19
+ }
20
+ return res.data?.items ?? [];
21
+ };
22
+ }
23
+ async function formatMessageItem(item, accountId, nameResolver, ctxOverrides) {
24
+ const messageId = item.message_id ?? "";
25
+ const msgType = item.msg_type ?? "unknown";
26
+ let content = "";
27
+ try {
28
+ const rawContent = item.body?.content ?? "";
29
+ if (rawContent) {
30
+ const ctx = {
31
+ ...buildConvertContextFromItem(item, messageId, accountId),
32
+ ...ctxOverrides
33
+ };
34
+ const result = await convertMessageContent(rawContent, msgType, ctx);
35
+ content = result.content;
36
+ }
37
+ } catch (err) {
38
+ log.warn("converter failed, falling back to raw content", {
39
+ messageId,
40
+ msgType,
41
+ error: err instanceof Error ? err.message : String(err)
42
+ });
43
+ content = item.body?.content ?? "";
44
+ }
45
+ const senderId = item.sender?.id ?? "";
46
+ const senderType = item.sender?.sender_type ?? "unknown";
47
+ let senderName;
48
+ if (senderId && senderType === "user") {
49
+ senderName = nameResolver(senderId);
50
+ }
51
+ const sender = {
52
+ id: senderId,
53
+ sender_type: senderType
54
+ };
55
+ if (senderName) {
56
+ sender.name = senderName;
57
+ }
58
+ let mentions;
59
+ if (item.mentions && item.mentions.length > 0) {
60
+ mentions = item.mentions.map((m) => ({
61
+ key: m.key ?? "",
62
+ id: extractMentionOpenId(m.id),
63
+ name: m.name ?? ""
64
+ }));
65
+ }
66
+ const createTime = item.create_time ? millisStringToDateTime(item.create_time) : "";
67
+ const formatted = {
68
+ message_id: messageId,
69
+ msg_type: msgType,
70
+ content,
71
+ sender,
72
+ create_time: createTime,
73
+ deleted: item.deleted ?? false,
74
+ updated: item.updated ?? false
75
+ };
76
+ if (item.thread_id) {
77
+ formatted.thread_id = item.thread_id;
78
+ } else if (item.parent_id) {
79
+ formatted.reply_to = item.parent_id;
80
+ }
81
+ if (mentions) {
82
+ formatted.mentions = mentions;
83
+ }
84
+ return formatted;
85
+ }
86
+ async function formatMessageList(items, account, log2, client) {
87
+ const accountId = account.accountId;
88
+ const nameResolver = (openId) => getUATUserName(accountId, openId);
89
+ const mentionNames = /* @__PURE__ */ new Map();
90
+ for (const item of items) {
91
+ for (const m of item.mentions ?? []) {
92
+ const openId = extractMentionOpenId(m.id);
93
+ if (openId && m.name) {
94
+ mentionNames.set(openId, m.name);
95
+ }
96
+ }
97
+ }
98
+ if (mentionNames.size > 0) {
99
+ setUATUserNames(accountId, mentionNames);
100
+ }
101
+ const senderIds = [
102
+ ...new Set(
103
+ items.map((item) => item.sender?.sender_type === "user" ? item.sender.id : void 0).filter((id) => !!id)
104
+ )
105
+ ];
106
+ if (senderIds.length > 0) {
107
+ const missing = senderIds.filter((id) => getUATUserName(accountId, id) === void 0);
108
+ if (missing.length > 0) {
109
+ await batchResolveUserNamesAsUser({ client, openIds: missing, log: log2 });
110
+ }
111
+ }
112
+ const uatBatchResolve = async (openIds) => {
113
+ await batchResolveUserNamesAsUser({ client, openIds, log: log2 });
114
+ };
115
+ const ctxOverrides = {
116
+ account,
117
+ accountId,
118
+ resolveUserName: nameResolver,
119
+ batchResolveNames: uatBatchResolve,
120
+ fetchSubMessages: createUATFetchSubMessages(client)
121
+ };
122
+ return Promise.all(items.map((item) => formatMessageItem(item, accountId, nameResolver, ctxOverrides)));
123
+ }
124
+ export {
125
+ formatMessageItem,
126
+ formatMessageList
127
+ };
128
+ //# sourceMappingURL=format-messages.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/im/format-messages.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u6D88\u606F\u683C\u5F0F\u5316\u516C\u5171\u51FD\u6570\n *\n * \u5C06\u98DE\u4E66 IM API \u8FD4\u56DE\u7684\u539F\u59CB\u6D88\u606F\u5BF9\u8C61\u8F6C\u6362\u4E3A AI \u53EF\u8BFB\u7684 JSON \u683C\u5F0F\u3002\n * \u7531 feishu_im_user_get_messages \u548C feishu_im_user_get_thread_messages \u5171\u4EAB\u3002\n *\n * \u6240\u6709 API \u8C03\u7528\u5747\u901A\u8FC7 UAT\uFF08\u7528\u6237\u8EAB\u4EFD\uFF09\u8FDB\u884C\u3002\n */\n\nimport type { LarkAccount } from '../../../core/types';\nimport type { ToolClient } from '../../../core/tool-client';\nimport type { ApiMessageItem } from '../../../messaging/converters/types';\nimport { larkLogger } from '../../../core/lark-logger';\nimport {\n convertMessageContent,\n buildConvertContextFromItem,\n extractMentionOpenId,\n} from '../../../messaging/converters/content-converter';\nimport { getUATUserName, setUATUserNames, batchResolveUserNamesAsUser } from './user-name-uat';\nimport { millisStringToDateTime } from './time-utils';\n\nconst log = larkLogger('oapi/im/format-messages');\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface FormattedMessage {\n message_id: string;\n msg_type: string;\n content: string;\n sender: { id: string; sender_type: string; name?: string };\n create_time: string;\n /** \u56DE\u590D\u7684\u6D88\u606F ID\uFF08parent_id\uFF09\u3002\u6709 thread_id \u65F6\u7701\u7565\uFF0C\u56E0\u4E3A\u8BDD\u9898\u4E0A\u4E0B\u6587\u53EF\u63A8\u65AD */\n reply_to?: string;\n thread_id?: string;\n mentions?: Array<{ key: string; id: string; name: string }>;\n deleted: boolean;\n updated: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// UAT callbacks for merge_forward expansion\n// ---------------------------------------------------------------------------\n\n/** \u901A\u8FC7 UAT \u83B7\u53D6\u5408\u5E76\u8F6C\u53D1\u5B50\u6D88\u606F */\nfunction createUATFetchSubMessages(client: ToolClient) {\n return async (messageId: string): Promise<ApiMessageItem[]> => {\n const res = await client.invokeByPath<{\n code?: number;\n msg?: string;\n data?: { items?: ApiMessageItem[] };\n }>('feishu_im_user_get_messages.default', `/open-apis/im/v1/messages/${messageId}`, {\n method: 'GET',\n query: { user_id_type: 'open_id', card_msg_content_type: 'raw_card_content' },\n as: 'user',\n });\n if (res.code !== 0) {\n throw new Error(`API error: code=${res.code} msg=${res.msg}`);\n }\n return res.data?.items ?? [];\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * \u683C\u5F0F\u5316\u5355\u6761\u6D88\u606F\u5BF9\u8C61\u3002\n *\n * \u4F7F\u7528 convertMessageContent \u5C06 body.content \u8F6C\u4E3A AI \u53EF\u8BFB\u6587\u672C\uFF0C\n * \u5E76\u8FC7\u6EE4\u6389 AI \u4E0D\u9700\u8981\u7684\u5B57\u6BB5\uFF08upper_message_id\u3001tenant_key \u7B49\uFF09\u3002\n */\nexport async function formatMessageItem(\n item: ApiMessageItem,\n accountId: string,\n nameResolver: (openId: string) => string | undefined,\n ctxOverrides?: Partial<import('../../../messaging/converters/types.js').ConvertContext>,\n): Promise<FormattedMessage> {\n const messageId: string = item.message_id ?? '';\n const msgType: string = item.msg_type ?? 'unknown';\n\n // \u4F7F\u7528 converter \u5904\u7406\u6D88\u606F\u5185\u5BB9\n let content = '';\n try {\n const rawContent: string = item.body?.content ?? '';\n if (rawContent) {\n const ctx = {\n ...buildConvertContextFromItem(item, messageId, accountId),\n ...ctxOverrides,\n };\n const result = await convertMessageContent(rawContent, msgType, ctx);\n content = result.content;\n }\n } catch (err) {\n log.warn('converter failed, falling back to raw content', {\n messageId,\n msgType,\n error: err instanceof Error ? err.message : String(err),\n });\n content = item.body?.content ?? '';\n }\n\n // \u6784\u5EFA sender\uFF08\u4ECE UAT \u7F13\u5B58\u4E2D\u8BFB\u53D6\u540D\u5B57\uFF09\n const senderId: string = item.sender?.id ?? '';\n const senderType: string = item.sender?.sender_type ?? 'unknown';\n let senderName: string | undefined;\n if (senderId && senderType === 'user') {\n senderName = nameResolver(senderId);\n }\n\n const sender: FormattedMessage['sender'] = {\n id: senderId,\n sender_type: senderType,\n };\n if (senderName) {\n sender.name = senderName;\n }\n\n // \u6784\u5EFA mentions\uFF08\u7B80\u5316\u683C\u5F0F\uFF09\n let mentions: FormattedMessage['mentions'];\n if (item.mentions && item.mentions.length > 0) {\n mentions = item.mentions.map((m) => ({\n key: m.key ?? '',\n id: extractMentionOpenId(m.id),\n name: m.name ?? '',\n }));\n }\n\n // \u8F6C\u6362 create_time\uFF08\u98DE\u4E66 API \u8FD4\u56DE\u6BEB\u79D2\u65F6\u95F4\u6233\u5B57\u7B26\u4E32 \u2192 ISO 8601 +08:00\uFF09\n const createTime = item.create_time ? millisStringToDateTime(item.create_time) : '';\n\n const formatted: FormattedMessage = {\n message_id: messageId,\n msg_type: msgType,\n content,\n sender,\n create_time: createTime,\n deleted: item.deleted ?? false,\n updated: item.updated ?? false,\n };\n\n // \u53EF\u9009\u5B57\u6BB5\n // reply_to\uFF08parent_id\uFF09\u548C thread_id \u7684\u5C55\u793A\u903B\u8F91\u53C2\u8003 Go MCP\uFF1A\n // - \u6709 thread_id \u65F6\u53EA\u5C55\u793A thread_id\uFF0C\u7701\u7565 reply_to\uFF08\u8BDD\u9898\u4E0A\u4E0B\u6587\u53EF\u63A8\u65AD\uFF09\n // - \u65E0 thread_id \u4F46\u6709 parent_id \u65F6\uFF0C\u5C55\u793A\u4E3A reply_to\n if (item.thread_id) {\n formatted.thread_id = item.thread_id;\n } else if (item.parent_id) {\n formatted.reply_to = item.parent_id;\n }\n if (mentions) {\n formatted.mentions = mentions;\n }\n\n return formatted;\n}\n\n/**\n * \u6279\u91CF\u683C\u5F0F\u5316\u6D88\u606F\u5217\u8868\uFF08UAT \u8DEF\u5F84\uFF09\u3002\n *\n * \u5148\u6279\u91CF\u89E3\u6790\u6240\u6709 sender \u7684\u540D\u5B57\uFF08\u5199\u5165 UAT \u7F13\u5B58\uFF09\uFF0C\u518D\u9010\u6761\u683C\u5F0F\u5316\u3002\n * \u8FD9\u6837 formatMessageItem \u4E2D\u7684 sender.name \u548C converter \u7684\n * resolveUserName \u90FD\u80FD\u4ECE UAT \u7F13\u5B58\u4E2D\u8BFB\u5230\u540D\u5B57\u3002\n */\nexport async function formatMessageList(\n items: ApiMessageItem[],\n account: LarkAccount,\n log: (...args: unknown[]) => void,\n client: ToolClient,\n): Promise<FormattedMessage[]> {\n const accountId = account.accountId;\n const nameResolver = (openId: string) => getUATUserName(accountId, openId);\n\n // 1. \u628A mention \u81EA\u5E26\u7684\u540D\u5B57\u5199\u5165 UAT \u7F13\u5B58\uFF08\u514D\u8D39\u4FE1\u606F\uFF09\n const mentionNames = new Map<string, string>();\n for (const item of items) {\n for (const m of item.mentions ?? []) {\n const openId = extractMentionOpenId(m.id);\n if (openId && m.name) {\n mentionNames.set(openId, m.name);\n }\n }\n }\n if (mentionNames.size > 0) {\n setUATUserNames(accountId, mentionNames);\n }\n\n // 2. \u6536\u96C6\u6240\u6709 user \u7C7B\u578B sender \u7684 open_id\n const senderIds = [\n ...new Set(\n items\n .map((item) => (item.sender?.sender_type === 'user' ? item.sender.id : undefined))\n .filter((id): id is string => !!id),\n ),\n ];\n\n // 3. \u6279\u91CF\u89E3\u6790 UAT \u7F13\u5B58\u4E2D\u7F3A\u5931\u7684\u540D\u5B57\n if (senderIds.length > 0) {\n const missing = senderIds.filter((id) => getUATUserName(accountId, id) === undefined);\n if (missing.length > 0) {\n await batchResolveUserNamesAsUser({ client, openIds: missing, log });\n }\n }\n\n // 4. \u6784\u5EFA merge_forward \u5C55\u5F00\u6240\u9700\u7684\u56DE\u8C03\n const uatBatchResolve = async (openIds: string[]) => {\n await batchResolveUserNamesAsUser({ client, openIds, log });\n };\n const ctxOverrides = {\n account,\n accountId,\n resolveUserName: nameResolver,\n batchResolveNames: uatBatchResolve,\n fetchSubMessages: createUATFetchSubMessages(client),\n };\n\n // 5. \u9010\u6761\u683C\u5F0F\u5316\n return Promise.all(items.map((item) => formatMessageItem(item, accountId, nameResolver, ctxOverrides)));\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["log"]
7
+ }
@@ -0,0 +1,15 @@
1
+ import { registerFeishuImUserMessageTool } from "./message";
2
+ import { registerFeishuImUserFetchResourceTool } from "./resource";
3
+ import { registerMessageReadTools } from "./message-read";
4
+ function registerFeishuImTools(api) {
5
+ registerFeishuImUserMessageTool(api);
6
+ registerFeishuImUserFetchResourceTool(api);
7
+ registerMessageReadTools(api);
8
+ api.logger.info?.(
9
+ "feishu_im: Registered feishu_im_user_message, feishu_im_user_fetch_resource, feishu_im_user_get_messages, feishu_im_user_get_thread_messages, feishu_im_user_search_messages"
10
+ );
11
+ }
12
+ export {
13
+ registerFeishuImTools
14
+ };
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/tools/oapi/im/index.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * IM Tools Index\n *\n * \u5373\u65F6\u901A\u8BAF\u76F8\u5173\u5DE5\u5177\n */\n\nimport type { OpenClawPluginApi } from 'openclaw/plugin-sdk';\nimport { registerFeishuImUserMessageTool } from './message';\nimport { registerFeishuImUserFetchResourceTool } from './resource';\nimport { registerMessageReadTools } from './message-read';\n\nexport function registerFeishuImTools(api: OpenClawPluginApi) {\n registerFeishuImUserMessageTool(api);\n registerFeishuImUserFetchResourceTool(api);\n registerMessageReadTools(api);\n\n api.logger.info?.(\n 'feishu_im: Registered feishu_im_user_message, feishu_im_user_fetch_resource, feishu_im_user_get_messages, feishu_im_user_get_thread_messages, feishu_im_user_search_messages',\n );\n}\n"],
5
+ "mappings": "AAUA,SAAS,uCAAuC;AAChD,SAAS,6CAA6C;AACtD,SAAS,gCAAgC;AAElC,SAAS,sBAAsB,KAAwB;AAC5D,kCAAgC,GAAG;AACnC,wCAAsC,GAAG;AACzC,2BAAyB,GAAG;AAE5B,MAAI,OAAO;AAAA,IACT;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }