@openclaw/signal 2026.7.1-beta.1 → 2026.7.1-beta.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.
@@ -8,7 +8,8 @@ function mergeSignalAccountConfig(cfg, accountId) {
8
8
  return resolveMergedAccountConfig({
9
9
  channelConfig: cfg.channels?.signal,
10
10
  accounts: cfg.channels?.signal?.accounts,
11
- accountId
11
+ accountId,
12
+ nestedObjectKeys: ["aliases"]
12
13
  });
13
14
  }
14
15
  function resolveSignalAccount(params) {
package/dist/api.js CHANGED
@@ -1,12 +1,12 @@
1
- import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-hOCHbEhX.js";
1
+ import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-B7Rz3_xV.js";
2
2
  import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
3
- import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, r as markdownToSignalText, t as signalMessageActions } from "./message-actions-BnugYXjB.js";
4
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BRJCLiqK.js";
5
- import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-aQhurb0Z.js";
3
+ import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, r as markdownToSignalText, t as signalMessageActions } from "./message-actions-Cs9XckSd.js";
4
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BkAxQPGs.js";
5
+ import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-BfWp-F-r.js";
6
6
  import { a as looksLikeArchive, n as extractSignalCliArchive, o as pickAsset, r as installSignalCli } from "./install-signal-cli-TwhJ0DGy.js";
7
- import { t as monitorSignalProvider } from "./monitor-C1gdgT7W.js";
8
- import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
9
- import { t as probeSignal } from "./probe-BvFJLOBi.js";
7
+ import { t as monitorSignalProvider } from "./monitor-C9SiyrFt.js";
8
+ import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-CLzc3RUg.js";
9
+ import { t as probeSignal } from "./probe-BL2BqTbG.js";
10
10
  //#region extensions/signal/src/channel.setup.ts
