@openclaw/feishu 2026.5.28 → 2026.5.31-beta.1

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 (33) hide show
  1. package/dist/{accounts-CXnY5H8g.js → accounts-Bpe6CjpS.js} +35 -3
  2. package/dist/api.js +18 -11
  3. package/dist/{channel-BfeesQob.js → channel-TXwK9jIG.js} +32 -24
  4. package/dist/channel-plugin-api.js +1 -1
  5. package/dist/{channel.runtime-BLnKcmtO.js → channel.runtime-AAff9iBZ.js} +6 -6
  6. package/dist/contract-api.js +1 -1
  7. package/dist/{drive-USxqssMG.js → drive-BIrffRwc.js} +18 -6
  8. package/dist/{monitor-CyD0CQxm.js → monitor-Ccev4ogO.js} +5 -3
  9. package/dist/{monitor.account-ByxawtBB.js → monitor.account-DYaT0fVd.js} +204 -88
  10. package/dist/{monitor.state-t4Ae5VIa.js → monitor.state-r4OLFBfg.js} +2 -2
  11. package/dist/{probe-956I34qH.js → probe-BjKRV7em.js} +21 -9
  12. package/dist/runtime-api.js +1 -1
  13. package/dist/{send-Djou0Z5a.js → send-Cze2qlca.js} +4 -4
  14. package/dist/{send-result-DSTSkRDM.js → send-result-D9rgEUlm.js} +1 -1
  15. package/dist/setup-api.js +1 -1
  16. package/dist/{subagent-hooks-fuyBHOVu.js → subagent-hooks-Bw3Dg2mS.js} +2 -2
  17. package/dist/subagent-hooks-api.js +2 -7
  18. package/node_modules/es-object-atoms/CHANGELOG.md +21 -14
  19. package/node_modules/es-object-atoms/isObject.d.ts +1 -1
  20. package/node_modules/es-object-atoms/package.json +6 -7
  21. package/node_modules/es-object-atoms/tsconfig.json +1 -0
  22. package/node_modules/hasown/CHANGELOG.md +7 -0
  23. package/node_modules/hasown/index.d.ts +0 -1
  24. package/node_modules/hasown/package.json +4 -5
  25. package/node_modules/typebox/build/type/script/mapping.d.mts +5 -2
  26. package/node_modules/typebox/build/type/script/mapping.mjs +15 -8
  27. package/node_modules/typebox/build/type/script/parser.d.mts +3 -1
  28. package/node_modules/typebox/build/type/script/parser.mjs +2 -1
  29. package/node_modules/typebox/package.json +29 -29
  30. package/npm-shrinkwrap.json +13 -13
  31. package/openclaw.plugin.json +124 -0
  32. package/package.json +5 -5
  33. package/dist/{thread-bindings-D24m3Cjy.js → thread-bindings-C58Uq5Y1.js} +1 -1
@@ -342,18 +342,50 @@ function resolveDefaultFeishuAccountSelection(cfg) {
342
342
  function resolveDefaultFeishuAccountId(cfg) {
343
343
  return resolveDefaultAccountId(cfg);
344
344
  }
345
+ function resolveRawFeishuAccountConfig(accounts, accountId) {
346
+ if (!accounts || typeof accounts !== "object") return;
347
+ if (Object.hasOwn(accounts, accountId)) return accounts[accountId];
348
+ const normalized = accountId.toLowerCase();
349
+ const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalized);
350
+ return matchKey ? accounts[matchKey] : void 0;
351
+ }
345
352
  /**
346
353
  * Merge top-level config with account-specific config.
347
354
  * Account-specific fields override top-level fields.
348
355
  */
