@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,207 @@
1
+ const TOOL_SCOPES = {
2
+ "feishu_bitable_app.create": ["base:app:create"],
3
+ "feishu_bitable_app.get": ["base:app:read"],
4
+ "feishu_bitable_app.list": ["space:document:retrieve"],
5
+ "feishu_bitable_app.patch": ["base:app:update"],
6
+ "feishu_bitable_app.copy": ["base:app:copy"],
7
+ "feishu_bitable_app_table.create": ["base:table:create"],
8
+ "feishu_bitable_app_table.list": ["base:table:read"],
9
+ "feishu_bitable_app_table.patch": ["base:table:update"],
10
+ "feishu_bitable_app_table.delete": ["base:table:delete"],
11
+ "feishu_bitable_app_table.batch_create": ["base:table:create"],
12
+ "feishu_bitable_app_table.batch_delete": ["base:table:delete"],
13
+ "feishu_bitable_app_table_record.create": ["base:record:create"],
14
+ "feishu_bitable_app_table_record.update": ["base:record:update"],
15
+ "feishu_bitable_app_table_record.delete": ["base:record:delete"],
16
+ "feishu_bitable_app_table_record.batch_create": ["base:record:create"],
17
+ "feishu_bitable_app_table_record.batch_update": ["base:record:update"],
18
+ "feishu_bitable_app_table_record.batch_delete": ["base:record:delete"],
19
+ "feishu_bitable_app_table_record.list": ["base:record:retrieve"],
20
+ "feishu_bitable_app_table_field.create": ["base:field:create"],
21
+ "feishu_bitable_app_table_field.list": ["base:field:read"],
22
+ "feishu_bitable_app_table_field.update": ["base:field:read", "base:field:update"],
23
+ "feishu_bitable_app_table_field.delete": ["base:field:delete"],
24
+ "feishu_bitable_app_table_view.create": ["base:view:write_only"],
25
+ "feishu_bitable_app_table_view.get": ["base:view:read"],
26
+ "feishu_bitable_app_table_view.list": ["base:view:read"],
27
+ "feishu_bitable_app_table_view.patch": ["base:view:write_only"],
28
+ "feishu_bitable_app_table_view.delete": ["base:view:write_only"],
29
+ "feishu_calendar_calendar.list": ["calendar:calendar:read"],
30
+ "feishu_calendar_calendar.get": ["calendar:calendar:read"],
31
+ "feishu_calendar_calendar.primary": ["calendar:calendar:read"],
32
+ "feishu_calendar_event.create": ["calendar:calendar.event:create", "calendar:calendar.event:update"],
33
+ "feishu_calendar_event.list": ["calendar:calendar.event:read"],
34
+ "feishu_calendar_event.get": ["calendar:calendar.event:read"],
35
+ "feishu_calendar_event.patch": ["calendar:calendar.event:update"],
36
+ "feishu_calendar_event.delete": ["calendar:calendar.event:delete"],
37
+ "feishu_calendar_event.search": ["calendar:calendar.event:read"],
38
+ "feishu_calendar_event.reply": ["calendar:calendar.event:reply"],
39
+ "feishu_calendar_event.instances": ["calendar:calendar.event:read"],
40
+ "feishu_calendar_event.instance_view": ["calendar:calendar.event:read"],
41
+ "feishu_calendar_event_attendee.create": ["calendar:calendar.event:update"],
42
+ "feishu_calendar_event_attendee.list": ["calendar:calendar.event:read"],
43
+ "feishu_calendar_event_attendee.batch_delete": ["calendar:calendar.event:read", "calendar:calendar.event:update"],
44
+ "feishu_calendar_freebusy.list": ["calendar:calendar.free_busy:read"],
45
+ "feishu_task_task.create": ["task:task:write", "task:task:writeonly"],
46
+ "feishu_task_task.get": ["task:task:read", "task:task:write"],
47
+ "feishu_task_task.list": ["task:task:read", "task:task:write"],
48
+ "feishu_task_task.patch": ["task:task:write", "task:task:writeonly"],
49
+ "feishu_task_tasklist.create": ["task:tasklist:write"],
50
+ "feishu_task_tasklist.get": ["task:tasklist:read", "task:tasklist:write"],
51
+ "feishu_task_tasklist.list": ["task:tasklist:read", "task:tasklist:write"],
52
+ "feishu_task_tasklist.tasks": ["task:tasklist:read", "task:tasklist:write"],
53
+ "feishu_task_tasklist.patch": ["task:tasklist:write"],
54
+ "feishu_task_tasklist.delete": ["task:tasklist:write"],
55
+ "feishu_task_tasklist.add_members": ["task:tasklist:write"],
56
+ "feishu_task_tasklist.remove_members": ["task:tasklist:write"],
57
+ "feishu_task_comment.create": ["task:comment:write"],
58
+ "feishu_task_comment.list": ["task:comment:read", "task:comment:write"],
59
+ "feishu_task_comment.get": ["task:comment:read", "task:comment:write"],
60
+ "feishu_task_subtask.create": ["task:task:write"],
61
+ "feishu_task_subtask.list": ["task:task:read", "task:task:write"],
62
+ "feishu_chat.search": ["im:chat:read"],
63
+ "feishu_chat.get": ["im:chat:read"],
64
+ "feishu_chat_members.default": ["im:chat.members:read"],
65
+ "feishu_drive_file.list": ["space:document:retrieve"],
66
+ "feishu_drive_file.get_meta": ["drive:drive.metadata:readonly"],
67
+ "feishu_drive_file.copy": ["docs:document:copy"],
68
+ "feishu_drive_file.move": ["space:document:move"],
69
+ "feishu_drive_file.delete": ["space:document:delete"],
70
+ "feishu_drive_file.upload": ["drive:file:upload"],
71
+ "feishu_drive_file.download": ["drive:file:download"],
72
+ "feishu_doc_media.download": ["board:whiteboard:node:read", "docs:document.media:download"],
73
+ "feishu_doc_media.insert": ["docx:document:write_only", "docs:document.media:upload"],
74
+ "feishu_doc_comments.list": ["wiki:node:read", "docs:document.comment:read"],
75
+ "feishu_doc_comments.create": ["wiki:node:read", "docs:document.comment:create"],
76
+ "feishu_doc_comments.patch": ["docs:document.comment:update"],
77
+ "feishu_wiki_space.list": ["wiki:space:retrieve"],
78
+ "feishu_wiki_space.get": ["wiki:space:read"],
79
+ "feishu_wiki_space.create": ["wiki:space:write_only"],
80
+ "feishu_wiki_space_node.list": ["wiki:node:retrieve"],
81
+ "feishu_wiki_space_node.get": ["wiki:node:read"],
82
+ "feishu_wiki_space_node.create": ["wiki:node:create"],
83
+ "feishu_wiki_space_node.move": ["wiki:node:move"],
84
+ "feishu_wiki_space_node.copy": ["wiki:node:copy"],
85
+ "feishu_im_user_message.send": ["im:message", "im:message.send_as_user"],
86
+ "feishu_im_user_message.reply": ["im:message", "im:message.send_as_user"],
87
+ "feishu_im_user_fetch_resource.default": [
88
+ "im:message.group_msg:get_as_user",
89
+ "im:message.p2p_msg:get_as_user",
90
+ "im:message:readonly"
91
+ ],
92
+ "feishu_im_user_get_messages.default": [
93
+ "im:chat:read",
94
+ "im:message:readonly",
95
+ "im:message.group_msg:get_as_user",
96
+ "im:message.p2p_msg:get_as_user",
97
+ "contact:contact.base:readonly",
98
+ "contact:user.base:readonly"
99
+ ],
100
+ "feishu_im_user_search_messages.default": [
101
+ "im:chat:read",
102
+ "im:message:readonly",
103
+ "im:message.group_msg:get_as_user",
104
+ "im:message.p2p_msg:get_as_user",
105
+ "contact:contact.base:readonly",
106
+ "contact:user.base:readonly",
107
+ "search:message"
108
+ ],
109
+ "feishu_search_doc_wiki.search": ["search:docs:read"],
110
+ "feishu_get_user.default": ["contact:contact.base:readonly", "contact:user.base:readonly"],
111
+ "feishu_search_user.default": ["contact:user:search"],
112
+ "feishu_create_doc.default": [
113
+ "board:whiteboard:node:create",
114
+ "docx:document:create",
115
+ "docx:document:readonly",
116
+ "docx:document:write_only",
117
+ "wiki:node:create",
118
+ "wiki:node:read",
119
+ "docs:document.media:upload"
120
+ ],
121
+ "feishu_fetch_doc.default": ["docx:document:readonly", "wiki:node:read"],
122
+ "feishu_update_doc.default": [
123
+ "board:whiteboard:node:create",
124
+ "docx:document:create",
125
+ "docx:document:readonly",
126
+ "docx:document:write_only"
127
+ ],
128
+ "feishu_sheet.info": ["sheets:spreadsheet.meta:read", "sheets:spreadsheet:read"],
129
+ "feishu_sheet.read": ["sheets:spreadsheet.meta:read", "sheets:spreadsheet:read"],
130
+ "feishu_sheet.write": [
131
+ "sheets:spreadsheet.meta:read",
132
+ "sheets:spreadsheet:read",
133
+ "sheets:spreadsheet:create",
134
+ "sheets:spreadsheet:write_only"
135
+ ],
136
+ "feishu_sheet.append": [
137
+ "sheets:spreadsheet.meta:read",
138
+ "sheets:spreadsheet:read",
139
+ "sheets:spreadsheet:create",
140
+ "sheets:spreadsheet:write_only"
141
+ ],
142
+ "feishu_sheet.find": ["sheets:spreadsheet.meta:read", "sheets:spreadsheet:read"],
143
+ "feishu_sheet.create": [
144
+ "sheets:spreadsheet.meta:read",
145
+ "sheets:spreadsheet:read",
146
+ "sheets:spreadsheet:create",
147
+ "sheets:spreadsheet:write_only"
148
+ ],
149
+ "feishu_sheet.export": ["docs:document:export"]
150
+ };
151
+ const REQUIRED_APP_SCOPES = [
152
+ "contact:contact.base:readonly",
153
+ "docx:document:readonly",
154
+ "im:chat:read",
155
+ "im:chat:update",
156
+ "im:message.group_at_msg:readonly",
157
+ "im:message.p2p_msg:readonly",
158
+ "im:message.pins:read",
159
+ "im:message.pins:write_only",
160
+ "im:message.reactions:read",
161
+ "im:message.reactions:write_only",
162
+ "im:message:readonly",
163
+ "im:message:recall",
164
+ "im:message:send_as_bot",
165
+ "im:message:send_multi_users",
166
+ "im:message:send_sys_msg",
167
+ "im:message:update",
168
+ "im:resource",
169
+ "application:application:self_manage",
170
+ "cardkit:card:write",
171
+ "cardkit:card:read"
172
+ ];
173
+ const REQUIRED_SCOPE_DESCRIPTIONS = {
174
+ "contact:contact.base:readonly": "\u83B7\u53D6\u7528\u6237\u57FA\u672C\u4FE1\u606F\uFF08\u59D3\u540D\u3001\u5934\u50CF\uFF09",
175
+ "docx:document:readonly": "\u8BFB\u53D6\u6587\u6863\u5185\u5BB9\u3001\u9884\u89C8\u6587\u6863\u94FE\u63A5",
176
+ "im:chat:read": "\u8BFB\u53D6\u7FA4\u804A\u4FE1\u606F\u3001\u83B7\u53D6\u7FA4\u6210\u5458\u5217\u8868",
177
+ "im:chat:update": "\u4FEE\u6539\u7FA4\u804A\u8BBE\u7F6E\uFF08\u7FA4\u540D\u79F0\u3001\u7FA4\u516C\u544A\u7B49\uFF09",
178
+ "im:message.group_at_msg:readonly": "\u63A5\u6536\u7FA4\u804A\u4E2D @ \u673A\u5668\u4EBA\u7684\u6D88\u606F",
179
+ "im:message.p2p_msg:readonly": "\u63A5\u6536\u79C1\u804A\u6D88\u606F",
180
+ "im:message.pins:read": "\u8BFB\u53D6\u6D88\u606F\u7F6E\u9876\u72B6\u6001",
181
+ "im:message.pins:write_only": "\u7F6E\u9876/\u53D6\u6D88\u7F6E\u9876\u6D88\u606F",
182
+ "im:message.reactions:read": "\u8BFB\u53D6\u6D88\u606F\u8868\u60C5\u56DE\u590D",
183
+ "im:message.reactions:write_only": "\u6DFB\u52A0/\u5220\u9664\u6D88\u606F\u8868\u60C5\u56DE\u590D",
184
+ "im:message:readonly": "\u8BFB\u53D6\u6D88\u606F\u5185\u5BB9\u3001\u5386\u53F2\u6D88\u606F",
185
+ "im:message:recall": "\u21A9\u64A4\u56DE\u673A\u5668\u4EBA\u53D1\u9001\u7684\u6D88\u606F",
186
+ "im:message:send_as_bot": "\u4EE5\u673A\u5668\u4EBA\u8EAB\u4EFD\u53D1\u9001\u6D88\u606F",
187
+ "im:message:send_multi_users": "\u6279\u91CF\u53D1\u9001\u79C1\u804A\u6D88\u606F",
188
+ "im:message:send_sys_msg": "\u53D1\u9001\u7CFB\u7EDF\u901A\u77E5\u6D88\u606F",
189
+ "im:message:update": "\u66F4\u65B0/\u7F16\u8F91\u5DF2\u53D1\u9001\u7684\u6D88\u606F",
190
+ "im:resource": "\u4E0A\u4F20/\u4E0B\u8F7D\u6D88\u606F\u8D44\u6E90\uFF08\u56FE\u7247\u3001\u6587\u4EF6\u7B49\uFF09",
191
+ "application:application:self_manage": "\u67E5\u8BE2\u5E94\u7528\u81EA\u8EAB\u6743\u9650\u72B6\u6001\uFF08\u8BCA\u65AD\u57FA\u7840\uFF09",
192
+ "cardkit:card:write": "\u521B\u5EFA\u548C\u66F4\u65B0\u6D88\u606F\u5361\u7247",
193
+ "cardkit:card:read": "\u8BFB\u53D6\u6D88\u606F\u5361\u7247\u72B6\u6001"
194
+ };
195
+ const SENSITIVE_SCOPES = ["im:message.send_as_user"];
196
+ function filterSensitiveScopes(scopes) {
197
+ const sensitiveSet = new Set(SENSITIVE_SCOPES);
198
+ return scopes.filter((scope) => !sensitiveSet.has(scope));
199
+ }
200
+ export {
201
+ REQUIRED_APP_SCOPES,
202
+ REQUIRED_SCOPE_DESCRIPTIONS,
203
+ SENSITIVE_SCOPES,
204
+ TOOL_SCOPES,
205
+ filterSensitiveScopes
206
+ };
207
+ //# sourceMappingURL=tool-scopes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/tool-scopes.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Tool Scopes \u914D\u7F6E\n *\n * \u5B9A\u4E49\u6240\u6709\u5DE5\u5177\u52A8\u4F5C\u6240\u9700\u7684\u98DE\u4E66\u6743\u9650\u6620\u5C04\u3002\n *\n * ## \u7EF4\u62A4\u65B9\u5F0F\n *\n * \u26A0\uFE0F \u6B64\u6587\u4EF6\u91C7\u7528**\u624B\u52A8\u7EF4\u62A4**\uFF0C\u65B0\u589E\u6216\u4FEE\u6539\u5DE5\u5177\u65F6\u9700\u540C\u6B65\u66F4\u65B0\u3002\n *\n * ### \u65B0\u589E\u5DE5\u5177\u52A8\u4F5C\n *\n * 1. \u5728 `ToolActionKey` \u7C7B\u578B\u4E2D\u6DFB\u52A0\u65B0\u952E\uFF1A\n * ```typescript\n * export type ToolActionKey =\n * | \"feishu_calendar_event.create\"\n * | \"feishu_new_tool.action\" // \u65B0\u589E\n * ```\n *\n * 2. \u5728 `TOOL_SCOPES` \u5BF9\u8C61\u4E2D\u6DFB\u52A0\u5BF9\u5E94\u914D\u7F6E\uFF1A\n * ```typescript\n * export const TOOL_SCOPES: ToolScopeMapping = {\n * \"feishu_new_tool.action\": [\n * \"required:scope:here\"\n * ],\n * };\n * ```\n *\n * 3. \u8FD0\u884C TypeScript \u7C7B\u578B\u68C0\u67E5\u9A8C\u8BC1\u4E00\u81F4\u6027\uFF1A\n * ```bash\n * cd openclaw/feishu && npx tsc --noEmit\n * ```\n *\n * ### \u5982\u4F55\u786E\u5B9A\u6240\u9700 Scope\n *\n * 1. **\u67E5\u9605\u98DE\u4E66\u5F00\u653E\u5E73\u53F0 API \u6587\u6863**\uFF1Ahttps://open.feishu.cn/document\n * 2. **\u4F7F\u7528 feishu-oapi-search skill**\uFF1A\u5728 Claude Code \u4E2D\u641C\u7D22 API \u6587\u6863\n * 3. **\u53C2\u8003\u7C7B\u4F3C\u5DE5\u5177**\uFF1A\u67E5\u770B\u529F\u80FD\u76F8\u8FD1\u7684\u5DE5\u5177\u7684 scope \u914D\u7F6E\n * 4. **\u5B9E\u9645\u6D4B\u8BD5**\uFF1A\u89C2\u5BDF API \u8C03\u7528\u7684\u9519\u8BEF\u7801\uFF08LARK_ERROR.APP_SCOPE_MISSING/99991672=\u5E94\u7528\u7F3A\u6743\u9650\uFF0CLARK_ERROR.USER_SCOPE_INSUFFICIENT/99991679=\u7528\u6237\u7F3A\u6388\u6743\uFF09\n *\n * \u6700\u540E\u66F4\u65B0: 2026-03-03\n */\n\n// ===== \u7C7B\u578B\u5B9A\u4E49 =====\n\n/**\n * \u6240\u6709\u53EF\u7528\u7684\u5DE5\u5177\u52A8\u4F5C\u952E\n *\n * \u683C\u5F0F\uFF1A{tool_name}.{action_name}\n *\n * \u793A\u4F8B\uFF1A\n * - \"feishu_calendar_event.create\"\n * - \"feishu_bitable_app_table_record.update\"\n *\n * \u603B\u8BA1\uFF1A98 \u4E2A\u5DE5\u5177\u52A8\u4F5C\n */\nexport type ToolActionKey =\n | 'feishu_bitable_app.copy'\n | 'feishu_bitable_app.create'\n | 'feishu_bitable_app.get'\n | 'feishu_bitable_app.list'\n | 'feishu_bitable_app.patch'\n | 'feishu_bitable_app_table.batch_create'\n | 'feishu_bitable_app_table.batch_delete'\n | 'feishu_bitable_app_table.create'\n | 'feishu_bitable_app_table.delete'\n | 'feishu_bitable_app_table.list'\n | 'feishu_bitable_app_table.patch'\n | 'feishu_bitable_app_table_field.create'\n | 'feishu_bitable_app_table_field.delete'\n | 'feishu_bitable_app_table_field.list'\n | 'feishu_bitable_app_table_field.update'\n | 'feishu_bitable_app_table_record.batch_create'\n | 'feishu_bitable_app_table_record.batch_delete'\n | 'feishu_bitable_app_table_record.batch_update'\n | 'feishu_bitable_app_table_record.create'\n | 'feishu_bitable_app_table_record.delete'\n | 'feishu_bitable_app_table_record.list'\n | 'feishu_bitable_app_table_record.update'\n | 'feishu_bitable_app_table_view.create'\n | 'feishu_bitable_app_table_view.delete'\n | 'feishu_bitable_app_table_view.get'\n | 'feishu_bitable_app_table_view.list'\n | 'feishu_bitable_app_table_view.patch'\n | 'feishu_calendar_calendar.get'\n | 'feishu_calendar_calendar.list'\n | 'feishu_calendar_calendar.primary'\n | 'feishu_calendar_event.create'\n | 'feishu_calendar_event.delete'\n | 'feishu_calendar_event.get'\n | 'feishu_calendar_event.instance_view'\n | 'feishu_calendar_event.instances'\n | 'feishu_calendar_event.list'\n | 'feishu_calendar_event.patch'\n | 'feishu_calendar_event.reply'\n | 'feishu_calendar_event.search'\n | 'feishu_calendar_event_attendee.batch_delete'\n | 'feishu_calendar_event_attendee.create'\n | 'feishu_calendar_event_attendee.list'\n | 'feishu_calendar_freebusy.list'\n | 'feishu_chat.get'\n | 'feishu_chat.search'\n | 'feishu_chat_members.default'\n | 'feishu_create_doc.default'\n | 'feishu_doc_comments.create'\n | 'feishu_doc_comments.list'\n | 'feishu_doc_comments.patch'\n | 'feishu_doc_media.download'\n | 'feishu_doc_media.insert'\n | 'feishu_drive_file.copy'\n | 'feishu_drive_file.delete'\n | 'feishu_drive_file.download'\n | 'feishu_drive_file.get_meta'\n | 'feishu_drive_file.list'\n | 'feishu_drive_file.move'\n | 'feishu_drive_file.upload'\n | 'feishu_fetch_doc.default'\n | 'feishu_get_user.default'\n | 'feishu_im_user_fetch_resource.default'\n | 'feishu_im_user_get_messages.default'\n | 'feishu_im_user_message.reply'\n | 'feishu_im_user_message.send'\n | 'feishu_im_user_search_messages.default'\n | 'feishu_search_doc_wiki.search'\n | 'feishu_search_user.default'\n | 'feishu_task_comment.create'\n | 'feishu_task_comment.get'\n | 'feishu_task_comment.list'\n | 'feishu_task_subtask.create'\n | 'feishu_task_subtask.list'\n | 'feishu_task_task.create'\n | 'feishu_task_task.get'\n | 'feishu_task_task.list'\n | 'feishu_task_task.patch'\n | 'feishu_task_tasklist.add_members'\n | 'feishu_task_tasklist.create'\n | 'feishu_task_tasklist.delete'\n | 'feishu_task_tasklist.get'\n | 'feishu_task_tasklist.list'\n | 'feishu_task_tasklist.patch'\n | 'feishu_task_tasklist.remove_members'\n | 'feishu_task_tasklist.tasks'\n | 'feishu_update_doc.default'\n | 'feishu_wiki_space.create'\n | 'feishu_wiki_space.get'\n | 'feishu_wiki_space.list'\n | 'feishu_wiki_space_node.copy'\n | 'feishu_wiki_space_node.create'\n | 'feishu_wiki_space_node.get'\n | 'feishu_wiki_space_node.list'\n | 'feishu_wiki_space_node.move'\n | 'feishu_sheet.info'\n | 'feishu_sheet.read'\n | 'feishu_sheet.write'\n | 'feishu_sheet.append'\n | 'feishu_sheet.find'\n | 'feishu_sheet.create'\n | 'feishu_sheet.export';\n/**\n * Tool Scope \u6620\u5C04\u7C7B\u578B\n *\n * \u5C06\u6BCF\u4E2A ToolActionKey \u6620\u5C04\u5230\u5176\u6240\u9700\u7684 scope \u6570\u7EC4\n */\nexport type ToolScopeMapping = Record<ToolActionKey, string[]>;\n\n// ===== \u6570\u636E =====\n\n/**\n * Tool Scope \u6570\u636E\n *\n * \u6BCF\u4E2A\u5DE5\u5177\u52A8\u4F5C\u6240\u9700\u7684\u98DE\u4E66\u6743\u9650\u5217\u8868\uFF08Required Scopes\uFF09\n *\n * ## \u6570\u636E\u8BF4\u660E\n *\n * - \u7A7A\u6570\u7EC4 `[]` \u8868\u793A\u8BE5\u5DE5\u5177\u52A8\u4F5C\u4E0D\u9700\u8981\u4EFB\u4F55\u6743\u9650\n * - \u591A\u4E2A\u6743\u9650\u8868\u793A\u9700\u8981\u540C\u65F6\u62E5\u6709\u6240\u6709\u6743\u9650\uFF08AND \u5173\u7CFB\uFF09\n * - \u6240\u6709 scope \u90FD\u662F user scopes\uFF08\u7528\u6237\u7EA7\u6743\u9650\uFF09\n *\n * ## \u793A\u4F8B\n *\n * ```typescript\n * TOOL_SCOPES[\"feishu_calendar_event.create\"]\n * // \u8FD4\u56DE: [\"calendar:calendar.event:create\", \"calendar:calendar.event:update\"]\n * ```\n *\n * @see {@link ToolActionKey} \u6240\u6709\u53EF\u7528\u7684\u5DE5\u5177\u52A8\u4F5C\u952E\n */\nexport const TOOL_SCOPES: ToolScopeMapping = {\n 'feishu_bitable_app.create': ['base:app:create'],\n 'feishu_bitable_app.get': ['base:app:read'],\n 'feishu_bitable_app.list': ['space:document:retrieve'],\n 'feishu_bitable_app.patch': ['base:app:update'],\n 'feishu_bitable_app.copy': ['base:app:copy'],\n 'feishu_bitable_app_table.create': ['base:table:create'],\n 'feishu_bitable_app_table.list': ['base:table:read'],\n 'feishu_bitable_app_table.patch': ['base:table:update'],\n 'feishu_bitable_app_table.delete': ['base:table:delete'],\n 'feishu_bitable_app_table.batch_create': ['base:table:create'],\n 'feishu_bitable_app_table.batch_delete': ['base:table:delete'],\n 'feishu_bitable_app_table_record.create': ['base:record:create'],\n 'feishu_bitable_app_table_record.update': ['base:record:update'],\n 'feishu_bitable_app_table_record.delete': ['base:record:delete'],\n 'feishu_bitable_app_table_record.batch_create': ['base:record:create'],\n 'feishu_bitable_app_table_record.batch_update': ['base:record:update'],\n 'feishu_bitable_app_table_record.batch_delete': ['base:record:delete'],\n 'feishu_bitable_app_table_record.list': ['base:record:retrieve'],\n 'feishu_bitable_app_table_field.create': ['base:field:create'],\n 'feishu_bitable_app_table_field.list': ['base:field:read'],\n 'feishu_bitable_app_table_field.update': ['base:field:read', 'base:field:update'],\n 'feishu_bitable_app_table_field.delete': ['base:field:delete'],\n 'feishu_bitable_app_table_view.create': ['base:view:write_only'],\n 'feishu_bitable_app_table_view.get': ['base:view:read'],\n 'feishu_bitable_app_table_view.list': ['base:view:read'],\n 'feishu_bitable_app_table_view.patch': ['base:view:write_only'],\n 'feishu_bitable_app_table_view.delete': ['base:view:write_only'],\n 'feishu_calendar_calendar.list': ['calendar:calendar:read'],\n 'feishu_calendar_calendar.get': ['calendar:calendar:read'],\n 'feishu_calendar_calendar.primary': ['calendar:calendar:read'],\n 'feishu_calendar_event.create': ['calendar:calendar.event:create', 'calendar:calendar.event:update'],\n 'feishu_calendar_event.list': ['calendar:calendar.event:read'],\n 'feishu_calendar_event.get': ['calendar:calendar.event:read'],\n 'feishu_calendar_event.patch': ['calendar:calendar.event:update'],\n 'feishu_calendar_event.delete': ['calendar:calendar.event:delete'],\n 'feishu_calendar_event.search': ['calendar:calendar.event:read'],\n 'feishu_calendar_event.reply': ['calendar:calendar.event:reply'],\n 'feishu_calendar_event.instances': ['calendar:calendar.event:read'],\n 'feishu_calendar_event.instance_view': ['calendar:calendar.event:read'],\n 'feishu_calendar_event_attendee.create': ['calendar:calendar.event:update'],\n 'feishu_calendar_event_attendee.list': ['calendar:calendar.event:read'],\n 'feishu_calendar_event_attendee.batch_delete': ['calendar:calendar.event:read', 'calendar:calendar.event:update'],\n 'feishu_calendar_freebusy.list': ['calendar:calendar.free_busy:read'],\n 'feishu_task_task.create': ['task:task:write', 'task:task:writeonly'],\n 'feishu_task_task.get': ['task:task:read', 'task:task:write'],\n 'feishu_task_task.list': ['task:task:read', 'task:task:write'],\n 'feishu_task_task.patch': ['task:task:write', 'task:task:writeonly'],\n 'feishu_task_tasklist.create': ['task:tasklist:write'],\n 'feishu_task_tasklist.get': ['task:tasklist:read', 'task:tasklist:write'],\n 'feishu_task_tasklist.list': ['task:tasklist:read', 'task:tasklist:write'],\n 'feishu_task_tasklist.tasks': ['task:tasklist:read', 'task:tasklist:write'],\n 'feishu_task_tasklist.patch': ['task:tasklist:write'],\n 'feishu_task_tasklist.delete': ['task:tasklist:write'],\n 'feishu_task_tasklist.add_members': ['task:tasklist:write'],\n 'feishu_task_tasklist.remove_members': ['task:tasklist:write'],\n 'feishu_task_comment.create': ['task:comment:write'],\n 'feishu_task_comment.list': ['task:comment:read', 'task:comment:write'],\n 'feishu_task_comment.get': ['task:comment:read', 'task:comment:write'],\n 'feishu_task_subtask.create': ['task:task:write'],\n 'feishu_task_subtask.list': ['task:task:read', 'task:task:write'],\n 'feishu_chat.search': ['im:chat:read'],\n 'feishu_chat.get': ['im:chat:read'],\n 'feishu_chat_members.default': ['im:chat.members:read'],\n 'feishu_drive_file.list': ['space:document:retrieve'],\n 'feishu_drive_file.get_meta': ['drive:drive.metadata:readonly'],\n 'feishu_drive_file.copy': ['docs:document:copy'],\n 'feishu_drive_file.move': ['space:document:move'],\n 'feishu_drive_file.delete': ['space:document:delete'],\n 'feishu_drive_file.upload': ['drive:file:upload'],\n 'feishu_drive_file.download': ['drive:file:download'],\n 'feishu_doc_media.download': ['board:whiteboard:node:read', 'docs:document.media:download'],\n 'feishu_doc_media.insert': ['docx:document:write_only', 'docs:document.media:upload'],\n 'feishu_doc_comments.list': ['wiki:node:read', 'docs:document.comment:read'],\n 'feishu_doc_comments.create': ['wiki:node:read', 'docs:document.comment:create'],\n 'feishu_doc_comments.patch': ['docs:document.comment:update'],\n 'feishu_wiki_space.list': ['wiki:space:retrieve'],\n 'feishu_wiki_space.get': ['wiki:space:read'],\n 'feishu_wiki_space.create': ['wiki:space:write_only'],\n 'feishu_wiki_space_node.list': ['wiki:node:retrieve'],\n 'feishu_wiki_space_node.get': ['wiki:node:read'],\n 'feishu_wiki_space_node.create': ['wiki:node:create'],\n 'feishu_wiki_space_node.move': ['wiki:node:move'],\n 'feishu_wiki_space_node.copy': ['wiki:node:copy'],\n 'feishu_im_user_message.send': ['im:message', 'im:message.send_as_user'],\n 'feishu_im_user_message.reply': ['im:message', 'im:message.send_as_user'],\n 'feishu_im_user_fetch_resource.default': [\n 'im:message.group_msg:get_as_user',\n 'im:message.p2p_msg:get_as_user',\n 'im:message:readonly',\n ],\n 'feishu_im_user_get_messages.default': [\n 'im:chat:read',\n 'im:message:readonly',\n 'im:message.group_msg:get_as_user',\n 'im:message.p2p_msg:get_as_user',\n 'contact:contact.base:readonly',\n 'contact:user.base:readonly',\n ],\n 'feishu_im_user_search_messages.default': [\n 'im:chat:read',\n 'im:message:readonly',\n 'im:message.group_msg:get_as_user',\n 'im:message.p2p_msg:get_as_user',\n 'contact:contact.base:readonly',\n 'contact:user.base:readonly',\n 'search:message',\n ],\n 'feishu_search_doc_wiki.search': ['search:docs:read'],\n 'feishu_get_user.default': ['contact:contact.base:readonly', 'contact:user.base:readonly'],\n 'feishu_search_user.default': ['contact:user:search'],\n 'feishu_create_doc.default': [\n 'board:whiteboard:node:create',\n 'docx:document:create',\n 'docx:document:readonly',\n 'docx:document:write_only',\n 'wiki:node:create',\n 'wiki:node:read',\n 'docs:document.media:upload',\n ],\n 'feishu_fetch_doc.default': ['docx:document:readonly', 'wiki:node:read'],\n 'feishu_update_doc.default': [\n 'board:whiteboard:node:create',\n 'docx:document:create',\n 'docx:document:readonly',\n 'docx:document:write_only',\n ],\n 'feishu_sheet.info': ['sheets:spreadsheet.meta:read', 'sheets:spreadsheet:read'],\n 'feishu_sheet.read': ['sheets:spreadsheet.meta:read', 'sheets:spreadsheet:read'],\n 'feishu_sheet.write': [\n 'sheets:spreadsheet.meta:read',\n 'sheets:spreadsheet:read',\n 'sheets:spreadsheet:create',\n 'sheets:spreadsheet:write_only',\n ],\n 'feishu_sheet.append': [\n 'sheets:spreadsheet.meta:read',\n 'sheets:spreadsheet:read',\n 'sheets:spreadsheet:create',\n 'sheets:spreadsheet:write_only',\n ],\n 'feishu_sheet.find': ['sheets:spreadsheet.meta:read', 'sheets:spreadsheet:read'],\n 'feishu_sheet.create': [\n 'sheets:spreadsheet.meta:read',\n 'sheets:spreadsheet:read',\n 'sheets:spreadsheet:create',\n 'sheets:spreadsheet:write_only',\n ],\n 'feishu_sheet.export': ['docs:document:export'],\n} as const;\n\n// ===== \u5FC5\u9700\u7684\u5E94\u7528\u8EAB\u4EFD\u6743\u9650 =====\n\n/**\n * \u98DE\u4E66\u63D2\u4EF6\u8FD0\u884C\u5FC5\u987B\u5F00\u901A\u7684\u5E94\u7528\u8EAB\u4EFD\u6743\u9650\u6E05\u5355\n *\n * \u8FD9\u4E9B\u6743\u9650\u662F\u63D2\u4EF6\u57FA\u7840\u529F\u80FD\uFF08\u6D88\u606F\u63A5\u6536\u3001\u5361\u7247\u4EA4\u4E92\u3001\u57FA\u672C\u4FE1\u606F\u67E5\u8BE2\u7B49\uFF09\u6240\u5FC5\u9700\u7684\uFF0C\n * \u5982\u679C\u7F3A\u5931\u8FD9\u4E9B\u6743\u9650\uFF0C\u63D2\u4EF6\u5C06\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C\u3002\n *\n * \u6743\u9650\u5206\u7C7B\uFF1A\n * - im:message.* - \u6D88\u606F\u63A5\u6536\u548C\u53D1\u9001\n * - im:chat.* - \u7FA4\u804A\u7BA1\u7406\n * - im:resource - \u6D88\u606F\u8D44\u6E90\uFF08\u56FE\u7247\u3001\u6587\u4EF6\u7B49\uFF09\n * - cardkit:card.* - \u5361\u7247\u4EA4\u4E92\n * - application:application:self_manage - \u5E94\u7528\u81EA\u8EAB\u6743\u9650\u67E5\u8BE2\uFF08\u6743\u9650\u68C0\u67E5\u57FA\u7840\uFF09\n * - contact:contact.base:readonly - \u901A\u8BAF\u5F55\u57FA\u7840\u4FE1\u606F\n * - docx:document:readonly - \u6587\u6863\u57FA\u7840\u53EA\u8BFB\uFF08\u6587\u6863\u94FE\u63A5\u9884\u89C8\u7B49\uFF09\n *\n * \u6700\u540E\u66F4\u65B0: 2026-03-03\n */\nexport const REQUIRED_APP_SCOPES = [\n 'contact:contact.base:readonly',\n 'docx:document:readonly',\n 'im:chat:read',\n 'im:chat:update',\n 'im:message.group_at_msg:readonly',\n 'im:message.p2p_msg:readonly',\n 'im:message.pins:read',\n 'im:message.pins:write_only',\n 'im:message.reactions:read',\n 'im:message.reactions:write_only',\n 'im:message:readonly',\n 'im:message:recall',\n 'im:message:send_as_bot',\n 'im:message:send_multi_users',\n 'im:message:send_sys_msg',\n 'im:message:update',\n 'im:resource',\n 'application:application:self_manage',\n 'cardkit:card:write',\n 'cardkit:card:read',\n] as const;\n\n/**\n * \u5FC5\u9700\u5E94\u7528\u6743\u9650\u7C7B\u578B\n */\nexport type RequiredAppScope = (typeof REQUIRED_APP_SCOPES)[number];\n\n/**\n * \u5FC5\u9700\u6743\u9650\u7528\u9014\u8BF4\u660E\n *\n * \u63CF\u8FF0\u6BCF\u4E2A\u5FC5\u9700\u6743\u9650\u7684\u5177\u4F53\u7528\u9014\uFF0C\u5E2E\u52A9\u7BA1\u7406\u5458\u7406\u89E3\u4E3A\u4EC0\u4E48\u9700\u8981\u5F00\u901A\u8BE5\u6743\u9650\u3002\n */\nexport const REQUIRED_SCOPE_DESCRIPTIONS: Record<RequiredAppScope, string> = {\n 'contact:contact.base:readonly': '\u83B7\u53D6\u7528\u6237\u57FA\u672C\u4FE1\u606F\uFF08\u59D3\u540D\u3001\u5934\u50CF\uFF09',\n 'docx:document:readonly': '\u8BFB\u53D6\u6587\u6863\u5185\u5BB9\u3001\u9884\u89C8\u6587\u6863\u94FE\u63A5',\n 'im:chat:read': '\u8BFB\u53D6\u7FA4\u804A\u4FE1\u606F\u3001\u83B7\u53D6\u7FA4\u6210\u5458\u5217\u8868',\n 'im:chat:update': '\u4FEE\u6539\u7FA4\u804A\u8BBE\u7F6E\uFF08\u7FA4\u540D\u79F0\u3001\u7FA4\u516C\u544A\u7B49\uFF09',\n 'im:message.group_at_msg:readonly': '\u63A5\u6536\u7FA4\u804A\u4E2D @ \u673A\u5668\u4EBA\u7684\u6D88\u606F',\n 'im:message.p2p_msg:readonly': '\u63A5\u6536\u79C1\u804A\u6D88\u606F',\n 'im:message.pins:read': '\u8BFB\u53D6\u6D88\u606F\u7F6E\u9876\u72B6\u6001',\n 'im:message.pins:write_only': '\u7F6E\u9876/\u53D6\u6D88\u7F6E\u9876\u6D88\u606F',\n 'im:message.reactions:read': '\u8BFB\u53D6\u6D88\u606F\u8868\u60C5\u56DE\u590D',\n 'im:message.reactions:write_only': '\u6DFB\u52A0/\u5220\u9664\u6D88\u606F\u8868\u60C5\u56DE\u590D',\n 'im:message:readonly': '\u8BFB\u53D6\u6D88\u606F\u5185\u5BB9\u3001\u5386\u53F2\u6D88\u606F',\n 'im:message:recall': '\u21A9\u64A4\u56DE\u673A\u5668\u4EBA\u53D1\u9001\u7684\u6D88\u606F',\n 'im:message:send_as_bot': '\u4EE5\u673A\u5668\u4EBA\u8EAB\u4EFD\u53D1\u9001\u6D88\u606F',\n 'im:message:send_multi_users': '\u6279\u91CF\u53D1\u9001\u79C1\u804A\u6D88\u606F',\n 'im:message:send_sys_msg': '\u53D1\u9001\u7CFB\u7EDF\u901A\u77E5\u6D88\u606F',\n 'im:message:update': '\u66F4\u65B0/\u7F16\u8F91\u5DF2\u53D1\u9001\u7684\u6D88\u606F',\n 'im:resource': '\u4E0A\u4F20/\u4E0B\u8F7D\u6D88\u606F\u8D44\u6E90\uFF08\u56FE\u7247\u3001\u6587\u4EF6\u7B49\uFF09',\n 'application:application:self_manage': '\u67E5\u8BE2\u5E94\u7528\u81EA\u8EAB\u6743\u9650\u72B6\u6001\uFF08\u8BCA\u65AD\u57FA\u7840\uFF09',\n 'cardkit:card:write': '\u521B\u5EFA\u548C\u66F4\u65B0\u6D88\u606F\u5361\u7247',\n 'cardkit:card:read': '\u8BFB\u53D6\u6D88\u606F\u5361\u7247\u72B6\u6001',\n};\n\n// ===== \u9AD8\u654F\u611F\u6743\u9650 =====\n\n/**\n * \u9AD8\u654F\u611F\u6743\u9650\u6E05\u5355\n *\n * \u8FD9\u4E9B\u6743\u9650\u5177\u6709\u8F83\u9AD8\u7684\u654F\u611F\u5EA6\uFF0C\u4E0D\u5E94\u5728\u6279\u91CF\u6388\u6743\u65F6\u81EA\u52A8\u7533\u8BF7\u3002\n * \u7528\u6237\u9700\u8981\u660E\u786E\u77E5\u6653\u8FD9\u4E9B\u6743\u9650\u7684\u5F71\u54CD\u540E\uFF0C\u624D\u80FD\u624B\u52A8\u6388\u6743\u3002\n *\n * \u6743\u9650\u8BF4\u660E\uFF1A\n * - im:message:send_as_user - \u4EE5\u7528\u6237\u8EAB\u4EFD\u53D1\u9001\u6D88\u606F\uFF08\u9AD8\u98CE\u9669\uFF0C\u53EF\u80FD\u88AB\u6EE5\u7528\u53D1\u9001\u9493\u9C7C\u6216\u5783\u573E\u6D88\u606F\uFF09\n *\n * \u4F7F\u7528\u573A\u666F\uFF1A\n * - \u6279\u91CF\u6388\u6743\u65F6\u4F1A\u81EA\u52A8\u8FC7\u6EE4\u6389\u8FD9\u4E9B\u6743\u9650\n * - \u9700\u8981\u8FD9\u4E9B\u6743\u9650\u7684\u529F\u80FD\u4F1A\u5355\u72EC\u63D0\u793A\u7528\u6237\u6388\u6743\n *\n * \u6700\u540E\u66F4\u65B0: 2026-03-03\n */\nexport const SENSITIVE_SCOPES = ['im:message.send_as_user'] as const;\n\n/**\n * \u9AD8\u654F\u611F\u6743\u9650\u7C7B\u578B\n */\nexport type SensitiveScope = (typeof SENSITIVE_SCOPES)[number];\n\n/**\n * \u8FC7\u6EE4\u6389\u9AD8\u654F\u611F\u6743\u9650\n *\n * \u7528\u4E8E\u6279\u91CF\u6388\u6743\u65F6\u6392\u9664\u9AD8\u654F\u611F\u6743\u9650\uFF0C\u8FD9\u4E9B\u6743\u9650\u9700\u8981\u7528\u6237\u660E\u786E\u6388\u6743\u3002\n *\n * @param scopes - \u539F\u59CB\u6743\u9650\u5217\u8868\n * @returns \u8FC7\u6EE4\u540E\u7684\u6743\u9650\u5217\u8868\uFF08\u4E0D\u5305\u542B\u9AD8\u654F\u611F\u6743\u9650\uFF09\n *\n * @example\n * ```typescript\n * const allScopes = [\"im:message\", \"im:message:send_as_user\", \"calendar:calendar:read\"];\n * const safeScopes = filterSensitiveScopes(allScopes);\n * // \u8FD4\u56DE: [\"im:message\", \"calendar:calendar:read\"]\n * ```\n */\nexport function filterSensitiveScopes(scopes: string[]): string[] {\n const sensitiveSet = new Set<string>(SENSITIVE_SCOPES);\n return scopes.filter((scope) => !sensitiveSet.has(scope));\n}\n\n// ===== \u7EDF\u8BA1\u4FE1\u606F =====\n\n/**\n * \u5DE5\u5177\u52A8\u4F5C\u603B\u6570: 98\n * \u552F\u4E00 scope \u603B\u6570: 66\n * \u5FC5\u9700\u5E94\u7528\u6743\u9650\u603B\u6570: 20\n * \u9AD8\u654F\u611F\u6743\u9650\u603B\u6570: 1\n */\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,57 @@
1
+ const DEFAULT_TOOLS_CONFIG = {
2
+ doc: true,
3
+ wiki: true,
4
+ drive: true,
5
+ scopes: true,
6
+ perm: false,
7
+ mail: true,
8
+ sheets: true,
9
+ okr: false,
10
+ project: true
11
+ };
12
+ function resolveToolsConfig(cfg) {
13
+ if (!cfg) return { ...DEFAULT_TOOLS_CONFIG };
14
+ return {
15
+ doc: cfg.doc ?? DEFAULT_TOOLS_CONFIG.doc,
16
+ wiki: cfg.wiki ?? DEFAULT_TOOLS_CONFIG.wiki,
17
+ drive: cfg.drive ?? DEFAULT_TOOLS_CONFIG.drive,
18
+ perm: cfg.perm ?? DEFAULT_TOOLS_CONFIG.perm,
19
+ scopes: cfg.scopes ?? DEFAULT_TOOLS_CONFIG.scopes,
20
+ mail: cfg.mail ?? DEFAULT_TOOLS_CONFIG.mail,
21
+ sheets: cfg.sheets ?? DEFAULT_TOOLS_CONFIG.sheets,
22
+ okr: cfg.okr ?? DEFAULT_TOOLS_CONFIG.okr,
23
+ project: cfg.project ?? DEFAULT_TOOLS_CONFIG.project
24
+ };
25
+ }
26
+ function resolveAnyEnabledToolsConfig(accounts) {
27
+ const merged = {
28
+ doc: false,
29
+ wiki: false,
30
+ drive: false,
31
+ perm: false,
32
+ scopes: false,
33
+ mail: false,
34
+ sheets: false,
35
+ okr: false,
36
+ project: false
37
+ };
38
+ for (const account of accounts) {
39
+ const cfg = resolveToolsConfig(account.config.tools);
40
+ merged.doc = merged.doc || cfg.doc;
41
+ merged.wiki = merged.wiki || cfg.wiki;
42
+ merged.drive = merged.drive || cfg.drive;
43
+ merged.perm = merged.perm || cfg.perm;
44
+ merged.scopes = merged.scopes || cfg.scopes;
45
+ merged.mail = merged.mail || cfg.mail;
46
+ merged.sheets = merged.sheets || cfg.sheets;
47
+ merged.okr = merged.okr || cfg.okr;
48
+ merged.project = merged.project || cfg.project;
49
+ }
50
+ return merged;
51
+ }
52
+ export {
53
+ DEFAULT_TOOLS_CONFIG,
54
+ resolveAnyEnabledToolsConfig,
55
+ resolveToolsConfig
56
+ };
57
+ //# sourceMappingURL=tools-config.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/tools-config.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Default values and resolution logic for the Feishu tools configuration.\n *\n * Each boolean flag controls whether a particular category of Feishu-specific\n * agent tools (document access, wiki queries, drive operations, etc.) is\n * enabled for a given account.\n */\n\nimport type { FeishuToolsConfig, LarkAccount } from './types';\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\n/**\n * The default tools configuration.\n *\n * By default every non-destructive capability is enabled. The `perm` flag\n * (permission management) defaults to `false` because granting / revoking\n * permissions is a privileged operation that admins should opt into\n * explicitly.\n */\nexport const DEFAULT_TOOLS_CONFIG: Required<FeishuToolsConfig> = {\n doc: true,\n wiki: true,\n drive: true,\n scopes: true,\n perm: false,\n mail: true,\n sheets: true,\n okr: false,\n project: true,\n};\n\n// ---------------------------------------------------------------------------\n// Resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Merge a partial tools configuration with `DEFAULT_TOOLS_CONFIG`.\n *\n * Fields present in the input take precedence; anything absent falls back\n * to the default value.\n */\nexport function resolveToolsConfig(cfg?: FeishuToolsConfig): Required<FeishuToolsConfig> {\n if (!cfg) return { ...DEFAULT_TOOLS_CONFIG };\n\n return {\n doc: cfg.doc ?? DEFAULT_TOOLS_CONFIG.doc,\n wiki: cfg.wiki ?? DEFAULT_TOOLS_CONFIG.wiki,\n drive: cfg.drive ?? DEFAULT_TOOLS_CONFIG.drive,\n perm: cfg.perm ?? DEFAULT_TOOLS_CONFIG.perm,\n scopes: cfg.scopes ?? DEFAULT_TOOLS_CONFIG.scopes,\n mail: cfg.mail ?? DEFAULT_TOOLS_CONFIG.mail,\n sheets: cfg.sheets ?? DEFAULT_TOOLS_CONFIG.sheets,\n okr: cfg.okr ?? DEFAULT_TOOLS_CONFIG.okr,\n project: cfg.project ?? DEFAULT_TOOLS_CONFIG.project,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Multi-account aggregation\n// ---------------------------------------------------------------------------\n\n/**\n * \u5408\u5E76\u591A\u4E2A\u8D26\u6237\u7684\u5DE5\u5177\u914D\u7F6E\uFF08\u53D6\u5E76\u96C6\uFF09\u3002\n *\n * \u5DE5\u5177\u6CE8\u518C\u662F\u5168\u5C40\u7684\uFF08\u542F\u52A8\u65F6\u6CE8\u518C\u4E00\u6B21\uFF09\uFF0C\u53EA\u8981\u4EFB\u610F\u4E00\u4E2A\u8D26\u6237\u542F\u7528\u4E86\u67D0\u5DE5\u5177\uFF0C\n * \u8BE5\u5DE5\u5177\u5C31\u5E94\u88AB\u6CE8\u518C\u3002\u6267\u884C\u65F6\u7531 LarkTicket \u8DEF\u7531\u5230\u5177\u4F53\u8D26\u6237\u3002\n */\nexport function resolveAnyEnabledToolsConfig(accounts: LarkAccount[]): Required<FeishuToolsConfig> {\n const merged: Required<FeishuToolsConfig> = {\n doc: false,\n wiki: false,\n drive: false,\n perm: false,\n scopes: false,\n mail: false,\n sheets: false,\n okr: false,\n project: false,\n };\n for (const account of accounts) {\n const cfg = resolveToolsConfig((account.config as { tools?: FeishuToolsConfig }).tools);\n merged.doc = merged.doc || cfg.doc;\n merged.wiki = merged.wiki || cfg.wiki;\n merged.drive = merged.drive || cfg.drive;\n merged.perm = merged.perm || cfg.perm;\n merged.scopes = merged.scopes || cfg.scopes;\n merged.mail = merged.mail || cfg.mail;\n merged.sheets = merged.sheets || cfg.sheets;\n merged.okr = merged.okr || cfg.okr;\n merged.project = merged.project || cfg.project;\n }\n return merged;\n}\n"],
5
+ "mappings": "AAyBO,MAAM,uBAAoD;AAAA,EAC/D,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,SAAS;AACX;AAYO,SAAS,mBAAmB,KAAsD;AACvF,MAAI,CAAC,IAAK,QAAO,EAAE,GAAG,qBAAqB;AAE3C,SAAO;AAAA,IACL,KAAK,IAAI,OAAO,qBAAqB;AAAA,IACrC,MAAM,IAAI,QAAQ,qBAAqB;AAAA,IACvC,OAAO,IAAI,SAAS,qBAAqB;AAAA,IACzC,MAAM,IAAI,QAAQ,qBAAqB;AAAA,IACvC,QAAQ,IAAI,UAAU,qBAAqB;AAAA,IAC3C,MAAM,IAAI,QAAQ,qBAAqB;AAAA,IACvC,QAAQ,IAAI,UAAU,qBAAqB;AAAA,IAC3C,KAAK,IAAI,OAAO,qBAAqB;AAAA,IACrC,SAAS,IAAI,WAAW,qBAAqB;AAAA,EAC/C;AACF;AAYO,SAAS,6BAA6B,UAAsD;AACjG,QAAM,SAAsC;AAAA,IAC1C,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AACA,aAAW,WAAW,UAAU;AAC9B,UAAM,MAAM,mBAAoB,QAAQ,OAAyC,KAAK;AACtF,WAAO,MAAM,OAAO,OAAO,IAAI;AAC/B,WAAO,OAAO,OAAO,QAAQ,IAAI;AACjC,WAAO,QAAQ,OAAO,SAAS,IAAI;AACnC,WAAO,OAAO,OAAO,QAAQ,IAAI;AACjC,WAAO,SAAS,OAAO,UAAU,IAAI;AACrC,WAAO,OAAO,OAAO,QAAQ,IAAI;AACjC,WAAO,SAAS,OAAO,UAAU,IAAI;AACrC,WAAO,MAAM,OAAO,OAAO,IAAI;AAC/B,WAAO,UAAU,OAAO,WAAW,IAAI;AAAA,EACzC;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,124 @@
1
+ import {
2
+ getStoredToken,
3
+ setStoredToken,
4
+ removeStoredToken,
5
+ tokenStatus,
6
+ maskToken
7
+ } from "./token-store";
8
+ import { resolveOAuthEndpoints } from "./device-flow";
9
+ import { larkLogger } from "./lark-logger";
10
+ const log = larkLogger("core/uat-client");
11
+ import { feishuFetch } from "./feishu-fetch";
12
+ import { REFRESH_TOKEN_IRRECOVERABLE, TOKEN_RETRY_CODES, NeedAuthorizationError } from "./auth-errors";
13
+ const refreshLocks = /* @__PURE__ */ new Map();
14
+ async function doRefreshToken(opts, stored) {
15
+ if (Date.now() >= stored.refreshExpiresAt) {
16
+ log.info(`refresh_token expired for ${opts.userOpenId}, clearing`);
17
+ await removeStoredToken(opts.appId, opts.userOpenId);
18
+ return null;
19
+ }
20
+ const endpoints = resolveOAuthEndpoints(opts.domain);
21
+ const resp = await feishuFetch(endpoints.token, {
22
+ method: "POST",
23
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
24
+ body: new URLSearchParams({
25
+ grant_type: "refresh_token",
26
+ refresh_token: stored.refreshToken,
27
+ client_id: opts.appId,
28
+ client_secret: opts.appSecret
29
+ }).toString()
30
+ });
31
+ const data = await resp.json();
32
+ const code = data.code;
33
+ const error = data.error;
34
+ if (code !== void 0 && code !== 0 || error) {
35
+ const errCode = code ?? error;
36
+ const errMsg = data.error_description ?? data.msg ?? "unknown";
37
+ if (REFRESH_TOKEN_IRRECOVERABLE.has(code)) {
38
+ log.warn(`refresh failed (code=${errCode}), clearing token for ${opts.userOpenId}`);
39
+ await removeStoredToken(opts.appId, opts.userOpenId);
40
+ return null;
41
+ }
42
+ throw new Error(`Token refresh failed (code=${errCode}): ${errMsg}`);
43
+ }
44
+ if (!data.access_token) {
45
+ throw new Error("Token refresh returned no access_token");
46
+ }
47
+ const now = Date.now();
48
+ const updated = {
49
+ userOpenId: stored.userOpenId,
50
+ appId: opts.appId,
51
+ accessToken: data.access_token,
52
+ // refresh_token is rotated – always use the new one.
53
+ refreshToken: data.refresh_token ?? stored.refreshToken,
54
+ expiresAt: now + (data.expires_in ?? 7200) * 1e3,
55
+ refreshExpiresAt: data.refresh_token_expires_in ? now + data.refresh_token_expires_in * 1e3 : stored.refreshExpiresAt,
56
+ scope: data.scope ?? stored.scope,
57
+ grantedAt: stored.grantedAt
58
+ };
59
+ await setStoredToken(updated);
60
+ log.info(`refreshed UAT for ${opts.userOpenId} (at:${maskToken(updated.accessToken)})`);
61
+ return updated;
62
+ }
63
+ async function refreshWithLock(opts, stored) {
64
+ const key = `${opts.appId}:${opts.userOpenId}`;
65
+ const existing = refreshLocks.get(key);
66
+ if (existing) {
67
+ await existing;
68
+ return getStoredToken(opts.appId, opts.userOpenId);
69
+ }
70
+ const promise = doRefreshToken(opts, stored);
71
+ refreshLocks.set(key, promise);
72
+ try {
73
+ return await promise;
74
+ } finally {
75
+ refreshLocks.delete(key);
76
+ }
77
+ }
78
+ async function getValidAccessToken(opts) {
79
+ const stored = await getStoredToken(opts.appId, opts.userOpenId);
80
+ if (!stored) {
81
+ throw new NeedAuthorizationError(opts.userOpenId);
82
+ }
83
+ const status = tokenStatus(stored);
84
+ if (status === "valid") {
85
+ return stored.accessToken;
86
+ }
87
+ if (status === "needs_refresh") {
88
+ const refreshed = await refreshWithLock(opts, stored);
89
+ if (!refreshed) {
90
+ throw new NeedAuthorizationError(opts.userOpenId);
91
+ }
92
+ return refreshed.accessToken;
93
+ }
94
+ await removeStoredToken(opts.appId, opts.userOpenId);
95
+ throw new NeedAuthorizationError(opts.userOpenId);
96
+ }
97
+ async function callWithUAT(opts, apiCall) {
98
+ const accessToken = await getValidAccessToken(opts);
99
+ try {
100
+ return await apiCall(accessToken);
101
+ } catch (err) {
102
+ const code = err?.code ?? err?.response?.data?.code;
103
+ if (TOKEN_RETRY_CODES.has(code)) {
104
+ log.warn(`API call failed (code=${code}), refreshing and retrying`);
105
+ const stored = await getStoredToken(opts.appId, opts.userOpenId);
106
+ if (!stored) throw new NeedAuthorizationError(opts.userOpenId);
107
+ const refreshed = await refreshWithLock(opts, stored);
108
+ if (!refreshed) throw new NeedAuthorizationError(opts.userOpenId);
109
+ return await apiCall(refreshed.accessToken);
110
+ }
111
+ throw err;
112
+ }
113
+ }
114
+ async function revokeUAT(appId, userOpenId) {
115
+ await removeStoredToken(appId, userOpenId);
116
+ log.info(`revoked UAT for ${userOpenId}`);
117
+ }
118
+ export {
119
+ NeedAuthorizationError,
120
+ callWithUAT,
121
+ getValidAccessToken,
122
+ revokeUAT
123
+ };
124
+ //# sourceMappingURL=uat-client.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/uat-client.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * UAT (User Access Token) API call wrapper.\n *\n * Provides a safe, auto-refreshing interface for making Feishu API calls on\n * behalf of a user. Tokens are read from the OS Keychain, refreshed\n * transparently, and **never** exposed to the AI layer.\n */\n\nimport type { LarkBrand } from './types';\nimport {\n getStoredToken,\n setStoredToken,\n removeStoredToken,\n tokenStatus,\n maskToken,\n type StoredUAToken,\n} from './token-store';\nimport { resolveOAuthEndpoints } from './device-flow';\nimport { larkLogger } from './lark-logger';\n\nconst log = larkLogger('core/uat-client');\nimport { feishuFetch } from './feishu-fetch';\nimport { REFRESH_TOKEN_IRRECOVERABLE, TOKEN_RETRY_CODES, NeedAuthorizationError } from './auth-errors';\n\n// Re-export for backward compatibility\nexport { NeedAuthorizationError };\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UATCallOptions {\n userOpenId: string;\n appId: string;\n appSecret: string;\n domain: LarkBrand;\n}\n\nexport interface UATStatus {\n authorized: boolean;\n userOpenId: string;\n scope?: string;\n expiresAt?: number;\n refreshExpiresAt?: number;\n grantedAt?: number;\n tokenStatus?: 'valid' | 'needs_refresh' | 'expired';\n}\n\n// ---------------------------------------------------------------------------\n// Per-user refresh lock\n// ---------------------------------------------------------------------------\n\n/**\n * Guards against concurrent refresh operations for the same user.\n *\n * refresh_token is single-use: if two requests trigger a refresh\n * simultaneously, the second one would use an already-consumed token and\n * fail. The lock ensures only one refresh runs at a time per user.\n */\nconst refreshLocks = new Map<string, Promise<StoredUAToken | null>>();\n\n// ---------------------------------------------------------------------------\n// Refresh implementation\n// ---------------------------------------------------------------------------\n\nasync function doRefreshToken(opts: UATCallOptions, stored: StoredUAToken): Promise<StoredUAToken | null> {\n // refresh_token already expired \u2192 can't refresh, need re-auth.\n if (Date.now() >= stored.refreshExpiresAt) {\n log.info(`refresh_token expired for ${opts.userOpenId}, clearing`);\n await removeStoredToken(opts.appId, opts.userOpenId);\n return null;\n }\n\n const endpoints = resolveOAuthEndpoints(opts.domain);\n\n const resp = await feishuFetch(endpoints.token, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: stored.refreshToken,\n client_id: opts.appId,\n client_secret: opts.appSecret,\n }).toString(),\n });\n\n const data = (await resp.json()) as Record<string, unknown>;\n\n // Feishu v2 token endpoint returns `code: 0` on success.\n // Some responses use `error` field instead (standard OAuth).\n const code = data.code as number | undefined;\n const error = data.error as string | undefined;\n\n if ((code !== undefined && code !== 0) || error) {\n const errCode = code ?? error;\n const errMsg = (data.error_description as string) ?? (data.msg as string) ?? 'unknown';\n\n // Known irrecoverable codes: invalid/expired/missing refresh_token\n if (REFRESH_TOKEN_IRRECOVERABLE.has(code as number)) {\n log.warn(`refresh failed (code=${errCode}), clearing token for ${opts.userOpenId}`);\n await removeStoredToken(opts.appId, opts.userOpenId);\n return null;\n }\n\n throw new Error(`Token refresh failed (code=${errCode}): ${errMsg}`);\n }\n\n if (!data.access_token) {\n throw new Error('Token refresh returned no access_token');\n }\n\n const now = Date.now();\n const updated: StoredUAToken = {\n userOpenId: stored.userOpenId,\n appId: opts.appId,\n accessToken: data.access_token as string,\n // refresh_token is rotated \u2013 always use the new one.\n refreshToken: (data.refresh_token as string) ?? stored.refreshToken,\n expiresAt: now + ((data.expires_in as number) ?? 7200) * 1000,\n refreshExpiresAt: data.refresh_token_expires_in\n ? now + (data.refresh_token_expires_in as number) * 1000\n : stored.refreshExpiresAt,\n scope: (data.scope as string) ?? stored.scope,\n grantedAt: stored.grantedAt,\n };\n\n await setStoredToken(updated);\n log.info(`refreshed UAT for ${opts.userOpenId} (at:${maskToken(updated.accessToken)})`);\n return updated;\n}\n\n/**\n * Refresh with per-user locking.\n */\nasync function refreshWithLock(opts: UATCallOptions, stored: StoredUAToken): Promise<StoredUAToken | null> {\n const key = `${opts.appId}:${opts.userOpenId}`;\n\n // Another refresh is already in-flight \u2013 wait for it and re-read.\n const existing = refreshLocks.get(key);\n if (existing) {\n await existing;\n return getStoredToken(opts.appId, opts.userOpenId);\n }\n\n const promise = doRefreshToken(opts, stored);\n refreshLocks.set(key, promise);\n try {\n return await promise;\n } finally {\n refreshLocks.delete(key);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Obtain a valid access_token for the given user.\n *\n * - Reads from Keychain.\n * - Refreshes proactively if the token is about to expire.\n * - Throws when no token exists or refresh fails irrecoverably.\n *\n * **The returned token must never be exposed to the AI layer.**\n */\nexport async function getValidAccessToken(opts: UATCallOptions): Promise<string> {\n // Owner \u68C0\u67E5\u5DF2\u8FC1\u79FB\u5230 owner-policy.ts\uFF08\u7531 tool-client.ts \u7684 invokeAsUser \u8C03\u7528\uFF09\n const stored = await getStoredToken(opts.appId, opts.userOpenId);\n if (!stored) {\n throw new NeedAuthorizationError(opts.userOpenId);\n }\n\n const status = tokenStatus(stored);\n\n if (status === 'valid') {\n return stored.accessToken;\n }\n\n if (status === 'needs_refresh') {\n const refreshed = await refreshWithLock(opts, stored);\n if (!refreshed) {\n throw new NeedAuthorizationError(opts.userOpenId);\n }\n return refreshed.accessToken;\n }\n\n // expired\n await removeStoredToken(opts.appId, opts.userOpenId);\n throw new NeedAuthorizationError(opts.userOpenId);\n}\n\n/**\n * Execute an API call with a valid UAT, retrying once on token-expiry errors.\n */\nexport async function callWithUAT<T>(opts: UATCallOptions, apiCall: (accessToken: string) => Promise<T>): Promise<T> {\n const accessToken = await getValidAccessToken(opts);\n try {\n return await apiCall(accessToken);\n } catch (err: unknown) {\n // Retry once if the server reports token invalid/expired.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const code = (err as any)?.code ?? (err as any)?.response?.data?.code;\n if (TOKEN_RETRY_CODES.has(code as number)) {\n log.warn(`API call failed (code=${code}), refreshing and retrying`);\n const stored = await getStoredToken(opts.appId, opts.userOpenId);\n if (!stored) throw new NeedAuthorizationError(opts.userOpenId);\n const refreshed = await refreshWithLock(opts, stored);\n if (!refreshed) throw new NeedAuthorizationError(opts.userOpenId);\n return await apiCall(refreshed.accessToken);\n }\n throw err;\n }\n}\n\n/**\n * Revoke a user's UAT by removing it from the Keychain.\n */\nexport async function revokeUAT(appId: string, userOpenId: string): Promise<void> {\n await removeStoredToken(appId, userOpenId);\n log.info(`revoked UAT for ${userOpenId}`);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,27 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { dirname, join } from "node:path";
3
+ import { readFileSync } from "node:fs";
4
+ let cachedVersion;
5
+ function getPluginVersion() {
6
+ if (cachedVersion) return cachedVersion;
7
+ try {
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ const packageJsonPath = join(__dirname, "..", "..", "package.json");
11
+ const raw = readFileSync(packageJsonPath, "utf8");
12
+ const pkg = JSON.parse(raw);
13
+ cachedVersion = pkg.version ?? "unknown";
14
+ return cachedVersion;
15
+ } catch {
16
+ cachedVersion = "unknown";
17
+ return cachedVersion;
18
+ }
19
+ }
20
+ function getUserAgent() {
21
+ return `feishu-openclaw-plugin/${getPluginVersion()}`;
22
+ }
23
+ export {
24
+ getPluginVersion,
25
+ getUserAgent
26
+ };
27
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/core/version.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * \u63D2\u4EF6\u7248\u672C\u53F7\u7BA1\u7406\n *\n * \u4ECE package.json \u8BFB\u53D6\u7248\u672C\u53F7\u5E76\u751F\u6210 User-Agent \u5B57\u7B26\u4E32\u3002\n */\n\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { readFileSync } from 'node:fs';\n\n/** \u7F13\u5B58\u7684\u7248\u672C\u53F7 */\nlet cachedVersion: string | undefined;\n\n/**\n * \u83B7\u53D6\u63D2\u4EF6\u7248\u672C\u53F7\uFF08\u4ECE package.json \u8BFB\u53D6\uFF09\n *\n * @returns \u7248\u672C\u53F7\u5B57\u7B26\u4E32\uFF0C\u5982 \"2026.2.28.5\"\uFF1B\u8BFB\u53D6\u5931\u8D25\u8FD4\u56DE \"unknown\"\n */\nexport function getPluginVersion(): string {\n if (cachedVersion) return cachedVersion;\n\n try {\n // \u5F53\u524D\u6587\u4EF6: src/core/version.ts \u2192 \u5411\u4E0A\u4E24\u7EA7\u5230\u8FBE\u9879\u76EE\u6839\u76EE\u5F55\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const packageJsonPath = join(__dirname, '..', '..', 'package.json');\n\n const raw = readFileSync(packageJsonPath, 'utf8');\n const pkg = JSON.parse(raw) as { version?: string };\n cachedVersion = pkg.version ?? 'unknown';\n return cachedVersion;\n } catch {\n cachedVersion = 'unknown';\n return cachedVersion;\n }\n}\n\n/**\n * \u751F\u6210 User-Agent \u5B57\u7B26\u4E32\n *\n * @returns User-Agent \u5B57\u7B26\u4E32\uFF0C\u683C\u5F0F\uFF1A`feishu-openclaw-plugin/{version}`\n *\n * @example\n * ```typescript\n * getUserAgent() // => \"feishu-openclaw-plugin/2026.2.28.5\"\n * ```\n */\nexport function getUserAgent(): string {\n return `feishu-openclaw-plugin/${getPluginVersion()}`;\n}\n"],
5
+ "mappings": "AASA,SAAS,qBAAqB;AAC9B,SAAS,SAAS,YAAY;AAC9B,SAAS,oBAAoB;AAG7B,IAAI;AAOG,SAAS,mBAA2B;AACzC,MAAI,cAAe,QAAO;AAE1B,MAAI;AAEF,UAAM,aAAa,cAAc,YAAY,GAAG;AAChD,UAAM,YAAY,QAAQ,UAAU;AACpC,UAAM,kBAAkB,KAAK,WAAW,MAAM,MAAM,cAAc;AAElE,UAAM,MAAM,aAAa,iBAAiB,MAAM;AAChD,UAAM,MAAM,KAAK,MAAM,GAAG;AAC1B,oBAAgB,IAAI,WAAW;AAC/B,WAAO;AAAA,EACT,QAAQ;AACN,oBAAgB;AAChB,WAAO;AAAA,EACT;AACF;AAYO,SAAS,eAAuB;AACrC,SAAO,0BAA0B,iBAAiB,CAAC;AACrD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,19 @@
1
+ import { safeParse } from "./utils";
2
+ import { formatDuration } from "./utils";
3
+ const convertAudio = (raw) => {
4
+ const parsed = safeParse(raw);
5
+ const fileKey = parsed?.file_key;
6
+ if (!fileKey) {
7
+ return { content: "[audio]", resources: [] };
8
+ }
9
+ const duration = parsed?.duration;
10
+ const durationAttr = duration != null ? ` duration="${formatDuration(duration)}"` : "";
11
+ return {
12
+ content: `<audio key="${fileKey}"${durationAttr}/>`,
13
+ resources: [{ type: "audio", fileKey, duration: duration ?? void 0 }]
14
+ };
15
+ };
16
+ export {
17
+ convertAudio
18
+ };
19
+ //# sourceMappingURL=audio.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/messaging/converters/audio.ts"],
4
+ "sourcesContent": ["/**\n * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n *\n * Converter for \"audio\" message type.\n */\n\nimport type { ContentConverterFn } from './types';\nimport { safeParse } from './utils';\nimport { formatDuration } from './utils';\n\nexport const convertAudio: ContentConverterFn = (raw) => {\n const parsed = safeParse(raw) as\n | {\n file_key?: string;\n duration?: number;\n }\n | undefined;\n\n const fileKey = parsed?.file_key;\n if (!fileKey) {\n return { content: '[audio]', resources: [] };\n }\n\n const duration = parsed?.duration;\n const durationAttr = duration != null ? ` duration=\"${formatDuration(duration)}\"` : '';\n\n return {\n content: `<audio key=\"${fileKey}\"${durationAttr}/>`,\n resources: [{ type: 'audio', fileKey, duration: duration ?? undefined }],\n };\n};\n"],
5
+ "mappings": "AAQA,SAAS,iBAAiB;AAC1B,SAAS,sBAAsB;AAExB,MAAM,eAAmC,CAAC,QAAQ;AACvD,QAAM,SAAS,UAAU,GAAG;AAO5B,QAAM,UAAU,QAAQ;AACxB,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,SAAS,WAAW,WAAW,CAAC,EAAE;AAAA,EAC7C;AAEA,QAAM,WAAW,QAAQ;AACzB,QAAM,eAAe,YAAY,OAAO,cAAc,eAAe,QAAQ,CAAC,MAAM;AAEpF,SAAO;AAAA,IACL,SAAS,eAAe,OAAO,IAAI,YAAY;AAAA,IAC/C,WAAW,CAAC,EAAE,MAAM,SAAS,SAAS,UAAU,YAAY,OAAU,CAAC;AAAA,EACzE;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,46 @@
1
+ import { safeParse, millisToDatetime } from "./utils";
2
+ function formatCalendarContent(parsed) {
3
+ const summary = parsed?.summary ?? "";
4
+ const parts = [];
5
+ if (summary) {
6
+ parts.push(`\u{1F4C5} ${summary}`);
7
+ }
8
+ const start = parsed?.start_time ? millisToDatetime(parsed.start_time) : "";
9
+ const end = parsed?.end_time ? millisToDatetime(parsed.end_time) : "";
10
+ if (start && end) {
11
+ parts.push(`\u{1F559} ${start} ~ ${end}`);
12
+ } else if (start) {
13
+ parts.push(`\u{1F559} ${start}`);
14
+ }
15
+ return parts.join("\n") || "[calendar event]";
16
+ }
17
+ const convertShareCalendarEvent = (raw) => {
18
+ const parsed = safeParse(raw);
19
+ const inner = formatCalendarContent(parsed);
20
+ return {
21
+ content: `<calendar_share>${inner}</calendar_share>`,
22
+ resources: []
23
+ };
24
+ };
25
+ const convertCalendar = (raw) => {
26
+ const parsed = safeParse(raw);
27
+ const inner = formatCalendarContent(parsed);
28
+ return {
29
+ content: `<calendar_invite>${inner}</calendar_invite>`,
30
+ resources: []
31
+ };
32
+ };
33
+ const convertGeneralCalendar = (raw) => {
34
+ const parsed = safeParse(raw);
35
+ const inner = formatCalendarContent(parsed);
36
+ return {
37
+ content: `<calendar>${inner}</calendar>`,
38
+ resources: []
39
+ };
40
+ };
41
+ export {
42
+ convertCalendar,
43
+ convertGeneralCalendar,
44
+ convertShareCalendarEvent
45
+ };
46
+ //# sourceMappingURL=calendar.js.map