@openclaw/feishu 2026.7.2-beta.3 → 2026.7.2-beta.5

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 (159) hide show
  1. package/README.md +1 -1
  2. package/dist/{accounts-BDoGHJDk.js → accounts-CKhCa76b.js} +2 -19
  3. package/dist/api.js +65 -43
  4. package/dist/{app-registration-BzkyrVZu.js → app-registration-cN1bVV6s.js} +5 -5
  5. package/dist/{channel-BdnXYU6g.js → channel-CBNICmK9.js} +37 -75
  6. package/dist/channel-plugin-api.js +1 -1
  7. package/dist/{channel.runtime-CVIzo2dV.js → channel.runtime-CSlJVqy4.js} +7 -7
  8. package/dist/{client-87BmeMpj.js → client-Dee7cKsS.js} +62 -1
  9. package/dist/contract-api.js +2 -2
  10. package/dist/doctor-contract-BiD9tyIv.js +102 -0
  11. package/dist/doctor-contract-api.js +1 -1
  12. package/dist/{drive-BHv8WW9i.js → drive-DG6pKTPE.js} +23 -20
  13. package/dist/{send-DcrXbqqA.js → media-DOwcLJ1j.js} +1050 -1021
  14. package/dist/{monitor-BVQf7-Bl.js → monitor-DEHJlyWW.js} +6 -5
  15. package/dist/{monitor.account-Blbf2T6J.js → monitor.account-DEHl8Non.js} +1556 -592
  16. package/dist/monitor.startup-CSUPT_U1.js +143 -0
  17. package/dist/{probe-BgboTHIn.js → probe-Za1kgUvx.js} +70 -10
  18. package/dist/runtime-api.js +1 -2
  19. package/dist/{security-audit-BIeA3W3Q.js → security-audit-D7WK_BHh.js} +1 -1
  20. package/dist/{security-audit-shared-BIHeF-S_.js → security-audit-shared-BgpY7AiJ.js} +6 -11
  21. package/dist/security-contract-api.js +1 -1
  22. package/dist/{send-result-DfE5Fhz6.js → send-result-Bcofg0Vv.js} +1 -1
  23. package/dist/session-binding-contract-api.js +1 -1
  24. package/dist/setup-api.js +1 -1
  25. package/dist/{subagent-hooks-BKTOxB-T.js → subagent-hooks-DL2SC5zX.js} +1 -1
  26. package/dist/subagent-hooks-api.js +1 -1
  27. package/dist/{thread-bindings-V0bwk0A1.js → thread-bindings-Dqs_A0du.js} +2 -1
  28. package/node_modules/@larksuiteoapi/node-sdk/README.md +13 -0
  29. package/node_modules/@larksuiteoapi/node-sdk/README.zh.md +12 -0
  30. package/node_modules/@larksuiteoapi/node-sdk/es/index.js +8950 -3084
  31. package/node_modules/@larksuiteoapi/node-sdk/lib/index.js +8951 -3083
  32. package/node_modules/@larksuiteoapi/node-sdk/package.json +1 -1
  33. package/node_modules/@larksuiteoapi/node-sdk/types/index.d.ts +12522 -698
  34. package/node_modules/@protobufjs/utf8/CHANGELOG.md +8 -0
  35. package/node_modules/@protobufjs/utf8/index.js +29 -18
  36. package/node_modules/@protobufjs/utf8/package.json +2 -2
  37. package/node_modules/@protobufjs/utf8/tests/index.js +5 -0
  38. package/node_modules/@types/node/README.md +1 -1
  39. package/node_modules/@types/node/fs/promises.d.ts +16 -6
  40. package/node_modules/@types/node/package.json +2 -2
  41. package/node_modules/agent-base/README.md +145 -0
  42. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  43. package/node_modules/agent-base/dist/src/index.js +203 -0
  44. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  45. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  46. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  47. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  48. package/node_modules/agent-base/package.json +64 -0
  49. package/node_modules/agent-base/src/index.ts +345 -0
  50. package/node_modules/agent-base/src/promisify.ts +33 -0
  51. package/node_modules/axios/CHANGELOG.md +197 -1
  52. package/node_modules/axios/README.md +424 -256
  53. package/node_modules/axios/dist/axios.js +589 -204
  54. package/node_modules/axios/dist/axios.min.js +3 -3
  55. package/node_modules/axios/dist/axios.min.js.map +1 -1
  56. package/node_modules/axios/dist/browser/axios.cjs +630 -185
  57. package/node_modules/axios/dist/esm/axios.js +630 -185
  58. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  59. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  60. package/node_modules/axios/dist/node/axios.cjs +949 -301
  61. package/node_modules/axios/index.d.cts +28 -5
  62. package/node_modules/axios/index.d.ts +24 -3
  63. package/node_modules/axios/lib/adapters/adapters.js +1 -1
  64. package/node_modules/axios/lib/adapters/fetch.js +223 -49
  65. package/node_modules/axios/lib/adapters/http.js +408 -193
  66. package/node_modules/axios/lib/adapters/xhr.js +3 -1
  67. package/node_modules/axios/lib/core/Axios.js +4 -2
  68. package/node_modules/axios/lib/core/AxiosError.js +13 -1
  69. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  70. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  71. package/node_modules/axios/lib/core/mergeConfig.js +35 -0
  72. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  73. package/node_modules/axios/lib/env/data.js +1 -1
  74. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
  75. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  76. package/node_modules/axios/lib/helpers/buildURL.js +7 -4
  77. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  78. package/node_modules/axios/lib/helpers/cookies.js +5 -1
  79. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  80. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  81. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  82. package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
  83. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  84. package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
  85. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  86. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  87. package/node_modules/axios/lib/helpers/toFormData.js +48 -12
  88. package/node_modules/axios/lib/helpers/validator.js +1 -1
  89. package/node_modules/axios/lib/utils.js +105 -19
  90. package/node_modules/axios/package.json +31 -13
  91. package/node_modules/https-proxy-agent/README.md +137 -0
  92. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  93. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  94. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  95. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  96. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  97. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  98. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  99. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  100. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  101. package/node_modules/https-proxy-agent/package.json +56 -0
  102. package/node_modules/protobufjs/dist/light/protobuf.js +145 -188
  103. package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
  104. package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
  105. package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
  106. package/node_modules/protobufjs/dist/minimal/protobuf.js +33 -76
  107. package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
  108. package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
  109. package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
  110. package/node_modules/protobufjs/dist/protobuf.js +168 -208
  111. package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
  112. package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
  113. package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
  114. package/node_modules/protobufjs/index.d.ts +0 -8
  115. package/node_modules/protobufjs/package.json +2 -3
  116. package/node_modules/protobufjs/src/parse.js +3 -0
  117. package/node_modules/protobufjs/src/util/minimal.js +0 -3
  118. package/node_modules/qs/CHANGELOG.md +11 -0
  119. package/node_modules/qs/dist/qs.js +17 -17
  120. package/node_modules/qs/lib/parse.js +19 -8
  121. package/node_modules/qs/lib/utils.js +47 -8
  122. package/node_modules/qs/package.json +6 -5
  123. package/node_modules/qs/test/parse.js +230 -0
  124. package/node_modules/qs/test/utils.js +194 -0
  125. package/node_modules/typebox/build/compile/validator.d.mts +1 -4
  126. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  127. package/node_modules/typebox/build/guard/guard.mjs +5 -2
  128. package/node_modules/typebox/build/guard/string.mjs +16 -4
  129. package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
  130. package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
  131. package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
  132. package/node_modules/typebox/build/typebox.d.mts +1 -1
  133. package/node_modules/typebox/build/typebox.mjs +1 -1
  134. package/node_modules/typebox/package.json +1 -1
  135. package/node_modules/typebox/readme.md +29 -32
  136. package/node_modules/ws/lib/receiver.js +15 -32
  137. package/node_modules/ws/lib/websocket-server.js +4 -4
  138. package/node_modules/ws/lib/websocket.js +4 -4
  139. package/node_modules/ws/package.json +5 -1
  140. package/openclaw.plugin.json +2 -16
  141. package/package.json +20 -8
  142. package/dist/doctor-contract-DXH5hux1.js +0 -97
  143. package/dist/monitor.startup-Cy8NPGAX.js +0 -43
  144. package/node_modules/@protobufjs/inquire/CHANGELOG.md +0 -8
  145. package/node_modules/@protobufjs/inquire/LICENSE +0 -26
  146. package/node_modules/@protobufjs/inquire/README.md +0 -13
  147. package/node_modules/@protobufjs/inquire/index.d.ts +0 -10
  148. package/node_modules/@protobufjs/inquire/index.js +0 -38
  149. package/node_modules/@protobufjs/inquire/package.json +0 -21
  150. package/node_modules/@protobufjs/inquire/tests/data/array.js +0 -1
  151. package/node_modules/@protobufjs/inquire/tests/data/emptyArray.js +0 -1
  152. package/node_modules/@protobufjs/inquire/tests/data/emptyObject.js +0 -1
  153. package/node_modules/@protobufjs/inquire/tests/data/object.js +0 -1
  154. package/node_modules/@protobufjs/inquire/tests/index.js +0 -20
  155. package/node_modules/axios/dist/axios.js.map +0 -1
  156. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  157. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  158. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
  159. package/npm-shrinkwrap.json +0 -1354
