@openclaw/feishu 2026.9.8 → 2026.10.1-beta.2

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 (225) hide show
  1. package/dist/.setup/{channel-DV4hM2Uf.mjs → channel-CX62T71S.mjs} +146 -245
  2. package/dist/.setup/{channel.runtime-CXQcH5zZ.mjs → channel.runtime-COiaq-Rv.mjs} +6 -12
  3. package/dist/.setup/{chat-D8MlFAZi.mjs → chat-BdyvImsY.mjs} +6 -9
  4. package/dist/.setup/{client-BYG-_IZl.mjs → client-BsBVWJzN.mjs} +1 -1
  5. package/dist/.setup/{doctor-contract-3XC0vbIw.mjs → doctor-contract-B1B9ogdd.mjs} +212 -27
  6. package/dist/.setup/{monitor-D_rsHBZ6.mjs → monitor-7DvwUs4Y.mjs} +5 -6
  7. package/dist/.setup/{monitor.account-DvvY7i6k.mjs → monitor.account-7xVu7XWY.mjs} +190 -393
  8. package/dist/.setup/{probe-_ViqSi0j.mjs → probe-B9o7iey6.mjs} +13 -39
  9. package/dist/.setup/{reply-delivery-result-COAjaukc.mjs → reply-delivery-result-Bt-BWBEA.mjs} +151 -297
  10. package/dist/.setup/{setup-api-C4S5I3ac.mjs → setup-api-DmzX9S01.mjs} +1 -1
  11. package/dist/.setup/{subagent-hooks-BaFoMu8W.mjs → subagent-hooks-CUXg0pC-.mjs} +5 -11
  12. package/dist/.setup/{thread-bindings-EdLXPXzw.mjs → thread-bindings-jW2x5VuN.mjs} +23 -41
  13. package/dist/api.js +234 -297
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/doctor-contract-api.js +2 -2
  16. package/dist/session-binding-contract-api.js +1 -1
  17. package/dist/setup-api.js +1 -1
  18. package/dist/setup-entry.js +1 -1
  19. package/dist/subagent-hooks-api.js +1 -1
  20. package/node_modules/@openclaw/fs-safe/CHANGELOG.md +95 -0
  21. package/node_modules/@openclaw/fs-safe/README.md +70 -379
  22. package/node_modules/@openclaw/fs-safe/dist/absolute-path.js +35 -51
  23. package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts +2 -0
  24. package/node_modules/@openclaw/fs-safe/dist/advanced.js +1 -0
  25. package/node_modules/@openclaw/fs-safe/dist/archive-input.js +2 -0
  26. package/node_modules/@openclaw/fs-safe/dist/archive-parser.wasm +0 -0
  27. package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts +1 -1
  28. package/node_modules/@openclaw/fs-safe/dist/archive-staging.js +9 -10
  29. package/node_modules/@openclaw/fs-safe/dist/archive.js +2 -5
  30. package/node_modules/@openclaw/fs-safe/dist/atomic-io.d.ts +51 -0
  31. package/node_modules/@openclaw/fs-safe/dist/atomic-io.js +242 -0
  32. package/node_modules/@openclaw/fs-safe/dist/config.d.ts +1 -1
  33. package/node_modules/@openclaw/fs-safe/dist/config.js +1 -1
  34. package/node_modules/@openclaw/fs-safe/dist/copy-file-input.d.ts +1 -1
  35. package/node_modules/@openclaw/fs-safe/dist/copy-file-input.js +2 -2
  36. package/node_modules/@openclaw/fs-safe/dist/copy-tree-portable.js +2 -0
  37. package/node_modules/@openclaw/fs-safe/dist/create.js +12 -5
  38. package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts +11 -0
  39. package/node_modules/@openclaw/fs-safe/dist/directory-guard.js +4 -7
  40. package/node_modules/@openclaw/fs-safe/dist/entry-publication-types.d.ts +55 -0
  41. package/node_modules/@openclaw/fs-safe/dist/entry-publication-types.js +1 -0
  42. package/node_modules/@openclaw/fs-safe/dist/entry-publication.d.ts +8 -0
  43. package/node_modules/@openclaw/fs-safe/dist/entry-publication.js +262 -0
  44. package/node_modules/@openclaw/fs-safe/dist/exclusive-create.d.ts +3 -0
  45. package/node_modules/@openclaw/fs-safe/dist/exclusive-create.js +22 -0
  46. package/node_modules/@openclaw/fs-safe/dist/file-cleanup.d.ts +1 -6
  47. package/node_modules/@openclaw/fs-safe/dist/file-cleanup.js +3 -6
  48. package/node_modules/@openclaw/fs-safe/dist/file-identity.js +3 -6
  49. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-io.js +2 -2
  50. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root-mutation.js +9 -0
  51. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-root.js +4 -6
  52. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync-stale-admission.js +1 -1
  53. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.js +8 -0
  54. package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.js +2 -0
  55. package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.js +20 -18
  56. package/node_modules/@openclaw/fs-safe/dist/file-store.js +4 -10
  57. package/node_modules/@openclaw/fs-safe/dist/fs.d.ts +2 -10
  58. package/node_modules/@openclaw/fs-safe/dist/fs.js +2 -10
  59. package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts +3 -4
  60. package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js +6 -18
  61. package/node_modules/@openclaw/fs-safe/dist/guest-dispatch-python.js +1 -1
  62. package/node_modules/@openclaw/fs-safe/dist/guest-native-python.js +0 -2
  63. package/node_modules/@openclaw/fs-safe/dist/guest.js +3 -9
  64. package/node_modules/@openclaw/fs-safe/dist/index.d.ts +1 -1
  65. package/node_modules/@openclaw/fs-safe/dist/index.js +1 -1
  66. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.js +1 -5
  67. package/node_modules/@openclaw/fs-safe/dist/json.js +19 -37
  68. package/node_modules/@openclaw/fs-safe/dist/move-path.js +2 -0
  69. package/node_modules/@openclaw/fs-safe/dist/mutation-authority.d.ts +1 -0
  70. package/node_modules/@openclaw/fs-safe/dist/mutation-authority.js +9 -1
  71. package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts +47 -2
  72. package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts +1 -9
  73. package/node_modules/@openclaw/fs-safe/dist/native-config.js +6 -40
  74. package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.d.ts +2 -0
  75. package/node_modules/@openclaw/fs-safe/dist/native-parent-admission.js +5 -2
  76. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.js +11 -316
  77. package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.d.ts +7 -7
  78. package/node_modules/@openclaw/fs-safe/dist/native-policy-parent-windows.js +28 -175
  79. package/node_modules/@openclaw/fs-safe/dist/native-policy-parent.d.ts +15 -0
  80. package/node_modules/@openclaw/fs-safe/dist/native-policy-parent.js +418 -0
  81. package/node_modules/@openclaw/fs-safe/dist/native-rename-outcome.js +9 -4
  82. package/node_modules/@openclaw/fs-safe/dist/native-staged-file.js +17 -13
  83. package/node_modules/@openclaw/fs-safe/dist/native-staged-symlink.js +6 -24
  84. package/node_modules/@openclaw/fs-safe/dist/native.js +5 -1
  85. package/node_modules/@openclaw/fs-safe/dist/path-case.js +10 -9
  86. package/node_modules/@openclaw/fs-safe/dist/path-scope-lexical.js +4 -1
  87. package/node_modules/@openclaw/fs-safe/dist/path-segment-route.d.ts +1 -0
  88. package/node_modules/@openclaw/fs-safe/dist/path-segment-route.js +3 -0
  89. package/node_modules/@openclaw/fs-safe/dist/path.js +4 -1
  90. package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts +0 -1
  91. package/node_modules/@openclaw/fs-safe/dist/pinned-mutation-admission.js +1 -3
  92. package/node_modules/@openclaw/fs-safe/dist/pinned-write-staged.js +2 -0
  93. package/node_modules/@openclaw/fs-safe/dist/pinned-write.js +9 -10
  94. package/node_modules/@openclaw/fs-safe/dist/private-producer-handoff.js +3 -6
  95. package/node_modules/@openclaw/fs-safe/dist/publish-copy-stage.js +2 -2
  96. package/node_modules/@openclaw/fs-safe/dist/publish-file.js +4 -3
  97. package/node_modules/@openclaw/fs-safe/dist/replace-file-buffer.d.ts +3 -4
  98. package/node_modules/@openclaw/fs-safe/dist/replace-file-buffer.js +18 -32
  99. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts +5 -17
  100. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.js +92 -230
  101. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts +4 -15
  102. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.js +22 -63
  103. package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts +9 -34
  104. package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.js +78 -83
  105. package/node_modules/@openclaw/fs-safe/dist/replace-file-destination.d.ts +18 -20
  106. package/node_modules/@openclaw/fs-safe/dist/replace-file-destination.js +64 -98
  107. package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts +16 -33
  108. package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js +61 -200
  109. package/node_modules/@openclaw/fs-safe/dist/replace-file-types.d.ts +1 -6
  110. package/node_modules/@openclaw/fs-safe/dist/replace-file.js +76 -216
  111. package/node_modules/@openclaw/fs-safe/dist/root-boundary.js +14 -24
  112. package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts +1 -4
  113. package/node_modules/@openclaw/fs-safe/dist/root-context.js +4 -19
  114. package/node_modules/@openclaw/fs-safe/dist/root-create-native.d.ts +52 -0
  115. package/node_modules/@openclaw/fs-safe/dist/root-create-native.js +350 -0
  116. package/node_modules/@openclaw/fs-safe/dist/root-directory-list-types.d.ts +35 -0
  117. package/node_modules/@openclaw/fs-safe/dist/root-directory-list-types.js +1 -0
  118. package/node_modules/@openclaw/fs-safe/dist/root-directory-list.d.ts +2 -27
  119. package/node_modules/@openclaw/fs-safe/dist/root-directory-list.js +31 -28
  120. package/node_modules/@openclaw/fs-safe/dist/root-directory.js +1 -4
  121. package/node_modules/@openclaw/fs-safe/dist/root-errors.js +34 -0
  122. package/node_modules/@openclaw/fs-safe/dist/root-file.js +9 -21
  123. package/node_modules/@openclaw/fs-safe/dist/root-impl.js +105 -37
  124. package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.d.ts +7 -2
  125. package/node_modules/@openclaw/fs-safe/dist/root-move-noreplace.js +67 -38
  126. package/node_modules/@openclaw/fs-safe/dist/root-observed-path.d.ts +1 -1
  127. package/node_modules/@openclaw/fs-safe/dist/root-observed-path.js +0 -2
  128. package/node_modules/@openclaw/fs-safe/dist/root-options.d.ts +2 -3
  129. package/node_modules/@openclaw/fs-safe/dist/root-path-existing.js +3 -1
  130. package/node_modules/@openclaw/fs-safe/dist/root-path-stat.js +68 -85
  131. package/node_modules/@openclaw/fs-safe/dist/root-path.js +6 -1
  132. package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.d.ts +4 -0
  133. package/node_modules/@openclaw/fs-safe/dist/root-paths-lexical.js +1 -1
  134. package/node_modules/@openclaw/fs-safe/dist/root-paths.js +4 -9
  135. package/node_modules/@openclaw/fs-safe/dist/root-remove-native.d.ts +4 -0
  136. package/node_modules/@openclaw/fs-safe/dist/root-remove-native.js +311 -0
  137. package/node_modules/@openclaw/fs-safe/dist/root-remove.d.ts +11 -0
  138. package/node_modules/@openclaw/fs-safe/dist/root-remove.js +3 -1
  139. package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts +2 -2
  140. package/node_modules/@openclaw/fs-safe/dist/root-walk.js +1 -3
  141. package/node_modules/@openclaw/fs-safe/dist/root-write-admission.d.ts +3 -3
  142. package/node_modules/@openclaw/fs-safe/dist/root-write-admission.js +8 -10
  143. package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts +0 -1
  144. package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.js +0 -4
  145. package/node_modules/@openclaw/fs-safe/dist/secret-file.js +12 -9
  146. package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts +0 -2
  147. package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.js +2 -0
  148. package/node_modules/@openclaw/fs-safe/dist/sibling-temp.js +7 -4
  149. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.js +13 -6
  150. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts +0 -3
  151. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js +5 -23
  152. package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.d.ts +2 -1
  153. package/node_modules/@openclaw/fs-safe/dist/staged-file-settlement.js +11 -6
  154. package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.js +1 -8
  155. package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.d.ts +1 -1
  156. package/node_modules/@openclaw/fs-safe/dist/temp-workspace-child-admission.js +2 -9
  157. package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts +1 -6
  158. package/node_modules/@openclaw/fs-safe/dist/trash.js +6 -2
  159. package/node_modules/@openclaw/fs-safe/dist/walk.js +100 -46
  160. package/node_modules/@openclaw/fs-safe/dist/watch-hints.d.ts +7 -0
  161. package/node_modules/@openclaw/fs-safe/dist/watch-hints.js +235 -19
  162. package/node_modules/@openclaw/fs-safe/dist/watch-native.d.ts +21 -2
  163. package/node_modules/@openclaw/fs-safe/dist/watch-native.js +21 -3
  164. package/node_modules/@openclaw/fs-safe/dist/watch-rescan.d.ts +6 -0
  165. package/node_modules/@openclaw/fs-safe/dist/watch-rescan.js +111 -0
  166. package/node_modules/@openclaw/fs-safe/dist/watch-scan.d.ts +13 -0
  167. package/node_modules/@openclaw/fs-safe/dist/watch-scan.js +27 -4
  168. package/node_modules/@openclaw/fs-safe/dist/watch-stream.js +2 -0
  169. package/node_modules/@openclaw/fs-safe/dist/watch.js +131 -40
  170. package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.d.ts +8 -0
  171. package/node_modules/@openclaw/fs-safe/dist/windows-path-alias.js +24 -6
  172. package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.d.ts +13 -0
  173. package/node_modules/@openclaw/fs-safe/dist/windows-path-syntax.js +51 -0
  174. package/node_modules/@openclaw/fs-safe/docs/advanced.md +4 -0
  175. package/node_modules/@openclaw/fs-safe/docs/atomic.md +4 -1
  176. package/node_modules/@openclaw/fs-safe/docs/config.md +6 -14
  177. package/node_modules/@openclaw/fs-safe/docs/contributing.md +4 -14
  178. package/node_modules/@openclaw/fs-safe/docs/durability.md +6 -29
  179. package/node_modules/@openclaw/fs-safe/docs/entry-publication.md +146 -0
  180. package/node_modules/@openclaw/fs-safe/docs/errors.md +16 -0
  181. package/node_modules/@openclaw/fs-safe/docs/file-store.md +28 -5
  182. package/node_modules/@openclaw/fs-safe/docs/index.md +2 -31
  183. package/node_modules/@openclaw/fs-safe/docs/install.md +10 -31
  184. package/node_modules/@openclaw/fs-safe/docs/json.md +1 -1
  185. package/node_modules/@openclaw/fs-safe/docs/local-roots.md +0 -1
  186. package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.5.md +12 -12
  187. package/node_modules/@openclaw/fs-safe/docs/native-helper.md +35 -96
  188. package/node_modules/@openclaw/fs-safe/docs/native.md +22 -20
  189. package/node_modules/@openclaw/fs-safe/docs/path.md +1 -1
  190. package/node_modules/@openclaw/fs-safe/docs/permissions.md +1 -2
  191. package/node_modules/@openclaw/fs-safe/docs/public-api.md +1 -2
  192. package/node_modules/@openclaw/fs-safe/docs/reading.md +1 -2
  193. package/node_modules/@openclaw/fs-safe/docs/root.md +26 -184
  194. package/node_modules/@openclaw/fs-safe/docs/secret-file.md +1 -1
  195. package/node_modules/@openclaw/fs-safe/docs/security-model.md +115 -3
  196. package/node_modules/@openclaw/fs-safe/docs/store.md +2 -2
  197. package/node_modules/@openclaw/fs-safe/docs/temp.md +29 -65
  198. package/node_modules/@openclaw/fs-safe/docs/testing.md +90 -58
  199. package/node_modules/@openclaw/fs-safe/docs/types.md +3 -16
  200. package/node_modules/@openclaw/fs-safe/docs/walk.md +33 -5
  201. package/node_modules/@openclaw/fs-safe/docs/watch.md +96 -14
  202. package/node_modules/@openclaw/fs-safe/docs/writing.md +172 -16
  203. package/node_modules/@openclaw/fs-safe/package.json +10 -10
  204. package/node_modules/@openclaw/fs-safe-darwin-arm64/fs-safe-native.node +0 -0
  205. package/node_modules/@openclaw/fs-safe-darwin-arm64/package.json +1 -1
  206. package/node_modules/@openclaw/fs-safe-darwin-x64/fs-safe-native.node +0 -0
  207. package/node_modules/@openclaw/fs-safe-darwin-x64/package.json +1 -1
  208. package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/fs-safe-native.node +0 -0
  209. package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/package.json +1 -1
  210. package/node_modules/@openclaw/fs-safe-linux-arm64-musl/fs-safe-native.node +0 -0
  211. package/node_modules/@openclaw/fs-safe-linux-arm64-musl/package.json +1 -1
  212. package/node_modules/@openclaw/fs-safe-linux-x64-gnu/fs-safe-native.node +0 -0
  213. package/node_modules/@openclaw/fs-safe-linux-x64-gnu/package.json +1 -1
  214. package/node_modules/@openclaw/fs-safe-linux-x64-musl/fs-safe-native.node +0 -0
  215. package/node_modules/@openclaw/fs-safe-linux-x64-musl/package.json +1 -1
  216. package/node_modules/@openclaw/fs-safe-win32-x64-msvc/fs-safe-native.node +0 -0
  217. package/node_modules/@openclaw/fs-safe-win32-x64-msvc/package.json +1 -1
  218. package/package.json +5 -5
  219. package/skills/feishu-wiki/SKILL.md +1 -1
  220. package/dist/.setup/accounts-wRqItHug.mjs +0 -206
  221. package/node_modules/@openclaw/fs-safe/dist/watch-alias.d.ts +0 -6
  222. package/node_modules/@openclaw/fs-safe/dist/watch-alias.js +0 -88
  223. package/node_modules/@openclaw/fs-safe/docs/mutation-policy-proof.md +0 -69
  224. package/node_modules/@openclaw/fs-safe/docs/private-file-store.md +0 -68
  225. package/node_modules/@openclaw/fs-safe/docs/test-hooks.md +0 -110
