@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,223 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Zod-based configuration schema for the OpenClaw Lark/Feishu channel plugin.
7
+ *
8
+ * Provides runtime validation, sensible defaults, and cross-field refinements
9
+ * so that every consuming module can rely on well-typed configuration objects.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FEISHU_CONFIG_JSON_SCHEMA = exports.FeishuConfigSchema = exports.FeishuAccountConfigSchema = exports.FeishuGroupSchema = exports.UATConfigSchema = exports.z = void 0;
13
+ const zod_1 = require("zod");
14
+ Object.defineProperty(exports, "z", { enumerable: true, get: function () { return zod_1.z; } });
15
+ // ---------------------------------------------------------------------------
16
+ // Shared micro-schemas
17
+ // ---------------------------------------------------------------------------
18
+ const DmPolicyEnum = zod_1.z.enum(['open', 'pairing', 'allowlist', 'disabled']);
19
+ const GroupPolicyEnum = zod_1.z.enum(['open', 'allowlist', 'disabled']);
20
+ const ConnectionModeEnum = zod_1.z.enum(['websocket', 'webhook']);
21
+ const ReplyModeValue = zod_1.z.enum(['auto', 'static', 'streaming']);
22
+ const ReplyModeSchema = zod_1.z
23
+ .union([
24
+ ReplyModeValue,
25
+ zod_1.z.object({
26
+ default: ReplyModeValue.optional(),
27
+ group: ReplyModeValue.optional(),
28
+ direct: ReplyModeValue.optional(),
29
+ }),
30
+ ])
31
+ .optional();
32
+ const ChunkModeEnum = zod_1.z.enum(['newline', 'paragraph', 'none']);
33
+ const DomainSchema = zod_1.z.union([zod_1.z.literal('feishu'), zod_1.z.literal('lark'), zod_1.z.string().regex(/^https:\/\//)]).optional();
34
+ const AllowFromSchema = zod_1.z
35
+ .union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())])
36
+ .optional()
37
+ .transform((v) => {
38
+ if (v === undefined || v == null)
39
+ return undefined;
40
+ return Array.isArray(v) ? v : [v];
41
+ });
42
+ const ToolPolicySchema = zod_1.z
43
+ .object({
44
+ allow: zod_1.z.array(zod_1.z.string()).optional(),
45
+ deny: zod_1.z.array(zod_1.z.string()).optional(),
46
+ })
47
+ .optional();
48
+ const FeishuToolsFlagSchema = zod_1.z
49
+ .object({
50
+ doc: zod_1.z.boolean().optional(),
51
+ wiki: zod_1.z.boolean().optional(),
52
+ drive: zod_1.z.boolean().optional(),
53
+ perm: zod_1.z.boolean().optional(),
54
+ scopes: zod_1.z.boolean().optional(),
55
+ })
56
+ .optional();
57
+ const FeishuFooterSchema = zod_1.z
58
+ .object({
59
+ status: zod_1.z.boolean().optional(),
60
+ elapsed: zod_1.z.boolean().optional(),
61
+ tokens: zod_1.z.boolean().optional(),
62
+ cache: zod_1.z.boolean().optional(),
63
+ context: zod_1.z.boolean().optional(),
64
+ model: zod_1.z.boolean().optional(),
65
+ })
66
+ .optional();
67
+ const BlockStreamingCoalesceSchema = zod_1.z
68
+ .object({
69
+ minChars: zod_1.z.number().optional(),
70
+ maxChars: zod_1.z.number().optional(),
71
+ idleMs: zod_1.z.number().optional(),
72
+ })
73
+ .optional();
74
+ const MarkdownConfigSchema = zod_1.z
75
+ .object({
76
+ tables: zod_1.z.enum(['off', 'bullets', 'code']).optional(),
77
+ })
78
+ .optional();
79
+ const HeartbeatSchema = zod_1.z
80
+ .object({
81
+ every: zod_1.z.string().optional(),
82
+ activeHours: zod_1.z
83
+ .object({
84
+ start: zod_1.z.string().optional(),
85
+ end: zod_1.z.string().optional(),
86
+ timezone: zod_1.z.string().optional(),
87
+ })
88
+ .optional(),
89
+ target: zod_1.z.string().optional(),
90
+ to: zod_1.z.string().optional(),
91
+ prompt: zod_1.z.string().optional(),
92
+ accountId: zod_1.z.string().optional(),
93
+ })
94
+ .optional();
95
+ const CapabilitiesSchema = zod_1.z
96
+ .object({
97
+ image: zod_1.z.boolean().optional(),
98
+ audio: zod_1.z.boolean().optional(),
99
+ video: zod_1.z.boolean().optional(),
100
+ })
101
+ .optional();
102
+ const DedupSchema = zod_1.z
103
+ .object({
104
+ ttlMs: zod_1.z.number().optional(), // default 43200000 (12h)
105
+ maxEntries: zod_1.z.number().optional(), // default 5000
106
+ })
107
+ .optional();
108
+ const AllowBotsSchema = zod_1.z.union([zod_1.z.boolean(), zod_1.z.literal('mentions')]).optional();
109
+ const ReactionNotificationModeSchema = zod_1.z.enum(['off', 'own', 'all']).optional();
110
+ exports.UATConfigSchema = zod_1.z
111
+ .object({
112
+ enabled: zod_1.z.boolean().optional(),
113
+ allowedScopes: zod_1.z.array(zod_1.z.string()).optional(),
114
+ blockedScopes: zod_1.z.array(zod_1.z.string()).optional(),
115
+ })
116
+ .optional();
117
+ const DmConfigSchema = zod_1.z
118
+ .object({
119
+ historyLimit: zod_1.z.number().optional(),
120
+ })
121
+ .optional();
122
+ // ---------------------------------------------------------------------------
123
+ // Group schema
124
+ // ---------------------------------------------------------------------------
125
+ exports.FeishuGroupSchema = zod_1.z.object({
126
+ groupPolicy: GroupPolicyEnum.optional(),
127
+ requireMention: zod_1.z.boolean().optional(),
128
+ respondToMentionAll: zod_1.z.boolean().optional(),
129
+ tools: ToolPolicySchema,
130
+ skills: zod_1.z.array(zod_1.z.string()).optional(),
131
+ enabled: zod_1.z.boolean().optional(),
132
+ allowFrom: AllowFromSchema,
133
+ systemPrompt: zod_1.z.string().optional(),
134
+ allowBots: AllowBotsSchema,
135
+ // When true, bot-to-bot replies are allowed to stay inside a thread/topic
136
+ // instead of being forced to the main chat (relaxes the #32980 guard).
137
+ replyInThread: zod_1.z.boolean().optional(),
138
+ });
139
+ // ---------------------------------------------------------------------------
140
+ // Account config schema (same shape as top-level minus `accounts`)
141
+ // ---------------------------------------------------------------------------
142
+ exports.FeishuAccountConfigSchema = zod_1.z.object({
143
+ appId: zod_1.z.string().optional(),
144
+ appSecret: zod_1.z.string().optional(),
145
+ encryptKey: zod_1.z.string().optional(),
146
+ verificationToken: zod_1.z.string().optional(),
147
+ name: zod_1.z.string().optional(),
148
+ enabled: zod_1.z.boolean().optional(),
149
+ domain: DomainSchema,
150
+ connectionMode: ConnectionModeEnum.optional(),
151
+ webhookPath: zod_1.z.string().optional(),
152
+ webhookPort: zod_1.z.number().optional(),
153
+ dmPolicy: DmPolicyEnum.optional(),
154
+ allowFrom: AllowFromSchema,
155
+ groupPolicy: GroupPolicyEnum.optional(),
156
+ groupAllowFrom: AllowFromSchema,
157
+ requireMention: zod_1.z.boolean().optional(),
158
+ respondToMentionAll: zod_1.z.boolean().optional(),
159
+ groups: zod_1.z.record(zod_1.z.string(), exports.FeishuGroupSchema).optional(),
160
+ historyLimit: zod_1.z.number().optional(),
161
+ dmHistoryLimit: zod_1.z.number().optional(),
162
+ dms: DmConfigSchema,
163
+ textChunkLimit: zod_1.z.number().optional(),
164
+ chunkMode: ChunkModeEnum.optional(),
165
+ blockStreamingCoalesce: BlockStreamingCoalesceSchema,
166
+ mediaMaxMb: zod_1.z.number().optional(),
167
+ heartbeat: HeartbeatSchema,
168
+ replyMode: ReplyModeSchema,
169
+ streaming: zod_1.z.boolean().optional(),
170
+ blockStreaming: zod_1.z.boolean().optional(),
171
+ toolUseDisplay: zod_1.z
172
+ .object({
173
+ showFullPaths: zod_1.z.boolean().optional(),
174
+ })
175
+ .optional(),
176
+ tools: FeishuToolsFlagSchema,
177
+ footer: FeishuFooterSchema,
178
+ markdown: MarkdownConfigSchema,
179
+ configWrites: zod_1.z.boolean().optional(),
180
+ capabilities: CapabilitiesSchema,
181
+ dedup: DedupSchema,
182
+ reactionNotifications: ReactionNotificationModeSchema,
183
+ threadSession: zod_1.z.boolean().optional(),
184
+ allowBots: AllowBotsSchema,
185
+ // Account-level default for letting bot-to-bot replies stay in a thread
186
+ // (per-group `replyInThread` overrides this).
187
+ replyInThread: zod_1.z.boolean().optional(),
188
+ uat: exports.UATConfigSchema,
189
+ });
190
+ // ---------------------------------------------------------------------------
191
+ // Top-level Feishu config schema
192
+ // ---------------------------------------------------------------------------
193
+ exports.FeishuConfigSchema = exports.FeishuAccountConfigSchema.extend({
194
+ accounts: zod_1.z.record(zod_1.z.string(), exports.FeishuAccountConfigSchema).optional(),
195
+ }).superRefine((data, ctx) => {
196
+ // When dmPolicy is "open", allowFrom must contain the wildcard "*".
197
+ if (data.dmPolicy === 'open') {
198
+ const list = data.allowFrom;
199
+ const hasWildcard = Array.isArray(list) && list.includes('*');
200
+ if (!hasWildcard) {
201
+ ctx.addIssue({
202
+ code: zod_1.z.ZodIssueCode.custom,
203
+ path: ['allowFrom'],
204
+ message: 'When dmPolicy is "open", allowFrom must include "*" to permit all senders.',
205
+ });
206
+ }
207
+ }
208
+ });
209
+ // ---------------------------------------------------------------------------
210
+ // Auto-generated JSON Schema (single source of truth)
211
+ // ---------------------------------------------------------------------------
212
+ /**
213
+ * JSON Schema derived from FeishuConfigSchema.
214
+ *
215
+ * - `io: "input"` exposes the input type for `.transform()` schemas (e.g. AllowFromSchema).
216
+ * - `unrepresentable: "any"` degrades `.superRefine()` constraints to `{}`.
217
+ * - `target: "draft-07"` matches the plugin system's expected JSON Schema version.
218
+ */
219
+ exports.FEISHU_CONFIG_JSON_SCHEMA = (0, zod_1.toJSONSchema)(exports.FeishuConfigSchema, {
220
+ target: 'draft-07',
221
+ io: 'input',
222
+ unrepresentable: 'any',
223
+ });
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * OAuth 2.0 Device Authorization Grant (RFC 8628) for Lark/Feishu.
6
+ *
7
+ * Two-step flow:
8
+ * 1. `requestDeviceAuthorization` – obtains device_code + user_code.
9
+ * 2. `pollDeviceToken` – polls the token endpoint until the user authorises,
10
+ * rejects, or the code expires.
11
+ *
12
+ * All HTTP calls use the built-in `fetch` (Node 18+). The Lark SDK is not
13
+ * used here because these OAuth endpoints are outside the SDK's scope.
14
+ */
15
+ import type { LarkBrand } from './types';
16
+ export interface DeviceAuthResponse {
17
+ deviceCode: string;
18
+ userCode: string;
19
+ verificationUri: string;
20
+ verificationUriComplete: string;
21
+ expiresIn: number;
22
+ interval: number;
23
+ }
24
+ export interface DeviceFlowTokenData {
25
+ accessToken: string;
26
+ refreshToken: string;
27
+ expiresIn: number;
28
+ refreshExpiresIn: number;
29
+ scope: string;
30
+ }
31
+ export type DeviceFlowResult = {
32
+ ok: true;
33
+ token: DeviceFlowTokenData;
34
+ } | {
35
+ ok: false;
36
+ error: DeviceFlowError;
37
+ message: string;
38
+ };
39
+ export type DeviceFlowError = 'authorization_pending' | 'slow_down' | 'access_denied' | 'expired_token';
40
+ /**
41
+ * Resolve the two OAuth endpoint URLs based on the configured brand.
42
+ */
43
+ export declare function resolveOAuthEndpoints(brand: LarkBrand): {
44
+ deviceAuthorization: string;
45
+ token: string;
46
+ };
47
+ /**
48
+ * Request a device authorisation code from the Feishu OAuth server.
49
+ *
50
+ * Uses Confidential Client authentication (HTTP Basic with appId:appSecret).
51
+ * The `offline_access` scope is automatically appended so that the token
52
+ * response includes a refresh_token.
53
+ */
54
+ export declare function requestDeviceAuthorization(params: {
55
+ appId: string;
56
+ appSecret: string;
57
+ brand: LarkBrand;
58
+ scope?: string;
59
+ }): Promise<DeviceAuthResponse>;
60
+ /**
61
+ * Poll the token endpoint until the user authorises, rejects, or the code
62
+ * expires.
63
+ *
64
+ * Handles `authorization_pending` (keep polling), `slow_down` (back off by
65
+ * +5 s), `access_denied` and `expired_token` (terminal errors).
66
+ *
67
+ * Pass an `AbortSignal` to cancel polling from the outside.
68
+ */
69
+ export declare function pollDeviceToken(params: {
70
+ appId: string;
71
+ appSecret: string;
72
+ brand: LarkBrand;
73
+ deviceCode: string;
74
+ interval: number;
75
+ expiresIn: number;
76
+ signal?: AbortSignal;
77
+ }): Promise<DeviceFlowResult>;
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * OAuth 2.0 Device Authorization Grant (RFC 8628) for Lark/Feishu.
7
+ *
8
+ * Two-step flow:
9
+ * 1. `requestDeviceAuthorization` – obtains device_code + user_code.
10
+ * 2. `pollDeviceToken` – polls the token endpoint until the user authorises,
11
+ * rejects, or the code expires.
12
+ *
13
+ * All HTTP calls use the built-in `fetch` (Node 18+). The Lark SDK is not
14
+ * used here because these OAuth endpoints are outside the SDK's scope.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.resolveOAuthEndpoints = resolveOAuthEndpoints;
18
+ exports.requestDeviceAuthorization = requestDeviceAuthorization;
19
+ exports.pollDeviceToken = pollDeviceToken;
20
+ const lark_logger_1 = require("./lark-logger.js");
21
+ const log = (0, lark_logger_1.larkLogger)('core/device-flow');
22
+ const feishu_fetch_1 = require("./feishu-fetch.js");
23
+ // ---------------------------------------------------------------------------
24
+ // Endpoint resolution
25
+ // ---------------------------------------------------------------------------
26
+ /**
27
+ * Resolve the two OAuth endpoint URLs based on the configured brand.
28
+ */
29
+ function resolveOAuthEndpoints(brand) {
30
+ if (!brand || brand === 'feishu') {
31
+ return {
32
+ deviceAuthorization: 'https://accounts.feishu.cn/oauth/v1/device_authorization',
33
+ token: 'https://open.feishu.cn/open-apis/authen/v2/oauth/token',
34
+ };
35
+ }
36
+ if (brand === 'lark') {
37
+ return {
38
+ deviceAuthorization: 'https://accounts.larksuite.com/oauth/v1/device_authorization',
39
+ token: 'https://open.larksuite.com/open-apis/authen/v2/oauth/token',
40
+ };
41
+ }
42
+ // Custom domain – derive paths by convention.
43
+ // Smart derivation: open.X → accounts.X for the device authorization endpoint.
44
+ const base = brand.replace(/\/+$/, '');
45
+ let accountsBase = base;
46
+ try {
47
+ const parsed = new URL(base);
48
+ if (parsed.hostname.startsWith('open.')) {
49
+ accountsBase = `${parsed.protocol}//${parsed.hostname.replace(/^open\./, 'accounts.')}`;
50
+ }
51
+ }
52
+ catch {
53
+ /* fallback to base */
54
+ }
55
+ return {
56
+ deviceAuthorization: `${accountsBase}/oauth/v1/device_authorization`,
57
+ token: `${base}/open-apis/authen/v2/oauth/token`,
58
+ };
59
+ }
60
+ // ---------------------------------------------------------------------------
61
+ // Step 1 – Device Authorization Request
62
+ // ---------------------------------------------------------------------------
63
+ /**
64
+ * Request a device authorisation code from the Feishu OAuth server.
65
+ *
66
+ * Uses Confidential Client authentication (HTTP Basic with appId:appSecret).
67
+ * The `offline_access` scope is automatically appended so that the token
68
+ * response includes a refresh_token.
69
+ */
70
+ async function requestDeviceAuthorization(params) {
71
+ const { appId, appSecret, brand } = params;
72
+ const endpoints = resolveOAuthEndpoints(brand);
73
+ // Ensure offline_access is always requested.
74
+ let scope = params.scope ?? '';
75
+ if (!scope.includes('offline_access')) {
76
+ scope = scope ? `${scope} offline_access` : 'offline_access';
77
+ }
78
+ const basicAuth = Buffer.from(`${appId}:${appSecret}`).toString('base64');
79
+ const body = new URLSearchParams();
80
+ body.set('client_id', appId);
81
+ body.set('scope', scope);
82
+ log.info(`requesting device authorization (scope="${scope}") url=${endpoints.deviceAuthorization} token_url=${endpoints.token}`);
83
+ const resp = await (0, feishu_fetch_1.feishuFetch)(endpoints.deviceAuthorization, {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/x-www-form-urlencoded',
87
+ Authorization: `Basic ${basicAuth}`,
88
+ },
89
+ body: body.toString(),
90
+ });
91
+ const text = await resp.text();
92
+ log.info(`response status=${resp.status} body=${text.slice(0, 500)}`);
93
+ let data;
94
+ try {
95
+ data = JSON.parse(text);
96
+ }
97
+ catch {
98
+ throw new Error(`Device authorization failed: HTTP ${resp.status} – ${text.slice(0, 200)}`);
99
+ }
100
+ if (!resp.ok || data.error) {
101
+ const msg = data.error_description ?? data.error ?? 'Unknown error';
102
+ throw new Error(`Device authorization failed: ${msg}`);
103
+ }
104
+ const expiresIn = data.expires_in ?? 240;
105
+ const interval = data.interval ?? 5;
106
+ log.info(`device_code obtained, expires_in=${expiresIn}s (${Math.round(expiresIn / 60)}min), interval=${interval}s`);
107
+ return {
108
+ deviceCode: data.device_code,
109
+ userCode: data.user_code,
110
+ verificationUri: data.verification_uri,
111
+ verificationUriComplete: data.verification_uri_complete ?? data.verification_uri,
112
+ expiresIn,
113
+ interval,
114
+ };
115
+ }
116
+ // ---------------------------------------------------------------------------
117
+ // Step 2 – Poll Token Endpoint
118
+ // ---------------------------------------------------------------------------
119
+ function sleep(ms, signal) {
120
+ return new Promise((resolve, reject) => {
121
+ const timer = setTimeout(resolve, ms);
122
+ signal?.addEventListener('abort', () => {
123
+ clearTimeout(timer);
124
+ reject(new DOMException('Aborted', 'AbortError'));
125
+ }, { once: true });
126
+ });
127
+ }
128
+ /**
129
+ * Poll the token endpoint until the user authorises, rejects, or the code
130
+ * expires.
131
+ *
132
+ * Handles `authorization_pending` (keep polling), `slow_down` (back off by
133
+ * +5 s), `access_denied` and `expired_token` (terminal errors).
134
+ *
135
+ * Pass an `AbortSignal` to cancel polling from the outside.
136
+ */
137
+ async function pollDeviceToken(params) {
138
+ const MAX_POLL_INTERVAL = 60; // slow_down 最大间隔 60 秒
139
+ const MAX_POLL_ATTEMPTS = 200; // 安全上限(远超设备码有效期)
140
+ const { appId, appSecret, brand, deviceCode, expiresIn, signal } = params;
141
+ let interval = params.interval;
142
+ const endpoints = resolveOAuthEndpoints(brand);
143
+ const deadline = Date.now() + expiresIn * 1000;
144
+ let attempts = 0;
145
+ while (Date.now() < deadline && attempts < MAX_POLL_ATTEMPTS) {
146
+ attempts++;
147
+ if (signal?.aborted) {
148
+ return { ok: false, error: 'expired_token', message: 'Polling was cancelled' };
149
+ }
150
+ await sleep(interval * 1000, signal);
151
+ let data;
152
+ try {
153
+ const resp = await (0, feishu_fetch_1.feishuFetch)(endpoints.token, {
154
+ method: 'POST',
155
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
156
+ body: new URLSearchParams({
157
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
158
+ device_code: deviceCode,
159
+ client_id: appId,
160
+ client_secret: appSecret,
161
+ }).toString(),
162
+ });
163
+ data = (await resp.json());
164
+ }
165
+ catch (err) {
166
+ log.warn(`poll network error: ${err}`);
167
+ interval = Math.min(interval + 1, MAX_POLL_INTERVAL);
168
+ continue;
169
+ }
170
+ const error = data.error;
171
+ if (!error && data.access_token) {
172
+ log.info('token obtained successfully');
173
+ const refreshToken = data.refresh_token ?? '';
174
+ const expiresIn = data.expires_in ?? 7200;
175
+ let refreshExpiresIn = data.refresh_token_expires_in ?? 604800;
176
+ if (!refreshToken) {
177
+ log.warn('no refresh_token in response, token will not be refreshable');
178
+ refreshExpiresIn = expiresIn;
179
+ }
180
+ return {
181
+ ok: true,
182
+ token: {
183
+ accessToken: data.access_token,
184
+ refreshToken,
185
+ expiresIn,
186
+ refreshExpiresIn,
187
+ scope: data.scope ?? '',
188
+ },
189
+ };
190
+ }
191
+ if (error === 'authorization_pending') {
192
+ log.debug('authorization_pending, retrying...');
193
+ continue;
194
+ }
195
+ if (error === 'slow_down') {
196
+ interval = Math.min(interval + 5, MAX_POLL_INTERVAL);
197
+ log.info(`slow_down, interval increased to ${interval}s`);
198
+ continue;
199
+ }
200
+ if (error === 'access_denied') {
201
+ log.info('user denied authorization');
202
+ return { ok: false, error: 'access_denied', message: '用户拒绝了授权' };
203
+ }
204
+ if (error === 'expired_token' || error === 'invalid_grant') {
205
+ log.info(`device code expired/invalid (error=${error})`);
206
+ return { ok: false, error: 'expired_token', message: '授权码已过期,请重新发起' };
207
+ }
208
+ // Unknown error – treat as terminal.
209
+ const desc = data.error_description ?? error ?? 'Unknown error';
210
+ log.warn(`unexpected error: error=${error}, desc=${desc}`);
211
+ return { ok: false, error: 'expired_token', message: desc };
212
+ }
213
+ if (attempts >= MAX_POLL_ATTEMPTS) {
214
+ log.warn(`max poll attempts (${MAX_POLL_ATTEMPTS}) reached`);
215
+ }
216
+ return { ok: false, error: 'expired_token', message: '授权超时,请重新发起' };
217
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Centralized domain helpers for Feishu / Lark brand-aware URL generation.
6
+ *
7
+ * All runtime code that needs to construct platform URLs should use these
8
+ * helpers instead of hardcoding domain strings.
9
+ */
10
+ import type { LarkBrand } from './types';
11
+ /** 开放平台域名 (API & 权限管理页面) */
12
+ export declare function openPlatformDomain(brand?: LarkBrand): string;
13
+ /** Applink 域名 */
14
+ export declare function applinkDomain(brand?: LarkBrand): string;
15
+ /** 主站域名 (文档、表格等用户可见链接) */
16
+ export declare function wwwDomain(brand?: LarkBrand): string;
17
+ /** MCP 服务域名 */
18
+ export declare function mcpDomain(brand?: LarkBrand): string;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Centralized domain helpers for Feishu / Lark brand-aware URL generation.
7
+ *
8
+ * All runtime code that needs to construct platform URLs should use these
9
+ * helpers instead of hardcoding domain strings.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.openPlatformDomain = openPlatformDomain;
13
+ exports.applinkDomain = applinkDomain;
14
+ exports.wwwDomain = wwwDomain;
15
+ exports.mcpDomain = mcpDomain;
16
+ // ---------------------------------------------------------------------------
17
+ // Domain helpers
18
+ // ---------------------------------------------------------------------------
19
+ /** 开放平台域名 (API & 权限管理页面) */
20
+ function openPlatformDomain(brand) {
21
+ return brand === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn';
22
+ }
23
+ /** Applink 域名 */
24
+ function applinkDomain(brand) {
25
+ return brand === 'lark' ? 'https://applink.larksuite.com' : 'https://applink.feishu.cn';
26
+ }
27
+ /** 主站域名 (文档、表格等用户可见链接) */
28
+ function wwwDomain(brand) {
29
+ return brand === 'lark' ? 'https://www.larksuite.com' : 'https://www.feishu.cn';
30
+ }
31
+ /** MCP 服务域名 */
32
+ function mcpDomain(brand) {
33
+ return brand === 'lark' ? 'https://mcp.larksuite.com' : 'https://mcp.feishu.cn';
34
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Header-aware fetch for Feishu API calls.
6
+ *
7
+ * Drop-in replacement for `fetch()` that automatically injects
8
+ * the User-Agent header.
9
+ */
10
+ /**
11
+ * Drop-in replacement for `fetch()` that automatically injects
12
+ * the User-Agent header.
13
+ *
14
+ * Used by `device-flow.ts` and `uat-client.ts` so that the custom
15
+ * User-Agent is transparently applied without changing every
16
+ * call-site's signature.
17
+ */
18
+ export declare function feishuFetch(url: string | URL | Request, init?: RequestInit): Promise<Response>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Header-aware fetch for Feishu API calls.
7
+ *
8
+ * Drop-in replacement for `fetch()` that automatically injects
9
+ * the User-Agent header.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.feishuFetch = feishuFetch;
13
+ const version_1 = require("./version.js");
14
+ /**
15
+ * Drop-in replacement for `fetch()` that automatically injects
16
+ * the User-Agent header.
17
+ *
18
+ * Used by `device-flow.ts` and `uat-client.ts` so that the custom
19
+ * User-Agent is transparently applied without changing every
20
+ * call-site's signature.
21
+ */
22
+ function feishuFetch(url, init) {
23
+ const headers = {
24
+ ...init?.headers,
25
+ 'User-Agent': (0, version_1.getUserAgent)(),
26
+ };
27
+ return fetch(url, { ...init, headers });
28
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Default values and resolution logic for the Feishu card footer configuration.
6
+ *
7
+ * Each boolean flag controls whether a particular metadata item is displayed
8
+ * in the card footer (e.g. elapsed time, model name).
9
+ */
10
+ import type { FeishuFooterConfig } from './types';
11
+ /**
12
+ * The default footer configuration.
13
+ *
14
+ * By default all metadata items are hidden — neither status text
15
+ * ("已完成" / "出错" / "已停止") nor elapsed time are shown.
16
+ */
17
+ export declare const DEFAULT_FOOTER_CONFIG: Required<FeishuFooterConfig>;
18
+ /**
19
+ * Merge a partial footer configuration with `DEFAULT_FOOTER_CONFIG`.
20
+ *
21
+ * Fields present in the input take precedence; anything absent falls back
22
+ * to the default value.
23
+ */
24
+ export declare function resolveFooterConfig(cfg?: FeishuFooterConfig): Required<FeishuFooterConfig>;