11
11
  const signalSetupPlugin = { ...createSignalPluginBase({
12
12
  setupWizard: signalSetupWizard,
@@ -0,0 +1,151 @@
1
+ import { i as resolveSignalAccount } from "./accounts-B7Rz3_xV.js";
2
+ import { d as normalizeSignalMessagingTarget, l as looksLikeUuid, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
3
+ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
5
+ import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
6
+ //#region extensions/signal/src/aliases.ts
7
+ function normalizeAliasKey(raw) {
8
+ const trimmed = raw.trim();
9
+ if (!trimmed) return;
10
+ return normalizeLowercaseStringOrEmpty(/^signal:/i.test(trimmed) ? trimmed.slice(7).trim() : trimmed) || void 0;
11
+ }
12
+ function resolveAliasMap(params) {
13
+ const account = resolveSignalAccount({
14
+ cfg: params.cfg,
15
+ accountId: params.accountId
16
+ });
17
+ const aliases = /* @__PURE__ */ new Map();
18
+ for (const [rawKey, rawValue] of Object.entries(account.config.aliases ?? {})) {
19
+ const key = normalizeAliasKey(rawKey);
20
+ if (!key) continue;
21
+ aliases.set(key, rawValue);
22
+ }
23
+ return aliases;
24
+ }
25
+ function resolveTargetKind(target) {
26
+ return normalizeLowercaseStringOrEmpty(target).startsWith("group:") ? "group" : "user";
27
+ }
28
+ function resolveRawSignalTarget(input) {
29
+ const normalized = normalizeSignalMessagingTarget(input);
30
+ if (!normalized || !looksLikeSignalTargetId(input, normalized)) return null;
31
+ return {
32
+ to: normalized,
33
+ kind: resolveTargetKind(normalized)
34
+ };
35
+ }
36
+ function resolveSignalAliasTargetFromMap(params) {
37
+ const initialAlias = normalizeAliasKey(params.input);
38
+ if (!initialAlias || !params.aliases.has(initialAlias)) return null;
39
+ const visited = /* @__PURE__ */ new Set();
40
+ let alias = initialAlias;
41
+ for (;;) {
42
+ if (visited.has(alias)) throw new Error(`Signal alias "${initialAlias}" resolves recursively through "${alias}".`);
43
+ visited.add(alias);
44
+ const rawValue = params.aliases.get(alias);
45
+ if (typeof rawValue !== "string" || !rawValue.trim()) throw new Error(`Signal alias "${alias}" must point to a non-empty Signal target.`);
46
+ const rawTarget = resolveRawSignalTarget(rawValue);
47
+ if (rawTarget) return {
48
+ ...rawTarget,
49
+ alias: initialAlias
50
+ };
51
+ const nextAlias = normalizeAliasKey(rawValue);
52
+ if (nextAlias && params.aliases.has(nextAlias)) {
53
+ alias = nextAlias;
54
+ continue;
55
+ }
56
+ throw new Error(`Signal alias "${initialAlias}" must point to an E.164 number, uuid:<id>, username:<name>, or group:<id>.`);
57
+ }
58
+ }
59
+ function resolveSignalAliasTarget(params) {
60
+ return resolveSignalAliasTargetFromMap({
61
+ aliases: resolveAliasMap(params),
62
+ input: params.input
63
+ });
64
+ }
65
+ function resolveSignalTarget(params) {
66
+ const rawTarget = resolveRawSignalTarget(params.input);
67
+ if (rawTarget) return {
68
+ ...rawTarget,
69
+ source: "raw"
70
+ };
71
+ const aliasTarget = resolveSignalAliasTarget(params);
72
+ if (aliasTarget) return {
73
+ ...aliasTarget,
74
+ source: "alias"
75
+ };
76
+ return null;
77
+ }
78
+ function listSignalAliasDirectoryEntries(params) {
79
+ const aliases = resolveAliasMap(params);
80
+ const query = normalizeLowercaseStringOrEmpty(params.query);
81
+ const limit = typeof params.limit === "number" && params.limit > 0 ? params.limit : void 0;
82
+ const exactAlias = params.query ? normalizeAliasKey(params.query) : void 0;
83
+ if (exactAlias && aliases.has(exactAlias)) {
84
+ const target = resolveSignalAliasTargetFromMap({
85
+ aliases,
86
+ input: exactAlias
87
+ });
88
+ if (target?.kind === params.kind) return [{
89
+ kind: params.kind,
90
+ id: target.to,
91
+ name: target.alias
92
+ }];
93
+ if (target) return [];
94
+ }
95
+ const entries = [];
96
+ for (const alias of aliases.keys()) {
97
+ let target;
98
+ try {
99
+ target = resolveSignalAliasTargetFromMap({
100
+ aliases,
101
+ input: alias
102
+ });
103
+ } catch {
104
+ continue;
105
+ }
106
+ if (!target) continue;
107
+ if (target.kind !== params.kind) continue;
108
+ if (query && !alias.includes(query) && !normalizeLowercaseStringOrEmpty(target.to).includes(query)) continue;
109
+ entries.push({
110
+ kind: params.kind,
111
+ id: target.to,
112
+ name: alias
113
+ });
114
+ if (typeof limit === "number" && entries.length >= limit) break;
115
+ }
116
+ return entries;
117
+ }
118
+ //#endregion
119
+ //#region extensions/signal/src/approval-auth.ts
120
+ function normalizeSignalApproverId(value) {
121
+ const normalized = normalizeSignalMessagingTarget(String(value));
122
+ if (!normalized || normalized.startsWith("group:") || normalized.startsWith("username:")) return;
123
+ if (looksLikeUuid(normalized)) return `uuid:${normalized}`;
124
+ const e164 = normalizeE164(normalized);
125
+ return e164.length > 1 ? e164 : void 0;
126
+ }
127
+ function getSignalApprovalApprovers(params) {
128
+ const account = resolveSignalAccount(params).config;
129
+ let defaultTo = account.defaultTo;
130
+ if (typeof account.defaultTo === "string") try {
131
+ defaultTo = resolveSignalTarget({
132
+ cfg: params.cfg,
133
+ accountId: params.accountId,
134
+ input: account.defaultTo
135
+ })?.to ?? account.defaultTo;
136
+ } catch {
137
+ defaultTo = account.defaultTo;
138
+ }
139
+ return resolveApprovalApprovers({
140
+ allowFrom: account.allowFrom,
141
+ defaultTo,
142
+ normalizeApprover: normalizeSignalApproverId
143
+ });
144
+ }
145
+ const signalApprovalAuth = createResolvedApproverActionAuthAdapter({
146
+ channelLabel: "Signal",
147
+ resolveApprovers: getSignalApprovalApprovers,
148
+ normalizeSenderId: (value) => normalizeSignalApproverId(value)
149
+ });
150
+ //#endregion
151
+ export { resolveSignalTarget as i, signalApprovalAuth as n, listSignalAliasDirectoryEntries as r, getSignalApprovalApprovers as t };
@@ -1,6 +1,8 @@
1
+ import { r as resolveDefaultSignalAccountId } from "./accounts-B7Rz3_xV.js";
1
2
  import { d as normalizeSignalMessagingTarget } from "./identity-B6O4k8xg.js";
2
- import { a as registerSignalApprovalReactionTarget, c as resolveSignalApprovalTargetAuthorKeys, l as unregisterSignalApprovalReactionTarget, r as hasSignalApprovalReactionApprovers, s as resolveSignalApprovalConversationKey } from "./approval-reactions-H-RPGBK7.js";
3
- import { r as sendTypingSignal, t as sendMessageSignal } from "./send-De6LIOLq.js";
3
+ import { i as resolveSignalTarget } from "./approval-auth-DPVK9A_l.js";
4
+ import { a as registerSignalApprovalReactionTarget, c as resolveSignalApprovalTargetAuthorKeys, l as unregisterSignalApprovalReactionTarget, r as hasSignalApprovalReactionApprovers, s as resolveSignalApprovalConversationKey } from "./approval-reactions-5x1kmQEq.js";
5
+ import { r as sendTypingSignal, t as sendMessageSignal } from "./send-CLzc3RUg.js";
4
6
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
5
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
8
  import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
@@ -49,8 +51,28 @@ const signalApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
49
51
  })
50
52
  },
51
53
  transport: {
52
- prepareTarget: ({ plannedTarget, accountId, context }) => {
53
- const to = normalizeSignalMessagingTarget(plannedTarget.target.to);
54
+ prepareTarget: ({ cfg, plannedTarget, accountId, context }) => {
55
+ const plannedAccountId = plannedTarget.target.accountId;
56
+ const explicitAccountId = resolvePreparedApprovalAccountId({
57
+ plannedAccountId,
58
+ contextAccountId: accountId
59
+ });
60
+ const preparedAccountId = resolvePreparedApprovalAccountId({
61
+ plannedAccountId,
62
+ contextAccountId: accountId,
63
+ fallbackAccountId: cfg ? resolveDefaultSignalAccountId(cfg) : DEFAULT_ACCOUNT_ID
64
+ });
65
+ const rawTo = plannedTarget.target.to;
66
+ let to = normalizeSignalMessagingTarget(rawTo);
67
+ if (cfg) try {
68
+ to = resolveSignalTarget({
69
+ cfg,
70
+ accountId: explicitAccountId,
71
+ input: rawTo
72
+ })?.to ?? to;
73
+ } catch {
74
+ return null;
75
+ }
54
76
  if (!to) return null;
55
77
  const runtimeContext = readSignalApprovalRuntimeContext(context);
56
78
  const targetAuthorKeys = resolveSignalApprovalTargetAuthorKeys({
@@ -59,11 +81,7 @@ const signalApprovalNativeRuntime = createChannelApprovalNativeRuntimeAdapter({
59
81
  });
60
82
  const prepared = {
61
83
  to,
62
- accountId: resolvePreparedApprovalAccountId({
63
- plannedAccountId: plannedTarget.target.accountId,
64
- contextAccountId: accountId,
65
- fallbackAccountId: DEFAULT_ACCOUNT_ID
66
- }),
84
+ accountId: preparedAccountId,
67
85
  ...runtimeContext.baseUrl ? { baseUrl: runtimeContext.baseUrl } : {},
68
86
  ...runtimeContext.account ? { account: runtimeContext.account } : {},
69
87
  ...runtimeContext.accountUuid ? { accountUuid: runtimeContext.accountUuid } : {},
@@ -1,6 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-B6O4k8xg.js";
3
- import { c as getSignalApprovalApprovers, l as signalApprovalAuth } from "./message-actions-BnugYXjB.js";
3
+ import { i as resolveSignalTarget, n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-DPVK9A_l.js";
4
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
4
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
5
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
7
  import { buildApprovalReactionHint, createApprovalReactionTargetStore, listApprovalReactionBindings, resolveApprovalReactionTarget } from "openclaw/plugin-sdk/approval-reaction-runtime";
@@ -33,7 +34,7 @@ var approval_reactions_exports = /* @__PURE__ */ __exportAll({
33
34
  const PERSISTENT_NAMESPACE = "signal.approval-reactions.v2";
34
35
  const PERSISTENT_MAX_ENTRIES = 1e3;
35
36
  const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
36
- let resolverRuntimePromise;
37
+ const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver-BR0MioAA.js"));
37
38
  const signalApprovalReactionTargets = createApprovalReactionTargetStore({
38
39
  namespace: PERSISTENT_NAMESPACE,
39
40
  maxEntries: PERSISTENT_MAX_ENTRIES,
@@ -42,10 +43,7 @@ const signalApprovalReactionTargets = createApprovalReactionTargetStore({
42
43
  logPersistentError: reportPersistentApprovalReactionError,
43
44
  readPersistedTarget
44
45
  });
45
- function loadApprovalResolver() {
46
- resolverRuntimePromise ??= import("./approval-resolver-BR0MioAA.js");
47
- return resolverRuntimePromise;
48
- }
46
+ const loadApprovalResolver = resolverRuntimeLoader;
49
47
  function resolveApprovalKindFromId(approvalId) {
50
48
  return approvalId.startsWith("plugin:") ? "plugin" : "exec";
51
49
  }
@@ -78,10 +76,25 @@ function targetAccountMatches(params) {
78
76
  const routeAccountId = normalizeOptionalString(params.routeAccountId);
79
77
  return Boolean(routeAccountId && normalizeAccountId(routeAccountId) === normalizeAccountId(configuredAccountId));
80
78
  }
79
+ function resolveSignalApprovalRouteTarget(params) {
80
+ try {
81
+ return resolveSignalTarget({
82
+ cfg: params.cfg,
83
+ accountId: params.accountId,
84
+ input: params.to
85
+ })?.to ?? normalizeSignalMessagingTarget(params.to) ?? null;
86
+ } catch {
87
+ return null;
88
+ }
89
+ }
81
90
  function hasMatchingSignalApprovalReactionTarget(params) {
82
91
  return (params.config.targets ?? []).some((target) => {
83
92
  if (normalizeLowercaseStringOrEmpty(target.channel) !== "signal") return false;
84
- const configuredTo = normalizeSignalMessagingTarget(target.to);
93
+ const configuredTo = resolveSignalApprovalRouteTarget({
94
+ cfg: params.cfg,
95
+ accountId: target.accountId ?? params.route.accountId,
96
+ to: target.to
97
+ });
85
98
  if (!configuredTo || configuredTo !== params.route.to) return false;
86
99
  return targetAccountMatches({
87
100
  routeAccountId: params.route.accountId,
@@ -100,6 +113,7 @@ function isSignalApprovalReactionRouteStillEnabled(params) {
100
113
  config,
101
114
  route: params.target.route
102
115
  }) && hasMatchingSignalApprovalReactionTarget({
116
+ cfg: params.cfg,
103
117
  config,
104
118
  route: params.target.route
105
119
  });
@@ -112,6 +126,17 @@ function isSignalApprovalReactionRouteStillEnabled(params) {
112
126
  function resolveSignalApprovalConversationKey(to) {
113
127
  return normalizeSignalMessagingTarget(to) ?? null;
114
128
  }
129
+ function resolveSignalApprovalConversationKeyForDeliveredTarget(params) {
130
+ try {
131
+ return resolveSignalTarget({
132
+ cfg: params.cfg,
133
+ accountId: params.accountId,
134
+ input: params.to
135
+ })?.to ?? resolveSignalApprovalConversationKey(params.to);
136
+ } catch {
137
+ return resolveSignalApprovalConversationKey(params.to);
138
+ }
139
+ }
115
140
  function normalizeSignalApprovalTargetAuthorKey(value) {
116
141
  const normalized = normalizeOptionalString(value);
117
142
  if (!normalized) return null;
@@ -195,7 +220,11 @@ function hasSignalApprovalReactionHintText(text) {
195
220
  return /(^|\n)React with:\s*(\n|$)/i.test(text ?? "");
196
221
  }
197
222
  function buildTargetRoute(params) {
198
- const to = normalizeSignalMessagingTarget(params.to);
223
+ const to = resolveSignalApprovalRouteTarget({
224
+ cfg: params.cfg,
225
+ accountId: params.accountId,
226
+ to: params.to
227
+ });
199
228
  if (!to) return null;
200
229
  const route = {
201
230
  deliveryMode: "target",
@@ -290,7 +319,11 @@ function registerSignalApprovalReactionTargetForDeliveredPayload(params) {
290
319
  cfg: params.cfg,
291
320
  accountId: params.target.accountId
292
321
  })) return false;
293
- const conversationKey = resolveSignalApprovalConversationKey(params.target.to);
322
+ const conversationKey = resolveSignalApprovalConversationKeyForDeliveredTarget({
323
+ cfg: params.cfg,
324
+ accountId: params.target.accountId,
325
+ to: params.target.to
326
+ });
294
327
  if (!conversationKey) return false;
295
328
  const route = buildTargetRoute({
296
329
  cfg: params.cfg,
@@ -420,7 +453,7 @@ async function maybeResolveSignalApprovalReaction(params) {
420
453
  }
421
454
  function clearSignalApprovalReactionTargetsForTest() {
422
455
  signalApprovalReactionTargets.clearForTest();
423
- resolverRuntimePromise = void 0;
456
+ resolverRuntimeLoader.clear();
424
457
  }
425
458
  //#endregion
426
459
  export { registerSignalApprovalReactionTarget as a, resolveSignalApprovalTargetAuthorKeys as c, maybeResolveSignalApprovalReaction as i, unregisterSignalApprovalReactionTarget as l, approval_reactions_exports as n, registerSignalApprovalReactionTargetForDeliveredPayload as o, hasSignalApprovalReactionApprovers as r, resolveSignalApprovalConversationKey as s, addSignalApprovalReactionHintToStructuredPayload as t, setSignalRuntime as u };
@@ -1,6 +1,7 @@
1
- import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId } from "./accounts-hOCHbEhX.js";
1
+ import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId } from "./accounts-B7Rz3_xV.js";
2
2
  import { c as resolveSignalSender, d as normalizeSignalMessagingTarget, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient, u as looksLikeSignalTargetId } from "./identity-B6O4k8xg.js";
3
- import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, o as shouldSuppressLocalSignalExecApprovalPrompt, s as signalApprovalCapability, t as signalMessageActions } from "./message-actions-BnugYXjB.js";
3
+ import { i as resolveSignalTarget, r as listSignalAliasDirectoryEntries } from "./approval-auth-DPVK9A_l.js";
4
+ import { i as markdownToSignalTextChunks, n as resolveSignalReactionLevel, o as shouldSuppressLocalSignalExecApprovalPrompt, s as signalApprovalCapability, t as signalMessageActions } from "./message-actions-Cs9XckSd.js";
4
5
  import { t as SignalChannelConfigSchema } from "./config-schema-BiojLEsX.js";
5
6
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
6
7
  import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
@@ -9,6 +10,7 @@ import { defineChannelMessageAdapter, resolveOutboundSendDep } from "openclaw/pl
9
10
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
10
11
  import { attachChannelToResult, attachChannelToResults } from "openclaw/plugin-sdk/channel-send-result";
11
12
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
13
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
12
14
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
13
15
  import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
14
16
  import { chunkText, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
@@ -235,27 +237,45 @@ function createSignalSetupWizardProxy(loadWizard) {
235
237
  //#region extensions/signal/src/shared.ts
236
238
  const SIGNAL_CHANNEL = "signal";
237
239
  async function loadSignalChannelRuntime() {
238
- return await import("./channel.runtime-C5skg4Q0.js");
240
+ return await import("./channel.runtime-Ks7GIWM1.js");
239
241
  }
240
242
  const signalSetupWizard = createSignalSetupWizardProxy(async () => (await loadSignalChannelRuntime()).signalSetupWizard);
241
- const signalConfigAdapter = createScopedChannelConfigAdapter({
242
- sectionKey: SIGNAL_CHANNEL,
243
- listAccountIds: (cfg) => listSignalAccountIds(cfg),
244
- resolveAccount: adaptScopedAccountAccessor((params) => resolveSignalAccount(params)),
245
- defaultAccountId: (cfg) => resolveDefaultSignalAccountId(cfg),
246
- clearBaseFields: [
247
- "account",
248
- "configPath",
249
- "httpUrl",
250
- "httpHost",
251
- "httpPort",
252
- "cliPath",
253
- "name"
254
- ],
255
- resolveAllowFrom: (account) => account.config.allowFrom,
256
- formatAllowFrom: (allowFrom) => normalizeStringifiedEntries(allowFrom).map((entry) => entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))).filter(Boolean),
257
- resolveDefaultTo: (account) => account.config.defaultTo
258
- });
243
+ const signalConfigAdapter = {
244
+ ...createScopedChannelConfigAdapter({
245
+ sectionKey: SIGNAL_CHANNEL,
246
+ listAccountIds: (cfg) => listSignalAccountIds(cfg),
247
+ resolveAccount: adaptScopedAccountAccessor((params) => resolveSignalAccount(params)),
248
+ defaultAccountId: (cfg) => resolveDefaultSignalAccountId(cfg),
249
+ clearBaseFields: [
250
+ "account",
251
+ "configPath",
252
+ "httpUrl",
253
+ "httpHost",
254
+ "httpPort",
255
+ "cliPath",
256
+ "name"
257
+ ],
258
+ resolveAllowFrom: (account) => account.config.allowFrom,
259
+ formatAllowFrom: (allowFrom) => normalizeStringifiedEntries(allowFrom).map((entry) => entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))).filter(Boolean),
260
+ resolveDefaultTo: (account) => account.config.defaultTo
261
+ }),
262
+ resolveDefaultTo({ cfg, accountId }) {
263
+ const raw = resolveSignalAccount({
264
+ cfg,
265
+ accountId
266
+ }).config.defaultTo;
267
+ if (typeof raw !== "string" || !raw.trim()) return;
268
+ try {
269
+ return resolveSignalTarget({
270
+ cfg,
271
+ accountId,
272
+ input: raw
273
+ })?.to ?? raw.trim();
274
+ } catch {
275
+ return raw.trim();
276
+ }
277
+ }
278
+ };
259
279
  const signalSecurityAdapter = createRestrictSendersChannelSecurity({
260
280
  channelKey: SIGNAL_CHANNEL,
261
281
  resolveDmPolicy: (account) => account.config.dmPolicy,
@@ -303,26 +323,10 @@ function createSignalPluginBase(params) {
303
323
  }
304
324
  //#endregion
305
325
  //#region extensions/signal/src/channel.ts
306
- let signalMonitorModulePromise = null;
307
- let signalProbeModulePromise = null;
308
- let signalSendRuntimePromise = null;
309
- let signalApprovalReactionsModulePromise = null;
310
- async function loadSignalMonitorModule() {
311
- signalMonitorModulePromise ??= import("./monitor-C1gdgT7W.js").then((n) => n.n);
312
- return await signalMonitorModulePromise;
313
- }
314
- async function loadSignalProbeModule() {
315
- signalProbeModulePromise ??= import("./probe-BvFJLOBi.js").then((n) => n.n);
316
- return await signalProbeModulePromise;
317
- }
318
- async function loadSignalSendRuntime() {
319
- signalSendRuntimePromise ??= import("./send.runtime-BnjSh7QP.js");
320
- return await signalSendRuntimePromise;
321
- }
322
- async function loadSignalApprovalReactionsModule() {
323
- signalApprovalReactionsModulePromise ??= import("./approval-reactions-H-RPGBK7.js").then((n) => n.n);
324
- return await signalApprovalReactionsModulePromise;
325
- }
326
+ const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor-C9SiyrFt.js").then((n) => n.n));
327
+ const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe-BL2BqTbG.js").then((n) => n.n));
328
+ const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-DgijYwpJ.js"));
329
+ const loadSignalApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-5x1kmQEq.js").then((n) => n.n));
326
330
  async function resolveSignalSendContext(params) {
327
331
  return {
328
332
  send: resolveOutboundSendDep(params.deps, "signal") ?? (await loadSignalSendRuntime()).sendMessageSignal,
@@ -333,9 +337,16 @@ async function resolveSignalSendContext(params) {
333
337
  })
334
338
  };
335
339
  }
340
+ function resolveSignalSendTarget(params) {
341
+ return resolveSignalTarget({
342
+ cfg: params.cfg,
343
+ accountId: params.accountId,
344
+ input: params.to
345
+ })?.to ?? params.to.trim();
346
+ }
336
347
  async function sendSignalOutbound(params) {
337
348
  const { send, maxBytes } = await resolveSignalSendContext(params);
338
- return await send(params.to, params.text, {
349
+ return await send(resolveSignalSendTarget(params), params.text, {
339
350
  cfg: params.cfg,
340
351
  ...params.mediaUrl ? { mediaUrl: params.mediaUrl } : {},
341
352
  ...params.mediaLocalRoots?.length ? { mediaLocalRoots: params.mediaLocalRoots } : {},
@@ -397,7 +408,7 @@ function buildSignalBaseSessionKey(params) {
397
408
  });
398
409
  }
399
410
  function resolveSignalOutboundSessionRoute(params) {
400
- const resolved = resolveSignalOutboundTarget(params.target);
411
+ const resolved = resolveSignalOutboundTarget(params.resolvedTarget?.to ?? params.target);
401
412
  if (!resolved) return null;
402
413
  const baseSessionKey = buildSignalBaseSessionKey({
403
414
  cfg: params.cfg,
@@ -418,6 +429,11 @@ async function sendFormattedSignalText(ctx) {
418
429
  deps: ctx.deps
419
430
  });
420
431
  const limit = resolveTextChunkLimit(ctx.cfg, "signal", ctx.accountId ?? void 0, { fallbackLimit: 4e3 });
432
+ const to = resolveSignalSendTarget({
433
+ cfg: ctx.cfg,
434
+ accountId: ctx.accountId ?? void 0,
435
+ to: ctx.to
436
+ });
421
437
  const tableMode = resolveMarkdownTableMode({
422
438
  cfg: ctx.cfg,
423
439
  channel: "signal",
@@ -431,7 +447,7 @@ async function sendFormattedSignalText(ctx) {
431
447
  const results = [];
432
448
  for (const chunk of chunks) {
433
449
  ctx.abortSignal?.throwIfAborted();
434
- const result = await send(ctx.to, chunk.text, {
450
+ const result = await send(to, chunk.text, {
435
451
  cfg: ctx.cfg,
436
452
  maxBytes,
437
453
  accountId: ctx.accountId ?? void 0,
@@ -449,6 +465,11 @@ async function sendFormattedSignalMedia(ctx) {
449
465
  accountId: ctx.accountId ?? void 0,
450
466
  deps: ctx.deps
451
467
  });
468
+ const to = resolveSignalSendTarget({
469
+ cfg: ctx.cfg,
470
+ accountId: ctx.accountId ?? void 0,
471
+ to: ctx.to
472
+ });
452
473
  const tableMode = resolveMarkdownTableMode({
453
474
  cfg: ctx.cfg,
454
475
  channel: "signal",
@@ -458,7 +479,7 @@ async function sendFormattedSignalMedia(ctx) {
458
479
  text: ctx.text,
459
480
  styles: []
460
481
  };
461
- return attachChannelToResult("signal", attachSignalVisibleText(await send(ctx.to, formatted.text, {
482
+ return attachChannelToResult("signal", attachSignalVisibleText(await send(to, formatted.text, {
462
483
  cfg: ctx.cfg,
463
484
  mediaUrl: ctx.mediaUrl,
464
485
  mediaLocalRoots: ctx.mediaLocalRoots,
@@ -537,9 +558,44 @@ const signalPlugin = createChatChannelPlugin({
537
558
  resolveOutboundSessionRoute: (params) => resolveSignalOutboundSessionRoute(params),
538
559
  targetResolver: {
539
560
  looksLikeId: looksLikeSignalTargetId,
540
- hint: "<E.164|uuid:ID|group:ID|signal:group:ID|signal:+E.164>"
561
+ hint: "<E.164|uuid:ID|group:ID|signal:group:ID|signal:+E.164>",
562
+ resolveTarget: async ({ cfg, accountId, input }) => {
563
+ let target;
564
+ try {
565
+ target = resolveSignalTarget({
566
+ cfg,
567
+ accountId,
568
+ input
569
+ });
570
+ } catch {
571
+ return null;
572
+ }
573
+ if (!target) return null;
574
+ return {
575
+ to: target.to,
576
+ kind: target.kind,
577
+ display: target.source === "alias" ? target.alias : void 0,
578
+ source: target.source === "alias" ? "directory" : "normalized"
579
+ };
580
+ }
541
581
  }
542
582
  },
583
+ directory: {
584
+ listPeers: async ({ cfg, accountId, query, limit }) => listSignalAliasDirectoryEntries({
585
+ cfg,
586
+ accountId,
587
+ query,
588
+ limit,
589
+ kind: "user"
590
+ }),
591
+ listGroups: async ({ cfg, accountId, query, limit }) => listSignalAliasDirectoryEntries({
592
+ cfg,
593
+ accountId,
594
+ query,
595
+ limit,
596
+ kind: "group"
597
+ })
598
+ },
543
599
  heartbeat: {
544
600
  sendTyping: async ({ cfg, to, accountId }) => {
545
601
  await (await loadSignalSendRuntime()).sendTypingSignal(to, {
@@ -608,6 +664,34 @@ const signalPlugin = createChatChannelPlugin({
608
664
  outbound: {
609
665
  base: {
610
666
  deliveryMode: "direct",
667
+ resolveTarget: ({ cfg, to, accountId }) => {
668
+ const raw = to?.trim();
669
+ if (!raw) return {
670
+ ok: false,
671
+ error: /* @__PURE__ */ new Error("Signal target is required")
672
+ };
673
+ let target;
674
+ try {
675
+ target = resolveSignalTarget({
676
+ cfg: cfg ?? {},
677
+ accountId,
678
+ input: raw
679
+ });
680
+ } catch (error) {
681
+ return {
682
+ ok: false,
683
+ error: error instanceof Error ? error : new Error(String(error))
684
+ };
685
+ }
686
+ if (!target) return {
687
+ ok: false,
688
+ error: /* @__PURE__ */ new Error(`Unknown Signal alias or target "${raw}". Configure channels.signal.aliases.${raw.replace(/^signal:/i, "")} or use E.164, uuid:<id>, username:<name>, or group:<id>.`)
689
+ };
690
+ return {
691
+ ok: true,
692
+ to: target.to
693
+ };
694
+ },
611
695
  chunker: chunkText,
612
696
  chunkerMode: "text",
613
697
  textChunkLimit: 4e3,
@@ -1,2 +1,2 @@
1
- import { t as signalPlugin } from "./channel-aQhurb0Z.js";
1
+ import { t as signalPlugin } from "./channel-BfWp-F-r.js";
2
2
  export { signalPlugin };
@@ -1,5 +1,5 @@
1
- import { i as resolveSignalAccount, n as listSignalAccountIds } from "./accounts-hOCHbEhX.js";
2
- import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-aQhurb0Z.js";
1
+ import { i as resolveSignalAccount, n as listSignalAccountIds } from "./accounts-B7Rz3_xV.js";
2
+ import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-BfWp-F-r.js";
3
3
  import { r as installSignalCli } from "./install-signal-cli-TwhJ0DGy.js";
4
4
  import { detectBinary } from "openclaw/plugin-sdk/setup-tools";
5
5
  import { createDetectedBinaryStatus, createSetupTranslator, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";