@openclaw/feishu 2026.8.1 → 2026.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/api.js +30 -26
  2. package/dist/{app-registration-BpfUzS9m.js → app-registration-BI99e_JI.js} +12 -9
  3. package/dist/{channel-CnpfeyYb.js → channel-BtM7n79m.js} +46 -33
  4. package/dist/channel-plugin-api.js +1 -1
  5. package/dist/{channel.runtime-BhBg13ML.js → channel.runtime-DmCiCQJE.js} +5 -5
  6. package/dist/{chat-BjgJQ9dk.js → chat-Cbr7P_JH.js} +12 -9
  7. package/dist/{client-DalLmpMf.js → client-vJJyfkxI.js} +2 -1
  8. package/dist/contract-api.js +2 -2
  9. package/dist/{doctor-contract-DpQKxB7B.js → doctor-contract-CQAuBotF.js} +3 -2
  10. package/dist/doctor-contract-api.js +1 -1
  11. package/dist/{json-response-CheljwGr.js → json-response-DXajw_FU.js} +1 -1
  12. package/dist/{monitor.startup-D-gL82OO.js → monitor-BVYpA9SO.js} +62 -2
  13. package/dist/{monitor.account-B6Fv45B2.js → monitor.account-CuOAmGJf.js} +74 -66
  14. package/dist/{probe-CfhhR_0a.js → probe-Cs1s-qSS.js} +3 -3
  15. package/dist/{reply-delivery-result-7Jezz03B.js → reply-delivery-result-BIIeISPG.js} +21 -15
  16. package/dist/{security-audit-D6Fz2h6p.js → security-audit-DKfR4Cv3.js} +1 -1
  17. package/dist/{security-audit-shared-BgpY7AiJ.js → security-audit-shared-CK5rVR-1.js} +2 -1
  18. package/dist/security-contract-api.js +1 -1
  19. package/dist/session-binding-contract-api.js +1 -1
  20. package/dist/setup-api.js +1 -1
  21. package/dist/{subagent-hooks-DOwDqgg7.js → subagent-hooks-BnO3ALWB.js} +1 -1
  22. package/dist/subagent-hooks-api.js +1 -1
  23. package/dist/{thread-bindings-DlDOHuiJ.js → thread-bindings-BiL1wGqK.js} +19 -8
  24. package/node_modules/@larksuiteoapi/node-sdk/node_modules/ws/lib/permessage-deflate.js +3 -1
  25. package/node_modules/@larksuiteoapi/node-sdk/node_modules/ws/package.json +1 -1
  26. package/node_modules/typebox/build/format/email.mjs +1 -1
  27. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
  28. package/node_modules/typebox/package.json +1 -1
  29. package/package.json +5 -5
  30. package/dist/monitor-DRVC2e_W.js +0 -62
@@ -1,16 +1,16 @@
1
1
  import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount } from "./accounts-RwSyseKr.js";
2
2
  import { i as resolveReceiveIdType } from "./targets-BUjQ1TcA.js";
