@larksuite/openclaw-lark 2025.7.15-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/bin/openclaw-lark.js +39 -0
  4. package/index.d.ts +36 -0
  5. package/index.js +188 -0
  6. package/openclaw.plugin.json +64 -0
  7. package/package.json +63 -0
  8. package/secret-contract-api.d.ts +15 -0
  9. package/secret-contract-api.js +78 -0
  10. package/skills/feishu-bitable/SKILL.md +248 -0
  11. package/skills/feishu-bitable/references/examples.md +813 -0
  12. package/skills/feishu-bitable/references/field-properties.md +763 -0
  13. package/skills/feishu-bitable/references/record-values.md +911 -0
  14. package/skills/feishu-calendar/SKILL.md +242 -0
  15. package/skills/feishu-channel-rules/SKILL.md +18 -0
  16. package/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  17. package/skills/feishu-create-doc/SKILL.md +719 -0
  18. package/skills/feishu-fetch-doc/SKILL.md +93 -0
  19. package/skills/feishu-im-read/SKILL.md +163 -0
  20. package/skills/feishu-task/SKILL.md +340 -0
  21. package/skills/feishu-troubleshoot/SKILL.md +70 -0
  22. package/skills/feishu-update-doc/SKILL.md +285 -0
  23. package/src/card/builder.d.ts +152 -0
  24. package/src/card/builder.js +794 -0
  25. package/src/card/card-error.d.ts +91 -0
  26. package/src/card/card-error.js +206 -0
  27. package/src/card/cardkit.d.ts +90 -0
  28. package/src/card/cardkit.js +203 -0
  29. package/src/card/flush-controller.d.ts +45 -0
  30. package/src/card/flush-controller.js +138 -0
  31. package/src/card/image-resolver.d.ts +45 -0
  32. package/src/card/image-resolver.js +116 -0
  33. package/src/card/markdown-style.d.ts +16 -0
  34. package/src/card/markdown-style.js +106 -0
  35. package/src/card/reasoning-utils.d.ts +14 -0
  36. package/src/card/reasoning-utils.js +64 -0
  37. package/src/card/reply-dispatcher-types.d.ts +132 -0
  38. package/src/card/reply-dispatcher-types.js +61 -0
  39. package/src/card/reply-dispatcher.d.ts +15 -0
  40. package/src/card/reply-dispatcher.js +447 -0
  41. package/src/card/reply-mode.d.ts +41 -0
  42. package/src/card/reply-mode.js +70 -0
  43. package/src/card/streaming-card-controller.d.ts +118 -0
  44. package/src/card/streaming-card-controller.js +1045 -0
  45. package/src/card/tool-use-config.d.ts +26 -0
  46. package/src/card/tool-use-config.js +76 -0
  47. package/src/card/tool-use-display.d.ts +37 -0
  48. package/src/card/tool-use-display.js +476 -0
  49. package/src/card/tool-use-trace-store.d.ts +51 -0
  50. package/src/card/tool-use-trace-store.js +271 -0
  51. package/src/card/unavailable-guard.d.ts +35 -0
  52. package/src/card/unavailable-guard.js +87 -0
  53. package/src/channel/abort-detect.d.ts +47 -0
  54. package/src/channel/abort-detect.js +219 -0
  55. package/src/channel/chat-queue.d.ts +41 -0
  56. package/src/channel/chat-queue.js +68 -0
  57. package/src/channel/config-adapter.d.ts +23 -0
  58. package/src/channel/config-adapter.js +107 -0
  59. package/src/channel/directory.d.ts +57 -0
  60. package/src/channel/directory.js +197 -0
  61. package/src/channel/event-handlers.d.ts +17 -0
  62. package/src/channel/event-handlers.js +380 -0
  63. package/src/channel/interactive-dispatch.d.ts +59 -0
  64. package/src/channel/interactive-dispatch.js +195 -0
  65. package/src/channel/monitor.d.ts +17 -0
  66. package/src/channel/monitor.js +140 -0
  67. package/src/channel/onboarding-config.d.ts +18 -0
  68. package/src/channel/onboarding-config.js +96 -0
  69. package/src/channel/onboarding-migrate.d.ts +25 -0
  70. package/src/channel/onboarding-migrate.js +70 -0
  71. package/src/channel/onboarding.d.ts +12 -0
  72. package/src/channel/onboarding.js +300 -0
  73. package/src/channel/plugin.d.ts +13 -0
  74. package/src/channel/plugin.js +310 -0
  75. package/src/channel/probe.d.ts +14 -0
  76. package/src/channel/probe.js +24 -0
  77. package/src/channel/types.d.ts +37 -0
  78. package/src/channel/types.js +8 -0
  79. package/src/commands/auth.d.ts +21 -0
  80. package/src/commands/auth.js +165 -0
  81. package/src/commands/diagnose.d.ts +69 -0
  82. package/src/commands/diagnose.js +848 -0
  83. package/src/commands/doctor.d.ts +27 -0
  84. package/src/commands/doctor.js +588 -0
  85. package/src/commands/index.d.ts +25 -0
  86. package/src/commands/index.js +219 -0
  87. package/src/commands/locale.d.ts +7 -0
  88. package/src/commands/locale.js +8 -0
  89. package/src/core/accounts.d.ts +51 -0
  90. package/src/core/accounts.js +219 -0
  91. package/src/core/agent-config.d.ts +100 -0
  92. package/src/core/agent-config.js +148 -0
  93. package/src/core/api-error.d.ts +48 -0
  94. package/src/core/api-error.js +117 -0
  95. package/src/core/app-owner-fallback.d.ts +22 -0
  96. package/src/core/app-owner-fallback.js +39 -0
  97. package/src/core/app-scope-checker.d.ts +87 -0
  98. package/src/core/app-scope-checker.js +198 -0
  99. package/src/core/auth-errors.d.ts +144 -0
  100. package/src/core/auth-errors.js +160 -0
  101. package/src/core/card-action-operator.d.ts +33 -0
  102. package/src/core/card-action-operator.js +30 -0
  103. package/src/core/chat-info-cache.d.ts +67 -0
  104. package/src/core/chat-info-cache.js +165 -0
  105. package/src/core/comment-target.d.ts +65 -0
  106. package/src/core/comment-target.js +100 -0
  107. package/src/core/config-schema.d.ts +490 -0
  108. package/src/core/config-schema.js +223 -0
  109. package/src/core/device-flow.d.ts +77 -0
  110. package/src/core/device-flow.js +217 -0
  111. package/src/core/domains.d.ts +18 -0
  112. package/src/core/domains.js +34 -0
  113. package/src/core/feishu-fetch.d.ts +18 -0
  114. package/src/core/feishu-fetch.js +28 -0
  115. package/src/core/footer-config.d.ts +24 -0
  116. package/src/core/footer-config.js +51 -0
  117. package/src/core/lark-client.d.ts +125 -0
  118. package/src/core/lark-client.js +468 -0
  119. package/src/core/lark-logger.d.ts +23 -0
  120. package/src/core/lark-logger.js +160 -0
  121. package/src/core/lark-ticket.d.ts +29 -0
  122. package/src/core/lark-ticket.js +40 -0
  123. package/src/core/message-unavailable.d.ts +53 -0
  124. package/src/core/message-unavailable.js +142 -0
  125. package/src/core/owner-policy.d.ts +32 -0
  126. package/src/core/owner-policy.js +55 -0
  127. package/src/core/permission-url.d.ts +22 -0
  128. package/src/core/permission-url.js +76 -0
  129. package/src/core/raw-request.d.ts +27 -0
  130. package/src/core/raw-request.js +90 -0
  131. package/src/core/runtime-store.d.ts +13 -0
  132. package/src/core/runtime-store.js +29 -0
  133. package/src/core/scope-manager.d.ts +168 -0
  134. package/src/core/scope-manager.js +224 -0
  135. package/src/core/sdk-compat.d.ts +20 -0
  136. package/src/core/sdk-compat.js +28 -0
  137. package/src/core/security-check.d.ts +72 -0
  138. package/src/core/security-check.js +184 -0
  139. package/src/core/shutdown-hooks.d.ts +22 -0
  140. package/src/core/shutdown-hooks.js +61 -0
  141. package/src/core/synthetic-target.d.ts +33 -0
  142. package/src/core/synthetic-target.js +40 -0
  143. package/src/core/targets.d.ts +60 -0
  144. package/src/core/targets.js +173 -0
  145. package/src/core/token-store.d.ts +54 -0
  146. package/src/core/token-store.js +326 -0
  147. package/src/core/tool-client.d.ts +176 -0
  148. package/src/core/tool-client.js +426 -0
  149. package/src/core/tool-scopes.d.ts +156 -0
  150. package/src/core/tool-scopes.js +344 -0
  151. package/src/core/tools-config.d.ts +55 -0
  152. package/src/core/tools-config.js +143 -0
  153. package/src/core/types.d.ts +91 -0
  154. package/src/core/types.js +12 -0
  155. package/src/core/uat-client.d.ts +46 -0
  156. package/src/core/uat-client.js +192 -0
  157. package/src/core/version.d.ts +31 -0
  158. package/src/core/version.js +69 -0
  159. package/src/messaging/converters/audio.d.ts +8 -0
  160. package/src/messaging/converters/audio.js +24 -0
  161. package/src/messaging/converters/calendar.d.ts +13 -0
  162. package/src/messaging/converters/calendar.js +56 -0
  163. package/src/messaging/converters/content-converter-helpers.d.ts +30 -0
  164. package/src/messaging/converters/content-converter-helpers.js +82 -0
  165. package/src/messaging/converters/content-converter.d.ts +24 -0
  166. package/src/messaging/converters/content-converter.js +40 -0
  167. package/src/messaging/converters/file.d.ts +8 -0
  168. package/src/messaging/converters/file.js +24 -0
  169. package/src/messaging/converters/folder.d.ts +8 -0
  170. package/src/messaging/converters/folder.js +24 -0
  171. package/src/messaging/converters/hongbao.d.ts +8 -0
  172. package/src/messaging/converters/hongbao.js +20 -0
  173. package/src/messaging/converters/image.d.ts +8 -0
  174. package/src/messaging/converters/image.js +22 -0
  175. package/src/messaging/converters/index.d.ts +8 -0
  176. package/src/messaging/converters/index.js +53 -0
  177. package/src/messaging/converters/interactive/card-converter.d.ts +76 -0
  178. package/src/messaging/converters/interactive/card-converter.js +1177 -0
  179. package/src/messaging/converters/interactive/card-utils.d.ts +9 -0
  180. package/src/messaging/converters/interactive/card-utils.js +47 -0
  181. package/src/messaging/converters/interactive/index.d.ts +8 -0
  182. package/src/messaging/converters/interactive/index.js +25 -0
  183. package/src/messaging/converters/interactive/legacy.d.ts +11 -0
  184. package/src/messaging/converters/interactive/legacy.js +60 -0
  185. package/src/messaging/converters/interactive/types.d.ts +23 -0
  186. package/src/messaging/converters/interactive/types.js +27 -0
  187. package/src/messaging/converters/location.d.ts +8 -0
  188. package/src/messaging/converters/location.js +23 -0
  189. package/src/messaging/converters/merge-forward.d.ts +32 -0
  190. package/src/messaging/converters/merge-forward.js +235 -0
  191. package/src/messaging/converters/post.d.ts +11 -0
  192. package/src/messaging/converters/post.js +235 -0
  193. package/src/messaging/converters/share.d.ts +9 -0
  194. package/src/messaging/converters/share.js +28 -0
  195. package/src/messaging/converters/sticker.d.ts +8 -0
  196. package/src/messaging/converters/sticker.js +22 -0
  197. package/src/messaging/converters/system.d.ts +12 -0
  198. package/src/messaging/converters/system.js +36 -0
  199. package/src/messaging/converters/text.d.ts +8 -0
  200. package/src/messaging/converters/text.js +18 -0
  201. package/src/messaging/converters/todo.d.ts +8 -0
  202. package/src/messaging/converters/todo.js +45 -0
  203. package/src/messaging/converters/types.d.ts +114 -0
  204. package/src/messaging/converters/types.js +8 -0
  205. package/src/messaging/converters/unknown.d.ts +8 -0
  206. package/src/messaging/converters/unknown.js +20 -0
  207. package/src/messaging/converters/utils.d.ts +22 -0
  208. package/src/messaging/converters/utils.js +57 -0
  209. package/src/messaging/converters/video-chat.d.ts +8 -0
  210. package/src/messaging/converters/video-chat.js +31 -0
  211. package/src/messaging/converters/video.d.ts +8 -0
  212. package/src/messaging/converters/video.js +35 -0
  213. package/src/messaging/converters/vote.d.ts +8 -0
  214. package/src/messaging/converters/vote.js +28 -0
  215. package/src/messaging/inbound/bot-content.d.ts +84 -0
  216. package/src/messaging/inbound/bot-content.js +117 -0
  217. package/src/messaging/inbound/bot-loop-guard.d.ts +48 -0
  218. package/src/messaging/inbound/bot-loop-guard.js +89 -0
  219. package/src/messaging/inbound/comment-context.d.ts +82 -0
  220. package/src/messaging/inbound/comment-context.js +353 -0
  221. package/src/messaging/inbound/comment-handler.d.ts +30 -0
  222. package/src/messaging/inbound/comment-handler.js +269 -0
  223. package/src/messaging/inbound/dedup.d.ts +59 -0
  224. package/src/messaging/inbound/dedup.js +121 -0
  225. package/src/messaging/inbound/dispatch-builders.d.ts +104 -0
  226. package/src/messaging/inbound/dispatch-builders.js +241 -0
  227. package/src/messaging/inbound/dispatch-commands.d.ts +22 -0
  228. package/src/messaging/inbound/dispatch-commands.js +131 -0
  229. package/src/messaging/inbound/dispatch-context.d.ts +67 -0
  230. package/src/messaging/inbound/dispatch-context.js +153 -0
  231. package/src/messaging/inbound/dispatch.d.ts +50 -0
  232. package/src/messaging/inbound/dispatch.js +477 -0
  233. package/src/messaging/inbound/enrich.d.ts +102 -0
  234. package/src/messaging/inbound/enrich.js +236 -0
  235. package/src/messaging/inbound/gate-effects.d.ts +23 -0
  236. package/src/messaging/inbound/gate-effects.js +46 -0
  237. package/src/messaging/inbound/gate.d.ts +91 -0
  238. package/src/messaging/inbound/gate.js +342 -0
  239. package/src/messaging/inbound/handler-registry.d.ts +25 -0
  240. package/src/messaging/inbound/handler-registry.js +23 -0
  241. package/src/messaging/inbound/handler.d.ts +37 -0
  242. package/src/messaging/inbound/handler.js +286 -0
  243. package/src/messaging/inbound/media-resolver.d.ts +32 -0
  244. package/src/messaging/inbound/media-resolver.js +91 -0
  245. package/src/messaging/inbound/mention-registry.d.ts +59 -0
  246. package/src/messaging/inbound/mention-registry.js +115 -0
  247. package/src/messaging/inbound/mention.d.ts +48 -0
  248. package/src/messaging/inbound/mention.js +102 -0
  249. package/src/messaging/inbound/parse-io.d.ts +50 -0
  250. package/src/messaging/inbound/parse-io.js +86 -0
  251. package/src/messaging/inbound/parse.d.ts +28 -0
  252. package/src/messaging/inbound/parse.js +128 -0
  253. package/src/messaging/inbound/permission.d.ts +17 -0
  254. package/src/messaging/inbound/permission.js +44 -0
  255. package/src/messaging/inbound/policy.d.ts +95 -0
  256. package/src/messaging/inbound/policy.js +168 -0
  257. package/src/messaging/inbound/reaction-handler.d.ts +62 -0
  258. package/src/messaging/inbound/reaction-handler.js +259 -0
  259. package/src/messaging/inbound/sentinel-store.d.ts +37 -0
  260. package/src/messaging/inbound/sentinel-store.js +98 -0
  261. package/src/messaging/inbound/synthetic-message.d.ts +26 -0
  262. package/src/messaging/inbound/synthetic-message.js +59 -0
  263. package/src/messaging/inbound/user-name-cache-store.d.ts +62 -0
  264. package/src/messaging/inbound/user-name-cache-store.js +236 -0
  265. package/src/messaging/inbound/user-name-cache.d.ts +78 -0
  266. package/src/messaging/inbound/user-name-cache.js +306 -0
  267. package/src/messaging/inbound/vc-meeting-invited-handler.d.ts +20 -0
  268. package/src/messaging/inbound/vc-meeting-invited-handler.js +236 -0
  269. package/src/messaging/inbound/vc-sender.d.ts +41 -0
  270. package/src/messaging/inbound/vc-sender.js +53 -0
  271. package/src/messaging/outbound/actions.d.ts +16 -0
  272. package/src/messaging/outbound/actions.js +329 -0
  273. package/src/messaging/outbound/bot-peer-context.d.ts +42 -0
  274. package/src/messaging/outbound/bot-peer-context.js +40 -0
  275. package/src/messaging/outbound/chat-manage.d.ts +64 -0
  276. package/src/messaging/outbound/chat-manage.js +117 -0
  277. package/src/messaging/outbound/deliver.d.ts +186 -0
  278. package/src/messaging/outbound/deliver.js +410 -0
  279. package/src/messaging/outbound/fetch.d.ts +12 -0
  280. package/src/messaging/outbound/fetch.js +17 -0
  281. package/src/messaging/outbound/forward.d.ts +26 -0
  282. package/src/messaging/outbound/forward.js +51 -0
  283. package/src/messaging/outbound/media-url-utils.d.ts +29 -0
  284. package/src/messaging/outbound/media-url-utils.js +172 -0
  285. package/src/messaging/outbound/media.d.ts +260 -0
  286. package/src/messaging/outbound/media.js +865 -0
  287. package/src/messaging/outbound/normalize-mentions.d.ts +50 -0
  288. package/src/messaging/outbound/normalize-mentions.js +166 -0
  289. package/src/messaging/outbound/outbound-mention.d.ts +41 -0
  290. package/src/messaging/outbound/outbound-mention.js +112 -0
  291. package/src/messaging/outbound/outbound.d.ts +79 -0
  292. package/src/messaging/outbound/outbound.js +195 -0
  293. package/src/messaging/outbound/reactions.d.ts +124 -0
  294. package/src/messaging/outbound/reactions.js +384 -0
  295. package/src/messaging/outbound/send.d.ts +153 -0
  296. package/src/messaging/outbound/send.js +417 -0
  297. package/src/messaging/outbound/typing.d.ts +60 -0
  298. package/src/messaging/outbound/typing.js +139 -0
  299. package/src/messaging/shared/message-lookup.d.ts +54 -0
  300. package/src/messaging/shared/message-lookup.js +120 -0
  301. package/src/messaging/types.d.ts +316 -0
  302. package/src/messaging/types.js +11 -0
  303. package/src/tools/ask-user-question.d.ts +32 -0
  304. package/src/tools/ask-user-question.js +922 -0
  305. package/src/tools/auto-auth.d.ts +57 -0
  306. package/src/tools/auto-auth.js +904 -0
  307. package/src/tools/helpers.d.ts +264 -0
  308. package/src/tools/helpers.js +389 -0
  309. package/src/tools/mcp/doc/create.d.ts +12 -0
  310. package/src/tools/mcp/doc/create.js +47 -0
  311. package/src/tools/mcp/doc/fetch.d.ts +12 -0
  312. package/src/tools/mcp/doc/fetch.js +39 -0
  313. package/src/tools/mcp/doc/index.d.ts +12 -0
  314. package/src/tools/mcp/doc/index.js +50 -0
  315. package/src/tools/mcp/doc/update.d.ts +12 -0
  316. package/src/tools/mcp/doc/update.js +64 -0
  317. package/src/tools/mcp/shared.d.ts +59 -0
  318. package/src/tools/mcp/shared.js +239 -0
  319. package/src/tools/oapi/bitable/app-table-field.d.ts +16 -0
  320. package/src/tools/oapi/bitable/app-table-field.js +225 -0
  321. package/src/tools/oapi/bitable/app-table-record.d.ts +20 -0
  322. package/src/tools/oapi/bitable/app-table-record.js +439 -0
  323. package/src/tools/oapi/bitable/app-table-view.d.ts +16 -0
  324. package/src/tools/oapi/bitable/app-table-view.js +172 -0
  325. package/src/tools/oapi/bitable/app-table.d.ts +17 -0
  326. package/src/tools/oapi/bitable/app-table.js +195 -0
  327. package/src/tools/oapi/bitable/app.d.ts +18 -0
  328. package/src/tools/oapi/bitable/app.js +189 -0
  329. package/src/tools/oapi/bitable/index.d.ts +9 -0
  330. package/src/tools/oapi/bitable/index.js +17 -0
  331. package/src/tools/oapi/calendar/calendar.d.ts +15 -0
  332. package/src/tools/oapi/calendar/calendar.js +125 -0
  333. package/src/tools/oapi/calendar/event-attendee.d.ts +14 -0
  334. package/src/tools/oapi/calendar/event-attendee.js +161 -0
  335. package/src/tools/oapi/calendar/event.d.ts +16 -0
  336. package/src/tools/oapi/calendar/event.js +712 -0
  337. package/src/tools/oapi/calendar/freebusy.d.ts +13 -0
  338. package/src/tools/oapi/calendar/freebusy.js +114 -0
  339. package/src/tools/oapi/calendar/index.d.ts +8 -0
  340. package/src/tools/oapi/calendar/index.js +15 -0
  341. package/src/tools/oapi/chat/chat.d.ts +16 -0
  342. package/src/tools/oapi/chat/chat.js +127 -0
  343. package/src/tools/oapi/chat/index.d.ts +10 -0
  344. package/src/tools/oapi/chat/index.js +23 -0
  345. package/src/tools/oapi/chat/members.d.ts +11 -0
  346. package/src/tools/oapi/chat/members.js +84 -0
  347. package/src/tools/oapi/common/get-user.d.ts +12 -0
  348. package/src/tools/oapi/common/get-user.js +109 -0
  349. package/src/tools/oapi/common/index.d.ts +6 -0
  350. package/src/tools/oapi/common/index.js +11 -0
  351. package/src/tools/oapi/common/search-user.d.ts +11 -0
  352. package/src/tools/oapi/common/search-user.js +76 -0
  353. package/src/tools/oapi/drive/doc-comments.d.ts +15 -0
  354. package/src/tools/oapi/drive/doc-comments.js +351 -0
  355. package/src/tools/oapi/drive/doc-media.d.ts +19 -0
  356. package/src/tools/oapi/drive/doc-media.js +371 -0
  357. package/src/tools/oapi/drive/file.d.ts +19 -0
  358. package/src/tools/oapi/drive/file.js +519 -0
  359. package/src/tools/oapi/drive/index.d.ts +12 -0
  360. package/src/tools/oapi/drive/index.js +45 -0
  361. package/src/tools/oapi/helpers.d.ts +183 -0
  362. package/src/tools/oapi/helpers.js +385 -0
  363. package/src/tools/oapi/im/format-messages.d.ts +50 -0
  364. package/src/tools/oapi/im/format-messages.js +169 -0
  365. package/src/tools/oapi/im/index.d.ts +10 -0
  366. package/src/tools/oapi/im/index.js +25 -0
  367. package/src/tools/oapi/im/message-read.d.ts +13 -0
  368. package/src/tools/oapi/im/message-read.js +419 -0
  369. package/src/tools/oapi/im/message.d.ts +16 -0
  370. package/src/tools/oapi/im/message.js +152 -0
  371. package/src/tools/oapi/im/resource.d.ts +13 -0
  372. package/src/tools/oapi/im/resource.js +186 -0
  373. package/src/tools/oapi/im/time-utils.d.ts +46 -0
  374. package/src/tools/oapi/im/time-utils.js +212 -0
  375. package/src/tools/oapi/im/user-name-uat.d.ts +26 -0
  376. package/src/tools/oapi/im/user-name-uat.js +143 -0
  377. package/src/tools/oapi/index.d.ts +11 -0
  378. package/src/tools/oapi/index.js +64 -0
  379. package/src/tools/oapi/sdk-types.d.ts +96 -0
  380. package/src/tools/oapi/sdk-types.js +13 -0
  381. package/src/tools/oapi/search/doc-search.d.ts +13 -0
  382. package/src/tools/oapi/search/doc-search.js +194 -0
  383. package/src/tools/oapi/search/index.d.ts +12 -0
  384. package/src/tools/oapi/search/index.js +37 -0
  385. package/src/tools/oapi/sheets/index.d.ts +12 -0
  386. package/src/tools/oapi/sheets/index.js +35 -0
  387. package/src/tools/oapi/sheets/sheet.d.ts +16 -0
  388. package/src/tools/oapi/sheets/sheet.js +688 -0
  389. package/src/tools/oapi/task/attachment.d.ts +18 -0
  390. package/src/tools/oapi/task/attachment.js +107 -0
  391. package/src/tools/oapi/task/comment.d.ts +15 -0
  392. package/src/tools/oapi/task/comment.js +149 -0
  393. package/src/tools/oapi/task/index.d.ts +11 -0
  394. package/src/tools/oapi/task/index.js +21 -0
  395. package/src/tools/oapi/task/section.d.ts +17 -0
  396. package/src/tools/oapi/task/section.js +293 -0
  397. package/src/tools/oapi/task/subtask.d.ts +14 -0
  398. package/src/tools/oapi/task/subtask.js +171 -0
  399. package/src/tools/oapi/task/task.d.ts +19 -0
  400. package/src/tools/oapi/task/task.js +512 -0
  401. package/src/tools/oapi/task/task_agent.d.ts +14 -0
  402. package/src/tools/oapi/task/task_agent.js +108 -0
  403. package/src/tools/oapi/task/tasklist.d.ts +19 -0
  404. package/src/tools/oapi/task/tasklist.js +276 -0
  405. package/src/tools/oapi/wiki/index.d.ts +12 -0
  406. package/src/tools/oapi/wiki/index.js +42 -0
  407. package/src/tools/oapi/wiki/space-node.d.ts +17 -0
  408. package/src/tools/oapi/wiki/space-node.js +233 -0
  409. package/src/tools/oapi/wiki/space.d.ts +15 -0
  410. package/src/tools/oapi/wiki/space.js +133 -0
  411. package/src/tools/oauth-batch-auth.d.ts +11 -0
  412. package/src/tools/oauth-batch-auth.js +150 -0
  413. package/src/tools/oauth-cards.d.ts +39 -0
  414. package/src/tools/oauth-cards.js +324 -0
  415. package/src/tools/oauth.d.ts +47 -0
  416. package/src/tools/oauth.js +592 -0
  417. package/src/tools/onboarding-auth.d.ts +27 -0
  418. package/src/tools/onboarding-auth.js +133 -0
  419. package/src/tools/tat/im/index.d.ts +15 -0
  420. package/src/tools/tat/im/index.js +22 -0
  421. package/src/tools/tat/im/resource.d.ts +15 -0
  422. package/src/tools/tat/im/resource.js +192 -0
  423. package/tsdown.config.d.ts +2 -0
  424. package/tsdown.config.js +25 -0
  425. package/vitest.config.d.ts +2 -0
  426. package/vitest.config.js +12 -0
