@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,138 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Generic throttled flush controller.
7
+ *
8
+ * A pure scheduling primitive that manages timer-based throttling,
9
+ * mutex-guarded flushing, and reflush-on-conflict. Contains no
10
+ * business logic — the actual flush work is provided via a callback.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FlushController = void 0;
14
+ const reply_dispatcher_types_1 = require("./reply-dispatcher-types.js");
15
+ // ---------------------------------------------------------------------------
16
+ // FlushController
17
+ // ---------------------------------------------------------------------------
18
+ class FlushController {
19
+ doFlush;
20
+ flushInProgress = false;
21
+ flushResolvers = [];
22
+ needsReflush = false;
23
+ pendingFlushTimer = null;
24
+ lastUpdateTime = 0;
25
+ isCompleted = false;
26
+ constructor(doFlush) {
27
+ this.doFlush = doFlush;
28
+ }
29
+ /** Mark the controller as completed — no more flushes after current one. */
30
+ complete() {
31
+ this.isCompleted = true;
32
+ }
33
+ /** Cancel any pending deferred flush timer. */
34
+ cancelPendingFlush() {
35
+ if (this.pendingFlushTimer) {
36
+ clearTimeout(this.pendingFlushTimer);
37
+ this.pendingFlushTimer = null;
38
+ }
39
+ }
40
+ /** Wait for any in-progress flush to finish. */
41
+ waitForFlush() {
42
+ if (!this.flushInProgress)
43
+ return Promise.resolve();
44
+ return new Promise((resolve) => this.flushResolvers.push(resolve));
45
+ }
46
+ /**
47
+ * Execute a flush (mutex-guarded, with reflush on conflict).
48
+ *
49
+ * If a flush is already in progress, marks needsReflush so a
50
+ * follow-up flush fires immediately after the current one completes.
51
+ */
52
+ async flush() {
53
+ if (!this.cardMessageReady() || this.flushInProgress || this.isCompleted) {
54
+ if (this.flushInProgress && !this.isCompleted)
55
+ this.needsReflush = true;
56
+ return;
57
+ }
58
+ this.flushInProgress = true;
59
+ this.needsReflush = false;
60
+ // Update timestamp BEFORE the API call to prevent concurrent callers
61
+ // from also entering the flush (race condition fix).
62
+ this.lastUpdateTime = Date.now();
63
+ try {
64
+ await this.doFlush();
65
+ this.lastUpdateTime = Date.now();
66
+ }
67
+ finally {
68
+ this.flushInProgress = false;
69
+ const resolvers = this.flushResolvers;
70
+ this.flushResolvers = [];
71
+ for (const resolve of resolvers)
72
+ resolve();
73
+ // If events arrived while the API call was in flight,
74
+ // schedule an immediate follow-up flush.
75
+ if (this.needsReflush && !this.isCompleted && !this.pendingFlushTimer) {
76
+ this.needsReflush = false;
77
+ this.pendingFlushTimer = setTimeout(() => {
78
+ this.pendingFlushTimer = null;
79
+ void this.flush();
80
+ }, 0);
81
+ }
82
+ }
83
+ }
84
+ /**
85
+ * Throttled update entry point.
86
+ *
87
+ * @param throttleMs - Minimum interval between flushes (varies by
88
+ * CardKit vs IM patch mode). Passed in by the caller so this
89
+ * controller remains business-logic-free.
90
+ */
91
+ async throttledUpdate(throttleMs) {
92
+ if (!this.cardMessageReady())
93
+ return;
94
+ const now = Date.now();
95
+ const elapsed = now - this.lastUpdateTime;
96
+ if (elapsed >= throttleMs) {
97
+ this.cancelPendingFlush();
98
+ if (elapsed > reply_dispatcher_types_1.THROTTLE_CONSTANTS.LONG_GAP_THRESHOLD_MS) {
99
+ // After a long gap, batch briefly so the first visible update
100
+ // contains meaningful text rather than just 1-2 characters.
101
+ this.lastUpdateTime = now;
102
+ this.pendingFlushTimer = setTimeout(() => {
103
+ this.pendingFlushTimer = null;
104
+ void this.flush();
105
+ }, reply_dispatcher_types_1.THROTTLE_CONSTANTS.BATCH_AFTER_GAP_MS);
106
+ }
107
+ else {
108
+ await this.flush();
109
+ }
110
+ }
111
+ else if (!this.pendingFlushTimer) {
112
+ // Inside throttle window — schedule a deferred flush
113
+ const delay = throttleMs - elapsed;
114
+ this.pendingFlushTimer = setTimeout(() => {
115
+ this.pendingFlushTimer = null;
116
+ void this.flush();
117
+ }, delay);
118
+ }
119
+ }
120
+ // ------------------------------------------------------------------
121
+ // Internal
122
+ // ------------------------------------------------------------------
123
+ /** Overridable gate: subclasses / consumers can set via setCardMessageReady. */
124
+ _cardMessageReady = false;
125
+ cardMessageReady() {
126
+ return this._cardMessageReady;
127
+ }
128
+ setCardMessageReady(ready) {
129
+ this._cardMessageReady = ready;
130
+ if (ready) {
131
+ // Initialize the timestamp so the first throttledUpdate sees a
132
+ // small elapsed time (matching original behavior where
133
+ // lastCardUpdateTime = Date.now() was set during card creation).
134
+ this.lastUpdateTime = Date.now();
135
+ }
136
+ }
137
+ }
138
+ exports.FlushController = FlushController;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * ImageResolver — converts image URLs in markdown to Feishu image keys.
6
+ *
7
+ * Used by StreamingCardController to asynchronously download and upload
8
+ * images referenced via `![alt](https://...)` in model-generated markdown,
9
+ * replacing them with `![alt](img_xxx)` that Feishu cards can render.
10
+ */
11
+ import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
12
+ export interface ImageResolverOptions {
13
+ cfg: ClawdbotConfig;
14
+ accountId: string | undefined;
15
+ /** Called when a previously-pending image upload completes. */
16
+ onImageResolved: () => void;
17
+ }
18
+ export declare class ImageResolver {
19
+ /** URL → imageKey for successfully uploaded images. */
20
+ private readonly resolved;
21
+ /** URL → upload Promise for in-flight uploads (dedup). */
22
+ private readonly pending;
23
+ /** URLs that have already failed — skip retries. */
24
+ private readonly failed;
25
+ private readonly cfg;
26
+ private readonly accountId;
27
+ private readonly onImageResolved;
28
+ constructor(opts: ImageResolverOptions);
29
+ /**
30
+ * Synchronously resolve image URLs in markdown text.
31
+ *
32
+ * - `img_xxx` references are kept as-is.
33
+ * - URLs with a cached imageKey are replaced inline.
34
+ * - URLs with an in-flight upload are stripped (will appear after re-flush).
35
+ * - New URLs trigger an async upload and are stripped for now.
36
+ */
37
+ resolveImages(text: string): string;
38
+ /**
39
+ * Resolve all image URLs in text synchronously: trigger uploads for new
40
+ * URLs, wait for all pending uploads, then return text with image keys.
41
+ */
42
+ resolveImagesAwait(text: string, timeoutMs: number): Promise<string>;
43
+ private startUpload;
44
+ private doUpload;
45
+ }
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * ImageResolver — converts image URLs in markdown to Feishu image keys.
7
+ *
8
+ * Used by StreamingCardController to asynchronously download and upload
9
+ * images referenced via `![alt](https://...)` in model-generated markdown,
10
+ * replacing them with `![alt](img_xxx)` that Feishu cards can render.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.ImageResolver = void 0;
14
+ const media_1 = require("../messaging/outbound/media.js");
15
+ const lark_logger_1 = require("../core/lark-logger.js");
16
+ const log = (0, lark_logger_1.larkLogger)('card/image-resolver');
17
+ /** Matches complete markdown image syntax: `![alt](value)` */
18
+ const IMAGE_RE = /!\[([^\]]*)\]\(([^)\s]+)\)/g;
19
+ class ImageResolver {
20
+ /** URL → imageKey for successfully uploaded images. */
21
+ resolved = new Map();
22
+ /** URL → upload Promise for in-flight uploads (dedup). */
23
+ pending = new Map();
24
+ /** URLs that have already failed — skip retries. */
25
+ failed = new Set();
26
+ cfg;
27
+ accountId;
28
+ onImageResolved;
29
+ constructor(opts) {
30
+ this.cfg = opts.cfg;
31
+ this.accountId = opts.accountId;
32
+ this.onImageResolved = opts.onImageResolved;
33
+ }
34
+ /**
35
+ * Synchronously resolve image URLs in markdown text.
36
+ *
37
+ * - `img_xxx` references are kept as-is.
38
+ * - URLs with a cached imageKey are replaced inline.
39
+ * - URLs with an in-flight upload are stripped (will appear after re-flush).
40
+ * - New URLs trigger an async upload and are stripped for now.
41
+ */
42
+ resolveImages(text) {
43
+ if (!text.includes('!['))
44
+ return text;
45
+ return text.replace(IMAGE_RE, (fullMatch, alt, value) => {
46
+ // Already a Feishu image key — keep.
47
+ if (value.startsWith('img_'))
48
+ return fullMatch;
49
+ // Not a remote URL — strip (local paths, data URIs, etc.).
50
+ if (!value.startsWith('http://') && !value.startsWith('https://'))
51
+ return '';
52
+ // Cached — replace with image key.
53
+ const cached = this.resolved.get(value);
54
+ if (cached)
55
+ return `![${alt}](${cached})`;
56
+ // Already failed — don't retry, strip.
57
+ if (this.failed.has(value))
58
+ return '';
59
+ // Upload in progress — strip for now.
60
+ if (this.pending.has(value))
61
+ return '';
62
+ // New URL — kick off async upload, strip for now.
63
+ this.startUpload(value);
64
+ return '';
65
+ });
66
+ }
67
+ /**
68
+ * Resolve all image URLs in text synchronously: trigger uploads for new
69
+ * URLs, wait for all pending uploads, then return text with image keys.
70
+ */
71
+ async resolveImagesAwait(text, timeoutMs) {
72
+ // First pass: trigger uploads for any new URLs
73
+ this.resolveImages(text);
74
+ if (this.pending.size > 0) {
75
+ log.info('resolveImagesAwait: waiting for uploads', { count: this.pending.size, timeoutMs });
76
+ const allUploads = Promise.all(this.pending.values());
77
+ const timeout = new Promise((resolve) => setTimeout(resolve, timeoutMs));
78
+ await Promise.race([allUploads, timeout]);
79
+ if (this.pending.size > 0) {
80
+ log.warn('resolveImagesAwait: timed out with pending uploads', {
81
+ remaining: this.pending.size,
82
+ });
83
+ }
84
+ }
85
+ // Second pass: replace URLs with resolved image keys
86
+ return this.resolveImages(text);
87
+ }
88
+ startUpload(url) {
89
+ const uploadPromise = this.doUpload(url);
90
+ this.pending.set(url, uploadPromise);
91
+ }
92
+ async doUpload(url) {
93
+ try {
94
+ log.info('uploading image', { url });
95
+ const buffer = await (0, media_1.fetchRemoteImageBuffer)(url);
96
+ const { imageKey } = await (0, media_1.uploadImageLark)({
97
+ cfg: this.cfg,
98
+ image: buffer,
99
+ imageType: 'message',
100
+ accountId: this.accountId,
101
+ });
102
+ log.info('image uploaded', { url, imageKey });
103
+ this.resolved.set(url, imageKey);
104
+ this.pending.delete(url);
105
+ this.onImageResolved();
106
+ return imageKey;
107
+ }
108
+ catch (err) {
109
+ log.warn('image upload failed', { url, error: String(err) });
110
+ this.pending.delete(url);
111
+ this.failed.add(url);
112
+ return null;
113
+ }
114
+ }
115
+ }
116
+ exports.ImageResolver = ImageResolver;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Markdown 样式优化工具
6
+ */
7
+ /**
8
+ * 优化 Markdown 样式:
9
+ * - 标题降级:H1 → H4,H2~H6 → H5
10
+ * - 表格前后增加段落间距
11
+ * - 有序列表:序号后确保只有一个空格
12
+ * - 无序列表:"- " 格式规范化(跳过分隔线 ---)
13
+ * - 表格:单元格前后补空格,分隔符行规范化,表格前后加空行
14
+ * - 代码块内容不受影响
15
+ */
16
+ export declare function optimizeMarkdownStyle(text: string, cardVersion?: number): string;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Markdown 样式优化工具
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.optimizeMarkdownStyle = optimizeMarkdownStyle;
10
+ /**
11
+ * 优化 Markdown 样式:
12
+ * - 标题降级:H1 → H4,H2~H6 → H5
13
+ * - 表格前后增加段落间距
14
+ * - 有序列表:序号后确保只有一个空格
15
+ * - 无序列表:"- " 格式规范化(跳过分隔线 ---)
16
+ * - 表格:单元格前后补空格,分隔符行规范化,表格前后加空行
17
+ * - 代码块内容不受影响
18
+ */
19
+ function optimizeMarkdownStyle(text, cardVersion = 2) {
20
+ try {
21
+ let r = _optimizeMarkdownStyle(text, cardVersion);
22
+ r = stripInvalidImageKeys(r);
23
+ return r;
24
+ }
25
+ catch {
26
+ return text;
27
+ }
28
+ }
29
+ function _optimizeMarkdownStyle(text, cardVersion = 2) {
30
+ // ── 1. 提取代码块,用占位符保护,处理后再还原 ─────────────────────
31
+ const MARK = '___CB_';
32
+ const codeBlocks = [];
33
+ let r = text.replace(/(^|\n)(`{3,})([^\n]*)\n[\s\S]*?\n\2(?=\n|$)/g, (m, prefix = '') => {
34
+ const block = m.slice(String(prefix).length);
35
+ return `${prefix}${MARK}${codeBlocks.push(block) - 1}___`;
36
+ });
37
+ // ── 2. 标题降级 ────────────────────────────────────────────────────
38
+ // 只有当原文档包含 h1~h3 标题时才执行降级
39
+ // 先处理 H2~H6 → H5,再处理 H1 → H4
40
+ // 顺序不能颠倒:若先 H1→H4,H4(####)会被后面的 #{2,6} 再次匹配成 H5
41
+ const hasH1toH3 = /^#{1,3} /m.test(text);
42
+ if (hasH1toH3) {
43
+ r = r.replace(/^#{2,6} (.+)$/gm, '##### $1'); // H2~H6 → H5
44
+ r = r.replace(/^# (.+)$/gm, '#### $1'); // H1 → H4
45
+ }
46
+ if (cardVersion >= 2) {
47
+ // ── 3. 连续标题间增加段落间距 ───────────────────────────────────────
48
+ r = r.replace(/^(#{4,5} .+)\n{1,2}(#{4,5} )/gm, '$1\n<br>\n$2');
49
+ // ── 4. 表格前后增加段落间距 ─────────────────────────────────────────
50
+ // 4a. 非表格行直接跟表格行时,先补一个空行
51
+ r = r.replace(/^([^|\n].*)\n(\|.+\|)/gm, '$1\n\n$2');
52
+ // 4b. 表格前:在空行之前插入 <br>(即 \n\n| → \n<br>\n\n| )
53
+ r = r.replace(/\n\n((?:\|.+\|[^\S\n]*\n?)+)/g, '\n\n<br>\n\n$1');
54
+ // 4c. 表格后:在表格块末尾追加 <br>(跳过后接分隔线/标题/加粗/文末的情况)
55
+ r = r.replace(/((?:^\|.+\|[^\S\n]*\n?)+)/gm, (m, _table, offset) => {
56
+ const after = r.slice(offset + m.length).replace(/^\n+/, '');
57
+ if (!after || /^(---|#{4,5} |\*\*)/.test(after))
58
+ return m;
59
+ return m + '\n<br>\n';
60
+ });
61
+ // 4d. 表格前是普通文本(非标题、非加粗行)时,只需 <br>,去掉多余空行
62
+ // "text\n\n<br>\n\n|" → "text\n<br>\n|"
63
+ r = r.replace(/^((?!#{4,5} )(?!\*\*).+)\n\n(<br>)\n\n(\|)/gm, '$1\n$2\n$3');
64
+ // 4d2. 表格前是加粗行时,<br> 紧贴加粗行,空行保留在后面
65
+ // "**bold**\n\n<br>\n\n|" → "**bold**\n<br>\n\n|"
66
+ r = r.replace(/^(\*\*.+)\n\n(<br>)\n\n(\|)/gm, '$1\n$2\n\n$3');
67
+ // 4e. 表格后是普通文本(非标题、非加粗行)时,只需 <br>,去掉多余空行
68
+ // "| row |\n\n<br>\ntext" → "| row |\n<br>\ntext"
69
+ r = r.replace(/(\|[^\n]*\n)\n(<br>\n)((?!#{4,5} )(?!\*\*))/gm, '$1$2$3');
70
+ // ── 5. 还原代码块,并在前后追加 <br> ──────────────────────────────
71
+ codeBlocks.forEach((block, i) => {
72
+ r = r.replace(`${MARK}${i}___`, `\n<br>\n${block}\n<br>\n`);
73
+ });
74
+ }
75
+ else {
76
+ // ── 5. 还原代码块(无 <br>)───────────────────────────────────────
77
+ codeBlocks.forEach((block, i) => {
78
+ r = r.replace(`${MARK}${i}___`, block);
79
+ });
80
+ }
81
+ // ── 6. 压缩多余空行(3 个以上连续换行 → 2 个)────────────────────
82
+ r = r.replace(/\n{3,}/g, '\n\n');
83
+ return r;
84
+ }
85
+ // ---------------------------------------------------------------------------
86
+ // stripInvalidImageKeys
87
+ // ---------------------------------------------------------------------------
88
+ /** Matches complete markdown image syntax: `![alt](value)` */
89
+ const IMAGE_RE = /!\[([^\]]*)\]\(([^)\s]+)\)/g;
90
+ /**
91
+ * Strip `![alt](value)` where value is not a valid Feishu image key
92
+ * (`img_xxx`). Prevents CardKit error 200570.
93
+ *
94
+ * HTTP URLs are stripped as well — ImageResolver should have already
95
+ * replaced them with `img_xxx` keys before this point. This serves
96
+ * as a safety net for any unresolved URLs.
97
+ */
98
+ function stripInvalidImageKeys(text) {
99
+ if (!text.includes('!['))
100
+ return text;
101
+ return text.replace(IMAGE_RE, (fullMatch, _alt, value) => {
102
+ if (value.startsWith('img_'))
103
+ return fullMatch;
104
+ return ''; // strip all non-img_ image references (URLs, local paths, etc.)
105
+ });
106
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Shared utilities for the reasoning display subsystem.
6
+ */
7
+ export declare function normalizeToolName(name?: string): string;
8
+ export declare function truncateText(value: string, maxLength: number): string;
9
+ export declare function redactInlineSecrets(value: string): string;
10
+ /**
11
+ * Sanitize tool params for safe logging.
12
+ * Logs only param key names (no values) to avoid leaking sensitive data.
13
+ */
14
+ export declare function sanitizeParamsForLog(params?: Record<string, unknown>): string;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * Shared utilities for the reasoning display subsystem.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.normalizeToolName = normalizeToolName;
10
+ exports.truncateText = truncateText;
11
+ exports.redactInlineSecrets = redactInlineSecrets;
12
+ exports.sanitizeParamsForLog = sanitizeParamsForLog;
13
+ function normalizeToolName(name) {
14
+ return name?.trim().toLowerCase() ?? '';
15
+ }
16
+ function truncateText(value, maxLength) {
17
+ if (value.length <= maxLength)
18
+ return value;
19
+ return `${value.slice(0, maxLength - 3)}...`;
20
+ }
21
+ const INLINE_ASSIGNMENT_RE = /(^|[\s"'`])([A-Za-z_][A-Za-z0-9_]*)(=(?:"[^"]*"|'[^']*'|[^\s"'`]+))/g;
22
+ const AUTH_HEADER_SECRET_RE = /(Authorization\s*:\s*(?:Bearer|Basic|Token)\s+)([^'"\s]+)/gi;
23
+ const QUOTED_HEADER_ARG_RE = /((?:^|[\s"'`])(?:-H|--header)\s+)(['"])([A-Za-z0-9_-]+)(\s*:\s*)([^'"]*)(\2)/gi;
24
+ const UNQUOTED_HEADER_ARG_RE = /((?:^|[\s"'`])(?:-H|--header)\s+)([A-Za-z0-9_-]+)(\s*:\s*)([^\s"'`]+)/gi;
25
+ const SECRET_FLAG_RE = /((?:^|[\s"'`]))(--?[A-Za-z0-9][A-Za-z0-9-]*)(=|\s+)(?:"([^"]*)"|'([^']*)'|([^\s"'`]+))/g;
26
+ const SENSITIVE_NAME_RE = /token|secret|password|api[_-]?key|authorization|cookie|credential|bearer|session[_-]?id|client[_-]?secret|access[_-]?key/i;
27
+ function redactInlineSecrets(value) {
28
+ return value
29
+ .replace(INLINE_ASSIGNMENT_RE, (match, prefix, key) => isSensitiveName(key) ? `${prefix}${key}=[redacted]` : match)
30
+ .replace(AUTH_HEADER_SECRET_RE, '$1[redacted]')
31
+ .replace(QUOTED_HEADER_ARG_RE, (match, prefix, quote, name, separator) => shouldRedactHeaderValue(name) ? `${prefix}${quote}${name}${separator}[redacted]${quote}` : match)
32
+ .replace(UNQUOTED_HEADER_ARG_RE, (match, prefix, name, separator) => shouldRedactHeaderValue(name) ? `${prefix}${name}${separator}[redacted]` : match)
33
+ .replace(SECRET_FLAG_RE, (match, prefix, flag, separator, doubleQuoted, singleQuoted, bare) => {
34
+ const normalizedFlag = flag.replace(/^-+/, '');
35
+ if (!isSensitiveName(normalizedFlag))
36
+ return match;
37
+ const redactedValue = doubleQuoted !== undefined
38
+ ? '"[redacted]"'
39
+ : singleQuoted !== undefined
40
+ ? "'[redacted]'"
41
+ : bare !== undefined
42
+ ? '[redacted]'
43
+ : '[redacted]';
44
+ return `${prefix}${flag}${separator}${redactedValue}`;
45
+ });
46
+ }
47
+ function isSensitiveName(value) {
48
+ return SENSITIVE_NAME_RE.test(value);
49
+ }
50
+ function shouldRedactHeaderValue(name) {
51
+ return !/^authorization$/i.test(name) && isSensitiveName(name);
52
+ }
53
+ /**
54
+ * Sanitize tool params for safe logging.
55
+ * Logs only param key names (no values) to avoid leaking sensitive data.
56
+ */
57
+ function sanitizeParamsForLog(params) {
58
+ if (!params || typeof params !== 'object')
59
+ return '';
60
+ const keys = Object.keys(params);
61
+ if (keys.length === 0)
62
+ return '{}';
63
+ return `{${keys.join(',')}}`;
64
+ }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Copyright (c) 2026 ByteDance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Type definitions for the Feishu reply dispatcher subsystem.
6
+ *
7
+ * Consolidates all interfaces, state shapes, and constants used across
8
+ * reply-dispatcher.ts, streaming-card-controller.ts, flush-controller.ts,
9
+ * and unavailable-guard.ts.
10
+ */
11
+ import type { ClawdbotConfig } from 'openclaw/plugin-sdk';
12
+ import type { ReplyDispatcher } from 'openclaw/plugin-sdk/reply-runtime';
13
+ import type { FeishuFooterConfig } from '../core/types';
14
+ import type { ToolUseDisplayConfig } from './tool-use-config';
15
+ export declare const CARD_PHASES: {
16
+ readonly idle: "idle";
17
+ readonly creating: "creating";
18
+ readonly streaming: "streaming";
19
+ readonly completed: "completed";
20
+ readonly aborted: "aborted";
21
+ readonly terminated: "terminated";
22
+ readonly creation_failed: "creation_failed";
23
+ };
24
+ export type CardPhase = (typeof CARD_PHASES)[keyof typeof CARD_PHASES];
25
+ export declare const TERMINAL_PHASES: ReadonlySet<CardPhase>;
26
+ /**
27
+ * Why a terminal phase was entered.
28
+ *
29
+ * - `normal` — streaming completed successfully (onIdle).
30
+ * - `error` — an error occurred during reply generation (onError).
31
+ * - `abort` — explicitly cancelled by the caller (abortCard).
32
+ * - `unavailable` — source message was deleted/recalled (UnavailableGuard).
33
+ * - `creation_failed` — card creation failed, falling back to static delivery.
34
+ */
35
+ export type TerminalReason = 'normal' | 'error' | 'abort' | 'unavailable' | 'creation_failed';
36
+ export declare const PHASE_TRANSITIONS: Record<CardPhase, ReadonlySet<CardPhase>>;
37
+ export interface ReasoningState {
38
+ accumulatedReasoningText: string;
39
+ reasoningStartTime: number | null;
40
+ reasoningElapsedMs: number;
41
+ isReasoningPhase: boolean;
42
+ }
43
+ export interface ToolUseState {
44
+ startedAt: number | null;
45
+ elapsedMs: number;
46
+ isActive: boolean;
47
+ }
48
+ export interface StreamingTextState {
49
+ accumulatedText: string;
50
+ completedText: string;
51
+ streamingPrefix: string;
52
+ lastPartialText: string;
53
+ lastFlushedText: string;
54
+ }
55
+ export interface CardKitState {
56
+ cardKitCardId: string | null;
57
+ originalCardKitCardId: string | null;
58
+ cardKitSequence: number;
59
+ cardMessageId: string | null;
60
+ }
61
+ /**
62
+ * Throttle intervals for card updates.
63
+ *
64
+ * - `CARDKIT_MS`: CardKit `cardElement.content()` — designed for streaming,
65
+ * low throttle is fine.
66
+ * - `PATCH_MS`: `im.message.patch` — strict rate limits (code 230020).
67
+ * - `LONG_GAP_THRESHOLD_MS`: After a long idle gap (tool call / LLM thinking),
68
+ * defer the first flush briefly.
69
+ * - `BATCH_AFTER_GAP_MS`: Batching window after a long gap.
70
+ */
71
+ export declare const THROTTLE_CONSTANTS: {
72
+ readonly CARDKIT_MS: 100;
73
+ readonly PATCH_MS: 1500;
74
+ readonly LONG_GAP_THRESHOLD_MS: 2000;
75
+ readonly BATCH_AFTER_GAP_MS: 300;
76
+ readonly REASONING_STATUS_MS: 1500;
77
+ };
78
+ export declare const EMPTY_REPLY_FALLBACK_TEXT = "Done.";
79
+ export interface CreateFeishuReplyDispatcherParams {
80
+ cfg: ClawdbotConfig;
81
+ agentId: string;
82
+ sessionKey: string;
83
+ chatId: string;
84
+ replyToMessageId?: string;
85
+ /** Account ID for multi-account support. */
86
+ accountId?: string;
87
+ /** Chat type for scene-aware reply mode selection. */
88
+ chatType?: 'p2p' | 'group';
89
+ /** When true, typing indicators are suppressed entirely. */
90
+ skipTyping?: boolean;
91
+ /** When true, replies are sent into the thread instead of main chat. */
92
+ replyInThread?: boolean;
93
+ /** Thread root id when the reply lives inside a thread; used for sentinel keying. */
94
+ threadId?: string;
95
+ toolUseDisplay: ToolUseDisplayConfig;
96
+ }
97
+ /**
98
+ * The structured return type of createFeishuReplyDispatcher.
99
+ *
100
+ * `replyOptions` is typed as `Record<string, unknown>` because the consumer
101
+ * (`dispatchReplyFromConfig`) accepts the SDK-internal `GetReplyOptions`
102
+ * which is not re-exported from `openclaw/plugin-sdk`. The record type
103
+ * is compatible with spread-assignment into `dispatchReplyFromConfig`.
104
+ */
105
+ export interface FeishuReplyDispatcherResult {
106
+ dispatcher: ReplyDispatcher;
107
+ replyOptions: Record<string, unknown>;
108
+ markDispatchIdle: () => void;
109
+ markFullyComplete: () => void;
110
+ abortCard: () => Promise<void>;
111
+ }
112
+ export interface FooterSessionMetrics {
113
+ inputTokens?: number;
114
+ outputTokens?: number;
115
+ cacheRead?: number;
116
+ cacheWrite?: number;
117
+ totalTokens?: number;
118
+ totalTokensFresh?: boolean;
119
+ contextTokens?: number;
120
+ model?: string;
121
+ }
122
+ export interface StreamingCardDeps {
123
+ cfg: ClawdbotConfig;
124
+ agentId: string;
125
+ sessionKey: string;
126
+ accountId: string | undefined;
127
+ chatId: string;
128
+ replyToMessageId: string | undefined;
129
+ replyInThread: boolean | undefined;
130
+ toolUseDisplay: ToolUseDisplayConfig;
131
+ resolvedFooter: Required<FeishuFooterConfig>;
132
+ }