3
- import { A as buildFeishuMediaFallbackText, C as extractMentionTargets, Ct as createFeishuCardInteractionEnvelope, D as parseInteractiveCardContent, E as isFeishuGroupChatType, H as createCommentTypingReactionLifecycle, J as buildFeishuCommentTarget, K as parseCommentContentElements, N as deliverCommentThreadText, O as parsePostContent, Q as resolveFeishuCardTemplate, S as sendStructuredCardFeishu, St as buildFeishuCardActionTextFallback, T as isMentionForwardRequest, U as encodeQuery, W as extractReplyText, Y as normalizeCommentFileType, b as sendCardFeishu, bt as resolveFeishuChatType, c as buildFeishuPresentationFallback, d as resolveFeishuRichReply, dt as hasExplicitFeishuGroupConfig, f as saveMessageResourceFeishu, ft as normalizeFeishuAllowEntry, g as chunkFeishuCardMarkdown, gt as resolveFeishuGroupSenderActivationIngressAccess, h as shouldSuppressFeishuTextForVoiceMedia, ht as resolveFeishuGroupConversationIngressAccess, i as noVisibleFeishuReplyDelivery, j as resolveFeishuIdentityEmoji, mt as resolveFeishuGroupConfig, n as createFeishuReplyDeliveryResult, nt as materializeFeishuPostMarkdownSoftBreaks, p as sendMediaFeishu, pt as resolveFeishuDmIngressAccess, q as requestFeishuApi, r as mergeFeishuReplyDeliveryResults, t as createFeishuPartialReplyDeliveryError, tt as chunkFeishuPostMarkdown, v as getMessageFeishu, vt as resolveFeishuReplyPolicy, w as isFeishuBroadcastMention, wt as decodeFeishuCardAction, x as sendMessageFeishu, y as listFeishuThreadMessages, yt as normalizeFeishuChatType$2 } from "./reply-delivery-result-7Jezz03B.js";
4
- import { a as normalizeFeishuWebhookPath, o as normalizeFeishuExternalKey } from "./doctor-contract-DpQKxB7B.js";
3
+ import { A as buildFeishuMediaFallbackText, C as extractMentionTargets, Ct as createFeishuCardInteractionEnvelope, D as parseInteractiveCardContent, E as isFeishuGroupChatType, H as createCommentTypingReactionLifecycle, J as buildFeishuCommentTarget, K as parseCommentContentElements, N as deliverCommentThreadText, O as parsePostContent, Q as resolveFeishuCardTemplate, S as sendStructuredCardFeishu, St as buildFeishuCardActionTextFallback, T as isMentionForwardRequest, U as encodeQuery, W as extractReplyText, Y as normalizeCommentFileType, b as sendCardFeishu, bt as resolveFeishuChatType, c as buildFeishuPresentationFallback, d as resolveFeishuRichReply, dt as hasExplicitFeishuGroupConfig, f as saveMessageResourceFeishu, ft as normalizeFeishuAllowEntry, g as chunkFeishuCardMarkdown, gt as resolveFeishuGroupSenderActivationIngressAccess, h as shouldSuppressFeishuTextForVoiceMedia, ht as resolveFeishuGroupConversationIngressAccess, i as noVisibleFeishuReplyDelivery, j as resolveFeishuIdentityEmoji, mt as resolveFeishuGroupConfig, n as createFeishuReplyDeliveryResult, nt as materializeFeishuPostMarkdownSoftBreaks, p as sendMediaFeishu, pt as resolveFeishuDmIngressAccess, q as requestFeishuApi, r as mergeFeishuReplyDeliveryResults, t as createFeishuPartialReplyDeliveryError, tt as chunkFeishuPostMarkdown, v as getMessageFeishu, vt as resolveFeishuReplyPolicy, w as isFeishuBroadcastMention, wt as decodeFeishuCardAction, x as sendMessageFeishu, y as listFeishuThreadMessages, yt as normalizeFeishuChatType$2 } from "./reply-delivery-result-BIIeISPG.js";
4
+ import { a as normalizeFeishuWebhookPath, o as normalizeFeishuExternalKey } from "./doctor-contract-CQAuBotF.js";
5
5
  import { o as resolveConfiguredFeishuGroupSessionScope, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
6
- import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-DalLmpMf.js";
6
+ import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-vJJyfkxI.js";
7
7
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
8
- import { r as getChatInfo } from "./chat-BjgJQ9dk.js";
9
- import { t as createFeishuThreadBindingManager } from "./thread-bindings-DlDOHuiJ.js";
8
+ import { r as getChatInfo } from "./chat-Cbr7P_JH.js";
9
+ import { t as createFeishuThreadBindingManager } from "./thread-bindings-BiL1wGqK.js";
10
10
  import { evaluateSupplementalContextVisibility, normalizeAgentId as normalizeAgentId$1, resolveChannelContextVisibilityMode } from "./runtime-api.js";
11
- import { t as readFeishuJsonResponse } from "./json-response-CheljwGr.js";
12
- import { a as waitForAbortableDelay, i as raceWithTimeoutAndAbort } from "./probe-CfhhR_0a.js";
13
- import { t as fetchBotIdentityForMonitor } from "./monitor.startup-D-gL82OO.js";
11
+ import { t as readFeishuJsonResponse } from "./json-response-DXajw_FU.js";
12
+ import { a as waitForAbortableDelay, i as raceWithTimeoutAndAbort } from "./probe-Cs1s-qSS.js";
13
+ import { t as fetchBotIdentityForMonitor } from "./monitor-BVYpA9SO.js";
14
14
  import { resolveAgentConfig } from "openclaw/plugin-sdk/agent-scope-runtime";
15
15
  import { DEFAULT_INGRESS_ADOPTION_STALL_MS, bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, createReplyPrefixContext, formatChannelProgressDraftLineForEntry, isChannelProgressDraftWorkToolName, resolveAgentOutboundIdentity, resolveChannelPreviewStreamMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
16
16
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
@@ -53,7 +53,7 @@ function formatMentionNameForAgentContext(name) {
53
53
  const normalized = Array.from(name, (char) => {
54
54
  return char.charCodeAt(0) < 32 || char === "[" || char === "]" ? " " : char;
55
55
  }).join("").replace(/\s+/g, " ").trim();
56
- const bounded = normalized.length > MAX_MENTION_CONTEXT_NAME_LENGTH ? `${truncateUtf16Safe(normalized, MAX_MENTION_CONTEXT_NAME_LENGTH - 3)}...` : normalized;
56
+ const bounded = normalized.length > MAX_MENTION_CONTEXT_NAME_LENGTH ? `${truncateUtf16Safe(normalized, 77)}...` : normalized;
57
57
  return JSON.stringify(bounded || "unknown");
58
58
  }
59
59
  function buildFeishuAgentBody(params) {
@@ -290,9 +290,7 @@ function resolveFeishuGroupSession(params) {
290
290
  senderOpenId
291
291
  });
292
292
  break;
293
- default:
294
- peerId = chatId;
295
- break;
293
+ default: peerId = chatId;
296
294
  }
297
295
  return {
298
296
  peerId,
@@ -541,7 +539,7 @@ async function resolveFeishuMediaList(params) {
541
539
  const feishuGroupNameCache = /* @__PURE__ */ new Map();
542
540
  //#endregion
543
541
  //#region extensions/feishu/src/bot-group-name.ts
544
- const GROUP_NAME_CACHE_TTL_MS = 1800 * 1e3;
542
+ const GROUP_NAME_CACHE_TTL_MS = 18e5;
545
543
  const GROUP_NAME_CACHE_MAX_SIZE = 500;
546
544
  function evictGroupNameCache() {
547
545
  const now = asDateTimestampMs(Date.now());
@@ -583,7 +581,8 @@ async function resolveGroupName(params) {
583
581
  }
584
582
  let resolvedName;
585
583
  try {
586
- const name = (await getChatInfo(createFeishuClient(account), chatId))?.name?.trim();
584
+ const client = createFeishuClient(account);
585
+ const name = (await getChatInfo(client, chatId))?.name?.trim();
587
586
  if (name) {
588
587
  setCacheEntry(cacheKey, name);
589
588
  resolvedName = name;
@@ -597,11 +596,11 @@ async function resolveGroupName(params) {
597
596
  }
598
597
  //#endregion
599
598
  //#region extensions/feishu/src/bot-name.ts
600
- const POSITIVE_TTL_MS = 10 * 6e4;
599
+ const POSITIVE_TTL_MS = 6e5;
601
600
  const NEGATIVE_TTL_MS = 6e4;
602
601
  const MAX_CACHE_ENTRIES = 5e3;
603
602
  const BREAKER_FAILURE_THRESHOLD = 10;
604
- const BREAKER_OPEN_MS = 60 * 6e4;
603
+ const BREAKER_OPEN_MS = 36e5;
605
604
  const PERMISSION_BACKOFF_MS = 6e4;
606
605
  const REQUEST_TIMEOUT_MS = 1500;
607
606
  const cache = /* @__PURE__ */ new Map();
@@ -739,8 +738,8 @@ async function resolveFeishuBotName(params) {
739
738
  const IGNORED_PERMISSION_SCOPE_TOKENS = ["contact:contact.base:readonly"];
740
739
  const FEISHU_SCOPE_CORRECTIONS = { "contact:contact.base:readonly": "contact:user.base:readonly" };
741
740
  const FEISHU_USER_LOOKUP_UNAUTHORIZED_CODE = 41050;
742
- const SENDER_NAME_TTL_MS = 600 * 1e3;
743
- const SENDER_NAME_NEGATIVE_TTL_MS = 1800 * 1e3;
741
+ const SENDER_NAME_TTL_MS = 6e5;
742
+ const SENDER_NAME_NEGATIVE_TTL_MS = 18e5;
744
743
  const SENDER_NAME_CACHE_MAX_SIZE = 500;
745
744
  const senderNameCache = /* @__PURE__ */ new Map();
746
745
  function correctFeishuScopeInUrl(url) {
@@ -841,7 +840,7 @@ async function resolveFeishuSenderName(params) {
841
840
  //#endregion
842
841
  //#region extensions/feishu/src/dedup-state.ts
843
842
  const DEDUPE_NAMESPACE_PREFIX = "feishu.dedup";
844
- const DEDUP_TTL_MS = 1440 * 60 * 1e3;
843
+ const DEDUP_TTL_MS = 864e5;
845
844
  const MEMORY_MAX_SIZE = 1e3;
846
845
  const STORE_MAX_ENTRIES = 1e4;
847
846
  function createFeishuDedupeGuard() {
@@ -1779,7 +1778,7 @@ function mergeStreamingFinalText(previousText, nextText, appendError) {
1779
1778
  }
1780
1779
  /** Maximum age (ms) for a message to receive a typing indicator reaction.
1781
1780
  * Messages older than this are likely replays after context compaction (#30418). */
1782
- const TYPING_INDICATOR_MAX_AGE_MS = 2 * 6e4;
1781
+ const TYPING_INDICATOR_MAX_AGE_MS = 12e4;
1783
1782
  const MS_EPOCH_MIN = 0xe8d4a51000;
1784
1783
  const STREAMING_START_FAILURE_BACKOFF_MS = 6e4;
1785
1784
  const NO_VISIBLE_REPLY_FALLBACK_TEXT = "⚠️ This reply completed without visible content. The turn may have been interrupted; please retry or ask me to recover from recent context.";
@@ -2413,7 +2412,8 @@ function createFeishuReplyDispatcher(params) {
2413
2412
  ...mediaPartial ? [mediaPartial] : []
2414
2413
  ], fallbackPartial?.visibleReplySent === true ? fallbackPartial.content : finalized.visibleReplySent === true ? finalized.content : paramsLocal.content);
2415
2414
  const mediaCause = mediaPartial && paramsLocal.error instanceof Error ? paramsLocal.error.cause ?? paramsLocal.error : paramsLocal.error;
2416
- throw createFeishuPartialReplyDeliveryError(finalizationError ? new AggregateError([mediaCause, finalizationError instanceof Error ? finalizationError.cause ?? finalizationError : finalizationError], "Feishu reply delivery and streaming finalization failed") : mediaCause, accepted);
2415
+ const cause = finalizationError ? new AggregateError([mediaCause, finalizationError instanceof Error ? finalizationError.cause ?? finalizationError : finalizationError], "Feishu reply delivery and streaming finalization failed") : mediaCause;
2416
+ throw createFeishuPartialReplyDeliveryError(cause, accepted);
2417
2417
  };
2418
2418
  const dispatcherOptions = {
2419
2419
  responsePrefix,
@@ -2617,7 +2617,8 @@ function createFeishuReplyDispatcher(params) {
2617
2617
  }
2618
2618
  }
2619
2619
  if (hasMedia) await collectMediaDelivery(payload, !ttsTextAlreadyVisible && hasVoiceMedia && hasText ? { fallbackText: text } : void 0);
2620
- const result = mergeFeishuReplyDeliveryResults(deliveredResults, hasVoiceMedia ? deliveredResults.at(-1)?.content ?? text : text);
2620
+ const deliveredContent = hasVoiceMedia ? deliveredResults.at(-1)?.content ?? text : text;
2621
+ const result = mergeFeishuReplyDeliveryResults(deliveredResults, deliveredContent);
2621
2622
  if (priorClosedStreamingSettlement?.error !== void 0) throw createFeishuPartialReplyDeliveryError(isChannelPartialDeliveryError(priorClosedStreamingSettlement.error) && priorClosedStreamingSettlement.error instanceof Error ? priorClosedStreamingSettlement.error.cause ?? priorClosedStreamingSettlement.error : priorClosedStreamingSettlement.error, result);
2622
2623
  return result;
2623
2624
  },
@@ -2683,7 +2684,7 @@ function getFeishuSyntheticDirectPreDispatchTarget(event) {
2683
2684
  //#endregion
2684
2685
  //#region extensions/feishu/src/bot.ts
2685
2686
  const permissionErrorNotifiedAt = /* @__PURE__ */ new Map();
2686
- const PERMISSION_ERROR_COOLDOWN_MS = 300 * 1e3;
2687
+ const PERMISSION_ERROR_COOLDOWN_MS = 3e5;
2687
2688
  function shouldSendNoVisibleReplyFallback(dispatchResult) {
2688
2689
  const emptyEligibleDispatch = dispatchResult.noVisibleReplyFallbackEligible === true && dispatchResult.settledReceipt?.anyVisibleDelivered !== true;
2689
2690
  const finalFailedBeforeSend = (dispatchResult.settledReceipt?.counts.final.failedBeforeSend ?? 0) > 0;
@@ -2891,32 +2892,34 @@ async function handleFeishuMessage(params) {
2891
2892
  }
2892
2893
  }
2893
2894
  let permissionErrorForAgent;
2894
- if (feishuCfg?.resolveSenderNames ?? true) if (ctx.senderType === "bot") {
2895
- const senderName = await resolveFeishuBotName({
2896
- account,
2897
- openId: ctx.senderOpenId,
2898
- log
2899
- });
2900
- if (senderName) ctx = {
2901
- ...ctx,
2902
- senderName
2903
- };
2904
- } else {
2905
- const senderResult = await resolveFeishuSenderName({
2906
- account,
2907
- senderId: ctx.senderOpenId,
2908
- log
2909
- });
2910
- if (senderResult.name) ctx = {
2911
- ...ctx,
2912
- senderName: senderResult.name
2913
- };
2914
- if (senderResult.permissionError) {
2915
- const appKey = account.appId ?? "default";
2916
- const now = Date.now();
2917
- if (now - (permissionErrorNotifiedAt.get(appKey) ?? 0) > PERMISSION_ERROR_COOLDOWN_MS) {
2918
- permissionErrorNotifiedAt.set(appKey, now);
2919
- permissionErrorForAgent = senderResult.permissionError;
2895
+ if (feishuCfg?.resolveSenderNames ?? true) {
2896
+ if (ctx.senderType === "bot") {
2897
+ const senderName = await resolveFeishuBotName({
2898
+ account,
2899
+ openId: ctx.senderOpenId,
2900
+ log
2901
+ });
2902
+ if (senderName) ctx = {
2903
+ ...ctx,
2904
+ senderName
2905
+ };
2906
+ } else {
2907
+ const senderResult = await resolveFeishuSenderName({
2908
+ account,
2909
+ senderId: ctx.senderOpenId,
2910
+ log
2911
+ });
2912
+ if (senderResult.name) ctx = {
2913
+ ...ctx,
2914
+ senderName: senderResult.name
2915
+ };
2916
+ if (senderResult.permissionError) {
2917
+ const appKey = account.appId ?? "default";
2918
+ const now = Date.now();
2919
+ if (now - (permissionErrorNotifiedAt.get(appKey) ?? 0) > PERMISSION_ERROR_COOLDOWN_MS) {
2920
+ permissionErrorNotifiedAt.set(appKey, now);
2921
+ permissionErrorForAgent = senderResult.permissionError;
2922
+ }
2920
2923
  }
2921
2924
  }
2922
2925
  }
@@ -3987,8 +3990,8 @@ function createApprovalCard(params) {
3987
3990
  }
3988
3991
  //#endregion
3989
3992
  //#region extensions/feishu/src/card-action.ts
3990
- const FEISHU_APPROVAL_CARD_TTL_MS = 5 * 6e4;
3991
- const FEISHU_CARD_ACTION_TOKEN_TTL_MS = 15 * 6e4;
3993
+ const FEISHU_APPROVAL_CARD_TTL_MS = 3e5;
3994
+ const FEISHU_CARD_ACTION_TOKEN_TTL_MS = 9e5;
3992
3995
  function pruneProcessedCardActionTokens(now) {
3993
3996
  const validNow = asDateTimestampMs(now);
3994
3997
  if (validNow === void 0) {
@@ -4080,7 +4083,7 @@ async function dispatchSyntheticCommand(params) {
4080
4083
  });
4081
4084
  }
4082
4085
  const resolvedChatTypeCache = resolvedCardActionChatTypes;
4083
- const CHAT_TYPE_CACHE_TTL_MS = 30 * 6e4;
4086
+ const CHAT_TYPE_CACHE_TTL_MS = 18e5;
4084
4087
  const CHAT_TYPE_CACHE_MAX_SIZE = 5e3;
4085
4088
  function pruneChatTypeCache(now) {
4086
4089
  const validNow = asDateTimestampMs(now);
@@ -4335,7 +4338,8 @@ function inspectFeishuIngressEnvelope(rawEnvelope, encryptKey, allowInvalidLane
4335
4338
  if (!eventId) throw new FeishuIngressPermanentError("invalid-event", `Feishu ${eventType} envelope is missing header.event_id.`);
4336
4339
  const event = nestedEvent ?? envelope;
4337
4340
  if (eventType === "im.message.receive_v1") {
4338
- const chatId = normalizeNullableString((isRecord$1(event.message) ? event.message : null)?.chat_id);
4341
+ const message = isRecord$1(event.message) ? event.message : null;
4342
+ const chatId = normalizeNullableString(message?.chat_id);
4339
4343
  if (!chatId) {
4340
4344
  if (allowInvalidLane) return {
4341
4345
  eventId,
@@ -4612,7 +4616,7 @@ const FEISHU_WEBHOOK_RATE_LIMIT_FALLBACK_DEFAULTS = {
4612
4616
  };
4613
4617
  const FEISHU_WEBHOOK_ANOMALY_FALLBACK_DEFAULTS = {
4614
4618
  maxTrackedKeys: 4096,
4615
- ttlMs: 360 * 6e4,
4619
+ ttlMs: 216e5,
4616
4620
  logEvery: 25
4617
4621
  };
4618
4622
  function coercePositiveInt(value, fallback) {
@@ -4643,7 +4647,7 @@ const httpServers = /* @__PURE__ */ new Map();
4643
4647
  const botOpenIds = /* @__PURE__ */ new Map();
4644
4648
  const botNames = /* @__PURE__ */ new Map();
4645
4649
  const botIdentityRevisions = /* @__PURE__ */ new Map();
4646
- const FEISHU_WEBHOOK_MAX_BODY_BYTES = 64 * 1024;
4650
+ const FEISHU_WEBHOOK_MAX_BODY_BYTES = 65536;
4647
4651
  const FEISHU_WEBHOOK_BODY_TIMEOUT_MS = 5e3;
4648
4652
  const FEISHU_HTTP_SERVER_CLOSE_TIMEOUT_MS = 5e3;
4649
4653
  const feishuWebhookRateLimitDefaults = resolveFeishuWebhookRateLimitDefaults(WEBHOOK_RATE_LIMIT_DEFAULTS);
@@ -4791,7 +4795,7 @@ function startBotIdentityRecovery(params) {
4791
4795
  }
4792
4796
  //#endregion
4793
4797
  //#region extensions/feishu/src/card-ux-launcher.ts
4794
- const FEISHU_QUICK_ACTION_CARD_TTL_MS = 10 * 6e4;
4798
+ const FEISHU_QUICK_ACTION_CARD_TTL_MS = 6e5;
4795
4799
  const QUICK_ACTION_MENU_KEYS = /* @__PURE__ */ new Set([
4796
4800
  "quick-actions",
4797
4801
  "quick_actions",
@@ -5013,10 +5017,11 @@ function createFeishuCommentReplyDispatcher(params) {
5013
5017
  channel: "feishu",
5014
5018
  accountId: params.accountId
5015
5019
  });
5016
- const client = createFeishuClient(resolveFeishuRuntimeAccount({
5020
+ const account = resolveFeishuRuntimeAccount({
5017
5021
  cfg: params.cfg,
5018
5022
  accountId: params.accountId
5019
- }));
5023
+ });
5024
+ const client = createFeishuClient(account);
5020
5025
  const textChunkLimit = core.channel.text.resolveTextChunkLimit(params.cfg, "feishu", params.accountId, { fallbackLimit: 4e3 });
5021
5026
  const chunkMode = core.channel.text.resolveChunkMode(params.cfg, "feishu", params.accountId);
5022
5027
  const typingReaction = createCommentTypingReactionLifecycle({
@@ -5964,7 +5969,8 @@ async function handleFeishuCommentEvent(params) {
5964
5969
  })
5965
5970
  }
5966
5971
  });
5967
- const counts = resolveInboundReplyDispatchCounts(turnResult.dispatched ? turnResult.dispatchResult : void 0);
5972
+ const dispatchResult = turnResult.dispatched ? turnResult.dispatchResult : void 0;
5973
+ const counts = resolveInboundReplyDispatchCounts(dispatchResult);
5968
5974
  log(`feishu[${account.accountId}]: drive comment dispatch complete (replies=${counts.final}, session=${commentSessionKey})`);
5969
5975
  } finally {
5970
5976
  cleanupTypingReaction();
@@ -5989,7 +5995,7 @@ async function handleFeishuCommentEvent(params) {
5989
5995
  * resolves) keeps later same-chat messages in `queued` state until the
5990
5996
  * gateway is restarted. See #70133.
5991
5997
  */
5992
- const DEFAULT_TASK_TIMEOUT_MS = 300 * 1e3;
5998
+ const DEFAULT_TASK_TIMEOUT_MS = 3e5;
5993
5999
  function createSequentialQueue(options = {}) {
5994
6000
  const queues = /* @__PURE__ */ new Map();
5995
6001
  const taskTimeoutMs = options.taskTimeoutMs ?? DEFAULT_TASK_TIMEOUT_MS;
@@ -6397,7 +6403,8 @@ function isFeishuWebhookSignatureValid(params) {
6397
6403
  const nonce = Array.isArray(nonceHeader) ? nonceHeader[0] : nonceHeader;
6398
6404
  const signature = Array.isArray(signatureHeader) ? signatureHeader[0] : signatureHeader;
6399
6405
  if (!timestamp || !nonce || !signature) return false;
6400
- return safeEqualSecret(crypto.createHash("sha256").update(timestamp + nonce + encryptKey + params.rawBody).digest("hex"), signature);
6406
+ const computedSignature = crypto.createHash("sha256").update(timestamp + nonce + encryptKey + params.rawBody).digest("hex");
6407
+ return safeEqualSecret(computedSignature, signature);
6401
6408
  }
6402
6409
  function respondText(res, statusCode, body) {
6403
6410
  res.statusCode = statusCode;
@@ -6599,16 +6606,17 @@ async function monitorWebhook({ account, accountId, runtime, abortSignal, eventD
6599
6606
  });
6600
6607
  }
6601
6608
  });
6609
+ const rateLimitKey = buildFeishuWebhookRateLimitKey({
6610
+ accountId,
6611
+ path,
6612
+ clientIp: resolveRequestClientIp(req)
6613
+ });
6602
6614
  if (!applyBasicWebhookRequestGuards({
6603
6615
  req,
6604
6616
  res,
6605
6617
  allowMethods: ["POST"],
6606
6618
  rateLimiter: feishuWebhookRateLimiter,
6607
- rateLimitKey: buildFeishuWebhookRateLimitKey({
6608
- accountId,
6609
- path,
6610
- clientIp: resolveRequestClientIp(req)
6611
- }),
6619
+ rateLimitKey,
6612
6620
  nowMs: Date.now(),
6613
6621
  requireJsonContentType: true
6614
6622
  })) return;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { r as createFeishuClient } from "./client-DalLmpMf.js";
2
+ import { r as createFeishuClient } from "./client-vJJyfkxI.js";
3
3
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
4
4
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { createHash } from "node:crypto";
@@ -74,8 +74,8 @@ var probe_exports = /* @__PURE__ */ __exportAll({
74
74
  * Successful bot info is effectively static, while failures are cached briefly
75
75
  * to avoid hammering the API during transient outages. */
76
76
  const probeCache = /* @__PURE__ */ new Map();
77
- const PROBE_SUCCESS_TTL_MS = 600 * 1e3;
78
- const PROBE_ERROR_TTL_MS = 60 * 1e3;
77
+ const PROBE_SUCCESS_TTL_MS = 6e5;
78
+ const PROBE_ERROR_TTL_MS = 6e4;
79
79
  const MAX_PROBE_CACHE_SIZE = 64;
80
80
  const FEISHU_PROBE_REQUEST_TIMEOUT_MS = 1e4;
81
81
  function buildProbeCacheKey(creds) {
@@ -1,7 +1,7 @@
1
1
  import { a as resolveDefaultFeishuAccountId, i as listFeishuAccountIds, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-RwSyseKr.js";
2
2
  import { i as resolveReceiveIdType, r as normalizeFeishuTarget, t as detectIdType } from "./targets-BUjQ1TcA.js";
3
- import { o as normalizeFeishuExternalKey } from "./doctor-contract-DpQKxB7B.js";
4
- import { r as createFeishuClient } from "./client-DalLmpMf.js";
3
+ import { o as normalizeFeishuExternalKey } from "./doctor-contract-CQAuBotF.js";
4
+ import { r as createFeishuClient } from "./client-vJJyfkxI.js";
5
5
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
6
6
  import { normalizeAccountId, normalizeOptionalAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
7
7
  import { compileAllowlist, resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
@@ -462,7 +462,7 @@ function canEnumerateAllFeishuPeers(account) {
462
462
  }
463
463
  //#endregion
464
464
  //#region extensions/feishu/src/markdown.ts
465
- const FEISHU_POST_MAX_BYTES = 30 * 1024;
465
+ const FEISHU_POST_MAX_BYTES = 30720;
466
466
  /** One parser contract for Feishu message and document Markdown decisions. */
467
467
  function parseFeishuMarkdown(text) {
468
468
  return fromMarkdown(text, {
@@ -834,7 +834,7 @@ async function requestFeishuApi(request, errorPrefix, options = {}) {
834
834
  return result;
835
835
  }, {
836
836
  attempts: 3,
837
- minDelayMs: options.retryDelayMs ?? FEISHU_SEND_RETRY_BASE_MS,
837
+ minDelayMs: FEISHU_SEND_RETRY_BASE_MS,
838
838
  shouldRetry: (error) => getFeishuSendRateLimitCode(error) !== void 0
839
839
  });
840
840
  } catch (error) {
@@ -847,7 +847,8 @@ function readDocsLinkUrl(element) {
847
847
  }
848
848
  function readMentionUserId(element) {
849
849
  const mention = isRecord(element.mention) ? element.mention : void 0;
850
- return normalizeOptionalString((isRecord(element.person) ? element.person : void 0)?.user_id) || normalizeOptionalString(mention?.user_id) || normalizeOptionalString(mention?.open_id) || normalizeOptionalString(element.mention_user) || normalizeOptionalString(element.user_id) || void 0;
850
+ const person = isRecord(element.person) ? element.person : void 0;
851
+ return normalizeOptionalString(person?.user_id) || normalizeOptionalString(mention?.user_id) || normalizeOptionalString(mention?.open_id) || normalizeOptionalString(element.mention_user) || normalizeOptionalString(element.user_id) || void 0;
851
852
  }
852
853
  function readMentionDisplayText(element, userId) {
853
854
  const mention = isRecord(element.mention) ? element.mention : void 0;
@@ -1965,10 +1966,11 @@ function resolveFeishuSendTarget(params) {
1965
1966
  const client = createFeishuClient(account);
1966
1967
  const receiveId = normalizeFeishuTarget(target);
1967
1968
  if (!receiveId) throw new Error(`Invalid Feishu target: ${params.to}`);
1969
+ const withoutProviderPrefix = target.replace(/^(feishu|lark):/i, "");
1968
1970
  return {
1969
1971
  client,
1970
1972
  receiveId,
1971
- receiveIdType: resolveReceiveIdType(target.replace(/^(feishu|lark):/i, ""))
1973
+ receiveIdType: resolveReceiveIdType(withoutProviderPrefix)
1972
1974
  };
1973
1975
  }
1974
1976
  //#endregion
@@ -2035,7 +2037,8 @@ function renderElement(element, attachments, mentionedOpenIds, renderMediaPlaceh
2035
2037
  case "a": return renderLinkElement(element);
2036
2038
  case "at":
2037
2039
  {
2038
- const normalizedMention = normalizeFeishuExternalKey(toStringOrEmpty(element.open_id) || toStringOrEmpty(element.user_id));
2040
+ const mentioned = toStringOrEmpty(element.open_id) || toStringOrEmpty(element.user_id);
2041
+ const normalizedMention = normalizeFeishuExternalKey(mentioned);
2039
2042
  if (normalizedMention) mentionedOpenIds.push(normalizedMention);
2040
2043
  }
2041
2044
  return renderMentionElement(element);
@@ -2383,7 +2386,8 @@ function parseFeishuMessageContent(rawContent, msgType, messageId) {
2383
2386
  try {
2384
2387
  parsed = JSON.parse(rawContent);
2385
2388
  } catch {
2386
- logVerbose(`feishu message content parse failed for ${msgType} message${messageId ? ` (id: ${messageId})` : ""}`);
2389
+ const safeId = messageId ? ` (id: ${messageId})` : "";
2390
+ logVerbose(`feishu message content parse failed for ${msgType} message${safeId}`);
2387
2391
  return rawContent;
2388
2392
  }
2389
2393
  if (msgType === "text") {
@@ -2574,10 +2578,11 @@ async function editMessageFeishu(params) {
2574
2578
  contentType: "interactive"
2575
2579
  };
2576
2580
  }
2577
- const content = buildFeishuPostMessageContent({ messageText: materializeFeishuPostMarkdownSoftBreaks(convertMarkdownTables(text, resolveMarkdownTableMode({
2581
+ const tableMode = resolveMarkdownTableMode({
2578
2582
  cfg,
2579
2583
  channel: "feishu"
2580
- }))) });
2584
+ });
2585
+ const content = buildFeishuPostMessageContent({ messageText: materializeFeishuPostMarkdownSoftBreaks(convertMarkdownTables(text, tableMode)) });
2581
2586
  assertFeishuPostWithinEnvelope(content, "Feishu message edit");
2582
2587
  const response = await client.im.message.update({
2583
2588
  path: { message_id: messageId },
@@ -2653,8 +2658,8 @@ async function sendStructuredCardFeishu(params) {
2653
2658
  //#endregion
2654
2659
  //#region extensions/feishu/src/media.ts
2655
2660
  const FEISHU_MEDIA_HTTP_TIMEOUT_MS = 12e4;
2656
- const FEISHU_MAX_FILE_UPLOAD_BYTES = 30 * 1024 * 1024;
2657
- const FEISHU_MAX_IMAGE_UPLOAD_BYTES = 10 * 1024 * 1024;
2661
+ const FEISHU_MAX_FILE_UPLOAD_BYTES = 31457280;
2662
+ const FEISHU_MAX_IMAGE_UPLOAD_BYTES = 10485760;
2658
2663
  const FEISHU_VOICE_FILE_NAME = "voice.ogg";
2659
2664
  const FEISHU_VOICE_SAMPLE_RATE_HZ = 48e3;
2660
2665
  const FEISHU_VOICE_BITRATE = "64k";
@@ -2775,7 +2780,7 @@ function extractFeishuDownloadMetadata(response) {
2775
2780
  };
2776
2781
  }
2777
2782
  function mediaLimitError(maxBytes) {
2778
- return /* @__PURE__ */ new Error(`Media exceeds ${Math.round(maxBytes / (1024 * 1024))}MB limit`);
2783
+ return /* @__PURE__ */ new Error(`Media exceeds ${Math.round(maxBytes / 1048576)}MB limit`);
2779
2784
  }
2780
2785
  async function saveFeishuResponseMedia(params) {
2781
2786
  const { response, maxBytes, contentType, fileName } = params;
@@ -3120,6 +3125,7 @@ async function probeMediaDurationMs(params) {
3120
3125
  }, async (workspace) => {
3121
3126
  const ext = normalizeLowercaseStringOrEmpty(path.extname(params.fileName));
3122
3127
  const inferredExt = ext && ext.length <= 12 ? ext : mediaKindFromMime(params.contentType) === "video" ? ".mp4" : ".ogg";
3128
+ const inputPath = await workspace.write(`input${inferredExt}`, params.buffer);
3123
3129
  const stdout = await runFfprobe([
3124
3130
  "-v",
3125
3131
  "error",
@@ -3127,7 +3133,7 @@ async function probeMediaDurationMs(params) {
3127
3133
  "format=duration",
3128
3134
  "-of",
3129
3135
  "csv=p=0",
3130
- await workspace.write(`input${inferredExt}`, params.buffer)
3136
+ inputPath
3131
3137
  ], { timeoutMs: 5e3 });
3132
3138
  const seconds = Number.parseFloat(stdout.trim());
3133
3139
  if (!Number.isFinite(seconds) || seconds <= 0) return;
@@ -3267,7 +3273,7 @@ async function sendMediaFeishu(params) {
3267
3273
  }
3268
3274
  //#endregion
3269
3275
  //#region extensions/feishu/src/presentation-card.ts
3270
- const FEISHU_CARD_MAX_BYTES = 30 * 1024;
3276
+ const FEISHU_CARD_MAX_BYTES = 30720;
3271
3277
  const FEISHU_CARD_MAX_ELEMENTS = 200;
3272
3278
  function resolveFeishuRichReply(payload) {
3273
3279
  const interactive = normalizeLegacyInteractiveReply(payload.interactive);
@@ -1,4 +1,4 @@
1
- import "./security-audit-shared-BgpY7AiJ.js";
1
+ import "./security-audit-shared-CK5rVR-1.js";
2
2
  //#region extensions/feishu/src/message-action-contract.ts
3
3
  const FEISHU_NATIVE_CHAT_TARGET_ALIASES = [
4
4
  "chatId",
@@ -2,7 +2,8 @@ import { asOptionalRecord, hasNonEmptyString } from "openclaw/plugin-sdk/string-
2
2
  import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
3
3
  //#region extensions/feishu/src/security-audit-shared.ts
4
4
  function isFeishuDocToolEnabled(cfg) {
5
- const feishu = asOptionalRecord(asOptionalRecord(cfg.channels)?.feishu);
5
+ const channels = asOptionalRecord(cfg.channels);
6
+ const feishu = asOptionalRecord(channels?.feishu);
6
7
  if (!feishu || feishu.enabled === false) return false;
7
8
  const baseTools = asOptionalRecord(feishu.tools);
8
9
  const baseDocEnabled = baseTools?.doc !== false;
@@ -1,2 +1,2 @@
1
- import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BgpY7AiJ.js";
1
+ import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-CK5rVR-1.js";
2
2
  export { collectFeishuSecurityAuditFindings };
@@ -1,2 +1,2 @@
1
- import { t as createFeishuThreadBindingManager } from "./thread-bindings-DlDOHuiJ.js";
1
+ import { t as createFeishuThreadBindingManager } from "./thread-bindings-BiL1wGqK.js";
2
2
  export { createFeishuThreadBindingManager };
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-CnpfeyYb.js";
1
+ import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-BtM7n79m.js";
2
2
  export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
2
  import { r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
3
3
  import { r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
4
- import { n as getFeishuThreadBindingManager } from "./thread-bindings-DlDOHuiJ.js";
4
+ import { n as getFeishuThreadBindingManager } from "./thread-bindings-BiL1wGqK.js";
5
5
  import { normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  //#region extensions/feishu/src/subagent-hooks.ts
7
7
  var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
1
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
2
  //#region extensions/feishu/subagent-hooks-api.ts
3
- const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-DOwDqgg7.js").then((n) => n.r));
3
+ const loadFeishuSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-BnO3ALWB.js").then((n) => n.r));
4
4
  function registerFeishuSubagentHooks(api) {
5
5
  api.on("subagent_delivery_target", async (event) => {
6
6
  const { handleFeishuSubagentDeliveryTarget } = await loadFeishuSubagentHooksModule();
@@ -3,6 +3,7 @@ import { registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBi
3
3
  import { isFutureDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
6
+ import { isPluginOwnedSessionBindingRecord } from "openclaw/plugin-sdk/conversation-binding-runtime";
6
7
  //#region extensions/feishu/src/thread-bindings.ts
7
8
  const FEISHU_THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.feishuThreadBindingsState");
8
9
  let state;
@@ -47,6 +48,7 @@ function toSessionBindingRecord(record, defaults) {
47
48
  boundAt: record.boundAt,
48
49
  expiresAt,
49
50
  metadata: {
51
+ ...record.metadata,
50
52
  agentId: record.agentId,
51
53
  label: record.label,
52
54
  boundBy: record.boundBy,
@@ -98,6 +100,12 @@ function createFeishuThreadBindingManager(params) {
98
100
  const normalizedTargetSessionKey = targetSessionKey.trim();
99
101
  if (!normalizedConversationId || !normalizedTargetSessionKey) return null;
100
102
  const existingLocal = manager.getByConversationId(normalizedConversationId);
103
+ const storedTargetKind = toFeishuTargetKind(targetKind);
104
+ const previous = existingLocal?.targetSessionKey === normalizedTargetSessionKey && existingLocal.targetKind === storedTargetKind ? existingLocal : void 0;
105
+ const targetMetadata = {
106
+ ...previous?.metadata,
107
+ ...metadata
108
+ };
101
109
  const now = Date.now();
102
110
  const record = {
103
111
  accountId,
@@ -105,16 +113,17 @@ function createFeishuThreadBindingManager(params) {
105
113
  parentConversationId: normalizeOptionalString(parentConversationId) ?? existingLocal?.parentConversationId,
106
114
  deliveryTo: typeof metadata?.deliveryTo === "string" && metadata.deliveryTo.trim() ? metadata.deliveryTo.trim() : existingLocal?.deliveryTo,
107
115
  deliveryThreadId: typeof metadata?.deliveryThreadId === "string" && metadata.deliveryThreadId.trim() ? metadata.deliveryThreadId.trim() : existingLocal?.deliveryThreadId,
108
- targetKind: toFeishuTargetKind(targetKind),
116
+ targetKind: storedTargetKind,
109
117
  targetSessionKey: normalizedTargetSessionKey,
110
- agentId: normalizeOptionalString(metadata?.agentId) ?? existingLocal?.agentId ?? resolveSessionAgentIdStrict({
118
+ agentId: normalizeOptionalString(metadata?.agentId) ?? previous?.agentId ?? (isPluginOwnedSessionBindingRecord({ metadata: targetMetadata }) ? void 0 : resolveSessionAgentIdStrict({
111
119
  config: params.cfg,
112
120
  sessionKey: normalizedTargetSessionKey
113
- }),
114
- label: typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() : existingLocal?.label,
115
- boundBy: typeof metadata?.boundBy === "string" && metadata.boundBy.trim() ? metadata.boundBy.trim() : existingLocal?.boundBy,
121
+ })),
122
+ label: normalizeOptionalString(metadata?.label) ?? previous?.label,
123
+ boundBy: normalizeOptionalString(metadata?.boundBy) ?? previous?.boundBy,
116
124
  boundAt: now,
117
- lastActivityAt: now
125
+ lastActivityAt: now,
126
+ metadata: targetMetadata
118
127
  };
119
128
  getState().bindingsByAccountConversation.set(resolveBindingKey({
120
129
  accountId,
@@ -159,8 +168,10 @@ function createFeishuThreadBindingManager(params) {
159
168
  return removed;
160
169
  },
161
170
  stop: () => {
162
- for (const key of getState().bindingsByAccountConversation.keys()) if (key.startsWith(`${accountId}:`)) getState().bindingsByAccountConversation.delete(key);
163
- getState().managersByAccountId.delete(accountId);
171
+ if (getState().managersByAccountId.get(accountId) === manager) {
172
+ for (const key of getState().bindingsByAccountConversation.keys()) if (key.startsWith(`${accountId}:`)) getState().bindingsByAccountConversation.delete(key);
173
+ getState().managersByAccountId.delete(accountId);
174
+ }
164
175
  unregisterSessionBindingAdapter({
165
176
  channel: "feishu",
166
177
  accountId,
@@ -167,7 +167,9 @@ class PerMessageDeflate {
167
167
  (typeof opts.serverMaxWindowBits === 'number' &&
168
168
  opts.serverMaxWindowBits > params.server_max_window_bits))) ||
169
169
  (typeof opts.clientMaxWindowBits === 'number' &&
170
- !params.client_max_window_bits)
170
+ (typeof params.client_max_window_bits === 'number'
171
+ ? opts.clientMaxWindowBits > params.client_max_window_bits
172
+ : !params.client_max_window_bits))
171
173
  ) {
172
174
  return false;
173
175
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ws",
3
- "version": "8.21.1",
3
+ "version": "8.21.3",
4
4
  "description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
5
5
  "keywords": [
6
6
  "HyBi",
@@ -1,4 +1,4 @@
1
- const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\.)*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
1
+ const Email = /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[^"\\]|\\[\x20-\x7e])*")@(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*|\[(?:IPv6:[a-f0-9:]+|(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?:\.(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})\])$/i;
2
2
  /**
3
3
  * Returns true if the value is an Email
4
4
  * @specification https://datatracker.ietf.org/doc/html/rfc5322