349
356
  function mergeFeishuAccountConfig(cfg, accountId) {
350
357
  const feishuCfg = cfg.channels?.feishu;
351
- return resolveMergedAccountConfig({
358
+ const accounts = feishuCfg?.accounts;
359
+ const accountTools = resolveRawFeishuAccountConfig(accounts, accountId)?.tools;
360
+ const merged = resolveMergedAccountConfig({
352
361
  channelConfig: feishuCfg,
353
- accounts: feishuCfg?.accounts,
362
+ accounts,
354
363
  accountId,
355
- omitKeys: ["defaultAccount"]
364
+ omitKeys: ["defaultAccount"],
365
+ nestedObjectKeys: ["tools"]
356
366
  });
367
+ const topTools = feishuCfg?.tools;
368
+ if (merged.tools === void 0 && topTools !== void 0) return {
369
+ ...merged,
370
+ tools: topTools
371
+ };
372
+ if (topTools?.bitable === false || topTools?.bitable === void 0 && topTools?.base === false) return {
373
+ ...merged,
374
+ tools: {
375
+ ...merged.tools,
376
+ bitable: false,
377
+ base: false
378
+ }
379
+ };
380
+ if (accountTools?.bitable === void 0 && accountTools?.base !== void 0) return {
381
+ ...merged,
382
+ tools: {
383
+ ...merged.tools,
384
+ bitable: accountTools.base,
385
+ base: accountTools.base
386
+ }
387
+ };
388
+ return merged;
357
389
  }
358
390
  function resolveFeishuCredentials(cfg, options) {
359
391
  const mode = options?.mode ?? (options?.allowUnresolvedSecretRef ? "inspect" : "strict");
package/dist/api.js CHANGED
@@ -1,10 +1,11 @@
1
+ import { r as listEnabledFeishuAccounts } from "./accounts-Bpe6CjpS.js";
2
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-TXwK9jIG.js";
1
3
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
2
- import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
3
- import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-fuyBHOVu.js";
4
- import { r as listEnabledFeishuAccounts } from "./accounts-CXnY5H8g.js";
5
- import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-BfeesQob.js";
6
4
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
7
- import { a as jsonToolResult, d as registerFeishuChatTools, f as createFeishuToolClient, m as resolveFeishuToolAccount, n as registerFeishuDriveTools, o as toolExecutionErrorResult, p as resolveAnyEnabledFeishuToolsConfig, s as unknownToolActionResult } from "./drive-USxqssMG.js";
5
+ import { r as createFeishuClient } from "./client-BhMNZBJD.js";
6
+ import { a as jsonToolResult, d as registerFeishuChatTools, f as createFeishuToolClient, h as resolveToolsConfig, m as resolveFeishuToolAccount, n as registerFeishuDriveTools, o as toolExecutionErrorResult, p as resolveAnyEnabledFeishuToolsConfig, s as unknownToolActionResult } from "./drive-BIrffRwc.js";
7
+ import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-C58Uq5Y1.js";
8
+ import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-Bw3Dg2mS.js";
8
9
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
9
10
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
10
11
  import { existsSync } from "node:fs";
@@ -2208,12 +2209,18 @@ const UpdateRecordSchema = Type.Object({
2208
2209
  });
2209
2210
  function registerFeishuBitableTools(api) {
2210
2211
  if (!api.config) return;
2211
- if (listEnabledFeishuAccounts(api.config).length === 0) return;
2212
- const getClient = (params, defaultAccountId) => createFeishuToolClient({
2213
- api,
2214
- executeParams: params,
2215
- defaultAccountId
2216
- });
2212
+ const accounts = listEnabledFeishuAccounts(api.config);
2213
+ if (accounts.length === 0) return;
2214
+ if (!resolveAnyEnabledFeishuToolsConfig(accounts).bitable) return;
2215
+ const getClient = (params, defaultAccountId) => {
2216
+ const account = resolveFeishuToolAccount({
2217
+ api,
2218
+ executeParams: params,
2219
+ defaultAccountId
2220
+ });
2221
+ if (!resolveToolsConfig(account.config.tools).bitable) throw new Error(`Feishu Bitable tools are disabled for account "${account.accountId}"`);
2222
+ return createFeishuClient(account);
2223
+ };
2217
2224
  const registerBitableTool = (params) => {
2218
2225
  api.registerTool((ctx) => ({
2219
2226
  name: params.name,
@@ -1,14 +1,11 @@
1
- import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
1
+ import { a as resolveDefaultFeishuAccountId, f as isRecord$2, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-Bpe6CjpS.js";
2
2
  import { n as looksLikeFeishuId, r as normalizeFeishuTarget, t as detectIdType } from "./targets-BUjQ1TcA.js";
3
- import { a as resolveDefaultFeishuAccountId, f as isRecord$2, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
4
- import { n as createFeishuSendReceipt, s as createFeishuCardInteractionEnvelope } from "./send-result-DSTSkRDM.js";
3
+ import { n as createFeishuSendReceipt, s as createFeishuCardInteractionEnvelope } from "./send-result-D9rgEUlm.js";
4
+ import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
5
5
  import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
6
6
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-ChjJKAJ9.js";
7
7
  import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
8
8
  import { t as resolveFeishuSessionConversation } from "./session-conversation-CZSMgac-.js";
9
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
- import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
11
- import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
12
9
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
13
10
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
14
11
  import { adaptScopedAccountAccessor, createHybridChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
@@ -16,23 +13,26 @@ import { buildChannelOutboundSessionRoute, createChatChannelPlugin, stripChannel
16
13
  import { createRuntimeOutboundDelegates, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
17
14
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
18
15
  import { createAllowlistProviderGroupPolicyWarningCollector, projectConfigAccountIdWarningCollector } from "openclaw/plugin-sdk/channel-policy";
16
+ import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
19
17
  import { createChannelDirectoryAdapter, createRuntimeDirectoryLiveAdapter, listDirectoryGroupEntriesFromMapKeysAndAllowFrom, listDirectoryUserEntriesFromAllowFromAndMapKeys } from "openclaw/plugin-sdk/directory-runtime";
20
18
  import { normalizeMessagePresentation, renderMessagePresentationFallbackText } from "openclaw/plugin-sdk/interactive-runtime";
21
19
  import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
22
20
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
23
21
  import { buildProbeChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
24
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normalizeAccountId as normalizeAccountId$1, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
22
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
23
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, normalizeAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
25
24
  import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
26
25
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
27
26
  import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-primitives";
28
27
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
29
28
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
30
- import { normalizeAccountId as normalizeAccountId$2 } from "openclaw/plugin-sdk/account-id";
29
+ import { normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/account-id";
31
30
  import { z } from "zod";
32
31
  import { buildSecretInputSchema, hasConfiguredSecretInput as hasConfiguredSecretInput$2 } from "openclaw/plugin-sdk/secret-input";
33
32
  import fs from "node:fs";
34
33
  import os from "node:os";
35
34
  import path from "node:path";
35
+ import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
36
36
  import { loadSessionStore, resolveSessionFilePath, resolveStorePath, updateSessionStore } from "openclaw/plugin-sdk/session-store-runtime";
37
37
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
38
38
  import { createChannelIngressResolver, defineStableChannelIngressIdentity } from "openclaw/plugin-sdk/channel-ingress-runtime";
@@ -150,7 +150,9 @@ const FeishuToolsConfigSchema = z.object({
150
150
  wiki: z.boolean().optional(),
151
151
  drive: z.boolean().optional(),
152
152
  perm: z.boolean().optional(),
153
- scopes: z.boolean().optional()
153
+ scopes: z.boolean().optional(),
154
+ bitable: z.boolean().optional(),
155
+ base: z.boolean().optional()
154
156
  }).strict().optional();
155
157
  /**
156
158
  * Group session scope for routing Feishu group messages.
@@ -278,8 +280,8 @@ const FeishuConfigSchema = z.object({
278
280
  }).strict().superRefine((value, ctx) => {
279
281
  const defaultAccount = value.defaultAccount?.trim();
280
282
  if (defaultAccount && value.accounts && Object.keys(value.accounts).length > 0) {
281
- const normalizedDefaultAccount = normalizeAccountId$2(defaultAccount);
282
- if (!Object.prototype.hasOwnProperty.call(value.accounts, normalizedDefaultAccount)) ctx.addIssue({
283
+ const normalizedDefaultAccount = normalizeAccountId$1(defaultAccount);
284
+ if (!Object.hasOwn(value.accounts, normalizedDefaultAccount)) ctx.addIssue({
283
285
  code: z.ZodIssueCode.custom,
284
286
  path: ["defaultAccount"],
285
287
  message: `channels.feishu.defaultAccount="${defaultAccount}" does not match a configured account key`
@@ -419,7 +421,7 @@ function isPathWithinRoot(targetPath, rootPath) {
419
421
  const resolvedTarget = path.resolve(targetPath);
420
422
  const resolvedRoot = path.resolve(rootPath);
421
423
  const relative = path.relative(resolvedRoot, resolvedTarget);
422
- return Boolean(relative) && !relative.startsWith("..") && !path.isAbsolute(relative);
424
+ return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
423
425
  }
424
426
  function formatDisplayPath(filePath) {
425
427
  const home = os.homedir();
@@ -824,7 +826,7 @@ async function repairFeishuDoctorState(params) {
824
826
  const keys = new Set(group.entries.map((entry) => entry.key));
825
827
  const removedEntries = await updateSessionStore(storePath, (store) => {
826
828
  const removed = [];
827
- for (const key of keys) if (Object.prototype.hasOwnProperty.call(store, key)) {
829
+ for (const key of keys) if (Object.hasOwn(store, key)) {
828
830
  delete store[key];
829
831
  const entry = group.entries.find((candidate) => candidate.key === key);
830
832
  if (entry) removed.push(entry);
@@ -982,7 +984,7 @@ function createFeishuIngressSubject(params) {
982
984
  function createFeishuIngressResolver(params) {
983
985
  return createChannelIngressResolver({
984
986
  channelId: "feishu",
985
- accountId: normalizeAccountId$1(params.accountId) ?? "default",
987
+ accountId: normalizeAccountId(params.accountId) ?? "default",
986
988
  identity: feishuIngressIdentity,
987
989
  cfg: params.cfg,
988
990
  ...params.readAllowFromStore ? { readStoreAllowFrom: params.readAllowFromStore } : {}
@@ -1070,7 +1072,7 @@ function hasExplicitFeishuGroupConfig(params) {
1070
1072
  const groups = params.cfg?.groups ?? {};
1071
1073
  const groupId = params.groupId?.trim();
1072
1074
  if (!groupId) return false;
1073
- if (Object.prototype.hasOwnProperty.call(groups, groupId) && groupId !== "*") return true;
1075
+ if (Object.hasOwn(groups, groupId) && groupId !== "*") return true;
1074
1076
  const lowered = normalizeOptionalLowercaseString(groupId) ?? "";
1075
1077
  return Object.keys(groups).some((key) => key !== "*" && normalizeOptionalLowercaseString(key) === lowered);
1076
1078
  }
@@ -1088,8 +1090,8 @@ function resolveFeishuReplyPolicy(params) {
1088
1090
  const resolvedCfg = resolveMergedAccountConfig({
1089
1091
  channelConfig: feishuCfg,
1090
1092
  accounts: feishuCfg?.accounts,
1091
- accountId: normalizeAccountId$1(params.accountId),
1092
- normalizeAccountId: normalizeAccountId$1,
1093
+ accountId: normalizeAccountId(params.accountId),
1094
+ normalizeAccountId,
1093
1095
  omitKeys: ["defaultAccount"]
1094
1096
  });
1095
1097
  const groupRequireMention = resolveFeishuGroupConfig({
@@ -1307,8 +1309,8 @@ function isFeishuConfigured(cfg) {
1307
1309
  const topLevelConfigured = isAppIdConfigured(feishuCfg?.appId) && hasConfiguredSecretInput$1(feishuCfg?.appSecret);
1308
1310
  const accountConfigured = Object.values(feishuCfg?.accounts ?? {}).some((account) => {
1309
1311
  if (!account || typeof account !== "object") return false;
1310
- const hasOwnAppId = Object.prototype.hasOwnProperty.call(account, "appId");
1311
- const hasOwnAppSecret = Object.prototype.hasOwnProperty.call(account, "appSecret");
1312
+ const hasOwnAppId = Object.hasOwn(account, "appId");
1313
+ const hasOwnAppSecret = Object.hasOwn(account, "appSecret");
1312
1314
  const accountAppIdConfigured = hasOwnAppId ? isAppIdConfigured(account.appId) : isAppIdConfigured(feishuCfg?.appId);
1313
1315
  const accountSecretConfigured = hasOwnAppSecret ? hasConfiguredSecretInput$1(account.appSecret) : hasConfiguredSecretInput$1(feishuCfg?.appSecret);
1314
1316
  return accountAppIdConfigured && accountSecretConfigured;
@@ -1426,6 +1428,11 @@ function applyNewAppSecurityPolicy(cfg, accountId, openId, groupPolicy) {
1426
1428
  next = patchFeishuConfig(next, accountId, groupPatch);
1427
1429
  return next;
1428
1430
  }
1431
+ let appRegistrationModulePromise = null;
1432
+ const loadAppRegistrationModule = async () => {
1433
+ appRegistrationModulePromise ??= import("./app-registration-DCy5-X_C.js");
1434
+ return await appRegistrationModulePromise;
1435
+ };
1429
1436
  async function promptFeishuDomain(params) {
1430
1437
  return await params.prompter.select({
1431
1438
  message: t("wizard.feishu.domainPrompt"),
@@ -1453,7 +1460,7 @@ async function promptFeishuSetupMethod(prompter) {
1453
1460
  });
1454
1461
  }
1455
1462
  async function runScanToCreate(prompter, domain) {
1456
- const { beginAppRegistration, initAppRegistration, pollAppRegistration, printQrCode } = await import("./app-registration-DCy5-X_C.js");
1463
+ const { beginAppRegistration, initAppRegistration, pollAppRegistration, printQrCode } = await loadAppRegistrationModule();
1457
1464
  try {
1458
1465
  await initAppRegistration(domain);
1459
1466
  } catch {
@@ -1538,7 +1545,7 @@ async function runNewAppFlow(params) {
1538
1545
  appSecretProbeValue = appSecretResult.resolvedValue;
1539
1546
  }
1540
1547
  if (appId && appSecretProbeValue) {
1541
- const { getAppOwnerOpenId } = await import("./app-registration-DCy5-X_C.js");
1548
+ const { getAppOwnerOpenId } = await loadAppRegistrationModule();
1542
1549
  scanOpenId = await getAppOwnerOpenId({
1543
1550
  appId,
1544
1551
  appSecret: appSecretProbeValue,
@@ -1648,7 +1655,7 @@ const feishuSetupWizard = {
1648
1655
  });
1649
1656
  let probeResult = null;
1650
1657
  if (configured && account.configured) try {
1651
- const { probeFeishu } = await import("./probe-956I34qH.js").then((n) => n.n);
1658
+ const { probeFeishu } = await import("./probe-BjKRV7em.js").then((n) => n.n);
1652
1659
  probeResult = await probeFeishu(account);
1653
1660
  } catch {}
1654
1661
  if (!configured) return [formatFeishuStatusLine("needs-credentials")];
@@ -1724,7 +1731,7 @@ const meta = {
1724
1731
  order: 70,
1725
1732
  preferSessionLookupForAnnounceTarget: true
1726
1733
  };
1727
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-BLnKcmtO.js"), "feishuChannelRuntime");
1734
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-AAff9iBZ.js"), "feishuChannelRuntime");
1728
1735
  function toFeishuMessageSendResult(result, kind) {
1729
1736
  const receipt = result.receipt ?? createFeishuSendReceipt({
1730
1737
  messageId: result.messageId,
@@ -2540,7 +2547,7 @@ const feishuPlugin = createChatChannelPlugin({
2540
2547
  })
2541
2548
  }),
2542
2549
  gateway: { startAccount: async (ctx) => {
2543
- const { monitorFeishuProvider } = await import("./monitor-CyD0CQxm.js");
2550
+ const { monitorFeishuProvider } = await import("./monitor-Ccev4ogO.js");
2544
2551
  const account = resolveFeishuRuntimeAccount({
2545
2552
  cfg: ctx.cfg,
2546
2553
  accountId: ctx.accountId
@@ -2554,6 +2561,7 @@ const feishuPlugin = createChatChannelPlugin({
2554
2561
  return monitorFeishuProvider({
2555
2562
  config: ctx.cfg,
2556
2563
  runtime: ctx.runtime,
2564
+ channelRuntime: ctx.channelRuntime,
2557
2565
  abortSignal: ctx.abortSignal,
2558
2566
  accountId: ctx.accountId
2559
2567
  });
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-BfeesQob.js";
1
+ import { t as feishuPlugin } from "./channel-TXwK9jIG.js";
2
2
  export { feishuPlugin };
@@ -1,12 +1,12 @@
1
- import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
2
- import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-BfeesQob.js";
1
+ import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-Bpe6CjpS.js";
2
+ import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-TXwK9jIG.js";
3
3
  import { r as createFeishuClient } from "./client-BhMNZBJD.js";
4
- import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-USxqssMG.js";
4
+ import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-BIrffRwc.js";
5
5
  import { chunkTextForOutbound } from "./runtime-api.js";
6
- import { a as sendCardFeishu, c as sendStructuredCardFeishu, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-Djou0Z5a.js";
7
- import { t as probeFeishu } from "./probe-956I34qH.js";
8
- import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
6
+ import { a as sendCardFeishu, c as sendStructuredCardFeishu, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-Cze2qlca.js";
7
+ import { t as probeFeishu } from "./probe-BjKRV7em.js";
9
8
  import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
9
+ import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
10
10
  import path from "node:path";
11
11
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
12
12
  import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
@@ -1,8 +1,8 @@
1
1
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
2
- import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
3
2
  import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
4
3
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-ChjJKAJ9.js";
5
4
  import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
5
+ import { r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-C58Uq5Y1.js";
6
6
  //#region extensions/feishu/contract-api.ts
7
7
  const feishuSessionBindingAdapterChannels = ["feishu"];
8
8
  //#endregion
@@ -1,4 +1,4 @@
1
- import { d as formatFeishuApiError, f as isRecord$1, h as readString, i as listFeishuAccountIds, l as encodeQuery, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as extractReplyText, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
1
+ import { d as formatFeishuApiError, f as isRecord$1, h as readString, i as listFeishuAccountIds, l as encodeQuery, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as extractReplyText, y as parseFeishuCommentTarget } from "./accounts-Bpe6CjpS.js";
2
2
  import { r as createFeishuClient } from "./client-BhMNZBJD.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
@@ -8,7 +8,7 @@ import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers";
8
8
  //#region extensions/feishu/src/tools-config.ts
9
9
  /**
10
10
  * Default tool configuration.
11
- * - doc, chat, wiki, drive, scopes: enabled by default
11
+ * - doc, chat, wiki, drive, scopes, bitable/base: enabled by default
12
12
  * - perm: disabled by default (sensitive operation)
13
13
  */
14
14
  const DEFAULT_TOOLS_CONFIG = {
@@ -17,15 +17,23 @@ const DEFAULT_TOOLS_CONFIG = {
17
17
  wiki: true,
18
18
  drive: true,
19
19
  perm: false,
20
- scopes: true
20
+ scopes: true,
21
+ bitable: true,
22
+ base: true
21
23
  };
22
24
  /**
23
25
  * Resolve tools config with defaults.
26
+ *
27
+ * `base` is a backward-compatible alias for the Bitable tool family. When both
28
+ * keys are present, the explicit `bitable` value wins and `base` mirrors it.
24
29
  */
25
30
  function resolveToolsConfig(cfg) {
31
+ const bitable = cfg?.bitable ?? cfg?.base ?? DEFAULT_TOOLS_CONFIG.bitable;
26
32
  return {
27
33
  ...DEFAULT_TOOLS_CONFIG,
28
- ...cfg
34
+ ...cfg,
35
+ bitable,
36
+ base: bitable
29
37
  };
30
38
  }
31
39
  //#endregion
@@ -60,7 +68,9 @@ function resolveAnyEnabledFeishuToolsConfig(accounts) {
60
68
  wiki: false,
61
69
  drive: false,
62
70
  perm: false,
63
- scopes: false
71
+ scopes: false,
72
+ bitable: false,
73
+ base: false
64
74
  };
65
75
  for (const account of accounts) {
66
76
  const cfg = resolveToolsConfig(account.config.tools);
@@ -70,6 +80,8 @@ function resolveAnyEnabledFeishuToolsConfig(accounts) {
70
80
  merged.drive = merged.drive || cfg.drive;
71
81
  merged.perm = merged.perm || cfg.perm;
72
82
  merged.scopes = merged.scopes || cfg.scopes;
83
+ merged.bitable = merged.bitable || cfg.bitable;
84
+ merged.base = merged.base || cfg.base;
73
85
  }
74
86
  return merged;
75
87
  }
@@ -892,4 +904,4 @@ function registerFeishuDriveTools(api) {
892
904
  }, { name: "feishu_drive" });
893
905
  }
894
906
  //#endregion
895
- export { jsonToolResult as a, getChatInfo as c, registerFeishuChatTools as d, createFeishuToolClient as f, createCommentTypingReactionLifecycle as i, getChatMembers as l, resolveFeishuToolAccount as m, registerFeishuDriveTools as n, toolExecutionErrorResult as o, resolveAnyEnabledFeishuToolsConfig as p, cleanupAmbientCommentTypingReaction as r, unknownToolActionResult as s, deliverCommentThreadText as t, getFeishuMemberInfo as u };
907
+ export { jsonToolResult as a, getChatInfo as c, registerFeishuChatTools as d, createFeishuToolClient as f, resolveToolsConfig as h, createCommentTypingReactionLifecycle as i, getChatMembers as l, resolveFeishuToolAccount as m, registerFeishuDriveTools as n, toolExecutionErrorResult as o, resolveAnyEnabledFeishuToolsConfig as p, cleanupAmbientCommentTypingReaction as r, unknownToolActionResult as s, deliverCommentThreadText as t, getFeishuMemberInfo as u };
@@ -1,9 +1,9 @@
1
- import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
2
- import { l as fetchBotIdentityForMonitor } from "./monitor.state-t4Ae5VIa.js";
1
+ import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-Bpe6CjpS.js";
2
+ import { l as fetchBotIdentityForMonitor } from "./monitor.state-r4OLFBfg.js";
3
3
  //#region extensions/feishu/src/monitor.ts
4
4
  let monitorAccountRuntimePromise;
5
5
  async function loadMonitorAccountRuntime() {
6
- monitorAccountRuntimePromise ??= import("./monitor.account-ByxawtBB.js");
6
+ monitorAccountRuntimePromise ??= import("./monitor.account-DYaT0fVd.js");
7
7
  return await monitorAccountRuntimePromise;
8
8
  }
9
9
  async function monitorFeishuProvider(opts = {}) {
@@ -20,6 +20,7 @@ async function monitorFeishuProvider(opts = {}) {
20
20
  return monitorSingleAccount({
21
21
  cfg,
22
22
  account,
23
+ channelRuntime: opts.channelRuntime,
23
24
  runtime: opts.runtime,
24
25
  abortSignal: opts.abortSignal
25
26
  });
@@ -45,6 +46,7 @@ async function monitorFeishuProvider(opts = {}) {
45
46
  monitorPromises.push(monitorSingleAccount({
46
47
  cfg,
47
48
  account,
49
+ channelRuntime: opts.channelRuntime,
48
50
  runtime: opts.runtime,
49
51
  abortSignal: opts.abortSignal,
50
52
  botOpenIdSource: {