@nextclaw/channel-plugin-feishu 0.2.14 → 0.2.16

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 (66) hide show
  1. package/index.ts +2 -2
  2. package/package.json +1 -2
  3. package/src/accounts.test.ts +10 -0
  4. package/src/accounts.ts +12 -12
  5. package/src/bitable.ts +1 -1
  6. package/src/bot.test.ts +1 -1
  7. package/src/bot.ts +2 -2
  8. package/src/card-action.ts +1 -1
  9. package/src/channel.test.ts +1 -1
  10. package/src/channel.ts +3 -3
  11. package/src/chat.ts +1 -1
  12. package/src/config-schema.ts +1 -1
  13. package/src/dedup.ts +1 -1
  14. package/src/directory.test.ts +1 -1
  15. package/src/directory.ts +2 -2
  16. package/src/docx.account-selection.test.ts +1 -1
  17. package/src/docx.ts +1 -1
  18. package/src/drive.ts +1 -1
  19. package/src/dynamic-agent.ts +1 -1
  20. package/src/media.ts +1 -1
  21. package/src/monitor.account.ts +1 -1
  22. package/src/monitor.reaction.test.ts +1 -1
  23. package/src/monitor.startup.test.ts +1 -1
  24. package/src/monitor.startup.ts +1 -1
  25. package/src/monitor.state.ts +1 -1
  26. package/src/monitor.transport.ts +1 -1
  27. package/src/monitor.ts +1 -1
  28. package/src/monitor.webhook.test-helpers.ts +1 -1
  29. package/src/nextclaw-sdk/account-id.ts +31 -0
  30. package/src/nextclaw-sdk/compat.ts +8 -0
  31. package/src/nextclaw-sdk/core-channel.ts +296 -0
  32. package/src/nextclaw-sdk/core-pairing.ts +224 -0
  33. package/src/nextclaw-sdk/core.ts +26 -0
  34. package/src/nextclaw-sdk/dedupe.ts +246 -0
  35. package/src/nextclaw-sdk/feishu.ts +77 -0
  36. package/src/nextclaw-sdk/history.ts +127 -0
  37. package/src/nextclaw-sdk/network-body.ts +245 -0
  38. package/src/nextclaw-sdk/network-fetch.ts +129 -0
  39. package/src/nextclaw-sdk/network-webhook.ts +182 -0
  40. package/src/nextclaw-sdk/network.ts +13 -0
  41. package/src/nextclaw-sdk/runtime-store.ts +26 -0
  42. package/src/nextclaw-sdk/secrets-config.ts +109 -0
  43. package/src/nextclaw-sdk/secrets-core.ts +170 -0
  44. package/src/nextclaw-sdk/secrets-prompt.ts +305 -0
  45. package/src/nextclaw-sdk/secrets.ts +18 -0
  46. package/src/nextclaw-sdk/types.ts +300 -0
  47. package/src/onboarding.status.test.ts +1 -1
  48. package/src/onboarding.ts +2 -2
  49. package/src/outbound.ts +1 -1
  50. package/src/perm.ts +1 -1
  51. package/src/policy.ts +2 -2
  52. package/src/reactions.ts +1 -1
  53. package/src/reply-dispatcher.ts +1 -1
  54. package/src/runtime.ts +2 -2
  55. package/src/secret-input.ts +1 -1
  56. package/src/send-target.test.ts +1 -1
  57. package/src/send-target.ts +1 -1
  58. package/src/send.test.ts +1 -1
  59. package/src/send.ts +1 -1
  60. package/src/streaming-card.ts +1 -1
  61. package/src/tool-account-routing.test.ts +1 -1
  62. package/src/tool-account.ts +1 -1
  63. package/src/tool-factory-test-harness.ts +1 -1
  64. package/src/types.ts +1 -1
  65. package/src/typing.ts +1 -1
  66. package/src/wiki.ts +1 -1
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
2
- import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/feishu";
1
+ import type { OpenClawPluginApi } from "./src/nextclaw-sdk/feishu.js";
2
+ import { emptyPluginConfigSchema } from "./src/nextclaw-sdk/feishu.js";
3
3
  import { registerFeishuBitableTools } from "./src/bitable.js";
4
4
  import { feishuPlugin } from "./src/channel.js";
5
5
  import { registerFeishuChatTools } from "./src/chat.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/channel-plugin-feishu",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "private": false,
