@openclaw/feishu 2026.5.27 → 2026.5.28-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.
package/dist/api.js CHANGED
@@ -2,9 +2,9 @@ import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as bu
2
2
  import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
3
3
  import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-fuyBHOVu.js";
4
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-DS2vP1nr.js";
5
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-DLfxURF2.js";
6
6
  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-DwgWWkJi.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-Grnpj510.js";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { existsSync } from "node:fs";
10
10
  import { homedir } from "node:os";
@@ -1647,7 +1647,7 @@ const feishuSetupWizard = {
1647
1647
  });
1648
1648
  let probeResult = null;
1649
1649
  if (configured && account.configured) try {
1650
- const { probeFeishu } = await import("./probe-Da81t6a5.js").then((n) => n.n);
1650
+ const { probeFeishu } = await import("./probe-RvCg70BY.js").then((n) => n.n);
1651
1651
  probeResult = await probeFeishu(account);
1652
1652
  } catch {}
1653
1653
  if (!configured) return [formatFeishuStatusLine("needs-credentials")];
@@ -1722,7 +1722,7 @@ const meta = {
1722
1722
  aliases: ["lark"],
1723
1723
  order: 70
1724
1724
  };
1725
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CxRDzbEQ.js"), "feishuChannelRuntime");
1725
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-i-X8-ZXc.js"), "feishuChannelRuntime");
1726
1726
  function toFeishuMessageSendResult(result, kind) {
1727
1727
  const receipt = result.receipt ?? createFeishuSendReceipt({
1728
1728
  messageId: result.messageId,
@@ -1754,7 +1754,7 @@ const feishuMessageAdapter = defineChannelMessageAdapter({
1754
1754
  }
1755
1755
  });
1756
1756
  async function createFeishuActionClient(account) {
1757
- const { createFeishuClient } = await import("./client-BnH2fRL2.js").then((n) => n.t);
1757
+ const { createFeishuClient } = await import("./client-DcSzLkSX.js").then((n) => n.t);
1758
1758
  return createFeishuClient(account);
1759
1759
  }
1760
1760
  const collectFeishuSecurityWarnings = createAllowlistProviderGroupPolicyWarningCollector({
@@ -1960,13 +1960,17 @@ function readFirstString(params, keys, fallback) {
1960
1960
  }
1961
1961
  if (typeof fallback === "string" && fallback.trim()) return fallback.trim();
1962
1962
  }
1963
- function readOptionalNumber(params, keys) {
1963
+ function isPositiveSafeInteger(value) {
1964
+ return Number.isSafeInteger(value) && value > 0;
1965
+ }
1966
+ function readOptionalPositiveInteger(params, keys) {
1964
1967
  for (const key of keys) {
1965
1968
  const value = params[key];
1966
- if (typeof value === "number" && Number.isFinite(value)) return value;
1969
+ if (typeof value === "number" && isPositiveSafeInteger(value)) return value;
1967
1970
  if (typeof value === "string" && value.trim()) {
1968
- const parsed = Number(value);
1969
- if (Number.isFinite(parsed)) return parsed;
1971
+ const trimmed = value.trim();
1972
+ const parsed = /^\d+$/.test(trimmed) ? Number(trimmed) : NaN;
1973
+ if (isPositiveSafeInteger(parsed)) return parsed;
1970
1974
  }
1971
1975
  }
1972
1976
  }
@@ -2262,7 +2266,7 @@ const feishuPlugin = createChatChannelPlugin({
2262
2266
  chatId,
2263
2267
  startTime: readFirstString(ctx.params, ["startTime", "start_time"]),
2264
2268
  endTime: readFirstString(ctx.params, ["endTime", "end_time"]),
2265
- pageSize: readOptionalNumber(ctx.params, ["pageSize", "page_size"]),
2269
+ pageSize: readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]),
2266
2270
  pageToken: readFirstString(ctx.params, ["pageToken", "page_token"]),
2267
2271
  accountId: ctx.accountId ?? void 0
2268
2272
  })
@@ -2285,7 +2289,7 @@ const feishuPlugin = createChatChannelPlugin({
2285
2289
  provider: "feishu",
2286
2290
  action: "channel-info",
2287
2291
  channel,
2288
- members: await runtime.getChatMembers(client, chatId, readOptionalNumber(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
2292
+ members: await runtime.getChatMembers(client, chatId, readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
2289
2293
  });
2290
2294
  }
2291
2295
  if (ctx.action === "member-info") {
@@ -2304,13 +2308,13 @@ const feishuPlugin = createChatChannelPlugin({
2304
2308
  ok: true,
2305
2309
  channel: "feishu",
2306
2310
  action: "member-info",
2307
- ...await runtime.getChatMembers(client, chatId, readOptionalNumber(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
2311
+ ...await runtime.getChatMembers(client, chatId, readOptionalPositiveInteger(ctx.params, ["pageSize", "page_size"]), readFirstString(ctx.params, ["pageToken", "page_token"]), resolveFeishuMemberIdType(ctx.params))
2308
2312
  });
2309
2313
  }
2310
2314
  if (ctx.action === "channel-list") {
2311
2315
  const runtime = await loadFeishuChannelRuntime();
2312
2316
  const query = readFirstString(ctx.params, ["query"]);
2313
- const limit = readOptionalNumber(ctx.params, ["limit"]);
2317
+ const limit = readOptionalPositiveInteger(ctx.params, ["limit"]);
2314
2318
  const scope = readFirstString(ctx.params, ["scope", "kind"]) ?? "all";
2315
2319
  if (scope === "groups" || scope === "group" || scope === "channels" || scope === "channel") return jsonActionResult({
2316
2320
  ok: true,
@@ -2542,7 +2546,7 @@ const feishuPlugin = createChatChannelPlugin({
2542
2546
  })
2543
2547
  }),
2544
2548
  gateway: { startAccount: async (ctx) => {
2545
- const { monitorFeishuProvider } = await import("./monitor-DNYcF9wy.js");
2549
+ const { monitorFeishuProvider } = await import("./monitor-w8w3-7EH.js");
2546
2550
  const account = resolveFeishuRuntimeAccount({
2547
2551
  cfg: ctx.cfg,
2548
2552
  accountId: ctx.accountId
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-DS2vP1nr.js";
1
+ import { t as feishuPlugin } from "./channel-DLfxURF2.js";
2
2
  export { feishuPlugin };
@@ -1,10 +1,10 @@
1
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-DS2vP1nr.js";
3
- import { r as createFeishuClient } from "./client-BnH2fRL2.js";
4
- import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-DwgWWkJi.js";
2
+ import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-DLfxURF2.js";
3
+ import { r as createFeishuClient } from "./client-DcSzLkSX.js";
4
+ import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-Grnpj510.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-jDh7bucI.js";
7
- import { t as probeFeishu } from "./probe-Da81t6a5.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-CKZz15KQ.js";
7
+ import { t as probeFeishu } from "./probe-RvCg70BY.js";
8
8
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
10
10
  import path from "node:path";
@@ -2,6 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
2
  import { createRequire } from "node:module";
3
3
  import * as Lark from "@larksuiteoapi/node-sdk";
4
4
  import { readPluginPackageVersion, resolveAmbientNodeProxyAgent } from "openclaw/plugin-sdk/extension-shared";
5
+ import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
5
6
  //#region extensions/feishu/src/client-timeout.ts
6
7
  /** Default HTTP timeout for Feishu API requests (30 seconds). */
7
8
  const FEISHU_HTTP_TIMEOUT_MS = 3e4;
@@ -15,8 +16,8 @@ function resolveConfiguredHttpTimeoutMs(creds) {
15
16
  if (typeof fromDirectField === "number" && Number.isFinite(fromDirectField) && fromDirectField > 0) return clampTimeout(fromDirectField);
16
17
  const envRaw = process.env[FEISHU_HTTP_TIMEOUT_ENV_VAR];
17
18
  if (envRaw) {
18
- const envValue = Number(envRaw);
19
- if (Number.isFinite(envValue) && envValue > 0) return clampTimeout(envValue);
19
+ const envValue = parseStrictPositiveInteger(envRaw);
20
+ if (envValue !== void 0) return clampTimeout(envValue);
20
21
  }
21
22
  const timeout = creds.config?.httpTimeoutMs;
22
23
  if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) return FEISHU_HTTP_TIMEOUT_MS;
@@ -1,5 +1,5 @@
1
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";
2
- import { r as createFeishuClient } from "./client-BnH2fRL2.js";
2
+ import { r as createFeishuClient } from "./client-DcSzLkSX.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
5
5
  import { Type } from "typebox";
@@ -1,9 +1,9 @@
1
1
  import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
2
- import { l as fetchBotIdentityForMonitor } from "./monitor.state-CxrHFQX2.js";
2
+ import { l as fetchBotIdentityForMonitor } from "./monitor.state-B6SoAUys.js";
3
3
  //#region extensions/feishu/src/monitor.ts
4
4
  let monitorAccountRuntimePromise;
5
5
  async function loadMonitorAccountRuntime() {
6
- monitorAccountRuntimePromise ??= import("./monitor.account-vUWzYlT_.js");
6
+ monitorAccountRuntimePromise ??= import("./monitor.account-tuA8NuVQ.js");
7
7
  return await monitorAccountRuntimePromise;
8
8
  }
9
9
  async function monitorFeishuProvider(opts = {}) {
@@ -2,15 +2,15 @@ import { t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
2
2
  import { i as resolveReceiveIdType } from "./targets-BUjQ1TcA.js";
3
3
  import { t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
4
4
  import { _ as buildFeishuCommentTarget, f as isRecord$1, h as readString, l as encodeQuery, m as parseCommentContentElements, p as normalizeString, s as resolveFeishuRuntimeAccount, u as extractReplyText, v as normalizeCommentFileType } from "./accounts-CXnY5H8g.js";
5
- import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-DS2vP1nr.js";
5
+ import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-DLfxURF2.js";
6
6
  import { c as decodeFeishuCardAction, o as buildFeishuCardActionTextFallback, s as createFeishuCardInteractionEnvelope } from "./send-result-DSTSkRDM.js";
7
7
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
8
- import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-BnH2fRL2.js";
9
- import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-DwgWWkJi.js";
8
+ import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-DcSzLkSX.js";
9
+ import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-Grnpj510.js";
10
10
  import { createReplyPrefixContext, evaluateSupplementalContextVisibility, loadSessionStore, normalizeAgentId as normalizeAgentId$2, resolveChannelContextVisibilityMode, resolveSessionStoreEntry } from "./runtime-api.js";
11
- import { _ as normalizeFeishuExternalKey, a as sendCardFeishu, c as sendStructuredCardFeishu, d as isFeishuBroadcastMention, f as isMentionForwardRequest, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-jDh7bucI.js";
12
- import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-Da81t6a5.js";
13
- import { a as feishuWebhookRateLimiter, c as wsClients, i as botOpenIds, l as fetchBotIdentityForMonitor, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as httpServers, r as botNames, s as recordWebhookStatus, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS } from "./monitor.state-CxrHFQX2.js";
11
+ import { _ as normalizeFeishuExternalKey, a as sendCardFeishu, c as sendStructuredCardFeishu, d as isFeishuBroadcastMention, f as isMentionForwardRequest, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-CKZz15KQ.js";
12
+ import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-RvCg70BY.js";
13
+ import { a as feishuWebhookRateLimiter, c as wsClients, i as botOpenIds, l as fetchBotIdentityForMonitor, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as httpServers, r as botNames, s as recordWebhookStatus, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS } from "./monitor.state-B6SoAUys.js";
14
14
  import { asBoolean, asNullableRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
15
15
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
16
16
  import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
@@ -22,6 +22,7 @@ import os from "node:os";
22
22
  import path from "node:path";
23
23
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
24
24
  import * as Lark from "@larksuiteoapi/node-sdk";
25
+ import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
25
26
  import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
26
27
  import { applyBasicWebhookRequestGuards, resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
27
28
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
@@ -4074,8 +4075,7 @@ function buildCommentSessionKey(params) {
4074
4075
  });
4075
4076
  }
4076
4077
  function parseTimestampMs(value) {
4077
- const parsed = value ? Number.parseInt(value, 10) : NaN;
4078
- return Number.isFinite(parsed) ? parsed : Date.now();
4078
+ return parseStrictNonNegativeInteger(value) ?? Date.now();
4079
4079
  }
4080
4080
  async function handleFeishuCommentEvent(params) {
4081
4081
  const account = resolveFeishuRuntimeAccount({
@@ -1,14 +1,15 @@
1
- import { t as probeFeishu } from "./probe-Da81t6a5.js";
1
+ import { t as probeFeishu } from "./probe-RvCg70BY.js";
2
2
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
3
4
  import { WEBHOOK_ANOMALY_COUNTER_DEFAULTS, WEBHOOK_RATE_LIMIT_DEFAULTS, createFixedWindowRateLimiter, createWebhookAnomalyTracker } from "openclaw/plugin-sdk/webhook-ingress";
4
5
  //#region extensions/feishu/src/monitor.startup.ts
5
6
  const FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS = 3e4;
6
7
  const FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV = "OPENCLAW_FEISHU_STARTUP_PROBE_TIMEOUT_MS";
7
- function resolveStartupProbeTimeoutMs() {
8
- const raw = process.env[FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV];
8
+ function resolveStartupProbeTimeoutMs(env = process.env) {
9
+ const raw = env[FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV];
9
10
  if (raw) {
10
- const parsed = Number(raw);
11
- if (Number.isFinite(parsed) && parsed > 0) return Math.floor(parsed);
11
+ const parsed = parseStrictPositiveInteger(raw);
12
+ if (parsed !== void 0) return parsed;
12
13
  console.warn(`[feishu] ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_ENV}="${raw}" is invalid; using default ${FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS}ms`);
13
14
  }
14
15
  return FEISHU_STARTUP_BOT_INFO_TIMEOUT_DEFAULT_MS;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { r as createFeishuClient } from "./client-BnH2fRL2.js";
2
+ import { r as createFeishuClient } from "./client-DcSzLkSX.js";
3
3
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
4
4
  //#region extensions/feishu/src/async.ts
5
5
  const RACE_TIMEOUT = Symbol("race-timeout");
@@ -2,7 +2,7 @@ import { i as resolveReceiveIdType, r as normalizeFeishuTarget } from "./targets
2
2
  import { c as createFeishuApiError, f as isRecord$1, g as requestFeishuApi, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
3
3
  import { i as toFeishuSendResult, r as resolveFeishuReceiptKind, t as assertFeishuMessageApiSuccess } from "./send-result-DSTSkRDM.js";
4
4
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
5
- import { r as createFeishuClient } from "./client-BnH2fRL2.js";
5
+ import { r as createFeishuClient } from "./client-DcSzLkSX.js";
6
6
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
8
8
  import fs from "node:fs";
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-DS2vP1nr.js";
1
+ import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-DLfxURF2.js";
2
2
  export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
@@ -691,6 +691,10 @@ try {
691
691
  | signal | `AbortSignal` to cancel the polling | AbortSignal | No | - |
692
692
  | onQRCodeReady | Callback when the verification URL is ready. Receives `{ url, expireIn }`. You can render the URL as a QR code for users to scan, or display it as a link | function | Yes | - |
693
693
  | onStatusChange | Callback on polling status changes. Receives `{ status, interval? }`. Status values: `polling`, `slow_down`, `domain_switched` | function | No | - |
694
+ | appPreset | Pre-fill values for the app-creation page. All fields are optional; users can still edit them on the page | AppPreset | No | - |
695
+ | appPreset.avatar | App avatar URL(s). 1-6 URLs supported; the first one is selected by default. Allowed formats: png / jpg / jpeg / webp / gif (gif is sampled to a single frame, not animated) | string \| string[] | No | - |
696
+ | appPreset.name | App name. Supports the `{user}` placeholder (replaced with the scanning user's name) | string | No | - |
697
+ | appPreset.desc | App description. Supports the `{user}` placeholder | string | No | - |
694
698
 
695
699
  #### Return value
696
700
 
@@ -753,6 +753,10 @@ try {
753
753
  | signal | 用于取消轮询的 `AbortSignal` | AbortSignal | 否 | - |
754
754
  | onQRCodeReady | 验证链接就绪时的回调,参数为 `{ url, expireIn }`。可将 URL 渲染为二维码供用户扫码,或直接作为链接展示 | function | 是 | - |
755
755
  | onStatusChange | 轮询状态变化时的回调,参数为 `{ status, interval? }`。status 取值:`polling`、`slow_down`、`domain_switched` | function | 否 | - |
756
+ | appPreset | 预设应用信息(头像、名称、描述)。所有字段都是可选的,用户扫码后仍可在页面手动修改 | AppPreset | 否 | - |
757
+ | appPreset.avatar | 应用头像 URL,支持 1-6 个;传多个时默认选中第一个。支持 png / jpg / jpeg / webp / gif(gif 自动取一帧,不保留动图) | string \| string[] | 否 | - |
758
+ | appPreset.name | 应用名称,支持 `{user}` 占位符(替换为扫码用户名称) | string | 否 | - |
759
+ | appPreset.desc | 应用描述,支持 `{user}` 占位符 | string | 否 | - |
756
760
 
757
761
  #### 返回值
758
762
 
@@ -89750,6 +89750,35 @@ const SDK_NAME = 'node-sdk';
89750
89750
  const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
89751
89751
  const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
89752
89752
  const ENDPOINT = '/oauth/v1/app/registration';
89753
+ const AVATAR_MAX_COUNT = 6;
89754
+ /**
89755
+ * Append `avatar` / `name` / `desc` query params to the QR code URL.
89756
+ * `URLSearchParams` handles URL encoding automatically.
89757
+ */
89758
+ function applyAppPreset(qrCodeUrl, preset) {
89759
+ const { avatar, name, desc } = preset;
89760
+ if (avatar !== undefined) {
89761
+ const avatars = Array.isArray(avatar) ? avatar : [avatar];
89762
+ if (avatars.length === 0) {
89763
+ throw new Error('appPreset.avatar must contain at least 1 URL');
89764
+ }
89765
+ if (avatars.length > AVATAR_MAX_COUNT) {
89766
+ throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
89767
+ }
89768
+ avatars.forEach((url, idx) => {
89769
+ if (typeof url !== 'string' || url === '') {
89770
+ throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
89771
+ }
89772
+ qrCodeUrl.searchParams.append('avatar', url);
89773
+ });
89774
+ }
89775
+ if (name !== undefined) {
89776
+ qrCodeUrl.searchParams.set('name', name);
89777
+ }
89778
+ if (desc !== undefined) {
89779
+ qrCodeUrl.searchParams.set('desc', desc);
89780
+ }
89781
+ }
89753
89782
  function requestRegistration(baseUrl, params) {
89754
89783
  var _a;
89755
89784
  return __awaiter(this, void 0, void 0, function* () {
@@ -89867,13 +89896,16 @@ function startPolling(ctx) {
89867
89896
  function registerApp(options) {
89868
89897
  var _a, _b, _c, _d;
89869
89898
  return __awaiter(this, void 0, void 0, function* () {
89870
- const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
89899
+ const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
89871
89900
  const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
89872
89901
  const beginRes = yield begin(baseUrl);
89873
89902
  const qrCodeUrl = new URL(beginRes.verification_uri_complete);
89874
89903
  qrCodeUrl.searchParams.set('from', 'sdk');
89875
89904
  qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
89876
89905
  qrCodeUrl.searchParams.set('tp', 'sdk');
89906
+ if (appPreset) {
89907
+ applyAppPreset(qrCodeUrl, appPreset);
89908
+ }
89877
89909
  onQRCodeReady({
89878
89910
  url: qrCodeUrl.toString(),
89879
89911
  expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
@@ -89768,6 +89768,35 @@ const SDK_NAME = 'node-sdk';
89768
89768
  const DEFAULT_FEISHU_DOMAIN = 'accounts.feishu.cn';
89769
89769
  const DEFAULT_LARK_DOMAIN = 'accounts.larksuite.com';
89770
89770
  const ENDPOINT = '/oauth/v1/app/registration';
89771
+ const AVATAR_MAX_COUNT = 6;
89772
+ /**
89773
+ * Append `avatar` / `name` / `desc` query params to the QR code URL.
89774
+ * `URLSearchParams` handles URL encoding automatically.
89775
+ */
89776
+ function applyAppPreset(qrCodeUrl, preset) {
89777
+ const { avatar, name, desc } = preset;
89778
+ if (avatar !== undefined) {
89779
+ const avatars = Array.isArray(avatar) ? avatar : [avatar];
89780
+ if (avatars.length === 0) {
89781
+ throw new Error('appPreset.avatar must contain at least 1 URL');
89782
+ }
89783
+ if (avatars.length > AVATAR_MAX_COUNT) {
89784
+ throw new Error(`appPreset.avatar supports at most ${AVATAR_MAX_COUNT} URLs, got ${avatars.length}`);
89785
+ }
89786
+ avatars.forEach((url, idx) => {
89787
+ if (typeof url !== 'string' || url === '') {
89788
+ throw new Error(`appPreset.avatar[${idx}] must be a non-empty string`);
89789
+ }
89790
+ qrCodeUrl.searchParams.append('avatar', url);
89791
+ });
89792
+ }
89793
+ if (name !== undefined) {
89794
+ qrCodeUrl.searchParams.set('name', name);
89795
+ }
89796
+ if (desc !== undefined) {
89797
+ qrCodeUrl.searchParams.set('desc', desc);
89798
+ }
89799
+ }
89771
89800
  function requestRegistration(baseUrl, params) {
89772
89801
  var _a;
89773
89802
  return __awaiter(this, void 0, void 0, function* () {
@@ -89885,13 +89914,16 @@ function startPolling(ctx) {
89885
89914
  function registerApp(options) {
89886
89915
  var _a, _b, _c, _d;
89887
89916
  return __awaiter(this, void 0, void 0, function* () {
89888
- const { domain, source, signal, onQRCodeReady, onStatusChange } = options;
89917
+ const { domain, source, signal, onQRCodeReady, onStatusChange, appPreset } = options;
89889
89918
  const baseUrl = `https://${domain !== null && domain !== void 0 ? domain : DEFAULT_FEISHU_DOMAIN}`;
89890
89919
  const beginRes = yield begin(baseUrl);
89891
89920
  const qrCodeUrl = new URL(beginRes.verification_uri_complete);
89892
89921
  qrCodeUrl.searchParams.set('from', 'sdk');
89893
89922
  qrCodeUrl.searchParams.set('source', source ? `${SDK_NAME}/${source}` : SDK_NAME);
89894
89923
  qrCodeUrl.searchParams.set('tp', 'sdk');
89924
+ if (appPreset) {
89925
+ applyAppPreset(qrCodeUrl, appPreset);
89926
+ }
89895
89927
  onQRCodeReady({
89896
89928
  url: qrCodeUrl.toString(),
89897
89929
  expireIn: (_a = beginRes.expires_in) !== null && _a !== void 0 ? _a : 600,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larksuiteoapi/node-sdk",
3
- "version": "1.65.0",
3
+ "version": "1.66.0",
4
4
  "description": "larksuite open sdk for nodejs",
5
5
  "keywords": [
6
6
  "feishu",
@@ -300741,6 +300741,23 @@ interface StatusChangeInfo {
300741
300741
  status: 'polling' | 'slow_down' | 'domain_switched';
300742
300742
  interval?: number;
300743
300743
  }
300744
+ /**
300745
+ * Pre-fill values shown on the app-creation page after the user scans the QR
300746
+ * code. All fields are optional and the user can still edit them on the page;
300747
+ * the final values are whatever the user submits.
300748
+ */
300749
+ interface AppPreset {
300750
+ /**
300751
+ * App avatar URL(s). Pass a single URL or 1-6 URLs. The first one is the
300752
+ * default selection. Each URL must point to a publicly reachable image
300753
+ * (png / jpg / jpeg / webp / gif).
300754
+ */
300755
+ avatar?: string | string[];
300756
+ /** App name. Supports `{user}` placeholder, replaced with the scanning user's name. */
300757
+ name?: string;
300758
+ /** App description. Supports `{user}` placeholder. */
300759
+ desc?: string;
300760
+ }
300744
300761
  interface RegisterAppOptions {
300745
300762
  domain?: string;
300746
300763
  larkDomain?: string;
@@ -300748,6 +300765,8 @@ interface RegisterAppOptions {
300748
300765
  signal?: AbortSignal;
300749
300766
  onQRCodeReady: (info: QRCodeInfo) => void;
300750
300767
  onStatusChange?: (info: StatusChangeInfo) => void;
300768
+ /** Pre-fill values for the app-creation page. See {@link AppPreset}. */
300769
+ appPreset?: AppPreset;
300751
300770
  }
300752
300771
  interface UserInfo {
300753
300772
  open_id?: string;
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@openclaw/feishu",
3
- "version": "2026.5.27",
3
+ "version": "2026.5.28-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/feishu",
9
- "version": "2026.5.27",
9
+ "version": "2026.5.28-beta.1",
10
10
  "dependencies": {
11
- "@larksuiteoapi/node-sdk": "1.65.0",
11
+ "@larksuiteoapi/node-sdk": "1.66.0",
12
12
  "typebox": "1.1.38",
13
13
  "zod": "4.4.3"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.5.27"
16
+ "openclaw": ">=2026.5.28-beta.1"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -22,9 +22,9 @@
22
22
  }
23
23
  },
24
24
  "node_modules/@larksuiteoapi/node-sdk": {
25
- "version": "1.65.0",
26
- "resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.65.0.tgz",
27
- "integrity": "sha512-SkMeiFvi4mMVGrmBBh50vWPOgAvfbcpdcAW+iryheFFHUmji49aDch/YtxsKGFtzFlL/rseQXFzNFL8+LdQQ5Q==",
25
+ "version": "1.66.0",
26
+ "resolved": "https://registry.npmjs.org/@larksuiteoapi/node-sdk/-/node-sdk-1.66.0.tgz",
27
+ "integrity": "sha512-ueKbbdvmVGVie3KvKbvHZqvDC/gg3M0rRDeyQanQWK+i2bQgiiTpIfpqVWvxuTgprV31yqV7HPMjN6KegWSCfA==",
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
30
  "axios": "~1.13.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/feishu",
3
- "version": "2026.5.27",
3
+ "version": "2026.5.28-beta.1",
4
4
  "description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,12 +8,12 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@larksuiteoapi/node-sdk": "1.65.0",
11
+ "@larksuiteoapi/node-sdk": "1.66.0",
12
12
  "typebox": "1.1.38",
13
13
  "zod": "4.4.3"
14
14
  },
15
15
  "peerDependencies": {
16
- "openclaw": ">=2026.5.27"
16
+ "openclaw": ">=2026.5.28-beta.1"
17
17
  },
18
18
  "peerDependenciesMeta": {
19
19
  "openclaw": {
@@ -44,10 +44,10 @@
44
44
  "minHostVersion": ">=2026.4.25"
45
45
  },
46
46
  "compat": {
47
- "pluginApi": ">=2026.5.27"
47
+ "pluginApi": ">=2026.5.28-beta.1"
48
48
  },
49
49
  "build": {
50
- "openclawVersion": "2026.5.27"
50
+ "openclawVersion": "2026.5.28-beta.1"
51
51
  },
52
52
  "release": {
53
53
  "publishToClawHub": true,