package/README.md CHANGED
@@ -5,7 +5,7 @@ Official OpenClaw channel plugin for Feishu and Lark workplace chats. Community
5
5
  Install from OpenClaw:
6
6
 
7
7
  ```bash
8
- openclaw plugin add @openclaw/feishu
8
+ openclaw plugins install @openclaw/feishu
9
9
  ```
10
10
 
11
11
  Configure the Feishu/Lark app credentials in OpenClaw, then connect the plugin to the chats where agents should receive and send messages.
@@ -372,13 +372,6 @@ function resolveDefaultFeishuAccountSelection(cfg) {
372
372
  function resolveDefaultFeishuAccountId(cfg) {
373
373
  return resolveDefaultAccountId(cfg);
374
374
  }
375
- function resolveRawFeishuAccountConfig(accounts, accountId) {
376
- if (!accounts || typeof accounts !== "object") return;
377
- if (Object.hasOwn(accounts, accountId)) return accounts[accountId];
378
- const normalized = accountId.toLowerCase();
379
- const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalized);
380
- return matchKey ? accounts[matchKey] : void 0;
381
- }
382
375
  /**
383
376
  * Merge top-level config with account-specific config.
384
377
  * Account-specific fields override top-level fields.
@@ -386,7 +379,6 @@ function resolveRawFeishuAccountConfig(accounts, accountId) {
386
379
  function mergeFeishuAccountConfig(cfg, accountId) {
387
380
  const feishuCfg = cfg.channels?.feishu;
388
381
  const accounts = feishuCfg?.accounts;
389
- const accountTools = resolveRawFeishuAccountConfig(accounts, accountId)?.tools;
390
382
  const merged = resolveMergedAccountConfig({
391
383
  channelConfig: feishuCfg,
392
384
  accounts,
@@ -399,20 +391,11 @@ function mergeFeishuAccountConfig(cfg, accountId) {
399
391
  ...merged,
400
392
  tools: topTools
401
393
  };
402
- if (topTools?.bitable === false || topTools?.bitable === void 0 && topTools?.base === false) return {
403
- ...merged,
404
- tools: {
405
- ...merged.tools,
406
- bitable: false,
407
- base: false
408
- }
409
- };
410
- if (accountTools?.bitable === void 0 && accountTools?.base !== void 0) return {
394
+ if (topTools?.bitable === false) return {
411
395
  ...merged,
412
396
  tools: {
413
397
  ...merged.tools,
414
- bitable: accountTools.base,
415
- base: accountTools.base
398
+ bitable: false
416
399
  }
417
400
  };
418
401
  return merged;
package/dist/api.js CHANGED
@@ -1,12 +1,12 @@
1
- import { r as listEnabledFeishuAccounts } from "./accounts-BDoGHJDk.js";
2
- import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-BdnXYU6g.js";
3
- import { p as parseFeishuMarkdown, u as chunkFeishuMarkdown } from "./send-result-DfE5Fhz6.js";
1
+ import { r as listEnabledFeishuAccounts } from "./accounts-CKhCa76b.js";
2
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-CBNICmK9.js";
3
+ import { p as parseFeishuMarkdown, u as chunkFeishuMarkdown } from "./send-result-Bcofg0Vv.js";
4
4
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
5
- import { r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-87BmeMpj.js";
5
+ import { r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-Dee7cKsS.js";
6
6
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
7
- import { a as toolExecutionErrorResult, f as registerFeishuChatTools, g as resolveToolsConfig, h as resolveFeishuToolAccount, m as resolveAnyEnabledFeishuToolsConfig, n as registerFeishuDriveTools, o as unknownToolActionResult, p as createFeishuToolClient } from "./drive-BHv8WW9i.js";
8
- import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-V0bwk0A1.js";
9
- import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-BKTOxB-T.js";
7
+ import { a as toolExecutionErrorResult, f as registerFeishuChatTools, g as resolveToolsConfig, h as resolveFeishuToolAccount, m as resolveAnyEnabledFeishuToolsConfig, n as registerFeishuDriveTools, o as unknownToolActionResult, p as createFeishuToolClient } from "./drive-DG6pKTPE.js";
8
+ import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-Dqs_A0du.js";
9
+ import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-DL2SC5zX.js";
10
10
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
11
11
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
12
12
  import { existsSync } from "node:fs";
@@ -1085,6 +1085,27 @@ async function processImages(client, docToken, images, insertedBlocks, maxBytes,
1085
1085
  }
1086
1086
  return processed;
1087
1087
  }
1088
+ async function convertInsertAndProcessDocx(params) {
1089
+ const { client, docToken, logger, target } = params;
1090
+ logger?.info?.("feishu_doc: Converting markdown...");
1091
+ const { blocks, firstLevelBlockIds, images } = await chunkedConvertMarkdown(client, createDocxMarkdownPlan(params.markdown).chunks);
1092
+ await params.onConverted(blocks.length);
1093
+ if (blocks.length === 0) return {
1094
+ blocks,
1095
+ inserted: [],
1096
+ imagesProcessed: 0
1097
+ };
1098
+ const { orderedBlocks, rootIds } = normalizeConvertedBlockTree(blocks, firstLevelBlockIds);
1099
+ logger?.info?.(`feishu_doc: Converted to ${blocks.length} blocks, inserting${target ? ` at index ${target.index}` : ""}...`);
1100
+ const { children: inserted } = blocks.length > 1e3 ? await insertBlocksInBatches(client, docToken, orderedBlocks, rootIds, logger, target?.parentBlockId, target?.index) : await insertBlocksWithDescendant(client, docToken, orderedBlocks, rootIds, target);
1101
+ const imagesProcessed = await processImages(client, docToken, images, inserted, params.maxBytes, params.imageReadTimeoutMs);
1102
+ logger?.info?.(`feishu_doc: Done (${blocks.length} blocks, ${imagesProcessed} images)`);
1103
+ return {
1104
+ blocks,
1105
+ inserted,
1106
+ imagesProcessed
1107
+ };
1108
+ }
1088
1109
  async function uploadImageBlock(client, docToken, maxBytes, imageReadTimeoutMs, localRoots, url, filePath, parentBlockId, filename, index, imageInput) {
1089
1110
  const upload = await resolveDocxUploadInput({
1090
1111
  url,
@@ -1263,21 +1284,18 @@ async function createDoc(client, title, folderToken, options) {
1263
1284
  };
1264
1285
  }
1265
1286
  async function writeDoc(client, docToken, markdown, maxBytes, imageReadTimeoutMs, logger) {
1266
- const markdownPlan = createDocxMarkdownPlan(markdown);
1267
- logger?.info?.("feishu_doc: Converting markdown...");
1268
- const { blocks, firstLevelBlockIds, images } = await chunkedConvertMarkdown(client, markdownPlan.chunks);
1269
- const deleted = await clearDocumentContent(client, docToken);
1270
- if (blocks.length === 0) return {
1271
- success: true,
1272
- blocks_deleted: deleted,
1273
- blocks_added: 0,
1274
- images_processed: 0
1275
- };
1276
- logger?.info?.(`feishu_doc: Converted to ${blocks.length} blocks, inserting...`);
1277
- const { orderedBlocks, rootIds } = normalizeConvertedBlockTree(blocks, firstLevelBlockIds);
1278
- const { children: inserted } = blocks.length > 1e3 ? await insertBlocksInBatches(client, docToken, orderedBlocks, rootIds, logger) : await insertBlocksWithDescendant(client, docToken, orderedBlocks, rootIds);
1279
- const imagesProcessed = await processImages(client, docToken, images, inserted, maxBytes, imageReadTimeoutMs);
1280
- logger?.info?.(`feishu_doc: Done (${blocks.length} blocks, ${imagesProcessed} images)`);
1287
+ let deleted = 0;
1288
+ const { blocks, imagesProcessed } = await convertInsertAndProcessDocx({
1289
+ client,
1290
+ docToken,
1291
+ markdown,
1292
+ maxBytes,
1293
+ imageReadTimeoutMs,
1294
+ logger,
1295
+ onConverted: async () => {
1296
+ deleted = await clearDocumentContent(client, docToken);
1297
+ }
1298
+ });
1281
1299
  return {
1282
1300
  success: true,
1283
1301
  blocks_deleted: deleted,
@@ -1286,15 +1304,17 @@ async function writeDoc(client, docToken, markdown, maxBytes, imageReadTimeoutMs
1286
1304
  };
1287
1305
  }
1288
1306
  async function appendDoc(client, docToken, markdown, maxBytes, imageReadTimeoutMs, logger) {
1289
- const markdownPlan = createDocxMarkdownPlan(markdown);
1290
- logger?.info?.("feishu_doc: Converting markdown...");
1291
- const { blocks, firstLevelBlockIds, images } = await chunkedConvertMarkdown(client, markdownPlan.chunks);
1292
- if (blocks.length === 0) throw new Error("Content is empty");
1293
- logger?.info?.(`feishu_doc: Converted to ${blocks.length} blocks, inserting...`);
1294
- const { orderedBlocks, rootIds } = normalizeConvertedBlockTree(blocks, firstLevelBlockIds);
1295
- const { children: inserted } = blocks.length > 1e3 ? await insertBlocksInBatches(client, docToken, orderedBlocks, rootIds, logger) : await insertBlocksWithDescendant(client, docToken, orderedBlocks, rootIds);
1296
- const imagesProcessed = await processImages(client, docToken, images, inserted, maxBytes, imageReadTimeoutMs);
1297
- logger?.info?.(`feishu_doc: Done (${blocks.length} blocks, ${imagesProcessed} images)`);
1307
+ const { blocks, inserted, imagesProcessed } = await convertInsertAndProcessDocx({
1308
+ client,
1309
+ docToken,
1310
+ markdown,
1311
+ maxBytes,
1312
+ imageReadTimeoutMs,
1313
+ logger,
1314
+ onConverted: (blockCount) => {
1315
+ if (blockCount === 0) throw new Error("Content is empty");
1316
+ }
1317
+ });
1298
1318
  return {
1299
1319
  success: true,
1300
1320
  blocks_added: blocks.length,
@@ -1303,7 +1323,6 @@ async function appendDoc(client, docToken, markdown, maxBytes, imageReadTimeoutM
1303
1323
  };
1304
1324
  }
1305
1325
  async function insertDoc(client, docToken, markdown, afterBlockId, maxBytes, imageReadTimeoutMs, logger) {
1306
- const markdownPlan = createDocxMarkdownPlan(markdown);
1307
1326
  const blockInfo = await client.docx.documentBlock.get({ path: {
1308
1327
  document_id: docToken,
1309
1328
  block_id: afterBlockId
@@ -1326,18 +1345,21 @@ async function insertDoc(client, docToken, markdown, afterBlockId, maxBytes, ima
1326
1345
  } while (pageToken);
1327
1346
  const blockIndex = items.findIndex((item) => item.block_id === afterBlockId);
1328
1347
  if (blockIndex === -1) throw new Error(`after_block_id "${afterBlockId}" was not found among the children of parent block "${parentId}". Use list_blocks to verify the block ID.`);
1329
- const insertIndex = blockIndex + 1;
1330
- logger?.info?.("feishu_doc: Converting markdown...");
1331
- const { blocks, firstLevelBlockIds, images } = await chunkedConvertMarkdown(client, markdownPlan.chunks);
1332
- if (blocks.length === 0) throw new Error("Content is empty");
1333
- const { orderedBlocks, rootIds } = normalizeConvertedBlockTree(blocks, firstLevelBlockIds);
1334
- logger?.info?.(`feishu_doc: Converted to ${blocks.length} blocks, inserting at index ${insertIndex}...`);
1335
- const { children: inserted } = blocks.length > 1e3 ? await insertBlocksInBatches(client, docToken, orderedBlocks, rootIds, logger, parentId, insertIndex) : await insertBlocksWithDescendant(client, docToken, orderedBlocks, rootIds, {
1336
- parentBlockId: parentId,
1337
- index: insertIndex
1348
+ const { blocks, inserted, imagesProcessed } = await convertInsertAndProcessDocx({
1349
+ client,
1350
+ docToken,
1351
+ markdown,
1352
+ maxBytes,
1353
+ imageReadTimeoutMs,
1354
+ logger,
1355
+ target: {
1356
+ parentBlockId: parentId,
1357
+ index: blockIndex + 1
1358
+ },
1359
+ onConverted: (blockCount) => {
1360
+ if (blockCount === 0) throw new Error("Content is empty");
1361
+ }
1338
1362
  });
1339
- const imagesProcessed = await processImages(client, docToken, images, inserted, maxBytes, imageReadTimeoutMs);
1340
- logger?.info?.(`feishu_doc: Done (${blocks.length} blocks, ${imagesProcessed} images)`);
1341
1363
  return {
1342
1364
  success: true,
1343
1365
  blocks_added: blocks.length,
@@ -1,7 +1,7 @@
1
1
  import { t as readFeishuJsonResponse } from "./json-response-CheljwGr.js";
2
2
  import { finiteSecondsToTimerSafeMilliseconds } from "openclaw/plugin-sdk/number-runtime";
3
3
  import { renderQrTerminal } from "openclaw/plugin-sdk/media-runtime";
4
- import { sleep } from "openclaw/plugin-sdk/runtime-env";
4
+ import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
5
5
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
6
6
  //#region extensions/feishu/src/app-registration.ts
7
7
  /**
@@ -108,7 +108,7 @@ async function pollAppRegistration(params) {
108
108
  lookupFn
109
109
  });
110
110
  } catch {
111
- await sleepRegistrationPollInterval(currentInterval);
111
+ await sleepRegistrationPollInterval(currentInterval, abortSignal);
112
112
  continue;
113
113
  }
114
114
  if (pollRes.user_info?.tenant_brand) {
@@ -135,7 +135,7 @@ async function pollAppRegistration(params) {
135
135
  status: "error",
136
136
  message: `${pollRes.error}: ${pollRes.error_description ?? "unknown"}`
137
137
  };
138
- await sleepRegistrationPollInterval(currentInterval);
138
+ await sleepRegistrationPollInterval(currentInterval, abortSignal);
139
139
  }
140
140
  return { status: "timeout" };
141
141
  }
@@ -194,8 +194,8 @@ async function getAppOwnerOpenId(params) {
194
194
  return;
195
195
  }
196
196
  }
197
- function sleepRegistrationPollInterval(intervalSeconds) {
198
- return sleep(finiteSecondsToTimerSafeMilliseconds(intervalSeconds) ?? DEFAULT_REGISTRATION_POLL_INTERVAL_SECONDS * 1e3);
197
+ async function sleepRegistrationPollInterval(intervalSeconds, abortSignal) {
198
+ await sleepWithAbort(finiteSecondsToTimerSafeMilliseconds(intervalSeconds) ?? DEFAULT_REGISTRATION_POLL_INTERVAL_SECONDS * 1e3, abortSignal).catch(() => {});
199
199
  }
200
200
  //#endregion
201
201
  export { beginAppRegistration, getAppOwnerOpenId, initAppRegistration, pollAppRegistration, printQrCode };
@@ -1,11 +1,11 @@
1
- import { a as resolveDefaultFeishuAccountId, d as isRecord$1, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-BDoGHJDk.js";
1
+ import { a as resolveDefaultFeishuAccountId, d as isRecord$1, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CKhCa76b.js";
2
2
  import { i as resolveReceiveIdType, n as looksLikeFeishuId, r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
3
- import { A as resolveFeishuChatType, D as resolveFeishuGroupToolPolicy, N as createFeishuCardInteractionEnvelope, _ as canEnumerateAllFeishuPeers, a as readNativeFeishuCardJson, b as resolveFeishuChatReadPreliminaryAuthorization, g as canEnumerateAllFeishuGroups, h as authorizeFeishuChatMemberRead, k as normalizeFeishuChatType, m as assertFeishuChatReadAllowed, n as createFeishuSendReceipt, u as chunkFeishuMarkdown, v as isFeishuGroupReadAllowed, w as resolveFeishuGroupConfig, y as isFeishuGroupReadEnabled } from "./send-result-DfE5Fhz6.js";
3
+ import { A as resolveFeishuChatType, D as resolveFeishuGroupToolPolicy, N as createFeishuCardInteractionEnvelope, _ as canEnumerateAllFeishuPeers, a as readNativeFeishuCardJson, b as resolveFeishuChatReadPreliminaryAuthorization, g as canEnumerateAllFeishuGroups, h as authorizeFeishuChatMemberRead, k as normalizeFeishuChatType, m as assertFeishuChatReadAllowed, n as createFeishuSendReceipt, u as chunkFeishuMarkdown, v as isFeishuGroupReadAllowed, w as resolveFeishuGroupConfig, y as isFeishuGroupReadEnabled } from "./send-result-Bcofg0Vv.js";
4
4
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, o as resolveConfiguredFeishuGroupSessionScope, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
5
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DXH5hux1.js";
6
- import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
5
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BiD9tyIv.js";
6
+ import { t as messageActionTargetAliases } from "./security-audit-D7WK_BHh.js";
7
7
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-BCpDLdg9.js";
8
- import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
8
+ import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BgpY7AiJ.js";
9
9
  import { t as resolveFeishuSessionConversation } from "./session-conversation-BksWrfzm.js";
10
10
  import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
11
11
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
@@ -36,7 +36,9 @@ import path from "node:path";
36
36
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
37
37
  import { deleteSessionEntry, isValidAgentHarnessSessionStoreEntry, listSessionEntries, loadTranscriptEventsSync, parseSqliteSessionFileMarker, resolveSessionStoreBackupPaths, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
38
38
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
39
+ import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
39
40
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, createSetupTranslator, formatDocsLink, hasConfiguredSecretInput as hasConfiguredSecretInput$1, mergeAllowFromEntries, patchTopLevelChannelConfigSection, promptSingleChannelSecretInput, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
41
+ import { createChannelDmPolicy } from "openclaw/plugin-sdk/channel-dm-policy";
40
42
  //#region extensions/feishu/src/approval-auth.ts
41
43
  function normalizeFeishuApproverId(value) {
42
44
  const trimmed = normalizeOptionalLowercaseString(normalizeFeishuTarget(String(value)));
@@ -144,8 +146,7 @@ const FeishuToolsConfigSchema = z.object({
144
146
  drive: z.boolean().optional(),
145
147
  perm: z.boolean().optional(),
146
148
  scopes: z.boolean().optional(),
147
- bitable: z.boolean().optional(),
148
- base: z.boolean().optional()
149
+ bitable: z.boolean().optional()
149
150
  }).strict().optional();
150
151
  /**
151
152
  * Group session scope for routing Feishu group messages.
@@ -212,7 +213,7 @@ const FeishuSharedConfigShape = {
212
213
  textChunkLimit: z.number().int().positive().optional(),
213
214
  mediaMaxMb: z.number().positive().optional(),
214
215
  httpTimeoutMs: z.number().int().positive().max(3e5).optional(),
215
- heartbeat: ChannelHeartbeatVisibilitySchema,
216
+ heartbeatVisibility: ChannelHeartbeatVisibilitySchema,
216
217
  renderMode: RenderModeSchema,
217
218
  streaming: FeishuStreamingSchema,
218
219
  tools: FeishuToolsConfigSchema,
@@ -1197,7 +1198,7 @@ function resolveFeishuOutboundSessionRoute(params) {
1197
1198
  }
1198
1199
  //#endregion
1199
1200
  //#region extensions/feishu/src/setup-core.ts
1200
- function setFeishuNamedAccountEnabled$1(cfg, accountId, enabled) {
1201
+ function setFeishuNamedAccountEnabled(cfg, accountId, enabled) {
1201
1202
  const feishuCfg = cfg.channels?.feishu;
1202
1203
  return {
1203
1204
  ...cfg,
@@ -1229,9 +1230,13 @@ const feishuSetupAdapter = {
1229
1230
  }
1230
1231
  }
1231
1232
  };
1232
- return setFeishuNamedAccountEnabled$1(cfg, accountId, true);
1233
+ return setFeishuNamedAccountEnabled(cfg, accountId, true);
1233
1234
  }
1234
1235
  };
1236
+ const feishuSetupContract = defineChannelSetupContract({
1237
+ fields: {},
1238
+ legacyAdapter: feishuSetupAdapter
1239
+ });
1235
1240
  //#endregion
1236
1241
  //#region extensions/feishu/src/setup-surface.ts
1237
1242
  const t = createSetupTranslator();
@@ -1328,38 +1333,25 @@ async function promptFeishuAppId(params) {
1328
1333
  validate: (value) => value?.trim() ? void 0 : t("common.required")
1329
1334
  })).trim();
1330
1335
  }
1331
- const feishuDmPolicy = {
1336
+ const feishuDmPolicy = createChannelDmPolicy({
1332
1337
  label: "Feishu",
1333
1338
  channel,
1334
- policyKey: "channels.feishu.dmPolicy",
1335
- allowFromKey: "channels.feishu.allowFrom",
1336
- resolveConfigKeys: (_cfg, accountId) => {
1337
- const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(_cfg);
1338
- return resolvedAccountId !== DEFAULT_ACCOUNT_ID$2 ? {
1339
- policyKey: `channels.feishu.accounts.${resolvedAccountId}.dmPolicy`,
1340
- allowFromKey: `channels.feishu.accounts.${resolvedAccountId}.allowFrom`
1341
- } : {
1342
- policyKey: "channels.feishu.dmPolicy",
1343
- allowFromKey: "channels.feishu.allowFrom"
1344
- };
1345
- },
1346
- getCurrent: (cfg, accountId) => {
1339
+ resolveAccount: (cfg, accountId) => {
1347
1340
  const feishuCfg = cfg.channels?.feishu;
1348
1341
  const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(cfg);
1349
- if (resolvedAccountId !== DEFAULT_ACCOUNT_ID$2) {
1350
- const account = feishuCfg?.accounts?.[resolvedAccountId];
1351
- if (account?.dmPolicy) return account.dmPolicy;
1352
- }
1353
- return feishuCfg?.dmPolicy ?? "pairing";
1354
- },
1355
- setPolicy: (cfg, policy, accountId) => {
1356
- return patchFeishuConfig(cfg, accountId ?? resolveDefaultFeishuAccountId(cfg), {
1357
- dmPolicy: policy,
1358
- ...policy === "open" ? { allowFrom: mergeAllowFromEntries([], ["*"]) } : {}
1359
- });
1342
+ const account = resolvedAccountId === DEFAULT_ACCOUNT_ID$2 ? void 0 : feishuCfg?.accounts?.[resolvedAccountId];
1343
+ return {
1344
+ accountId: resolvedAccountId,
1345
+ config: {
1346
+ dmPolicy: account?.dmPolicy ?? feishuCfg?.dmPolicy,
1347
+ allowFrom: account?.allowFrom ?? feishuCfg?.allowFrom
1348
+ }
1349
+ };
1360
1350
  },
1351
+ resolveAllowFrom: ({ policy }) => policy === "open" ? ["*"] : void 0,
1352
+ applyPatch: ({ cfg, account, patch }) => patchFeishuConfig(cfg, account.accountId, patch),
1361
1353
  promptAllowFrom: promptFeishuAllowFrom
1362
- };
1354
+ });
1363
1355
  function applyNewAppSecurityPolicy(cfg, accountId, openId, groupPolicy) {
1364
1356
  let next = cfg;
1365
1357
  if (openId) next = patchFeishuConfig(next, accountId, {
@@ -1371,7 +1363,7 @@ function applyNewAppSecurityPolicy(cfg, accountId, openId, groupPolicy) {
1371
1363
  next = patchFeishuConfig(next, accountId, groupPatch);
1372
1364
  return next;
1373
1365
  }
1374
- const loadAppRegistrationModule = createLazyRuntimeModule(() => import("./app-registration-BzkyrVZu.js"));
1366
+ const loadAppRegistrationModule = createLazyRuntimeModule(() => import("./app-registration-cN1bVV6s.js"));
1375
1367
  async function promptFeishuDomain(params) {
1376
1368
  return await params.prompter.select({
1377
1369
  message: t("wizard.feishu.domainPrompt"),
@@ -1596,7 +1588,7 @@ const feishuSetupWizard = {
1596
1588
  });
1597
1589
  let probeResult = null;
1598
1590
  if (configured && account.configured) try {
1599
- const { probeFeishu } = await import("./probe-BgboTHIn.js").then((n) => n.n);
1591
+ const { probeFeishu } = await import("./probe-Za1kgUvx.js").then((n) => n.n);
1600
1592
  probeResult = await probeFeishu(account);
1601
1593
  } catch {}
1602
1594
  if (!configured) return [formatFeishuStatusLine("needs-credentials")];
@@ -1668,7 +1660,7 @@ const meta = {
1668
1660
  order: 70,
1669
1661
  preferSessionLookupForAnnounceTarget: true
1670
1662
  };
1671
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CVIzo2dV.js"), "feishuChannelRuntime");
1663
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CSlJVqy4.js"), "feishuChannelRuntime");
1672
1664
  function toFeishuMessageSendResult(result, kind) {
1673
1665
  const receipt = result.receipt ?? createFeishuSendReceipt({
1674
1666
  messageId: result.messageId,
@@ -1712,7 +1704,7 @@ const feishuMessageAdapter = defineChannelMessageAdapter({
1712
1704
  }
1713
1705
  });
1714
1706
  async function createFeishuActionClient(account) {
1715
- const { createFeishuClient } = await import("./client-87BmeMpj.js").then((n) => n.t);
1707
+ const { createFeishuClient } = await import("./client-Dee7cKsS.js").then((n) => n.t);
1716
1708
  return createFeishuClient(account);
1717
1709
  }
1718
1710
  async function resolveFeishuChatTypeById(params) {
@@ -1776,25 +1768,6 @@ function describeFeishuMessageTool({ cfg, accountId }) {
1776
1768
  capabilities: enabled ? ["presentation"] : []
1777
1769
  };
1778
1770
  }
1779
- function setFeishuNamedAccountEnabled(cfg, accountId, enabled) {
1780
- const feishuCfg = cfg.channels?.feishu;
1781
- return {
1782
- ...cfg,
1783
- channels: {
1784
- ...cfg.channels,
1785
- feishu: {
1786
- ...feishuCfg,
1787
- accounts: {
1788
- ...feishuCfg?.accounts,
1789
- [accountId]: {
1790
- ...feishuCfg?.accounts?.[accountId],
1791
- enabled
1792
- }
1793
- }
1794
- }
1795
- }
1796
- };
1797
- }
1798
1771
  const feishuConfigAdapter = createHybridChannelConfigAdapter({
1799
1772
  sectionKey: "feishu",
1800
1773
  listAccountIds: listFeishuAccountIds,
@@ -1933,7 +1906,8 @@ function readFirstString(params, keys, fallback) {
1933
1906
  }
1934
1907
  const UNRESOLVED_RESPONSE_PREFIX_VAR_PATTERN = /\{[a-zA-Z][a-zA-Z0-9.]*\}/;
1935
1908
  function resolveFeishuMessageActionResponsePrefix(ctx) {
1936
- const configured = ctx.cfg.messages?.responsePrefix;
1909
+ const channel = ctx.cfg.channels?.feishu;
1910
+ const configured = (ctx.accountId ? channel?.accounts?.[ctx.accountId]?.responsePrefix : void 0) ?? channel?.responsePrefix ?? (channel === void 0 ? ctx.cfg.messages?.responsePrefix : void 0);
1937
1911
  if (!configured) return;
1938
1912
  const agentId = (ctx.agentId?.trim() || "main").toLowerCase();
1939
1913
  const identityName = ctx.cfg.agents?.list?.find((agent) => agent.id.trim().toLowerCase() === agentId)?.identity?.name?.trim();
@@ -2149,19 +2123,6 @@ const feishuPlugin = createChatChannelPlugin({
2149
2123
  configSchema: FeishuChannelConfigSchema,
2150
2124
  config: {
2151
2125
  ...feishuConfigAdapter,
2152
- setAccountEnabled: ({ cfg, accountId, enabled }) => {
2153
- if (accountId === DEFAULT_ACCOUNT_ID$3) return {
2154
- ...cfg,
2155
- channels: {
2156
- ...cfg.channels,
2157
- feishu: {
2158
- ...cfg.channels?.feishu,
2159
- enabled
2160
- }
2161
- }
2162
- };
2163
- return setFeishuNamedAccountEnabled(cfg, accountId, enabled);
2164
- },
2165
2126
  deleteAccount: ({ cfg, accountId }) => {
2166
2127
  if (accountId === DEFAULT_ACCOUNT_ID$3) {
2167
2128
  const next = { ...cfg };
@@ -2687,6 +2648,7 @@ const feishuPlugin = createChatChannelPlugin({
2687
2648
  });
2688
2649
  } },
2689
2650
  setup: feishuSetupAdapter,
2651
+ setupContract: feishuSetupContract,
2690
2652
  setupWizard: feishuSetupWizard,
2691
2653
  messaging: {
2692
2654
  targetPrefixes: ["feishu", "lark"],
@@ -2757,7 +2719,7 @@ const feishuPlugin = createChatChannelPlugin({
2757
2719
  })
2758
2720
  }),
2759
2721
  gateway: { startAccount: async (ctx) => {
2760
- const { monitorFeishuProvider } = await import("./monitor-BVQf7-Bl.js");
2722
+ const { monitorFeishuProvider } = await import("./monitor-DEHJlyWW.js");
2761
2723
  const account = resolveFeishuRuntimeAccount({
2762
2724
  cfg: ctx.cfg,
2763
2725
  accountId: ctx.accountId
@@ -2851,4 +2813,4 @@ const feishuPlugin = createChatChannelPlugin({
2851
2813
  }
2852
2814
  });
2853
2815
  //#endregion
2854
- export { setFeishuNamedAccountEnabled$1 as a, isFeishuCardWithinEnvelope as c, feishuSetupAdapter as i, listFeishuDirectoryGroups as l, feishuSetupWizard as n, assertFeishuCardWithinEnvelope as o, runFeishuLogin as r, buildFeishuPresentationCardElements as s, feishuPlugin as t, listFeishuDirectoryPeers as u };
2816
+ export { setFeishuNamedAccountEnabled as a, isFeishuCardWithinEnvelope as c, feishuSetupAdapter as i, listFeishuDirectoryGroups as l, feishuSetupWizard as n, assertFeishuCardWithinEnvelope as o, runFeishuLogin as r, buildFeishuPresentationCardElements as s, feishuPlugin as t, listFeishuDirectoryPeers as u };
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-BdnXYU6g.js";
1
+ import { t as feishuPlugin } from "./channel-CBNICmK9.js";
2
2
  export { feishuPlugin };
@@ -1,10 +1,10 @@
1
- import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, v as parseFeishuCommentTarget } from "./accounts-BDoGHJDk.js";
2
- import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-BdnXYU6g.js";
3
- import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-DfE5Fhz6.js";
4
- import { r as createFeishuClient } from "./client-87BmeMpj.js";
5
- import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-BHv8WW9i.js";
6
- import { _ as buildFeishuMediaFallbackText, a as sendMarkdownCardFeishu, h as shouldSuppressFeishuTextForVoiceMedia, i as sendCardFeishu, m as sendMediaFeishu, n as getMessageFeishu, o as sendMessageFeishu, s as sendStructuredCardFeishu, t as editMessageFeishu, y as resolveFeishuIdentityHeaderTitle } from "./send-DcrXbqqA.js";
7
- import { t as probeFeishu } from "./probe-BgboTHIn.js";
1
+ import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, v as parseFeishuCommentTarget } from "./accounts-CKhCa76b.js";
2
+ import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-CBNICmK9.js";
3
+ import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-Bcofg0Vv.js";
4
+ import { r as createFeishuClient } from "./client-Dee7cKsS.js";
5
+ import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-DG6pKTPE.js";
6
+ import { _ as buildFeishuMediaFallbackText, a as getMessageFeishu, c as sendMarkdownCardFeishu, i as editMessageFeishu, l as sendMessageFeishu, n as sendMediaFeishu, r as shouldSuppressFeishuTextForVoiceMedia, s as sendCardFeishu, u as sendStructuredCardFeishu, y as resolveFeishuIdentityHeaderTitle } from "./media-DOwcLJ1j.js";
7
+ import { t as probeFeishu } from "./probe-Za1kgUvx.js";
8
8
  import { createReplyToFanout } from "openclaw/plugin-sdk/channel-outbound";
9
9
  import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
10
10
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -62,6 +62,67 @@ function setRequestUserAgent(req) {
62
62
  return req;
63
63
  }
64
64
  Lark.defaultHttpInstance.interceptors?.request?.use(setRequestUserAgent);
65
+ function isRecord(value) {
66
+ return typeof value === "object" && value !== null && !Array.isArray(value);
67
+ }
68
+ function readHeader(headers, name) {
69
+ if (!isRecord(headers)) return;
70
+ const normalizedName = name.toLowerCase();
71
+ for (const [key, value] of Object.entries(headers)) {
72
+ if (key.toLowerCase() !== normalizedName) continue;
73
+ if (typeof value === "string") return value;
74
+ if (Array.isArray(value)) {
75
+ const first = value.find((entry) => typeof entry === "string");
76
+ return typeof first === "string" ? first : void 0;
77
+ }
78
+ }
79
+ }
80
+ function isMultipartFormRequest(opts) {
81
+ return /^multipart\/form-data(?:;|$)/i.test(readHeader(opts.headers, "content-type") ?? "");
82
+ }
83
+ const FEISHU_MESSAGE_MEDIA_UPLOAD_PATHS = /* @__PURE__ */ new Set(["/open-apis/im/v1/files", "/open-apis/im/v1/images"]);
84
+ function isFeishuMessageMediaUploadRequest(opts, data) {
85
+ if (typeof opts.url !== "string" || opts.method?.toUpperCase() !== "POST") return false;
86
+ let pathname;
87
+ try {
88
+ pathname = new URL(opts.url).pathname;
89
+ } catch {
90
+ return false;
91
+ }
92
+ return FEISHU_MESSAGE_MEDIA_UPLOAD_PATHS.has(pathname) && (Buffer.isBuffer(data.file) || Buffer.isBuffer(data.image));
93
+ }
94
+ function stringifyMultipartFieldValue(value) {
95
+ switch (typeof value) {
96
+ case "string": return value;
97
+ case "number":
98
+ case "boolean":
99
+ case "bigint": return String(value);
100
+ default: return;
101
+ }
102
+ }
103
+ function bufferToBlobPart(value) {
104
+ const bytes = new Uint8Array(value.byteLength);
105
+ bytes.set(value);
106
+ return bytes;
107
+ }
108
+ function normalizeMultipartUploadData(opts) {
109
+ if (!isMultipartFormRequest(opts) || !isRecord(opts.data) || !isFeishuMessageMediaUploadRequest(opts, opts.data)) return opts;
110
+ const form = new FormData();
111
+ const fileName = typeof opts.data.file_name === "string" && opts.data.file_name ? opts.data.file_name : void 0;
112
+ for (const [key, value] of Object.entries(opts.data)) {
113
+ if (value === void 0 || value === null) continue;
114
+ if (Buffer.isBuffer(value)) {
115
+ form.append(key, new Blob([bufferToBlobPart(value)]), key === "file" && fileName ? fileName : `${key}.bin`);
116
+ continue;
117
+ }
118
+ const fieldValue = stringifyMultipartFieldValue(value);
119
+ if (fieldValue !== void 0) form.append(key, fieldValue);
120
+ }
121
+ return {
122
+ ...opts,
123
+ data: form
124
+ };
125
+ }
65
126
  function isManagedProxyActive() {
66
127
  return process.env["OPENCLAW_PROXY_ACTIVE"] === "1";
67
128
  }
@@ -118,7 +179,7 @@ function createFeishuHttpInstance(defaultTimeoutMs) {
118
179
  return next;
119
180
  }
120
181
  return {
121
- request: async (opts) => base.request(await injectRequestOptions(opts)),
182
+ request: async (opts) => base.request(await injectRequestOptions(normalizeMultipartUploadData(opts))),
122
183
  get: async (url, opts) => base.get(url, await injectRequestOptions(opts)),
123
184
  post: async (url, data, opts) => base.post(url, data, await injectRequestOptions(opts)),
124
185
  put: async (url, data, opts) => base.put(url, data, await injectRequestOptions(opts)),
@@ -1,4 +1,4 @@
1
1
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
2
- import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
3
- import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
2
+ import { t as messageActionTargetAliases } from "./security-audit-D7WK_BHh.js";
3
+ import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BgpY7AiJ.js";
4
4
  export { buildFeishuConversationId, collectFeishuSecurityAuditFindings, messageActionTargetAliases, parseFeishuConversationId, parseFeishuDirectConversationId, parseFeishuTargetId };