@@ -0,0 +1,712 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * feishu_calendar_event tool -- Manage Feishu calendar events.
7
+ *
8
+ * P0 Actions: create, list, get
9
+ *
10
+ * Uses the Feishu Calendar API:
11
+ * - create: POST /open-apis/calendar/v4/calendars/:calendar_id/events
12
+ * POST /open-apis/calendar/v4/calendars/:calendar_id/events/:event_id/attendees/batch_create
13
+ * - list: GET /open-apis/calendar/v4/calendars/:calendar_id/events/instance_view
14
+ * - get: GET /open-apis/calendar/v4/calendars/:calendar_id/events/:event_id
15
+ */
16
+ /* eslint-disable @typescript-eslint/no-explicit-any */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.registerFeishuCalendarEventTool = registerFeishuCalendarEventTool;
19
+ const typebox_1 = require("@sinclair/typebox");
20
+ const helpers_1 = require("../helpers.js");
21
+ // ---------------------------------------------------------------------------
22
+ // Schema
23
+ // ---------------------------------------------------------------------------
24
+ const FeishuCalendarEventSchema = typebox_1.Type.Union([
25
+ // CREATE
26
+ typebox_1.Type.Object({
27
+ action: typebox_1.Type.Literal('create'),
28
+ start_time: typebox_1.Type.String({
29
+ description: "开始时间(必填)。ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00'",
30
+ }),
31
+ end_time: typebox_1.Type.String({
32
+ description: '结束时间(必填)。格式同 start_time。如果用户未指定时长,默认为开始时间后1小时。',
33
+ }),
34
+ summary: typebox_1.Type.Optional(typebox_1.Type.String({
35
+ description: '日程标题(可选,但强烈建议提供)',
36
+ })),
37
+ user_open_id: typebox_1.Type.Optional(typebox_1.Type.String({
38
+ description: '当前请求用户的 open_id(可选,但强烈建议提供)。从消息上下文的 SenderId 字段获取,格式为 ou_xxx。日程创建在应用日历上,必须通过此参数将用户加为参会人,日程才会出现在用户的飞书日历中。',
39
+ })),
40
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
41
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
42
+ })),
43
+ description: typebox_1.Type.Optional(typebox_1.Type.String({
44
+ description: '日程描述',
45
+ })),
46
+ attendees: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.Object({
47
+ type: (0, helpers_1.StringEnum)(['user', 'chat', 'resource', 'third_party']),
48
+ id: typebox_1.Type.String({
49
+ description: 'Attendee open_id, chat_id, resource_id, or email',
50
+ }),
51
+ }), {
52
+ description: "参会人列表(强烈建议提供,否则日程只在应用日历上,用户看不到)。type='user' 时 id 填 open_id,type='third_party' 时 id 填邮箱。",
53
+ })),
54
+ vchat: typebox_1.Type.Optional(typebox_1.Type.Object({
55
+ vc_type: typebox_1.Type.Optional((0, helpers_1.StringEnum)(['vc', 'third_party', 'no_meeting'], {
56
+ description: '视频会议类型:vc(飞书视频会议)、third_party(第三方链接)、no_meeting(无视频会议)。默认为空,首次添加参与人时自动生成飞书视频会议。',
57
+ })),
58
+ icon_type: typebox_1.Type.Optional((0, helpers_1.StringEnum)(['vc', 'live', 'default'], {
59
+ description: '第三方视频会议 icon 类型(仅 vc_type=third_party 时有效)。',
60
+ })),
61
+ description: typebox_1.Type.Optional(typebox_1.Type.String({
62
+ description: '第三方视频会议文案(仅 vc_type=third_party 时有效)。',
63
+ })),
64
+ meeting_url: typebox_1.Type.Optional(typebox_1.Type.String({
65
+ description: '第三方视频会议链接(仅 vc_type=third_party 时有效)。',
66
+ })),
67
+ }, {
68
+ description: '视频会议信息。不传则默认在首次添加参与人时自动生成飞书视频会议。',
69
+ })),
70
+ visibility: typebox_1.Type.Optional((0, helpers_1.StringEnum)(['default', 'public', 'private'], {
71
+ description: '日程公开范围。default(默认,跟随日历权限)、public(公开详情)、private(私密,仅自己可见)。默认值:default。',
72
+ })),
73
+ attendee_ability: typebox_1.Type.Optional((0, helpers_1.StringEnum)(['none', 'can_see_others', 'can_invite_others', 'can_modify_event'], {
74
+ description: '参与人权限。none(无法编辑、邀请、查看)、can_see_others(可查看参与人列表)、can_invite_others(可邀请其他人)、can_modify_event(可编辑日程)。默认值:none。',
75
+ })),
76
+ free_busy_status: typebox_1.Type.Optional((0, helpers_1.StringEnum)(['busy', 'free'], {
77
+ description: '日程占用的忙闲状态。busy(忙碌)、free(空闲)。默认值:busy。',
78
+ })),
79
+ location: typebox_1.Type.Optional(typebox_1.Type.Object({
80
+ name: typebox_1.Type.Optional(typebox_1.Type.String({
81
+ description: '地点名称',
82
+ })),
83
+ address: typebox_1.Type.Optional(typebox_1.Type.String({
84
+ description: '地点地址',
85
+ })),
86
+ latitude: typebox_1.Type.Optional(typebox_1.Type.Number({
87
+ description: '地点坐标纬度(国内采用 GCJ-02 标准,海外采用 WGS84 标准)',
88
+ })),
89
+ longitude: typebox_1.Type.Optional(typebox_1.Type.Number({
90
+ description: '地点坐标经度(国内采用 GCJ-02 标准,海外采用 WGS84 标准)',
91
+ })),
92
+ }, {
93
+ description: '日程地点信息',
94
+ })),
95
+ reminders: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.Object({
96
+ minutes: typebox_1.Type.Number({
97
+ description: '日程提醒时间的偏移量(分钟)。正数表示在日程开始前提醒,负数表示在日程开始后提醒。范围:-20160 ~ 20160。',
98
+ }),
99
+ }), {
100
+ description: '日程提醒列表',
101
+ })),
102
+ recurrence: typebox_1.Type.Optional(typebox_1.Type.String({
103
+ description: "重复日程的重复性规则(RFC5545 RRULE 格式)。例如:'FREQ=DAILY;INTERVAL=1' 表示每天重复。",
104
+ })),
105
+ }),
106
+ // LIST (使用 instance_view 接口)
107
+ typebox_1.Type.Object({
108
+ action: typebox_1.Type.Literal('list'),
109
+ start_time: typebox_1.Type.String({
110
+ description: "开始时间。ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00'。注意:start_time 与 end_time 之间的时间区间需要小于 40 天。",
111
+ }),
112
+ end_time: typebox_1.Type.String({
113
+ description: '结束时间。格式同 start_time。注意:start_time 与 end_time 之间的时间区间需要小于 40 天。',
114
+ }),
115
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
116
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
117
+ })),
118
+ }),
119
+ // GET
120
+ typebox_1.Type.Object({
121
+ action: typebox_1.Type.Literal('get'),
122
+ event_id: typebox_1.Type.String({
123
+ description: 'Event ID',
124
+ }),
125
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
126
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
127
+ })),
128
+ }),
129
+ // PATCH (P1)
130
+ typebox_1.Type.Object({
131
+ action: typebox_1.Type.Literal('patch'),
132
+ event_id: typebox_1.Type.String({
133
+ description: 'Event ID',
134
+ }),
135
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
136
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
137
+ })),
138
+ summary: typebox_1.Type.Optional(typebox_1.Type.String({
139
+ description: '新的日程标题',
140
+ })),
141
+ description: typebox_1.Type.Optional(typebox_1.Type.String({
142
+ description: '新的日程描述',
143
+ })),
144
+ start_time: typebox_1.Type.Optional(typebox_1.Type.String({
145
+ description: "新的开始时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
146
+ })),
147
+ end_time: typebox_1.Type.Optional(typebox_1.Type.String({
148
+ description: "新的结束时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
149
+ })),
150
+ location: typebox_1.Type.Optional(typebox_1.Type.String({
151
+ description: '新的地点',
152
+ })),
153
+ }),
154
+ // DELETE (P1)
155
+ typebox_1.Type.Object({
156
+ action: typebox_1.Type.Literal('delete'),
157
+ event_id: typebox_1.Type.String({
158
+ description: 'Event ID',
159
+ }),
160
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
161
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
162
+ })),
163
+ need_notification: typebox_1.Type.Optional(typebox_1.Type.Boolean({
164
+ description: '是否通知参会人(默认 true)',
165
+ })),
166
+ }),
167
+ // SEARCH (P1)
168
+ typebox_1.Type.Object({
169
+ action: typebox_1.Type.Literal('search'),
170
+ query: typebox_1.Type.String({
171
+ description: '搜索关键词',
172
+ }),
173
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
174
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
175
+ })),
176
+ page_size: typebox_1.Type.Optional(typebox_1.Type.Number({
177
+ description: '每页数量',
178
+ })),
179
+ page_token: typebox_1.Type.Optional(typebox_1.Type.String({
180
+ description: '分页标记',
181
+ })),
182
+ }),
183
+ // REPLY (P1)
184
+ typebox_1.Type.Object({
185
+ action: typebox_1.Type.Literal('reply'),
186
+ event_id: typebox_1.Type.String({
187
+ description: 'Event ID',
188
+ }),
189
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
190
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
191
+ })),
192
+ rsvp_status: (0, helpers_1.StringEnum)(['accept', 'decline', 'tentative']),
193
+ }),
194
+ // INSTANCES (P1)
195
+ typebox_1.Type.Object({
196
+ action: typebox_1.Type.Literal('instances'),
197
+ event_id: typebox_1.Type.String({
198
+ description: '重复日程的 Event ID',
199
+ }),
200
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
201
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
202
+ })),
203
+ start_time: typebox_1.Type.String({
204
+ description: "查询起始时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
205
+ }),
206
+ end_time: typebox_1.Type.String({
207
+ description: "查询结束时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
208
+ }),
209
+ page_size: typebox_1.Type.Optional(typebox_1.Type.Number({
210
+ description: '每页数量',
211
+ })),
212
+ page_token: typebox_1.Type.Optional(typebox_1.Type.String({
213
+ description: '分页标记',
214
+ })),
215
+ }),
216
+ // INSTANCE_VIEW (P1)
217
+ typebox_1.Type.Object({
218
+ action: typebox_1.Type.Literal('instance_view'),
219
+ start_time: typebox_1.Type.String({
220
+ description: "查询起始时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
221
+ }),
222
+ end_time: typebox_1.Type.String({
223
+ description: "查询结束时间(ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00')",
224
+ }),
225
+ calendar_id: typebox_1.Type.Optional(typebox_1.Type.String({
226
+ description: 'Calendar ID (optional; primary calendar used if omitted)',
227
+ })),
228
+ page_size: typebox_1.Type.Optional(typebox_1.Type.Number({
229
+ description: '每页数量',
230
+ })),
231
+ page_token: typebox_1.Type.Optional(typebox_1.Type.String({
232
+ description: '分页标记',
233
+ })),
234
+ }),
235
+ ]);
236
+ function normalizeCalendarTimeValue(value) {
237
+ if (value == null || value === undefined)
238
+ return undefined;
239
+ if (typeof value === 'string') {
240
+ const iso = (0, helpers_1.unixTimestampToISO8601)(value);
241
+ return iso ?? value;
242
+ }
243
+ if (typeof value !== 'object')
244
+ return undefined;
245
+ const timeObj = value;
246
+ const fromTimestamp = (0, helpers_1.unixTimestampToISO8601)(timeObj.timestamp);
247
+ if (fromTimestamp)
248
+ return fromTimestamp;
249
+ if (typeof timeObj.date === 'string')
250
+ return timeObj.date;
251
+ return undefined;
252
+ }
253
+ function normalizeEventTimeFields(event) {
254
+ if (!event)
255
+ return event;
256
+ const normalized = { ...event };
257
+ const startTime = normalizeCalendarTimeValue(event.start_time);
258
+ if (startTime) {
259
+ normalized.start_time = startTime;
260
+ }
261
+ const endTime = normalizeCalendarTimeValue(event.end_time);
262
+ if (endTime) {
263
+ normalized.end_time = endTime;
264
+ }
265
+ const createTime = (0, helpers_1.unixTimestampToISO8601)(event.create_time);
266
+ if (createTime) {
267
+ normalized.create_time = createTime;
268
+ }
269
+ return normalized;
270
+ }
271
+ function normalizeEventListTimeFields(events) {
272
+ if (!events)
273
+ return events;
274
+ return events.map((item) => normalizeEventTimeFields(item));
275
+ }
276
+ // ---------------------------------------------------------------------------
277
+ // Registration
278
+ // ---------------------------------------------------------------------------
279
+ function registerFeishuCalendarEventTool(api) {
280
+ if (!api.config)
281
+ return;
282
+ const cfg = api.config;
283
+ const { toolClient, log } = (0, helpers_1.createToolContext)(api, 'feishu_calendar_event');
284
+ const resolveCalendarId = async (client) => {
285
+ const primaryRes = await client.invoke('feishu_calendar_calendar.primary', (sdk, opts) => sdk.calendar.calendar.primary({}, opts), { as: 'user' });
286
+ const data = primaryRes.data;
287
+ const cid = data?.calendars?.[0]?.calendar?.calendar_id;
288
+ if (cid) {
289
+ log.info(`resolveCalendarId: primary() returned calendar_id=${cid}`);
290
+ return cid;
291
+ }
292
+ return null;
293
+ };
294
+ const resolveCalendarIdOrFail = async (calendarId, client) => {
295
+ if (calendarId)
296
+ return calendarId;
297
+ const resolved = await resolveCalendarId(client);
298
+ if (!resolved)
299
+ throw new Error('Could not determine primary calendar');
300
+ return resolved;
301
+ };
302
+ (0, helpers_1.registerTool)(api, {
303
+ name: 'feishu_calendar_event',
304
+ label: 'Feishu Calendar Events',
305
+ description: "【以用户身份】飞书日程管理工具。当用户要求查看日程、创建会议、约会议、修改日程、删除日程、搜索日程、回复日程邀请时使用。Actions: create(创建日历事件), list(查询时间范围内的日程,自动展开重复日程), get(获取日程详情), patch(更新日程), delete(删除日程), search(搜索日程), reply(回复日程邀请), instances(获取重复日程的实例列表,仅对重复日程有效), instance_view(查看展开后的日程列表)。【重要】create 时必须传 user_open_id 参数,值为消息上下文中的 SenderId(格式 ou_xxx),否则日程只在应用日历上,用户完全看不到。list 操作使用 instance_view 接口,会自动展开重复日程为多个实例,时间区间不能超过40天,返回实例数量上限1000。时间参数使用ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00'。",
306
+ parameters: FeishuCalendarEventSchema,
307
+ async execute(_toolCallId, params) {
308
+ const p = params;
309
+ try {
310
+ const client = toolClient();
311
+ switch (p.action) {
312
+ // -----------------------------------------------------------------
313
+ // CREATE EVENT
314
+ // -----------------------------------------------------------------
315
+ case 'create': {
316
+ if (!p.summary)
317
+ return (0, helpers_1.json)({ error: 'summary is required' });
318
+ if (!p.start_time)
319
+ return (0, helpers_1.json)({ error: 'start_time is required' });
320
+ if (!p.end_time)
321
+ return (0, helpers_1.json)({ error: 'end_time is required' });
322
+ const startTs = (0, helpers_1.parseTimeToTimestamp)(p.start_time);
323
+ const endTs = (0, helpers_1.parseTimeToTimestamp)(p.end_time);
324
+ if (!startTs || !endTs)
325
+ return (0, helpers_1.json)({
326
+ error: "Invalid time format. Must use ISO 8601 / RFC 3339 with timezone, e.g. '2024-01-01T00:00:00+08:00' or '2026-02-25 14:00:00'. Do not pass Unix timestamp numbers.",
327
+ received_start: p.start_time,
328
+ received_end: p.end_time,
329
+ });
330
+ log.info(`create: summary=${p.summary}, start_time=${p.start_time} -> ts=${startTs}, end_time=${p.end_time} -> ts=${endTs}, user_open_id=${p.user_open_id ?? 'MISSING'}, attendees=${JSON.stringify(p.attendees ?? [])}, vchat=${p.vchat?.vc_type ?? 'auto'}, location=${p.location?.name ?? 'none'}`);
331
+ // Resolve bot's calendar
332
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
333
+ const eventData = {
334
+ summary: p.summary,
335
+ start_time: { timestamp: startTs },
336
+ end_time: { timestamp: endTs },
337
+ need_notification: true,
338
+ attendee_ability: p.attendee_ability ?? 'can_modify_event',
339
+ };
340
+ if (p.description)
341
+ eventData.description = p.description;
342
+ // 视频会议配置
343
+ if (p.vchat) {
344
+ eventData.vchat = {};
345
+ if (p.vchat.vc_type)
346
+ eventData.vchat.vc_type = p.vchat.vc_type;
347
+ if (p.vchat.icon_type)
348
+ eventData.vchat.icon_type = p.vchat.icon_type;
349
+ if (p.vchat.description)
350
+ eventData.vchat.description = p.vchat.description;
351
+ if (p.vchat.meeting_url)
352
+ eventData.vchat.meeting_url = p.vchat.meeting_url;
353
+ }
354
+ // 公开范围
355
+ if (p.visibility)
356
+ eventData.visibility = p.visibility;
357
+ // 忙闲状态
358
+ if (p.free_busy_status)
359
+ eventData.free_busy_status = p.free_busy_status;
360
+ // 地点信息
361
+ if (p.location) {
362
+ eventData.location = {};
363
+ if (p.location.name)
364
+ eventData.location.name = p.location.name;
365
+ if (p.location.address)
366
+ eventData.location.address = p.location.address;
367
+ if (p.location.latitude !== undefined)
368
+ eventData.location.latitude = p.location.latitude;
369
+ if (p.location.longitude !== undefined)
370
+ eventData.location.longitude = p.location.longitude;
371
+ }
372
+ // 提醒列表
373
+ if (p.reminders) {
374
+ eventData.reminders = p.reminders.map((r) => ({ minutes: r.minutes }));
375
+ }
376
+ // 重复规则
377
+ if (p.recurrence)
378
+ eventData.recurrence = p.recurrence;
379
+ const res = await client.invoke('feishu_calendar_event.create', (sdk, opts) => sdk.calendar.calendarEvent.create({
380
+ path: { calendar_id: calendarId },
381
+ data: eventData,
382
+ }, opts), { as: 'user' });
383
+ (0, helpers_1.assertLarkOk)(res);
384
+ log.info(`event created: event_id=${res.data?.event?.event_id}`);
385
+ // Build attendee list: merge explicit attendees + user_open_id
386
+ const allAttendees = [...(p.attendees ?? [])];
387
+ if (p.user_open_id) {
388
+ const alreadyIncluded = allAttendees.some((a) => a.type === 'user' && a.id === p.user_open_id);
389
+ if (!alreadyIncluded) {
390
+ allAttendees.push({ type: 'user', id: p.user_open_id });
391
+ }
392
+ }
393
+ log.info(`allAttendees=${JSON.stringify(allAttendees)}`);
394
+ let attendeeError;
395
+ const operateId = p.user_open_id ?? p.attendees?.find((a) => a.type === 'user')?.id;
396
+ if (allAttendees.length > 0 && res.data?.event?.event_id) {
397
+ const attendeeData = allAttendees.map((a) => ({
398
+ type: a.type,
399
+ user_id: a.type === 'user' ? a.id : undefined,
400
+ chat_id: a.type === 'chat' ? a.id : undefined,
401
+ room_id: a.type === 'resource' ? a.id : undefined,
402
+ third_party_email: a.type === 'third_party' ? a.id : undefined,
403
+ operate_id: operateId,
404
+ }));
405
+ try {
406
+ const attendeeRes = await client.invoke('feishu_calendar_event.create', (sdk, opts) => sdk.calendar.calendarEventAttendee.create({
407
+ path: {
408
+ calendar_id: calendarId,
409
+ event_id: res.data?.event?.event_id ?? '',
410
+ },
411
+ params: { user_id_type: 'open_id' },
412
+ data: {
413
+ attendees: attendeeData,
414
+ need_notification: true,
415
+ },
416
+ }, opts), { as: 'user' });
417
+ (0, helpers_1.assertLarkOk)(attendeeRes);
418
+ log.info(`attendee API response: ${JSON.stringify(attendeeRes.data)}`);
419
+ }
420
+ catch (attendeeErr) {
421
+ attendeeError = (0, helpers_1.formatLarkError)(attendeeErr);
422
+ log.info(`attendee add FAILED: ${attendeeError}`);
423
+ }
424
+ }
425
+ // Strip calendarId from app_link — it points to bot's calendar, users can't access it
426
+ const appLink = res.data?.event?.app_link;
427
+ const safeEvent = res.data?.event
428
+ ? {
429
+ event_id: res.data.event.event_id,
430
+ summary: res.data.event.summary,
431
+ app_link: appLink,
432
+ start_time: (0, helpers_1.unixTimestampToISO8601)(startTs) ?? p.start_time,
433
+ end_time: (0, helpers_1.unixTimestampToISO8601)(endTs) ?? p.end_time,
434
+ }
435
+ : undefined;
436
+ const result = {
437
+ event: safeEvent,
438
+ attendees: allAttendees.map((a) => ({
439
+ type: a.type,
440
+ id: a.id,
441
+ })),
442
+ _debug: {
443
+ calendar_id: calendarId,
444
+ operate_id: operateId,
445
+ start_input: p.start_time,
446
+ start_iso8601: (0, helpers_1.unixTimestampToISO8601)(startTs) ?? p.start_time,
447
+ end_input: p.end_time,
448
+ end_iso8601: (0, helpers_1.unixTimestampToISO8601)(endTs) ?? p.end_time,
449
+ attendees_count: allAttendees.length,
450
+ },
451
+ };
452
+ if (attendeeError) {
453
+ result.warning = `日程已创建,但添加参会人失败:${attendeeError}`;
454
+ }
455
+ else if (allAttendees.length === 0) {
456
+ result.error =
457
+ '日程已创建在应用日历上,但未添加任何参会人,用户看不到此日程。请重新调用时传入 user_open_id 参数。';
458
+ }
459
+ else {
460
+ result.note = `已成功添加 ${allAttendees.length} 位参会人,日程应出现在参会人的飞书日历中。`;
461
+ }
462
+ return (0, helpers_1.json)(result);
463
+ }
464
+ // -----------------------------------------------------------------
465
+ // LIST EVENTS (使用 instance_view 接口,自动展开重复日程)
466
+ // -----------------------------------------------------------------
467
+ case 'list': {
468
+ if (!p.start_time)
469
+ return (0, helpers_1.json)({ error: 'start_time is required' });
470
+ if (!p.end_time)
471
+ return (0, helpers_1.json)({ error: 'end_time is required' });
472
+ const startTs = (0, helpers_1.parseTimeToTimestamp)(p.start_time);
473
+ const endTs = (0, helpers_1.parseTimeToTimestamp)(p.end_time);
474
+ if (!startTs || !endTs)
475
+ return (0, helpers_1.json)({
476
+ error: "Invalid time format. Must use ISO 8601 / RFC 3339 with timezone, e.g. '2024-01-01T00:00:00+08:00' or '2026-02-25 14:00:00'. Do not pass Unix timestamps.",
477
+ received_start: p.start_time,
478
+ received_end: p.end_time,
479
+ });
480
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
481
+ log.info(`list: calendar_id=${calendarId}, start_time=${startTs}, end_time=${endTs} (using instance_view)`);
482
+ const res = await client.invoke('feishu_calendar_event.instance_view', (sdk, opts) => sdk.calendar.calendarEvent.instanceView({
483
+ path: { calendar_id: calendarId },
484
+ params: {
485
+ start_time: startTs,
486
+ end_time: endTs,
487
+ user_id_type: 'open_id',
488
+ },
489
+ }, opts), { as: 'user' });
490
+ (0, helpers_1.assertLarkOk)(res);
491
+ const data = res.data;
492
+ log.info(`list: returned ${data?.items?.length ?? 0} event instances`);
493
+ return (0, helpers_1.json)({
494
+ events: normalizeEventListTimeFields(data?.items),
495
+ has_more: data?.has_more ?? false,
496
+ page_token: data?.page_token,
497
+ });
498
+ }
499
+ // -----------------------------------------------------------------
500
+ // GET EVENT
501
+ // -----------------------------------------------------------------
502
+ case 'get': {
503
+ if (!p.event_id)
504
+ return (0, helpers_1.json)({ error: 'event_id is required' });
505
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
506
+ log.info(`get: calendar_id=${calendarId}, event_id=${p.event_id}`);
507
+ const res = await client.invoke('feishu_calendar_event.get', (sdk, opts) => sdk.calendar.calendarEvent.get({
508
+ path: { calendar_id: calendarId, event_id: p.event_id },
509
+ }, opts), { as: 'user' });
510
+ (0, helpers_1.assertLarkOk)(res);
511
+ log.info(`get: retrieved event ${p.event_id}`);
512
+ return (0, helpers_1.json)({
513
+ event: normalizeEventTimeFields(res.data?.event),
514
+ });
515
+ }
516
+ // -----------------------------------------------------------------
517
+ // PATCH EVENT (P1)
518
+ // -----------------------------------------------------------------
519
+ case 'patch': {
520
+ if (!p.event_id)
521
+ return (0, helpers_1.json)({ error: 'event_id is required' });
522
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
523
+ const updateData = {};
524
+ // Handle time conversion if provided
525
+ if (p.start_time) {
526
+ const startTs = (0, helpers_1.parseTimeToTimestamp)(p.start_time);
527
+ if (!startTs)
528
+ return (0, helpers_1.json)({
529
+ error: "start_time 格式错误!必须使用ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00'",
530
+ received: p.start_time,
531
+ });
532
+ updateData.start_time = { timestamp: startTs };
533
+ }
534
+ if (p.end_time) {
535
+ const endTs = (0, helpers_1.parseTimeToTimestamp)(p.end_time);
536
+ if (!endTs)
537
+ return (0, helpers_1.json)({
538
+ error: "end_time 格式错误!必须使用ISO 8601 / RFC 3339 格式(包含时区),例如 '2024-01-01T00:00:00+08:00'",
539
+ received: p.end_time,
540
+ });
541
+ updateData.end_time = { timestamp: endTs };
542
+ }
543
+ if (p.summary)
544
+ updateData.summary = p.summary;
545
+ if (p.description)
546
+ updateData.description = p.description;
547
+ if (p.location)
548
+ updateData.location = { name: p.location };
549
+ log.info(`patch: calendar_id=${calendarId}, event_id=${p.event_id}, fields=${Object.keys(updateData).join(',')}`);
550
+ const res = await client.invoke('feishu_calendar_event.patch', (sdk, opts) => sdk.calendar.calendarEvent.patch({
551
+ path: { calendar_id: calendarId, event_id: p.event_id },
552
+ data: updateData,
553
+ }, opts), { as: 'user' });
554
+ (0, helpers_1.assertLarkOk)(res);
555
+ log.info(`patch: updated event ${p.event_id}`);
556
+ return (0, helpers_1.json)({
557
+ event: normalizeEventTimeFields(res.data?.event),
558
+ });
559
+ }
560
+ // -----------------------------------------------------------------
561
+ // DELETE EVENT (P1)
562
+ // -----------------------------------------------------------------
563
+ case 'delete': {
564
+ if (!p.event_id)
565
+ return (0, helpers_1.json)({ error: 'event_id is required' });
566
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
567
+ log.info(`delete: calendar_id=${calendarId}, event_id=${p.event_id}, notify=${p.need_notification ?? true}`);
568
+ const res = await client.invoke('feishu_calendar_event.delete', (sdk, opts) => sdk.calendar.calendarEvent.delete({
569
+ path: { calendar_id: calendarId, event_id: p.event_id },
570
+ params: {
571
+ need_notification: (p.need_notification ?? true),
572
+ },
573
+ }, opts), { as: 'user' });
574
+ (0, helpers_1.assertLarkOk)(res);
575
+ log.info(`delete: deleted event ${p.event_id}`);
576
+ return (0, helpers_1.json)({
577
+ success: true,
578
+ event_id: p.event_id,
579
+ });
580
+ }
581
+ // -----------------------------------------------------------------
582
+ // SEARCH EVENT (P1)
583
+ // -----------------------------------------------------------------
584
+ case 'search': {
585
+ if (!p.query)
586
+ return (0, helpers_1.json)({ error: 'query is required' });
587
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
588
+ log.info(`search: calendar_id=${calendarId}, query=${p.query}, page_size=${p.page_size ?? 50}`);
589
+ const res = await client.invoke('feishu_calendar_event.search', (sdk, opts) => sdk.calendar.calendarEvent.search({
590
+ path: { calendar_id: calendarId },
591
+ params: {
592
+ page_size: p.page_size,
593
+ page_token: p.page_token,
594
+ },
595
+ data: {
596
+ query: p.query,
597
+ },
598
+ }, opts), { as: 'user' });
599
+ (0, helpers_1.assertLarkOk)(res);
600
+ const data = res.data;
601
+ log.info(`search: found ${data?.items?.length ?? 0} events`);
602
+ return (0, helpers_1.json)({
603
+ events: normalizeEventListTimeFields(data?.items),
604
+ has_more: data?.has_more ?? false,
605
+ page_token: data?.page_token,
606
+ });
607
+ }
608
+ // -----------------------------------------------------------------
609
+ // REPLY EVENT (P1)
610
+ // -----------------------------------------------------------------
611
+ case 'reply': {
612
+ if (!p.event_id)
613
+ return (0, helpers_1.json)({ error: 'event_id is required' });
614
+ if (!p.rsvp_status)
615
+ return (0, helpers_1.json)({ error: 'rsvp_status is required' });
616
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
617
+ log.info(`reply: calendar_id=${calendarId}, event_id=${p.event_id}, rsvp=${p.rsvp_status}`);
618
+ const res = await client.invoke('feishu_calendar_event.reply', (sdk, opts) => sdk.calendar.calendarEvent.reply({
619
+ path: { calendar_id: calendarId, event_id: p.event_id },
620
+ data: {
621
+ rsvp_status: p.rsvp_status,
622
+ },
623
+ }, opts), { as: 'user' });
624
+ (0, helpers_1.assertLarkOk)(res);
625
+ log.info(`reply: replied to event ${p.event_id} with ${p.rsvp_status}`);
626
+ return (0, helpers_1.json)({
627
+ success: true,
628
+ event_id: p.event_id,
629
+ rsvp_status: p.rsvp_status,
630
+ });
631
+ }
632
+ // -----------------------------------------------------------------
633
+ // INSTANCES (P1)
634
+ // -----------------------------------------------------------------
635
+ case 'instances': {
636
+ if (!p.event_id)
637
+ return (0, helpers_1.json)({ error: 'event_id is required' });
638
+ if (!p.start_time)
639
+ return (0, helpers_1.json)({ error: 'start_time is required' });
640
+ if (!p.end_time)
641
+ return (0, helpers_1.json)({ error: 'end_time is required' });
642
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
643
+ const startTs = (0, helpers_1.parseTimeToTimestamp)(p.start_time);
644
+ const endTs = (0, helpers_1.parseTimeToTimestamp)(p.end_time);
645
+ if (!startTs || !endTs)
646
+ return (0, helpers_1.json)({
647
+ error: "Invalid time format. Must use ISO 8601 / RFC 3339 with timezone, e.g. '2024-01-01T00:00:00+08:00'",
648
+ received_start: p.start_time,
649
+ received_end: p.end_time,
650
+ });
651
+ log.info(`instances: calendar_id=${calendarId}, event_id=${p.event_id}, start=${startTs}, end=${endTs}`);
652
+ const res = await client.invoke('feishu_calendar_event.instances', (sdk, opts) => sdk.calendar.calendarEvent.instances({
653
+ path: { calendar_id: calendarId, event_id: p.event_id },
654
+ params: {
655
+ start_time: startTs,
656
+ end_time: endTs,
657
+ page_size: p.page_size,
658
+ page_token: p.page_token,
659
+ },
660
+ }, opts), { as: 'user' });
661
+ (0, helpers_1.assertLarkOk)(res);
662
+ const data = res.data;
663
+ log.info(`instances: returned ${data?.items?.length ?? 0} instances`);
664
+ return (0, helpers_1.json)({
665
+ instances: normalizeEventListTimeFields(data?.items),
666
+ has_more: data?.has_more ?? false,
667
+ page_token: data?.page_token,
668
+ });
669
+ }
670
+ // -----------------------------------------------------------------
671
+ // INSTANCE_VIEW (P1)
672
+ // -----------------------------------------------------------------
673
+ case 'instance_view': {
674
+ if (!p.start_time)
675
+ return (0, helpers_1.json)({ error: 'start_time is required' });
676
+ if (!p.end_time)
677
+ return (0, helpers_1.json)({ error: 'end_time is required' });
678
+ const calendarId = await resolveCalendarIdOrFail(p.calendar_id, client);
679
+ const startTs = (0, helpers_1.parseTimeToTimestamp)(p.start_time);
680
+ const endTs = (0, helpers_1.parseTimeToTimestamp)(p.end_time);
681
+ if (!startTs || !endTs)
682
+ return (0, helpers_1.json)({
683
+ error: "Invalid time format. Must use ISO 8601 / RFC 3339 with timezone, e.g. '2024-01-01T00:00:00+08:00'",
684
+ received_start: p.start_time,
685
+ received_end: p.end_time,
686
+ });
687
+ log.info(`instance_view: calendar_id=${calendarId}, start=${startTs}, end=${endTs}`);
688
+ const res = await client.invoke('feishu_calendar_event.instance_view', (sdk, opts) => sdk.calendar.calendarEvent.instanceView({
689
+ path: { calendar_id: calendarId },
690
+ params: {
691
+ start_time: startTs,
692
+ end_time: endTs,
693
+ user_id_type: 'open_id',
694
+ },
695
+ }, opts), { as: 'user' });
696
+ (0, helpers_1.assertLarkOk)(res);
697
+ const data = res.data;
698
+ log.info(`instance_view: returned ${data?.items?.length ?? 0} events`);
699
+ return (0, helpers_1.json)({
700
+ events: normalizeEventListTimeFields(data?.items),
701
+ has_more: data?.has_more ?? false,
702
+ page_token: data?.page_token,
703
+ });
704
+ }
705
+ }
706
+ }
707
+ catch (err) {
708
+ return await (0, helpers_1.handleInvokeErrorWithAutoAuth)(err, cfg);
709
+ }
710
+ },
711
+ }, { name: 'feishu_calendar_event' });
712
+ }