5
5
  "description": "NextClaw Feishu/Lark channel plugin with doc/wiki/drive tools.",
6
6
  "type": "module",
@@ -43,7 +43,6 @@
43
43
  "@larksuiteoapi/node-sdk": "^1.59.0",
44
44
  "@sinclair/typebox": "0.34.48",
45
45
  "https-proxy-agent": "^8.0.0",
46
- "openclaw": "2026.3.13",
47
46
  "zod": "^4.3.6"
48
47
  },
49
48
  "scripts": {
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import {
3
+ listFeishuAccountIds,
3
4
  resolveDefaultFeishuAccountId,
4
5
  resolveDefaultFeishuAccountSelection,
5
6
  resolveFeishuAccount,
@@ -56,6 +57,15 @@ function expectUnresolvedEnvSecretRefError(key: string) {
56
57
  }
57
58
 
58
59
  describe("resolveDefaultFeishuAccountId", () => {
60
+ it("falls back safely when channel config is missing", () => {
61
+ expect(listFeishuAccountIds(undefined)).toEqual(["default"]);
62
+ expect(resolveDefaultFeishuAccountId(undefined)).toBe("default");
63
+ expect(resolveDefaultFeishuAccountSelection(undefined)).toEqual({
64
+ accountId: "default",
65
+ source: "mapped-default",
66
+ });
67
+ });
68
+
59
69
  it("prefers channels.feishu.defaultAccount when configured", () => {
60
70
  const cfg = {
61
71
  channels: {
package/src/accounts.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
2
- import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
1
+ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "./nextclaw-sdk/account-id.js";
2
+ import type { ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
3
3
  import { normalizeResolvedSecretInputString, normalizeSecretInputString } from "./secret-input.js";
4
4
  import type {
5
5
  FeishuConfig,
@@ -12,8 +12,8 @@ import type {
12
12
  /**
13
13
  * List all configured account IDs from the accounts field.
14
14
  */
15
- function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
16
- const accounts = (cfg.channels?.feishu as FeishuConfig)?.accounts;
15
+ function listConfiguredAccountIds(cfg?: ClawdbotConfig): string[] {
16
+ const accounts = (cfg?.channels?.feishu as FeishuConfig | undefined)?.accounts;
17
17
  if (!accounts || typeof accounts !== "object") {
18
18
  return [];
19
19
  }
@@ -24,7 +24,7 @@ function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
24
24
  * List all Feishu account IDs.
25
25
  * If no accounts are configured, returns [DEFAULT_ACCOUNT_ID] for backward compatibility.
26
26
  */
27
- export function listFeishuAccountIds(cfg: ClawdbotConfig): string[] {
27
+ export function listFeishuAccountIds(cfg?: ClawdbotConfig): string[] {
28
28
  const ids = listConfiguredAccountIds(cfg);
29
29
  if (ids.length === 0) {
30
30
  // Backward compatibility: no accounts configured, use default
@@ -36,11 +36,11 @@ export function listFeishuAccountIds(cfg: ClawdbotConfig): string[] {
36
36
  /**
37
37
  * Resolve the default account selection and its source.
38
38
  */
39
- export function resolveDefaultFeishuAccountSelection(cfg: ClawdbotConfig): {
39
+ export function resolveDefaultFeishuAccountSelection(cfg?: ClawdbotConfig): {
40
40
  accountId: string;
41
41
  source: FeishuDefaultAccountSelectionSource;
42
42
  } {
43
- const preferredRaw = (cfg.channels?.feishu as FeishuConfig | undefined)?.defaultAccount?.trim();
43
+ const preferredRaw = (cfg?.channels?.feishu as FeishuConfig | undefined)?.defaultAccount?.trim();
44
44
  const preferred = preferredRaw ? normalizeAccountId(preferredRaw) : undefined;
45
45
  if (preferred) {
46
46
  return {
@@ -64,7 +64,7 @@ export function resolveDefaultFeishuAccountSelection(cfg: ClawdbotConfig): {
64
64
  /**
65
65
  * Resolve the default account ID.
66
66
  */
67
- export function resolveDefaultFeishuAccountId(cfg: ClawdbotConfig): string {
67
+ export function resolveDefaultFeishuAccountId(cfg?: ClawdbotConfig): string {
68
68
  return resolveDefaultFeishuAccountSelection(cfg).accountId;
69
69
  }
70
70
 
@@ -72,10 +72,10 @@ export function resolveDefaultFeishuAccountId(cfg: ClawdbotConfig): string {
72
72
  * Get the raw account-specific config.
73
73
  */
74
74
  function resolveAccountConfig(
75
- cfg: ClawdbotConfig,
75
+ cfg: ClawdbotConfig | undefined,
76
76
  accountId: string,
77
77
  ): FeishuAccountConfig | undefined {
78
- const accounts = (cfg.channels?.feishu as FeishuConfig)?.accounts;
78
+ const accounts = (cfg?.channels?.feishu as FeishuConfig | undefined)?.accounts;
79
79
  if (!accounts || typeof accounts !== "object") {
80
80
  return undefined;
81
81
  }
@@ -86,8 +86,8 @@ function resolveAccountConfig(
86
86
  * Merge top-level config with account-specific config.
87
87
  * Account-specific fields override top-level fields.
88
88
  */
89
- function mergeFeishuAccountConfig(cfg: ClawdbotConfig, accountId: string): FeishuConfig {
90
- const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
89
+ function mergeFeishuAccountConfig(cfg: ClawdbotConfig | undefined, accountId: string): FeishuConfig {
90
+ const feishuCfg = cfg?.channels?.feishu as FeishuConfig | undefined;
91
91
 
92
92
  // Extract base config (exclude accounts field to avoid recursion)
93
93
  const { accounts: _ignored, defaultAccount: _ignoredDefaultAccount, ...base } = feishuCfg ?? {};
package/src/bitable.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type * as Lark from "@larksuiteoapi/node-sdk";
2
2
  import { Type } from "@sinclair/typebox";
3
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
3
+ import type { OpenClawPluginApi } from "./nextclaw-sdk/feishu.js";
4
4
  import { listEnabledFeishuAccounts } from "./accounts.js";
5
5
  import { createFeishuToolClient } from "./tool-account.js";
6
6
 
package/src/bot.test.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig, PluginRuntime, RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import { beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { createPluginRuntimeMock } from "../../test-utils/plugin-runtime-mock.js";
4
4
  import type { FeishuMessageEvent } from "./bot.js";
package/src/bot.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig, RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import {
3
3
  buildAgentMediaPayload,
4
4
  buildPendingHistoryContextFromMap,
@@ -12,7 +12,7 @@ import {
12
12
  resolveOpenProviderRuntimeGroupPolicy,
13
13
  resolveDefaultGroupPolicy,
14
14
  warnMissingProviderGroupPolicyFallbackOnce,
15
- } from "openclaw/plugin-sdk/feishu";
15
+ } from "./nextclaw-sdk/feishu.js";
16
16
  import { resolveFeishuAccount } from "./accounts.js";
17
17
  import { createFeishuClient } from "./client.js";
18
18
  import { finalizeFeishuMessageProcessing, tryRecordMessagePersistent } from "./dedup.js";
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig, RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import { resolveFeishuAccount } from "./accounts.js";
3
3
  import { handleFeishuMessage, type FeishuMessageEvent } from "./bot.js";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { OpenClawConfig } from "openclaw/plugin-sdk/feishu";
1
+ import type { OpenClawConfig } from "./nextclaw-sdk/feishu.js";
2
2
  import { describe, expect, it, vi } from "vitest";
3
3
 
4
4
  const probeFeishuMock = vi.hoisted(() => vi.fn());
package/src/channel.ts CHANGED
@@ -2,15 +2,15 @@ import {
2
2
  collectAllowlistProviderRestrictSendersWarnings,
3
3
  formatAllowFromLowercase,
4
4
  mapAllowFromEntries,
5
- } from "openclaw/plugin-sdk/compat";
6
- import type { ChannelMeta, ChannelPlugin, ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
5
+ } from "./nextclaw-sdk/compat.js";
6
+ import type { ChannelMeta, ChannelPlugin, ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
7
7
  import {
8
8
  buildProbeChannelStatusSummary,
9
9
  buildRuntimeAccountStatusSnapshot,
10
10
  createDefaultChannelRuntimeState,
11
11
  DEFAULT_ACCOUNT_ID,
12
12
  PAIRING_APPROVED_MESSAGE,
13
- } from "openclaw/plugin-sdk/feishu";
13
+ } from "./nextclaw-sdk/feishu.js";
14
14
  import {
15
15
  resolveFeishuAccount,
16
16
  resolveFeishuCredentials,
package/src/chat.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type * as Lark from "@larksuiteoapi/node-sdk";
2
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
2
+ import type { OpenClawPluginApi } from "./nextclaw-sdk/feishu.js";
3
3
  import { listEnabledFeishuAccounts } from "./accounts.js";
4
4
  import { FeishuChatSchema, type FeishuChatParams } from "./chat-schema.js";
5
5
  import { createFeishuClient } from "./client.js";
@@ -1,4 +1,4 @@
1
- import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
1
+ import { normalizeAccountId } from "./nextclaw-sdk/account-id.js";
2
2
  import { z } from "zod";
3
3
  export { z };
4
4
  import { buildSecretInputSchema, hasConfiguredSecretInput } from "./secret-input.js";
package/src/dedup.ts CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  createDedupeCache,
5
5
  createPersistentDedupe,
6
6
  readJsonFileWithFallback,
7
- } from "openclaw/plugin-sdk/feishu";
7
+ } from "./nextclaw-sdk/feishu.js";
8
8
 
9
9
  // Persistent TTL: 24 hours — survives restarts & WebSocket reconnects.
10
10
  const DEDUP_TTL_MS = 24 * 60 * 60 * 1000;
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
2
2
  import { describe, expect, it, vi } from "vitest";
3
3
 
4
4
  vi.mock("./accounts.js", () => ({
package/src/directory.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  listDirectoryGroupEntriesFromMapKeysAndAllowFrom,
3
3
  listDirectoryUserEntriesFromAllowFromAndMapKeys,
4
- } from "openclaw/plugin-sdk/compat";
5
- import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
4
+ } from "./nextclaw-sdk/compat.js";
5
+ import type { ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
6
6
  import { resolveFeishuAccount } from "./accounts.js";
7
7
  import { createFeishuClient } from "./client.js";
8
8
  import { normalizeFeishuTarget } from "./targets.js";
@@ -1,4 +1,4 @@
1
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
1
+ import type { OpenClawPluginApi } from "./nextclaw-sdk/feishu.js";
2
2
  import { describe, expect, test, vi } from "vitest";
3
3
  import { registerFeishuDocTools } from "./docx.js";
4
4
  import { createToolFactoryHarness } from "./tool-factory-test-harness.js";
package/src/docx.ts CHANGED
@@ -4,7 +4,7 @@ import { isAbsolute } from "node:path";
4
4
  import { basename } from "node:path";
5
5
  import type * as Lark from "@larksuiteoapi/node-sdk";
6
6
  import { Type } from "@sinclair/typebox";
7
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
7
+ import type { OpenClawPluginApi } from "./nextclaw-sdk/feishu.js";
8
8
  import { listEnabledFeishuAccounts } from "./accounts.js";
9
9
  import { FeishuDocSchema, type FeishuDocParams } from "./doc-schema.js";
10
10
  import { BATCH_SIZE, insertBlocksInBatches } from "./docx-batch-insert.js";
package/src/drive.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type * as Lark from "@larksuiteoapi/node-sdk";
2
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
2
+ import type { OpenClawPluginApi } from "./nextclaw-sdk/feishu.js";
3
3
  import { listEnabledFeishuAccounts } from "./accounts.js";
4
4
  import { FeishuDriveSchema, type FeishuDriveParams } from "./drive-schema.js";
5
5
  import { createFeishuToolClient, resolveAnyEnabledFeishuToolsConfig } from "./tool-account.js";
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/feishu";
4
+ import type { OpenClawConfig, PluginRuntime } from "./nextclaw-sdk/feishu.js";
5
5
  import type { DynamicAgentCreationConfig } from "./types.js";
6
6
 
7
7
  export type MaybeCreateDynamicAgentResult = {
package/src/media.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { Readable } from "stream";
4
- import { withTempDownloadPath, type ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
4
+ import { withTempDownloadPath, type ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
5
5
  import { resolveFeishuAccount } from "./accounts.js";
6
6
  import { createFeishuClient } from "./client.js";
7
7
  import { normalizeFeishuExternalKey } from "./external-keys.js";
@@ -1,6 +1,6 @@
1
1
  import * as crypto from "crypto";
2
2
  import * as Lark from "@larksuiteoapi/node-sdk";
3
- import type { ClawdbotConfig, RuntimeEnv, HistoryEntry } from "openclaw/plugin-sdk/feishu";
3
+ import type { ClawdbotConfig, RuntimeEnv, HistoryEntry } from "./nextclaw-sdk/feishu.js";
4
4
  import { resolveFeishuAccount } from "./accounts.js";
5
5
  import { raceWithTimeoutAndAbort } from "./async.js";
6
6
  import {
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig, RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
3
  import { hasControlCommand } from "../../../src/auto-reply/command-detection.js";
4
4
  import {
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
2
2
  import { afterEach, describe, expect, it, vi } from "vitest";
3
3
  import { monitorFeishuProvider, stopFeishuMonitor } from "./monitor.js";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import { probeFeishu } from "./probe.js";
3
3
  import type { ResolvedFeishuAccount } from "./types.js";
4
4
 
@@ -6,7 +6,7 @@ import {
6
6
  type RuntimeEnv,
7
7
  WEBHOOK_ANOMALY_COUNTER_DEFAULTS as WEBHOOK_ANOMALY_COUNTER_DEFAULTS_FROM_SDK,
8
8
  WEBHOOK_RATE_LIMIT_DEFAULTS as WEBHOOK_RATE_LIMIT_DEFAULTS_FROM_SDK,
9
- } from "openclaw/plugin-sdk/feishu";
9
+ } from "./nextclaw-sdk/feishu.js";
10
10
 
11
11
  export const wsClients = new Map<string, Lark.WSClient>();
12
12
  export const httpServers = new Map<string, http.Server>();
@@ -6,7 +6,7 @@ import {
6
6
  readJsonBodyWithLimit,
7
7
  type RuntimeEnv,
8
8
  installRequestBodyLimitGuard,
9
- } from "openclaw/plugin-sdk/feishu";
9
+ } from "./nextclaw-sdk/feishu.js";
10
10
  import { createFeishuWSClient } from "./client.js";
11
11
  import {
12
12
  botNames,
package/src/monitor.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk/feishu";
1
+ import type { ClawdbotConfig, RuntimeEnv } from "./nextclaw-sdk/feishu.js";
2
2
  import { listEnabledFeishuAccounts, resolveFeishuAccount } from "./accounts.js";
3
3
  import {
4
4
  monitorSingleAccount,
@@ -1,6 +1,6 @@
1
1
  import { createServer } from "node:http";
2
2
  import type { AddressInfo } from "node:net";
3
- import type { ClawdbotConfig } from "openclaw/plugin-sdk/feishu";
3
+ import type { ClawdbotConfig } from "./nextclaw-sdk/feishu.js";
4
4
  import { vi } from "vitest";
5
5
  import type { monitorFeishuProvider } from "./monitor.js";
6
6
 
@@ -0,0 +1,31 @@
1
+ export const DEFAULT_ACCOUNT_ID = "default";
2
+
3
+ export function normalizeAccountId(accountId?: string | null): string {
4
+ const trimmed = accountId?.trim();
5
+ return trimmed || DEFAULT_ACCOUNT_ID;
6
+ }
7
+
8
+ export function normalizeOptionalAccountId(accountId?: string | null): string | undefined {
9
+ const trimmed = accountId?.trim();
10
+ return trimmed ? normalizeAccountId(trimmed) : undefined;
11
+ }
12
+
13
+ const VALID_AGENT_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;
14
+ const INVALID_AGENT_CHARS_RE = /[^a-z0-9_-]+/g;
15
+
16
+ export function normalizeAgentId(value?: string | null): string {
17
+ const trimmed = value?.trim();
18
+ if (!trimmed) {
19
+ return "main";
20
+ }
21
+ if (VALID_AGENT_ID_RE.test(trimmed)) {
22
+ return trimmed.toLowerCase();
23
+ }
24
+ const normalized = trimmed
25
+ .toLowerCase()
26
+ .replace(INVALID_AGENT_CHARS_RE, "-")
27
+ .replace(/^-+/, "")
28
+ .replace(/-+$/, "")
29
+ .slice(0, 64);
30
+ return normalized || "main";
31
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ collectAllowlistProviderRestrictSendersWarnings,
3
+ formatAllowFromLowercase,
4
+ listDirectoryGroupEntriesFromMapKeysAndAllowFrom,
5
+ listDirectoryUserEntriesFromAllowFromAndMapKeys,
6
+ mapAllowFromEntries,
7
+ } from "./core.js";
8
+ export { createPluginRuntimeStore } from "./runtime-store.js";