@@ -1,20 +1,20 @@
1
- import { o as normalizeFeishuExternalKey } from "./doctor-contract-3XC0vbIw.mjs";
2
- import { c as resolveFeishuRuntimeAccount, i as listFeishuAccountIds, o as resolveDefaultFeishuAccountId, r as listEnabledFeishuAccounts, s as resolveFeishuAccount } from "./accounts-wRqItHug.mjs";
1
+ import { d as listFeishuAccountIds, h as resolveFeishuRuntimeAccount, m as resolveFeishuAccount, p as resolveDefaultFeishuAccountId, s as normalizeFeishuExternalKey, u as listEnabledFeishuAccounts } from "./doctor-contract-B1B9ogdd.mjs";
3
2
  import { l as normalizeFeishuTarget, s as detectIdType, u as resolveReceiveIdType } from "./conversation-id-C1ofUfU8.mjs";
4
3
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.mjs";
5
- import { c as withFeishuMessageDispatch, o as captureFeishuSendAuthority, r as createFeishuClient, s as runBeforeFeishuMessageDispatch } from "./client-BYG-_IZl.mjs";
4
+ import { c as withFeishuMessageDispatch, o as captureFeishuSendAuthority, r as createFeishuClient, s as runBeforeFeishuMessageDispatch } from "./client-BsBVWJzN.mjs";
6
5
  import { normalizeAccountId, normalizeOptionalAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
7
6
  import { compileAllowlist, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
8
7
  import { ToolAuthorizationError } from "openclaw/plugin-sdk/channel-actions";
8
+ import { normalizeChannelDmPolicy } from "openclaw/plugin-sdk/channel-config-helpers";
9
9
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
10
10
  import { PlatformMessageNotDispatchedError, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
11
11
  import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText, renderPresentationForDelivery, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
12
12
  import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
13
13
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeTrimmedStringList, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { convertMarkdownTables, markdownToIRWithMeta } from "openclaw/plugin-sdk/text-chunking";
15
+ import { jsonResult } from "openclaw/plugin-sdk/tool-results";
15
16
  import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
16
17
  import { defineStableChannelIngressIdentity } from "openclaw/plugin-sdk/channel-ingress-runtime";
17
- import fs from "node:fs";
18
18
  import path from "node:path";
19
19
  import { fromMarkdown } from "mdast-util-from-markdown";
20
20
  import { gfmTableFromMarkdown } from "mdast-util-gfm-table";
@@ -26,13 +26,11 @@ import { wrapExternalContent, writeExternalFileWithinRoot } from "openclaw/plugi
26
26
  import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
27
27
  import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
28
28
  import { Type } from "typebox";
29
- import { jsonResult } from "openclaw/plugin-sdk/tool-results";
30
29
  import { isBlockedHostnameOrIp, resolvePinnedHostnameWithPolicy } from "openclaw/plugin-sdk/ssrf-runtime";
31
- import { Readable } from "node:stream";
32
30
  import { detectMime, mediaKindFromMime } from "openclaw/plugin-sdk/media-mime";
33
31
  import { MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS, buildOutboundMediaLoadOptions, runFfmpeg, runFfprobe } from "openclaw/plugin-sdk/media-runtime";
34
- import { saveMediaBuffer, saveMediaStream } from "openclaw/plugin-sdk/media-store";
35
- import { resolvePreferredOpenClawTmpDir, withTempDownloadPath, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
32
+ import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
33
+ import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
36
34
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
37
35
  import { escapeHtml, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
38
36
  //#region extensions/feishu/src/card-interaction.ts
@@ -73,30 +71,16 @@ function decodeFeishuCardAction(params) {
73
71
  kind: "invalid",
74
72
  reason: "malformed"
75
73
  };
76
- if (actionValue.m !== void 0) {
77
- if (!isRecord(actionValue.m)) return {
78
- kind: "invalid",
79
- reason: "malformed"
80
- };
81
- for (const value of Object.values(actionValue.m)) if (!isMetadataValue(value)) return {
82
- kind: "invalid",
83
- reason: "malformed"
84
- };
85
- }
74
+ if (actionValue.m !== void 0 && (!isRecord(actionValue.m) || !Object.values(actionValue.m).every(isMetadataValue))) return {
75
+ kind: "invalid",
76
+ reason: "malformed"
77
+ };
86
78
  if (actionValue.c !== void 0) {
87
79
  if (!isRecord(actionValue.c)) return {
88
80
  kind: "invalid",
89
81
  reason: "malformed"
90
82
  };
91
- if (actionValue.c.u !== void 0 && typeof actionValue.c.u !== "string") return {
92
- kind: "invalid",
93
- reason: "malformed"
94
- };
95
- if (actionValue.c.h !== void 0 && typeof actionValue.c.h !== "string") return {
96
- kind: "invalid",
97
- reason: "malformed"
98
- };
99
- if (actionValue.c.s !== void 0 && typeof actionValue.c.s !== "string") return {
83
+ if (actionValue.c.u !== void 0 && typeof actionValue.c.u !== "string" || actionValue.c.h !== void 0 && typeof actionValue.c.h !== "string" || actionValue.c.s !== void 0 && typeof actionValue.c.s !== "string") return {
100
84
  kind: "invalid",
101
85
  reason: "malformed"
102
86
  };
@@ -135,8 +119,7 @@ function normalizeFeishuChatType(value) {
135
119
  if (value === "p2p") return "p2p";
136
120
  }
137
121
  function normalizeFeishuChatMode(value) {
138
- if (value === "group" || value === "topic" || value === "topic_group") return "group";
139
- return value === "p2p" ? "p2p" : void 0;
122
+ return value === "topic" ? "group" : normalizeFeishuChatType(value);
140
123
  }
141
124
  function resolveFeishuChatType(chat) {
142
125
  return normalizeFeishuChatMode(chat.chat_mode) ?? normalizeFeishuChatType(chat.chat_type);
@@ -185,9 +168,6 @@ function normalizeFeishuAllowEntry(raw) {
185
168
  if (detectedType === "open_id" || detectedType === "user_id") return `user:${withoutProviderPrefix}`;
186
169
  return "";
187
170
  }
188
- function normalizeFeishuDmPolicy(policy) {
189
- return policy === "open" || policy === "pairing" || policy === "allowlist" || policy === "disabled" ? policy : "pairing";
190
- }
191
171
  function normalizeFeishuGroupPolicy(policy) {
192
172
  return policy === "allowall" ? "open" : policy;
193
173
  }
@@ -219,7 +199,7 @@ async function resolveFeishuDmIngressAccess(params) {
219
199
  },
220
200
  ...params.contextBinding ? { contextBinding: params.contextBinding } : {},
221
201
  event: { mayPair: params.mayPair },
222
- dmPolicy: normalizeFeishuDmPolicy(params.dmPolicy),
202
+ dmPolicy: normalizeChannelDmPolicy(params.dmPolicy ?? void 0) ?? "pairing",
223
203
  groupPolicy: "disabled",
224
204
  allowFrom: params.allowFrom ?? [],
225
205
  ...params.command ? { command: params.command } : {}
@@ -376,7 +356,7 @@ function isFeishuGroupReadEnabled(cfg, account, chatId) {
376
356
  groupId: chatId
377
357
  })?.enabled !== false;
378
358
  }
379
- function isDmUniversallyAllowed(account) {
359
+ function canEnumerateAllFeishuPeers(account) {
380
360
  return compileAllowlist(normalizeFeishuAllowlist(account.config.allowFrom)).wildcard;
381
361
  }
382
362
  function assertFeishuChatReadAllowed(params) {
@@ -399,7 +379,7 @@ function resolveFeishuChatReadPreliminaryAuthorization(params) {
399
379
  });
400
380
  const directOperator = readContextFields(params.ctx).directOperator;
401
381
  const groupAllowed = directOperator ? isFeishuGroupReadEnabled(params.cfg, params.account, chatId) : isFeishuGroupReadAllowed(params.cfg, params.account, chatId, current);
402
- const dmAllowed = directOperator || current || isDmUniversallyAllowed(params.account);
382
+ const dmAllowed = directOperator || current || canEnumerateAllFeishuPeers(params.account);
403
383
  if (knownGroup) return {
404
384
  chatId,
405
385
  decision: groupAllowed ? "allow" : "deny"
@@ -469,9 +449,6 @@ function canEnumerateAllFeishuGroups(cfg, account) {
469
449
  const policy = resolveFeishuReadGroupPolicy(cfg, account);
470
450
  return policy === "open" || policy === "allowlist" && compileAllowlist(normalizeFeishuAllowlist(account.config.groupAllowFrom)).wildcard;
471
451
  }
472
- function canEnumerateAllFeishuPeers(account) {
473
- return isDmUniversallyAllowed(account);
474
- }
475
452
  //#endregion
476
453
  //#region extensions/feishu/src/markdown.ts
477
454
  const FEISHU_POST_MAX_BYTES = 30720;
@@ -485,6 +462,18 @@ function parseFeishuMarkdown(text) {
485
462
  mdastExtensions: [gfmTableFromMarkdown()]
486
463
  });
487
464
  }
465
+ function visitFeishuMarkdown(root, visitor) {
466
+ const pending = [root];
467
+ while (pending.length > 0) {
468
+ const node = pending.pop();
469
+ if (!node) continue;
470
+ visitor(node);
471
+ for (let index = (node.children?.length ?? 0) - 1; index >= 0; index -= 1) {
472
+ const child = node.children?.[index];
473
+ if (child) pending.push(child);
474
+ }
475
+ }
476
+ }
488
477
  function buildFeishuPostMentionElements(mentions) {
489
478
  if (!mentions?.length) return [];
490
479
  const elements = [];
@@ -513,15 +502,11 @@ function assertFeishuPostWithinEnvelope(content, label) {
513
502
  function collectSoftBreakOffsets(text) {
514
503
  const root = parseFeishuMarkdown(text);
515
504
  const offsets = [];
516
- const pending = [root];
517
- while (pending.length > 0) {
518
- const node = pending.pop();
519
- if (!node) continue;
520
- if (node.children) pending.push(...node.children);
521
- if (node.type !== "text") continue;
505
+ visitFeishuMarkdown(root, (node) => {
506
+ if (node.type !== "text") return;
522
507
  const start = node.position?.start.offset;
523
508
  const end = node.position?.end.offset;
524
- if (start === void 0 || end === void 0) continue;
509
+ if (start === void 0 || end === void 0) return;
525
510
  for (let offset = start; offset < end; offset += 1) {
526
511
  const char = text[offset];
527
512
  if (char === "\n") {
@@ -533,7 +518,7 @@ function collectSoftBreakOffsets(text) {
533
518
  if (text[offset + 1] === "\n") offset += 1;
534
519
  }
535
520
  }
536
- }
521
+ });
537
522
  return offsets.toSorted((left, right) => left - right);
538
523
  }
539
524
  /**
@@ -628,14 +613,7 @@ function resolveFeishuCardTemplate(template) {
628
613
  return normalized;
629
614
  }
630
615
  function escapeFeishuCardMarkdownText(text) {
631
- return text.replace(/[&<>]/g, (char) => {
632
- switch (char) {
633
- case "&": return "&amp;";
634
- case "<": return "&lt;";
635
- case ">": return "&gt;";
636
- default: return char;
637
- }
638
- });
616
+ return text.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
639
617
  }
640
618
  function escapeFeishuCardPlainText(text) {
641
619
  return escapeFeishuCardMarkdownText(text).replace(/([\\`*_{}[\]()#+\-!|>~])/g, "\\$1");
@@ -664,11 +642,13 @@ function sanitizeNativeFeishuButtonBehavior(behavior) {
664
642
  value: behavior.value
665
643
  };
666
644
  }
645
+ function resolveFeishuButtonType(style) {
646
+ return style === "primary" || style === "success" ? "primary" : style === "danger" ? "danger" : "default";
647
+ }
667
648
  function sanitizeNativeFeishuCardButton(button) {
668
649
  if (!isRecord(button)) return;
669
650
  const text = isRecord(button.text) && typeof button.text.content === "string" ? button.text.content : void 0;
670
651
  if (!text?.trim()) return;
671
- const style = button.type === "danger" ? "danger" : button.type === "primary" || button.type === "success" ? "primary" : void 0;
672
652
  const behaviors = Array.isArray(button.behaviors) ? button.behaviors.map(sanitizeNativeFeishuButtonBehavior).filter((behavior) => Boolean(behavior)) : [];
673
653
  const rootSafeUrl = resolveSafeFeishuButtonUrl(button.url);
674
654
  if (rootSafeUrl) behaviors.push({
@@ -686,7 +666,7 @@ function sanitizeNativeFeishuCardButton(button) {
686
666
  tag: "plain_text",
687
667
  content: text
688
668
  },
689
- type: style ?? "default",
669
+ type: resolveFeishuButtonType(button.type),
690
670
  behaviors
691
671
  };
692
672
  }
@@ -784,8 +764,7 @@ function getFeishuSendRateLimitCode(error) {
784
764
  if (!isRecord(error)) return;
785
765
  const response = isRecord(error.response) ? error.response : void 0;
786
766
  if (response?.status === 429) return 429;
787
- const code = (isRecord(response?.data) ? response.data : void 0)?.code;
788
- return typeof code === "number" && FEISHU_SEND_RATE_LIMIT_CODES.has(code) ? code : void 0;
767
+ return getFeishuSendRateLimitCodeFromResponse(response?.data);
789
768
  }
790
769
  function getFeishuSendRateLimitCodeFromResponse(response) {
791
770
  if (!isRecord(response)) return;
@@ -1243,7 +1222,6 @@ const DEFAULT_TOOLS_CONFIG = {
1243
1222
  scopes: true,
1244
1223
  bitable: true
1245
1224
  };
1246
- /** Resolve tools config with defaults. */
1247
1225
  function resolveToolsConfig(cfg) {
1248
1226
  return {
1249
1227
  ...DEFAULT_TOOLS_CONFIG,
@@ -1369,11 +1347,8 @@ function registerFeishuTool(api, tool) {
1369
1347
  //#endregion
1370
1348
  //#region extensions/feishu/src/drive.ts
1371
1349
  const FEISHU_DRIVE_REQUEST_TIMEOUT_MS = 3e4;
1372
- function getDriveInternalClient(client) {
1373
- return client;
1374
- }
1375
- async function requestDriveApi(params) {
1376
- return await getDriveInternalClient(params.client).request({
1350
+ function requestDriveApi(params) {
1351
+ return params.client.request({
1377
1352
  method: params.method,
1378
1353
  url: params.url,
1379
1354
  params: params.query ?? {},
@@ -1449,9 +1424,8 @@ function extractDriveApiErrorMeta(error) {
1449
1424
  };
1450
1425
  }
1451
1426
  async function getRootFolderToken(client) {
1452
- const internalClient = getDriveInternalClient(client);
1453
- const domain = internalClient.domain ?? "https://open.feishu.cn";
1454
- const res = await internalClient.httpInstance.get(`${domain}/open-apis/drive/explorer/v2/root_folder/meta`);
1427
+ const domain = client.domain ?? "https://open.feishu.cn";
1428
+ const res = await client.httpInstance.get(`${domain}/open-apis/drive/explorer/v2/root_folder/meta`);
1455
1429
  if (res.code !== 0) throw new Error(res.msg ?? "Failed to get root folder");
1456
1430
  const token = res.data?.token;
1457
1431
  if (!token) throw new Error("Root folder token not found");
@@ -1652,35 +1626,24 @@ async function deliverCommentThreadText(client, params) {
1652
1626
  if (isWholeComment) {
1653
1627
  if (params.file_type !== "doc" && params.file_type !== "docx") throw new Error(`Whole-document comment follow-ups are only supported for doc/docx (got ${params.file_type})`);
1654
1628
  console.info(`[feishu_drive] whole-comment compatibility path comment=${params.comment_id} file_type=${params.file_type} mode=add_comment`);
1655
- return {
1656
- delivery_mode: "add_comment",
1657
- ...await addComment(client, {
1658
- file_token: params.file_token,
1659
- file_type: params.file_type,
1660
- content: params.content
1661
- })
1662
- };
1663
- }
1664
- try {
1629
+ } else try {
1665
1630
  return {
1666
1631
  delivery_mode: "reply_comment",
1667
1632
  ...await replyComment(client, params)
1668
1633
  };
1669
1634
  } catch (error) {
1670
- if (error instanceof FeishuReplyCommentError && error.feishuCode === 1069302) {
1671
- if (params.file_type !== "doc" && params.file_type !== "docx") throw error;
1672
- console.info(`[feishu_drive] reply-not-allowed compatibility path comment=${params.comment_id} file_type=${params.file_type} mode=add_comment log_id=${error.feishuLogId ?? "unknown"}`);
1673
- return {
1674
- delivery_mode: "add_comment",
1675
- ...await addComment(client, {
1676
- file_token: params.file_token,
1677
- file_type: params.file_type,
1678
- content: params.content
1679
- })
1680
- };
1681
- }
1682
- throw error;
1635
+ if (!(error instanceof FeishuReplyCommentError) || error.feishuCode !== 1069302) throw error;
1636
+ if (params.file_type !== "doc" && params.file_type !== "docx") throw error;
1637
+ console.info(`[feishu_drive] reply-not-allowed compatibility path comment=${params.comment_id} file_type=${params.file_type} mode=add_comment log_id=${error.feishuLogId ?? "unknown"}`);
1683
1638
  }
1639
+ return {
1640
+ delivery_mode: "add_comment",
1641
+ ...await addComment(client, {
1642
+ file_token: params.file_token,
1643
+ file_type: params.file_type,
1644
+ content: params.content
1645
+ })
1646
+ };
1684
1647
  }
1685
1648
  function registerFeishuDriveTools(api) {
1686
1649
  registerFeishuTool(api, {
@@ -1716,7 +1679,7 @@ function registerFeishuDriveTools(api) {
1716
1679
  return feishuExternalToolResult(await (resolved.action === "add_comment" ? addComment(client, resolved) : deliverCommentThreadText(client, resolved)));
1717
1680
  } finally {
1718
1681
  cleanupAmbientCommentTypingReaction({
1719
- client: getDriveInternalClient(client),
1682
+ client,
1720
1683
  deliveryContext: ctx.deliveryContext
1721
1684
  });
1722
1685
  }
@@ -1908,7 +1871,7 @@ function renderCodeBlockElement(element) {
1908
1871
  }
1909
1872
  function renderElement(element, attachments, mentionedOpenIds, renderMediaPlaceholders) {
1910
1873
  if (!isRecord(element)) return escapeMarkdownText(toStringOrEmpty(element));
1911
- switch (normalizeLowercaseStringOrEmpty(toStringOrEmpty(element.tag))) {
1874
+ switch (normalizeLowercaseStringOrEmpty(element.tag)) {
1912
1875
  case "text": return applyInlineStyles(escapeMarkdownText(toStringOrEmpty(element.text)), element.style);
1913
1876
  case "a": return applyInlineStyles(renderLinkElement(element), element.style);
1914
1877
  case "at":
@@ -1919,7 +1882,7 @@ function renderElement(element, attachments, mentionedOpenIds, renderMediaPlaceh
1919
1882
  }
1920
1883
  return applyInlineStyles(renderMentionElement(element), element.style);
1921
1884
  case "img": {
1922
- const imageKey = normalizeFeishuExternalKey(toStringOrEmpty(element.image_key));
1885
+ const imageKey = normalizeFeishuExternalKey(element.image_key);
1923
1886
  if (imageKey) attachments.push({
1924
1887
  kind: "image",
1925
1888
  key: imageKey
@@ -1927,7 +1890,7 @@ function renderElement(element, attachments, mentionedOpenIds, renderMediaPlaceh
1927
1890
  return renderMediaPlaceholders ? "![image]" : "";
1928
1891
  }
1929
1892
  case "media": {
1930
- const fileKey = normalizeFeishuExternalKey(toStringOrEmpty(element.file_key));
1893
+ const fileKey = normalizeFeishuExternalKey(element.file_key);
1931
1894
  if (fileKey) {
1932
1895
  const fileName = toStringOrEmpty(element.file_name) || void 0;
1933
1896
  attachments.push({
@@ -1952,11 +1915,29 @@ function renderElement(element, attachments, mentionedOpenIds, renderMediaPlaceh
1952
1915
  default: return escapeMarkdownText(toStringOrEmpty(element.text));
1953
1916
  }
1954
1917
  }
1918
+ function appendTopLevelPostFiles(attachments, files) {
1919
+ if (!Array.isArray(files)) return;
1920
+ const seenFileKeys = new Set(attachments.filter((attachment) => attachment.kind === "file").map((attachment) => attachment.key));
1921
+ for (const entry of files) {
1922
+ if (!isRecord(entry) || entry.is_folder === true) continue;
1923
+ const fileKey = normalizeFeishuExternalKey(entry.file_key);
1924
+ if (!fileKey || seenFileKeys.has(fileKey)) continue;
1925
+ seenFileKeys.add(fileKey);
1926
+ const fileName = toStringOrEmpty(entry.file_name) || void 0;
1927
+ attachments.push({
1928
+ kind: "file",
1929
+ key: fileKey,
1930
+ origin: "top-level",
1931
+ ...fileName ? { fileName } : {}
1932
+ });
1933
+ }
1934
+ }
1955
1935
  function toPostPayload(candidate) {
1956
1936
  if (!isRecord(candidate) || !Array.isArray(candidate.content)) return null;
1957
1937
  return {
1958
1938
  title: toStringOrEmpty(candidate.title),
1959
- content: candidate.content
1939
+ content: candidate.content,
1940
+ ...Array.isArray(candidate.files) ? { files: candidate.files } : {}
1960
1941
  };
1961
1942
  }
1962
1943
  function resolveLocalePayload(candidate) {
@@ -1970,12 +1951,7 @@ function resolveLocalePayload(candidate) {
1970
1951
  return null;
1971
1952
  }
1972
1953
  function resolvePostPayload(parsed) {
1973
- const direct = toPostPayload(parsed);
1974
- if (direct) return direct;
1975
- if (!isRecord(parsed)) return null;
1976
- const wrappedPost = resolveLocalePayload(parsed.post);
1977
- if (wrappedPost) return wrappedPost;
1978
- return resolveLocalePayload(parsed);
1954
+ return toPostPayload(parsed) ?? (isRecord(parsed) ? resolveLocalePayload(parsed.post) ?? resolveLocalePayload(parsed) : null);
1979
1955
  }
1980
1956
  function parsePostContent(content, options = {}) {
1981
1957
  try {
@@ -2005,6 +1981,10 @@ function renderPostContent(parsed, options = {}) {
2005
1981
  for (const element of paragraph) renderedParagraph += renderElement(element, attachments, mentionedOpenIds, options.renderMediaPlaceholders !== false);
2006
1982
  paragraphs.push(renderedParagraph);
2007
1983
  }
1984
+ if (options.includeTopLevelFiles !== false) {
1985
+ appendTopLevelPostFiles(attachments, payload.files);
1986
+ if (isRecord(parsed)) appendTopLevelPostFiles(attachments, parsed.files);
1987
+ }
2008
1988
  return {
2009
1989
  textContent: [escapeMarkdownText(payload.title.trim()), paragraphs.join("\n").trim()].filter(Boolean).join("\n\n").trim() || (options.emptyTextFallback ?? FALLBACK_POST_TEXT),
2010
1990
  attachments,
@@ -2093,13 +2073,12 @@ function extractInteractiveElementText(element, variables) {
2093
2073
  if (Array.isArray(element.fields)) parts.push(extractInteractiveElementsText(element.fields, variables));
2094
2074
  return parts.filter(Boolean).join("\n") || void 0;
2095
2075
  }
2096
- if ((tag === "markdown" || tag === "lark_md") && typeof element.content === "string") return applyCardTemplateVariables(element.content, variables);
2076
+ if ((tag === "markdown" || tag === "lark_md" || tag === "plain_text") && typeof element.content === "string") return applyCardTemplateVariables(element.content, variables);
2097
2077
  if ((tag === "text" || tag === "a" || tag === "button") && element.text !== void 0) return normalizeInteractiveValue(element.text, variables) || void 0;
2098
2078
  if (tag === "at") {
2099
2079
  const mention = normalizeInteractiveValue(element.user_name ?? element.user_id, variables);
2100
2080
  return mention ? mention.startsWith("@") ? mention : `@${mention}` : void 0;
2101
2081
  }
2102
- if (tag === "plain_text" && typeof element.content === "string") return applyCardTemplateVariables(element.content, variables);
2103
2082
  if (tag === "table") return extractInteractiveTableText(element, variables);
2104
2083
  return [
2105
2084
  element.elements,
@@ -2192,9 +2171,7 @@ function isMentionForwardRequest(event, botOpenId) {
2192
2171
  if (!normalizedBotOpenId) return false;
2193
2172
  const isDirectMessage = !isFeishuGroupChatType(event.message.chat_type);
2194
2173
  const userMentions = mentions.filter((m) => !isFeishuBroadcastMention(m));
2195
- const hasOtherMention = userMentions.some((m) => m.id.open_id !== normalizedBotOpenId);
2196
- if (isDirectMessage) return hasOtherMention;
2197
- return userMentions.some((m) => m.id.open_id === normalizedBotOpenId) && hasOtherMention;
2174
+ return userMentions.some((m) => m.id.open_id !== normalizedBotOpenId) && (isDirectMessage || userMentions.some((m) => m.id.open_id === normalizedBotOpenId));
2198
2175
  }
2199
2176
  function buildMentionedCardContent(targets, message) {
2200
2177
  if (targets.length === 0) return message;
@@ -2320,21 +2297,21 @@ function isWithdrawnReplyError(err) {
2320
2297
  if (cause && cause !== err) return isWithdrawnReplyError(cause);
2321
2298
  return false;
2322
2299
  }
2323
- /** Send a direct message as a fallback when a reply target is unavailable. */
2324
- async function sendFallbackDirect(client, params, errorPrefix) {
2325
- const response = await requestFeishuApi(() => withFeishuMessageDispatch(() => client.im.message.create({
2326
- params: { receive_id_type: params.receiveIdType },
2327
- data: {
2328
- receive_id: params.receiveId,
2329
- content: params.content,
2330
- msg_type: params.msgType
2331
- }
2332
- })), errorPrefix, { includeNestedErrorLogId: true });
2333
- assertFeishuApiSuccess(response, errorPrefix);
2334
- return toFeishuSendResult(response, params.receiveId, resolveFeishuReceiptKind(params.msgType), errorPrefix);
2335
- }
2336
- async function sendReplyOrFallbackDirect(client, params) {
2337
- if (!params.replyToMessageId) return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
2300
+ async function sendReplyOrFallbackDirect(target, params) {
2301
+ const { client, receiveId, receiveIdType } = target;
2302
+ const sendDirect = async () => {
2303
+ const response = await requestFeishuApi(() => withFeishuMessageDispatch(() => client.im.message.create({
2304
+ params: { receive_id_type: receiveIdType },
2305
+ data: {
2306
+ receive_id: receiveId,
2307
+ content: params.content,
2308
+ msg_type: params.msgType
2309
+ }
2310
+ })), params.directErrorPrefix, { includeNestedErrorLogId: true });
2311
+ assertFeishuApiSuccess(response, params.directErrorPrefix);
2312
+ return toFeishuSendResult(response, receiveId, resolveFeishuReceiptKind(params.msgType), params.directErrorPrefix);
2313
+ };
2314
+ if (!params.replyToMessageId) return sendDirect();
2338
2315
  const replyTargetFallbackError = params.replyInThread && params.allowTopLevelReplyFallback !== true ? /* @__PURE__ */ new Error("Feishu thread reply failed: reply target is unavailable and cannot safely fall back to a top-level send.") : null;
2339
2316
  let response;
2340
2317
  try {
@@ -2349,14 +2326,14 @@ async function sendReplyOrFallbackDirect(client, params) {
2349
2326
  } catch (err) {
2350
2327
  if (!isWithdrawnReplyError(err)) throw err;
2351
2328
  if (replyTargetFallbackError) throw replyTargetFallbackError;
2352
- return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
2329
+ return sendDirect();
2353
2330
  }
2354
2331
  if (shouldFallbackFromReplyTarget(response)) {
2355
2332
  if (replyTargetFallbackError) throw replyTargetFallbackError;
2356
- return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
2333
+ return sendDirect();
2357
2334
  }
2358
2335
  assertFeishuApiSuccess(response, params.replyErrorPrefix);
2359
- return toFeishuSendResult(response, params.directParams.receiveId, resolveFeishuReceiptKind(params.msgType), params.replyErrorPrefix, params.replyToMessageId);
2336
+ return toFeishuSendResult(response, receiveId, resolveFeishuReceiptKind(params.msgType), params.replyErrorPrefix, params.replyToMessageId);
2360
2337
  }
2361
2338
  function parseFeishuMessageContent(rawContent, msgType, messageId) {
2362
2339
  if (!rawContent) return "";
@@ -2398,10 +2375,6 @@ function parseFeishuMessageItem(item, fallbackMessageId) {
2398
2375
  threadId: item.thread_id || void 0
2399
2376
  };
2400
2377
  }
2401
- /**
2402
- * Get a message by its ID.
2403
- * Useful for fetching quoted/replied message content.
2404
- */
2405
2378
  async function getMessageFeishu(params) {
2406
2379
  const { cfg, messageId, accountId } = params;
2407
2380
  const client = createConfiguredFeishuClient({
@@ -2477,12 +2450,8 @@ async function listFeishuThreadMessages(params) {
2477
2450
  return results;
2478
2451
  }
2479
2452
  async function sendMessageFeishu(params) {
2480
- const { cfg, to, text, preparedPostText, replyToMessageId, replyInThread, allowTopLevelReplyFallback, mentions, accountId } = params;
2481
- const { client, receiveId, receiveIdType } = resolveFeishuSendTarget({
2482
- cfg,
2483
- to,
2484
- accountId
2485
- });
2453
+ const { cfg, text, preparedPostText, mentions } = params;
2454
+ const target = resolveFeishuSendTarget(params);
2486
2455
  let messageText = text;
2487
2456
  if (!preparedPostText) {
2488
2457
  const tableMode = resolveMarkdownTableMode({
@@ -2495,44 +2464,20 @@ async function sendMessageFeishu(params) {
2495
2464
  messageText,
2496
2465
  mentions
2497
2466
  });
2498
- const msgType = "post";
2499
2467
  assertFeishuPostWithinEnvelope(content, "Feishu post");
2500
- return sendReplyOrFallbackDirect(client, {
2501
- replyToMessageId,
2502
- replyInThread,
2503
- allowTopLevelReplyFallback,
2468
+ return sendReplyOrFallbackDirect(target, {
2469
+ ...params,
2504
2470
  content,
2505
- msgType,
2506
- directParams: {
2507
- receiveId,
2508
- receiveIdType,
2509
- content,
2510
- msgType
2511
- },
2471
+ msgType: "post",
2512
2472
  directErrorPrefix: "Feishu send failed",
2513
2473
  replyErrorPrefix: "Feishu reply failed"
2514
2474
  });
2515
2475
  }
2516
2476
  async function sendCardFeishu(params) {
2517
- const { cfg, to, card, replyToMessageId, replyInThread, allowTopLevelReplyFallback, accountId } = params;
2518
- const { client, receiveId, receiveIdType } = resolveFeishuSendTarget({
2519
- cfg,
2520
- to,
2521
- accountId
2522
- });
2523
- const content = JSON.stringify(card);
2524
- return sendReplyOrFallbackDirect(client, {
2525
- replyToMessageId,
2526
- replyInThread,
2527
- allowTopLevelReplyFallback,
2528
- content,
2477
+ return sendReplyOrFallbackDirect(resolveFeishuSendTarget(params), {
2478
+ ...params,
2479
+ content: JSON.stringify(params.card),
2529
2480
  msgType: "interactive",
2530
- directParams: {
2531
- receiveId,
2532
- receiveIdType,
2533
- content,
2534
- msgType: "interactive"
2535
- },
2536
2481
  directErrorPrefix: "Feishu card send failed",
2537
2482
  replyErrorPrefix: "Feishu card reply failed"
2538
2483
  });
@@ -2575,9 +2520,6 @@ async function editMessageFeishu(params) {
2575
2520
  contentType: "post"
2576
2521
  };
2577
2522
  }
2578
- /**
2579
- * Build a Feishu interactive card with optional header and note footer.
2580
- */
2581
2523
  function buildStructuredCard(text, options) {
2582
2524
  const elements = [{
2583
2525
  tag: "markdown",
@@ -2614,9 +2556,6 @@ function chunkFeishuCardMarkdown(params) {
2614
2556
  })), "utf8")
2615
2557
  });
2616
2558
  }
2617
- /**
2618
- * Send a message as a structured card with optional header and note.
2619
- */
2620
2559
  async function sendStructuredCardFeishu(params) {
2621
2560
  return sendCardFeishu({
2622
2561
  ...params,
@@ -2666,13 +2605,10 @@ function createConfiguredFeishuMediaClient(params) {
2666
2605
  accountId: params.accountId
2667
2606
  });
2668
2607
  if (!account.configured) throw new Error(`Feishu account "${account.accountId}" not configured`);
2669
- return {
2670
- account,
2671
- client: createFeishuClient({
2672
- ...account,
2673
- httpTimeoutMs: FEISHU_MEDIA_HTTP_TIMEOUT_MS
2674
- })
2675
- };
2608
+ return createFeishuClient({
2609
+ ...account,
2610
+ httpTimeoutMs: FEISHU_MEDIA_HTTP_TIMEOUT_MS
2611
+ });
2676
2612
  }
2677
2613
  function asHeaderMap(value) {
2678
2614
  if (!value) return;
@@ -2726,39 +2662,6 @@ function decodeDispositionFileName(value) {
2726
2662
  const plainFileName = value.match(/filename="?([^";]+)"?/i)?.[1]?.trim();
2727
2663
  return plainFileName ? recoverUtf8FileNameFromLatin1Header(plainFileName) : void 0;
2728
2664
  }
2729
- function extractFeishuDownloadMetadata(response) {
2730
- const responseWithOptionalFields = response;
2731
- const headers = asHeaderMap(responseWithOptionalFields.headers) ?? asHeaderMap(responseWithOptionalFields.header);
2732
- const contentType = readHeaderValue(headers, "content-type") ?? responseWithOptionalFields.contentType ?? responseWithOptionalFields.mime_type ?? responseWithOptionalFields.data?.contentType ?? responseWithOptionalFields.data?.mime_type;
2733
- const disposition = readHeaderValue(headers, "content-disposition");
2734
- return {
2735
- contentType,
2736
- fileName: (disposition ? decodeDispositionFileName(disposition) : void 0) ?? responseWithOptionalFields.file_name ?? responseWithOptionalFields.fileName ?? responseWithOptionalFields.data?.file_name ?? responseWithOptionalFields.data?.fileName
2737
- };
2738
- }
2739
- function mediaLimitError(maxBytes) {
2740
- return /* @__PURE__ */ new Error(`Media exceeds ${Math.round(maxBytes / 1048576)}MB limit`);
2741
- }
2742
- async function saveFeishuResponseMedia(params) {
2743
- const { response, maxBytes, contentType, fileName } = params;
2744
- if (Buffer.isBuffer(response)) return saveMediaBuffer(response, contentType, "inbound", maxBytes, fileName);
2745
- if (response instanceof ArrayBuffer) return saveMediaBuffer(Buffer.from(response), contentType, "inbound", maxBytes, fileName);
2746
- const responseWithOptionalFields = response;
2747
- if (responseWithOptionalFields.code !== void 0 && responseWithOptionalFields.code !== 0) throw new Error(`${params.errorPrefix}: ${responseWithOptionalFields.msg || `code ${responseWithOptionalFields.code}`}`);
2748
- const data = responseWithOptionalFields.data;
2749
- if (Buffer.isBuffer(data) || data instanceof ArrayBuffer) return saveMediaBuffer(Buffer.isBuffer(data) ? data : Buffer.from(data), contentType, "inbound", maxBytes, fileName);
2750
- const save = (stream) => saveMediaStreamWithIdleTimeout(stream, contentType, maxBytes, fileName, FEISHU_MEDIA_HTTP_TIMEOUT_MS);
2751
- if (typeof response.getReadableStream === "function") return save(response.getReadableStream());
2752
- if (typeof response.writeFile === "function") return await withTempDownloadPath({ prefix: params.tmpDirPrefix }, async (tmpPath) => {
2753
- await response.writeFile(tmpPath);
2754
- if ((await fs.promises.stat(tmpPath)).size > maxBytes) throw mediaLimitError(maxBytes);
2755
- return await save(fs.createReadStream(tmpPath));
2756
- });
2757
- if (responseWithOptionalFields[Symbol.asyncIterator]) return save(responseWithOptionalFields);
2758
- if (response instanceof Readable) return save(response);
2759
- const keys = Object.keys(response);
2760
- throw new Error(`${params.errorPrefix}: unexpected response format. Keys: [${keys.join(", ")}]`);
2761
- }
2762
2665
  async function saveMessageResourceWithType(params) {
2763
2666
  const response = await params.client.im.messageResource.get({
2764
2667
  path: {
@@ -2767,29 +2670,25 @@ async function saveMessageResourceWithType(params) {
2767
2670
  },
2768
2671
  params: { type: params.type }
2769
2672
  });
2770
- const meta = extractFeishuDownloadMetadata(response);
2673
+ const headers = asHeaderMap(response.headers);
2674
+ const contentType = readHeaderValue(headers, "content-type");
2675
+ const disposition = readHeaderValue(headers, "content-disposition");
2676
+ const fileName = disposition ? decodeDispositionFileName(disposition) : void 0;
2771
2677
  return {
2772
- saved: await saveFeishuResponseMedia({
2773
- response,
2774
- tmpDirPrefix: "openclaw-feishu-resource-",
2775
- errorPrefix: "Feishu message resource download failed",
2776
- maxBytes: params.maxBytes,
2777
- contentType: meta.contentType,
2778
- fileName: meta.fileName ?? (params.originalFilename ? recoverUtf8FileNameFromLatin1Header(params.originalFilename) : void 0)
2779
- }),
2780
- ...meta
2678
+ saved: await saveMediaStreamWithIdleTimeout(response.getReadableStream(), contentType, params.maxBytes, fileName ?? (params.originalFilename ? recoverUtf8FileNameFromLatin1Header(params.originalFilename) : void 0), FEISHU_MEDIA_HTTP_TIMEOUT_MS),
2679
+ contentType,
2680
+ fileName
2781
2681
  };
2782
2682
  }
2783
2683
  async function saveMessageResourceFeishu(params) {
2784
2684
  const { cfg, messageId, fileKey, type, accountId, maxBytes, originalFilename } = params;
2785
2685
  const normalizedFileKey = normalizeFeishuExternalKey(fileKey);
2786
2686
  if (!normalizedFileKey) throw new Error("Feishu message resource download failed: invalid file_key");
2787
- const { client } = createConfiguredFeishuMediaClient({
2788
- cfg,
2789
- accountId
2790
- });
2791
2687
  const request = {
2792
- client,
2688
+ client: createConfiguredFeishuMediaClient({
2689
+ cfg,
2690
+ accountId
2691
+ }),
2793
2692
  messageId,
2794
2693
  fileKey: normalizedFileKey,
2795
2694
  type,
@@ -2810,20 +2709,6 @@ async function saveMessageResourceFeishu(params) {
2810
2709
  }
2811
2710
  }
2812
2711
  }
2813
- async function uploadImageFeishu(params) {
2814
- const { cfg, image, accountId } = params;
2815
- const { client } = createConfiguredFeishuMediaClient({
2816
- cfg,
2817
- accountId
2818
- });
2819
- return extractFeishuUploadKey(await requestFeishuApi(() => client.im.image.create({ data: {
2820
- image_type: "message",
2821
- image
2822
- } }), "Feishu image upload failed", { includeNestedErrorLogId: true }), {
2823
- key: "image_key",
2824
- errorPrefix: "Feishu image upload failed"
2825
- });
2826
- }
2827
2712
  /**
2828
2713
  * Sanitize a filename for safe use in Feishu multipart/form-data uploads.
2829
2714
  * Strips control characters and multipart-injection vectors (CWE-93) while
@@ -2837,39 +2722,13 @@ async function uploadImageFeishu(params) {
2837
2722
  function sanitizeFileNameForUpload(fileName) {
2838
2723
  return fileName.replace(/[\p{Cc}"\\]/gu, "_");
2839
2724
  }
2840
- async function uploadFileFeishu(params) {
2841
- const { cfg, file, fileName, fileType, duration, accountId } = params;
2842
- const { client } = createConfiguredFeishuMediaClient({
2843
- cfg,
2844
- accountId
2845
- });
2846
- const safeFileName = sanitizeFileNameForUpload(fileName);
2847
- return extractFeishuUploadKey(await requestFeishuApi(() => client.im.file.create({ data: {
2848
- file_type: fileType,
2849
- file_name: safeFileName,
2850
- file,
2851
- ...duration !== void 0 ? { duration } : {}
2852
- } }), "Feishu file upload failed", { includeNestedErrorLogId: true }), {
2853
- key: "file_key",
2854
- errorPrefix: "Feishu file upload failed"
2855
- });
2856
- }
2857
2725
  async function sendUploadedMediaFeishu(params, media, msgType) {
2858
- const { client, receiveId, receiveIdType } = resolveFeishuSendTarget(params);
2859
- const content = JSON.stringify(media);
2726
+ const target = resolveFeishuSendTarget(params);
2860
2727
  const label = msgType === "image" ? "image" : "file";
2861
- return sendReplyOrFallbackDirect(client, {
2862
- replyToMessageId: params.replyToMessageId,
2863
- replyInThread: params.replyInThread,
2864
- allowTopLevelReplyFallback: params.allowTopLevelReplyFallback,
2865
- content,
2728
+ return sendReplyOrFallbackDirect(target, {
2729
+ ...params,
2730
+ content: JSON.stringify(media),
2866
2731
  msgType,
2867
- directParams: {
2868
- receiveId,
2869
- receiveIdType,
2870
- content,
2871
- msgType
2872
- },
2873
2732
  directErrorPrefix: `Feishu ${label} send failed`,
2874
2733
  replyErrorPrefix: `Feishu ${label} reply failed`
2875
2734
  });
@@ -2879,11 +2738,6 @@ function sendStickerFeishu(params) {
2879
2738
  }
2880
2739
  function detectFileType(fileName) {
2881
2740
  switch (normalizeLowercaseStringOrEmpty(path.extname(fileName))) {
2882
- case ".opus":
2883
- case ".ogg": return "opus";
2884
- case ".mp4":
2885
- case ".mov":
2886
- case ".avi": return "mp4";
2887
2741
  case ".pdf": return "pdf";
2888
2742
  case ".doc":
2889
2743
  case ".docx": return "doc";
@@ -3098,28 +2952,33 @@ async function sendMediaFeishu(params) {
3098
2952
  mediaMaxBytes,
3099
2953
  msgType: routing.msgType
3100
2954
  }));
3101
- if (routing.msgType === "image") return {
3102
- ...await sendUploadedMediaFeishu(params, { image_key: await runBeforeFeishuMessageDispatch(() => uploadImageFeishu({
3103
- cfg,
3104
- image: buffer,
3105
- accountId
3106
- })) }, "image"),
3107
- ...voiceIntentDegradedToFile ? { voiceIntentDegradedToFile: true } : {}
3108
- };
3109
2955
  const durationMs = routing.msgType === "audio" || routing.msgType === "media" ? await probeMediaDurationMs({
3110
2956
  buffer,
3111
2957
  fileName: name,
3112
2958
  contentType
3113
2959
  }) : void 0;
3114
2960
  return {
3115
- ...await sendUploadedMediaFeishu(params, { file_key: await runBeforeFeishuMessageDispatch(() => uploadFileFeishu({
3116
- cfg,
3117
- file: buffer,
3118
- fileName: name,
3119
- fileType: routing.fileType ?? "stream",
3120
- ...durationMs !== void 0 ? { duration: durationMs } : {},
3121
- accountId
3122
- })) }, routing.msgType),
2961
+ ...await sendUploadedMediaFeishu(params, await runBeforeFeishuMessageDispatch(async () => {
2962
+ const client = createConfiguredFeishuMediaClient({
2963
+ cfg,
2964
+ accountId
2965
+ });
2966
+ const isImage = routing.msgType === "image";
2967
+ const errorPrefix = `Feishu ${isImage ? "image" : "file"} upload failed`;
2968
+ const key = extractFeishuUploadKey(await requestFeishuApi(() => isImage ? client.im.image.create({ data: {
2969
+ image_type: "message",
2970
+ image: buffer
2971
+ } }) : client.im.file.create({ data: {
2972
+ file_type: routing.fileType ?? "stream",
2973
+ file_name: sanitizeFileNameForUpload(name),
2974
+ file: buffer,
2975
+ ...durationMs !== void 0 ? { duration: durationMs } : {}
2976
+ } }), errorPrefix, { includeNestedErrorLogId: true }), {
2977
+ key: isImage ? "image_key" : "file_key",
2978
+ errorPrefix
2979
+ });
2980
+ return isImage ? { image_key: key } : { file_key: key };
2981
+ }), routing.msgType),
3123
2982
  ...voiceIntentDegradedToFile ? { voiceIntentDegradedToFile: true } : {}
3124
2983
  };
3125
2984
  }
@@ -3236,11 +3095,6 @@ function renderFeishuPresentationFallbackText(params, textFormat = "plain") {
3236
3095
  }
3237
3096
  });
3238
3097
  }
3239
- function mapFeishuButtonType(style) {
3240
- if (style === "primary" || style === "success") return "primary";
3241
- if (style === "danger") return "danger";
3242
- return "default";
3243
- }
3244
3098
  function buildFeishuPayloadButton(button) {
3245
3099
  const url = resolveSafeFeishuButtonUrl(resolveFeishuButtonUrl(button));
3246
3100
  const value = resolveFeishuCommandButtonValue(button);
@@ -3267,7 +3121,7 @@ function buildFeishuPayloadButton(button) {
3267
3121
  tag: "plain_text",
3268
3122
  content: button.label
3269
3123
  },
3270
- type: mapFeishuButtonType(button.style),
3124
+ type: resolveFeishuButtonType(button.style),
3271
3125
  behaviors
3272
3126
  };
3273
3127
  }
@@ -3487,4 +3341,4 @@ function createFeishuPartialReplyDeliveryError(cause, result) {
3487
3341
  });
3488
3342
  }
3489
3343
  //#endregion
3490
- export { cleanupAmbientCommentTypingReaction as $, sendMessageFeishu as A, resolveFeishuGroupToolPolicy as At, parsePostContent as B, sendStickerFeishu as C, resolveFeishuChatReadPreliminaryAuthorization as Ct, getMessageFeishu as D, resolveFeishuGroupConfig as Dt, editMessageFeishu as E, resolveFeishuDmIngressAccess as Et, isFeishuBroadcastMention as F, buildFeishuCardActionTextFallback as Ft, deliverCommentThreadText as G, buildFeishuMediaFallbackText as H, isMentionForwardRequest as I, createFeishuCardInteractionEnvelope as It, feishuExternalToolResult as J, registerFeishuDriveTools as K, isFeishuGroupChatType as L, decodeFeishuCardAction as Lt, toFeishuMessageSendResult as M, normalizeFeishuChatType as Mt, formatFeishuMediaContent as N, resolveFeishuChatType as Nt, listFeishuThreadMessages as O, resolveFeishuGroupConversationIngressAccess as Ot, extractMentionTargets as P, FEISHU_CARD_INTERACTION_VERSION as Pt, assertFeishuApiSuccess as Q, normalizeFeishuEventChatType as R, sendMediaFeishu as S, readFeishuChatInfoWithAuthorization as St, chunkFeishuCardMarkdown as T, normalizeFeishuAllowEntry as Tt, resolveFeishuIdentityEmoji as U, createConfiguredFeishuClient as V, resolveFeishuIdentityHeaderTitle as W, createFeishuToolClient as X, unknownToolActionResult as Y, resolveFeishuToolAccount as Z, renderFeishuPresentationPayload as _, authorizeFeishuChatMemberRead as _t, shouldSendNoVisibleReplyFallback as a, requestFeishuApi as at, withinCardTableLimit as b, isFeishuGroupReadAllowed as bt, buildFeishuPayloadCard as c, parseFeishuCommentTarget as ct, consumeFeishuPresentationFallbackMarker as d, chunkFeishuMarkdown as dt, createCommentTypingReactionLifecycle as et, feishuCardWithinTableLimit as f, chunkFeishuPostMarkdown as ft, renderFeishuPresentationFallbackText as g, assertFeishuChatReadAllowed as gt, readNativeFeishuCard as h, shouldUseFeishuCard as ht, noVisibleFeishuReplyDelivery as i, parseCommentContentElements as it, sendStructuredCardFeishu as j, resolveFeishuReplyPolicy as jt, sendCardFeishu as k, resolveFeishuGroupSenderActivationIngressAccess as kt, buildFeishuPresentationCard as l, readNativeFeishuCardJson as lt, markRenderedFeishuCard as m, parseFeishuMarkdown as mt, createFeishuReplyDeliveryResult as n, extractReplyText as nt, FEISHU_PRESENTATION_CAPABILITIES as o, buildFeishuCommentTarget as ot, isFeishuCardWithinEnvelope as p, materializeFeishuPostMarkdownSoftBreaks as pt, registerFeishuTool as q, mergeFeishuReplyDeliveryResults as r, formatFeishuApiError as rt, assertFeishuCardWithinEnvelope as s, normalizeCommentFileType as st, createFeishuPartialReplyDeliveryError as t, encodeQuery as tt, buildFeishuPresentationFallback as u, resolveFeishuCardTemplate as ut, renderFeishuReplyPayload as v, canEnumerateAllFeishuGroups as vt, shouldSuppressFeishuTextForVoiceMedia as w, hasExplicitFeishuGroupConfig as wt, saveMessageResourceFeishu as x, isFeishuGroupReadEnabled as xt, resolveFeishuRichReply as y, canEnumerateAllFeishuPeers as yt, parseInteractiveCardContent as z };
3344
+ export { cleanupAmbientCommentTypingReaction as $, sendMessageFeishu as A, resolveFeishuGroupSenderActivationIngressAccess as At, parsePostContent as B, sendStickerFeishu as C, readFeishuChatInfoWithAuthorization as Ct, getMessageFeishu as D, resolveFeishuDmIngressAccess as Dt, editMessageFeishu as E, normalizeFeishuAllowEntry as Et, isFeishuBroadcastMention as F, FEISHU_CARD_INTERACTION_VERSION as Ft, deliverCommentThreadText as G, buildFeishuMediaFallbackText as H, isMentionForwardRequest as I, createFeishuCardInteractionEnvelope as It, feishuExternalToolResult as J, registerFeishuDriveTools as K, isFeishuGroupChatType as L, decodeFeishuCardAction as Lt, toFeishuMessageSendResult as M, resolveFeishuReplyPolicy as Mt, formatFeishuMediaContent as N, normalizeFeishuChatType as Nt, listFeishuThreadMessages as O, resolveFeishuGroupConfig as Ot, extractMentionTargets as P, resolveFeishuChatType as Pt, assertFeishuApiSuccess as Q, normalizeFeishuEventChatType as R, sendMediaFeishu as S, isFeishuGroupReadEnabled as St, chunkFeishuCardMarkdown as T, hasExplicitFeishuGroupConfig as Tt, resolveFeishuIdentityEmoji as U, createConfiguredFeishuClient as V, resolveFeishuIdentityHeaderTitle as W, createFeishuToolClient as X, unknownToolActionResult as Y, resolveFeishuToolAccount as Z, renderFeishuPresentationPayload as _, assertFeishuChatReadAllowed as _t, shouldSendNoVisibleReplyFallback as a, requestFeishuApi as at, withinCardTableLimit as b, canEnumerateAllFeishuPeers as bt, buildFeishuPayloadCard as c, parseFeishuCommentTarget as ct, consumeFeishuPresentationFallbackMarker as d, chunkFeishuMarkdown as dt, createCommentTypingReactionLifecycle as et, feishuCardWithinTableLimit as f, chunkFeishuPostMarkdown as ft, renderFeishuPresentationFallbackText as g, visitFeishuMarkdown as gt, readNativeFeishuCard as h, shouldUseFeishuCard as ht, noVisibleFeishuReplyDelivery as i, parseCommentContentElements as it, sendStructuredCardFeishu as j, resolveFeishuGroupToolPolicy as jt, sendCardFeishu as k, resolveFeishuGroupConversationIngressAccess as kt, buildFeishuPresentationCard as l, readNativeFeishuCardJson as lt, markRenderedFeishuCard as m, parseFeishuMarkdown as mt, createFeishuReplyDeliveryResult as n, extractReplyText as nt, FEISHU_PRESENTATION_CAPABILITIES as o, buildFeishuCommentTarget as ot, isFeishuCardWithinEnvelope as p, materializeFeishuPostMarkdownSoftBreaks as pt, registerFeishuTool as q, mergeFeishuReplyDeliveryResults as r, formatFeishuApiError as rt, assertFeishuCardWithinEnvelope as s, normalizeCommentFileType as st, createFeishuPartialReplyDeliveryError as t, encodeQuery as tt, buildFeishuPresentationFallback as u, resolveFeishuCardTemplate as ut, renderFeishuReplyPayload as v, authorizeFeishuChatMemberRead as vt, shouldSuppressFeishuTextForVoiceMedia as w, resolveFeishuChatReadPreliminaryAuthorization as wt, saveMessageResourceFeishu as x, isFeishuGroupReadAllowed as xt, resolveFeishuRichReply as y, canEnumerateAllFeishuGroups as yt, parseInteractiveCardContent as z };