@openclaw/signal 2026.8.1-beta.3 → 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 (32) hide show
  1. package/dist/api.js +9 -8
  2. package/dist/{approval-auth-BY6uuApE.js → approval-auth-CkljhI65.js} +4 -2
  3. package/dist/{approval-handler.runtime-Co6EVTqY.js → approval-handler.runtime-C5SsJ5ko.js} +4 -4
  4. package/dist/{approval-reactions-cs3Ox9Ow.js → approval-reactions-C5MzjYo0.js} +8 -6
  5. package/dist/{channel-zIopSllO.js → channel-CU23CLyl.js} +33 -30
  6. package/dist/channel-config-api.js +1 -1
  7. package/dist/channel-plugin-api.js +1 -1
  8. package/dist/{channel.runtime-CpDBElG8.js → channel.runtime-CdtB9bsX.js} +4 -3
  9. package/dist/{client-CvnR8_XA.js → client-DtHac18U.js} +4 -4
  10. package/dist/{client-adapter-D9SNPaNx.js → client-adapter-E06RAM6-.js} +1 -1
  11. package/dist/{config-schema-CkMIK7zp.js → config-schema-CHihQTOp.js} +10 -8
  12. package/dist/contract-api.js +4 -3
  13. package/dist/{doctor-contract-api-Dnp5eQQJ.js → doctor-contract-api-C18u1hW0.js} +1 -1
  14. package/dist/doctor-contract-api.js +1 -1
  15. package/dist/{identity-BQ4OzXXk.js → identity-YXPmgFMu.js} +2 -47
  16. package/dist/{install-signal-cli-Cpiyk0k1.js → install-signal-cli-7tEL37_j.js} +11 -7
  17. package/dist/{monitor-BLFIkpH0.js → monitor-CfRPorq9.js} +17 -15
  18. package/dist/normalize-l_b99hap.js +51 -0
  19. package/dist/{probe-B0E_cXQw.js → probe-CiVqVfko.js} +2 -2
  20. package/dist/{question-reactions-BaatFqJ7.js → question-reactions-Bw30cacw.js} +2 -2
  21. package/dist/{reaction-runtime-api-YGD6hhDh.js → reaction-runtime-api-BUy1VGT6.js} +12 -36
  22. package/dist/reaction-runtime-api.js +1 -1
  23. package/dist/runtime-api.js +9 -9
  24. package/dist/{send-BNl5folj.js → send-G6zfBh13.js} +21 -17
  25. package/dist/{send.runtime-DnMoKk27.js → send.runtime-CmnwC2vm.js} +1 -1
  26. package/dist/{transport-detection-D_M79R5f.js → transport-detection-DROVGqJp.js} +22 -49
  27. package/dist/{transport-detection.runtime-DKuuIHvf.js → transport-detection.runtime-BD5NyqbG.js} +1 -1
  28. package/dist/{transport-probes.runtime-BsJdp0oI.js → transport-probes.runtime-BMxOPSFh.js} +1 -1
  29. package/node_modules/ws/lib/permessage-deflate.js +3 -1
  30. package/node_modules/ws/package.json +1 -1
  31. package/openclaw.plugin.json +0 -6
  32. package/package.json +5 -5
package/dist/api.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-DO4HMqaK.js";
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-BQ4OzXXk.js";
3
- import { c as resolveSignalReactionLevel, d as markdownToSignalTextChunks, s as signalMessageActions, t as detectSignalTransport, u as markdownToSignalText } from "./transport-detection-D_M79R5f.js";
4
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-YGD6hhDh.js";
5
- import { a as normalizeSignalAccountInput, d as probeSignalTransport, f as writeSignalAccountTransport, l as signalSetupContract, n as createSignalPluginBase, p as resolveSignalOutboundTarget, r as signalSetupWizard, t as signalPlugin, u as prepareSignalManagedNativeTransport } from "./channel-zIopSllO.js";
6
- import { i as installSignalCli } from "./install-signal-cli-Cpiyk0k1.js";
7
- import { t as monitorSignalProvider } from "./monitor-BLFIkpH0.js";
8
- import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-BNl5folj.js";
9
- import { t as probeSignal } from "./probe-B0E_cXQw.js";
2
+ import { n as normalizeSignalMessagingTarget, t as looksLikeSignalTargetId } from "./normalize-l_b99hap.js";
3
+ import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine } from "./identity-YXPmgFMu.js";
4
+ import { c as resolveSignalReactionLevel, d as markdownToSignalTextChunks, s as signalMessageActions, t as detectSignalTransport, u as markdownToSignalText } from "./transport-detection-DROVGqJp.js";
5
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BUy1VGT6.js";
6
+ import { a as normalizeSignalAccountInput, d as probeSignalTransport, f as writeSignalAccountTransport, l as signalSetupContract, n as createSignalPluginBase, p as resolveSignalOutboundTarget, r as signalSetupWizard, t as signalPlugin, u as prepareSignalManagedNativeTransport } from "./channel-CU23CLyl.js";
7
+ import { i as installSignalCli } from "./install-signal-cli-7tEL37_j.js";
8
+ import { t as monitorSignalProvider } from "./monitor-CfRPorq9.js";
9
+ import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-G6zfBh13.js";
10
+ import { t as probeSignal } from "./probe-CiVqVfko.js";
10
11
  //#region extensions/signal/src/channel.setup.ts
11
12
  const signalSetupPlugin = { ...createSignalPluginBase({
12
13
  setupWizard: signalSetupWizard,
@@ -1,5 +1,6 @@
1
1
  import { i as resolveSignalAccount } from "./accounts-DO4HMqaK.js";
2
- import { d as normalizeSignalMessagingTarget, l as looksLikeUuid, u as looksLikeSignalTargetId } from "./identity-BQ4OzXXk.js";
2
+ import { n as normalizeSignalMessagingTarget, t as looksLikeSignalTargetId } from "./normalize-l_b99hap.js";
3
+ import { l as looksLikeUuid } from "./identity-YXPmgFMu.js";
3
4
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
4
5
  import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
5
6
  import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -7,7 +8,8 @@ import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
7
8
  function normalizeAliasKey(raw) {
8
9
  const trimmed = raw.trim();
9
10
  if (!trimmed) return;
10
- return normalizeLowercaseStringOrEmpty(/^signal:/i.test(trimmed) ? trimmed.slice(7).trim() : trimmed) || void 0;
11
+ const withoutSignal = /^signal:/i.test(trimmed) ? trimmed.slice(7).trim() : trimmed;
12
+ return normalizeLowercaseStringOrEmpty(withoutSignal) || void 0;
11
13
  }
12
14
  function resolveAliasMap(params) {
13
15
  const account = resolveSignalAccount({
@@ -1,8 +1,8 @@
1
1
  import { r as resolveDefaultSignalAccountId } from "./accounts-DO4HMqaK.js";
2
- import { d as normalizeSignalMessagingTarget } from "./identity-BQ4OzXXk.js";
3
- import { i as resolveSignalTarget } from "./approval-auth-BY6uuApE.js";
4
- import { a as registerSignalApprovalReactionTarget, c as resolveSignalApprovalTargetAuthorKeys, l as unregisterSignalApprovalReactionTarget, r as hasSignalApprovalReactionApprovers, s as resolveSignalApprovalConversationKey } from "./approval-reactions-cs3Ox9Ow.js";
5
- import { r as sendTypingSignal, t as sendMessageSignal } from "./send-BNl5folj.js";
2
+ import { n as normalizeSignalMessagingTarget } from "./normalize-l_b99hap.js";
3
+ import { i as resolveSignalTarget } from "./approval-auth-CkljhI65.js";
4
+ import { a as registerSignalApprovalReactionTarget, c as resolveSignalApprovalTargetAuthorKeys, l as unregisterSignalApprovalReactionTarget, r as hasSignalApprovalReactionApprovers, s as resolveSignalApprovalConversationKey } from "./approval-reactions-C5MzjYo0.js";
5
+ import { r as sendTypingSignal, t as sendMessageSignal } from "./send-G6zfBh13.js";
6
6
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
7
7
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
@@ -1,7 +1,8 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-BQ4OzXXk.js";
3
- import { i as resolveSignalTarget, n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-BY6uuApE.js";
4
- import { i as getOptionalSignalRuntime } from "./transport-detection-D_M79R5f.js";
2
+ import { n as normalizeSignalMessagingTarget } from "./normalize-l_b99hap.js";
3
+ import { i as resolveSignalTarget, n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-CkljhI65.js";
4
+ import { l as looksLikeUuid } from "./identity-YXPmgFMu.js";
5
+ import { i as getOptionalSignalRuntime } from "./transport-detection-DROVGqJp.js";
5
6
  import { createLazyRuntimeSurface } from "openclaw/plugin-sdk/lazy-runtime";
6
7
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
7
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -126,14 +127,15 @@ var approval_reactions_exports = /* @__PURE__ */ __exportAll({
126
127
  });
127
128
  const PERSISTENT_NAMESPACE = "signal.approval-reactions.v2";
128
129
  const PERSISTENT_MAX_ENTRIES = 1e3;
129
- const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
130
+ const DEFAULT_REACTION_TARGET_TTL_MS = 864e5;
130
131
  const loadResolveApprovalOverGateway = createLazyRuntimeSurface(() => import("openclaw/plugin-sdk/approval-gateway-runtime"), (runtime) => runtime.resolveApprovalOverGateway);
132
+ const reportPersistentApprovalReactionError = createPluginStateErrorReporter(getOptionalSignalRuntime, "signal", "approval-reaction-state", "Signal persistent approval reaction state failed");
131
133
  const signalApprovalReactionTargets = createApprovalReactionTargetStore({
132
134
  namespace: PERSISTENT_NAMESPACE,
133
135
  maxEntries: PERSISTENT_MAX_ENTRIES,
134
136
  defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS,
135
137
  openStore: (storeParams) => getOptionalSignalRuntime()?.state.openKeyedStore(storeParams),
136
- logPersistentError: createPluginStateErrorReporter(getOptionalSignalRuntime, "signal", "approval-reaction-state", "Signal persistent approval reaction state failed"),
138
+ logPersistentError: reportPersistentApprovalReactionError,
137
139
  readPersistedTarget
138
140
  });
139
141
  function resolveSignalApprovalConversationKey(to) {
@@ -420,7 +422,7 @@ async function maybeResolveSignalApprovalReaction(params) {
420
422
  return true;
421
423
  }
422
424
  params.logVerboseMessage?.(`signal: approval reaction failed id=${target.approvalId} sender=${actorId}: ${String(error)}`);
423
- return true;
425
+ throw error;
424
426
  }
425
427
  }
426
428
  function clearSignalApprovalReactionTargetsForTest() {
@@ -1,10 +1,12 @@
1
1
  import { a as isSignalManagedNativeConnectionUrlForBind, i as assignSignalManagedNativePort, l as normalizeSignalTransportHost, o as isValidSignalManagedNativePort, r as allocateSignalManagedNativePort, s as resolveLocalSignalTransportPort, u as normalizeSignalTransportUrl } from "./transport-policy-DxvSMHp9.js";
2
2
  import { a as resolveSignalAccountConfig, i as resolveSignalAccount, n as listSignalAccountIds, o as resolveSignalReplyToMode, r as resolveDefaultSignalAccountId, s as resolveSignalTransport } from "./accounts-DO4HMqaK.js";
3
- import { c as resolveSignalSender, d as normalizeSignalMessagingTarget, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient, u as looksLikeSignalTargetId } from "./identity-BQ4OzXXk.js";
4
- import { i as resolveSignalTarget, r as listSignalAliasDirectoryEntries } from "./approval-auth-BY6uuApE.js";
5
- import { c as resolveSignalReactionLevel, d as markdownToSignalTextChunks, l as formatSignalMediaText, m as signalApprovalCapability, o as materializeSignalPresentationFallback, p as shouldSuppressLocalSignalExecApprovalPrompt, r as resolveSignalReplyContextWithPersistence, s as signalMessageActions, t as detectSignalTransport } from "./transport-detection-D_M79R5f.js";
6
- import { i as migrateLegacySignalTransportConfig, n as normalizeCompatibilityConfig, r as clearLegacySignalTransportFieldsForAccount } from "./doctor-contract-api-Dnp5eQQJ.js";
7
- import { t as SignalChannelConfigSchema } from "./config-schema-CkMIK7zp.js";
3
+ import { n as normalizeSignalMessagingTarget, t as looksLikeSignalTargetId } from "./normalize-l_b99hap.js";
4
+ import { i as resolveSignalTarget, r as listSignalAliasDirectoryEntries } from "./approval-auth-CkljhI65.js";
5
+ import { c as resolveSignalSender, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient } from "./identity-YXPmgFMu.js";
6
+ import { c as resolveSignalReactionLevel, d as markdownToSignalTextChunks, l as formatSignalMediaText, m as signalApprovalCapability, o as materializeSignalPresentationFallback, p as shouldSuppressLocalSignalExecApprovalPrompt, r as resolveSignalReplyContextWithPersistence, s as signalMessageActions, t as detectSignalTransport } from "./transport-detection-DROVGqJp.js";
7
+ import { i as migrateLegacySignalTransportConfig, n as normalizeCompatibilityConfig, r as clearLegacySignalTransportFieldsForAccount } from "./doctor-contract-api-C18u1hW0.js";
8
+ import { t as SignalChannelConfigSchema } from "./config-schema-CHihQTOp.js";
9
+ import { describeAccountSnapshot, resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
8
10
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
9
11
  import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
10
12
  import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
@@ -14,7 +16,6 @@ import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
14
16
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
15
17
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
16
18
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
17
- import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
18
19
  import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
19
20
  import { chunkText, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
20
21
  import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
@@ -29,7 +30,6 @@ import { createChannelDmPolicy } from "openclaw/plugin-sdk/channel-dm-policy";
29
30
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
30
31
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, createCliPathTextInput, createDelegatedSetupWizardProxy, createDelegatedTextInputShouldPrompt, createPatchedAccountSetupAdapter, createSetupInputPresenceValidator, createSetupTranslator, patchChannelConfigForAccount, promptParsedAllowFromForAccount, setAccountAllowFromForChannel, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
31
32
  import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
32
- import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
33
33
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
34
34
  import { createRestrictSendersChannelSecurity } from "openclaw/plugin-sdk/channel-policy";
35
35
  //#region extensions/signal/src/outbound-session.ts
@@ -208,13 +208,14 @@ function prepareSignalManagedNativeTransport(params) {
208
208
  }
209
209
  async function probeSignalTransport(params) {
210
210
  const timeoutMs = params.timeoutMs ?? 1e4;
211
- const resolved = resolveSignalTransport(params.transport.kind === "managed-native" ? prepareSignalManagedNativeTransport({
211
+ const transport = params.transport.kind === "managed-native" ? prepareSignalManagedNativeTransport({
212
212
  cfg: params.cfg,
213
213
  accountId: params.accountId,
214
214
  overrides: managedTransportOptions(params.transport)
215
- }) : params.transport);
216
- if (resolved.kind === "container") return (params.probeContainer ?? (await import("./transport-probes.runtime-BsJdp0oI.js")).containerCheck)(resolved.baseUrl, timeoutMs, params.account);
217
- return (params.probeNative ?? (await import("./transport-probes.runtime-BsJdp0oI.js")).nativeCheck)(resolved.baseUrl, timeoutMs);
215
+ }) : params.transport;
216
+ const resolved = resolveSignalTransport(transport);
217
+ if (resolved.kind === "container") return (params.probeContainer ?? (await import("./transport-probes.runtime-BMxOPSFh.js")).containerCheck)(resolved.baseUrl, timeoutMs, params.account);
218
+ return (params.probeNative ?? (await import("./transport-probes.runtime-BMxOPSFh.js")).nativeCheck)(resolved.baseUrl, timeoutMs);
218
219
  }
219
220
  function writeSignalAccountTransport(params) {
220
221
  const transport = normalizeTransport(params.transport);
@@ -228,13 +229,14 @@ function writeSignalAccountTransport(params) {
228
229
  accountId: params.accountId,
229
230
  transport
230
231
  });
232
+ const next = patchChannelConfigForAccount({
233
+ cfg: params.cfg,
234
+ channel: "signal",
235
+ accountId: params.accountId,
236
+ patch: { transport }
237
+ });
231
238
  const canonical = clearLegacySignalTransportFieldsForAccount({
232
- cfg: patchChannelConfigForAccount({
233
- cfg: params.cfg,
234
- channel: "signal",
235
- accountId: params.accountId,
236
- patch: { transport }
237
- }),
239
+ cfg: next,
238
240
  accountId: params.accountId
239
241
  });
240
242
  if (transport.kind === "managed-native") resolveSignalAccount({
@@ -570,7 +572,7 @@ function createSignalSetupWizardProxy(loadWizard) {
570
572
  const signalDoctor = {
571
573
  normalizeCompatibilityConfig,
572
574
  cleanStaleConfig: async ({ cfg }) => {
573
- const { detectSignalTransport } = await import("./transport-detection.runtime-DKuuIHvf.js");
575
+ const { detectSignalTransport } = await import("./transport-detection.runtime-BD5NyqbG.js");
574
576
  return await migrateLegacySignalTransportConfig({
575
577
  cfg,
576
578
  detect: detectSignalTransport
@@ -581,7 +583,7 @@ const signalDoctor = {
581
583
  //#region extensions/signal/src/shared.ts
582
584
  const SIGNAL_CHANNEL = "signal";
583
585
  async function loadSignalChannelRuntime() {
584
- return await import("./channel.runtime-CpDBElG8.js");
586
+ return await import("./channel.runtime-CdtB9bsX.js");
585
587
  }
586
588
  const signalSetupWizard = createSignalSetupWizardProxy(async () => (await loadSignalChannelRuntime()).signalSetupWizard);
587
589
  const signalConfigAdapter = {
@@ -666,17 +668,16 @@ function createSignalPluginBase(params) {
666
668
  }
667
669
  //#endregion
668
670
  //#region extensions/signal/src/channel.ts
669
- const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor-BLFIkpH0.js").then((n) => n.n));
670
- const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe-B0E_cXQw.js").then((n) => n.n));
671
- const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-DnMoKk27.js"));
672
- const loadSignalApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-cs3Ox9Ow.js").then((n) => n.n));
671
+ const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor-CfRPorq9.js").then((n) => n.n));
672
+ const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe-CiVqVfko.js").then((n) => n.n));
673
+ const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-CmnwC2vm.js"));
674
+ const loadSignalApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-C5MzjYo0.js").then((n) => n.n));
673
675
  async function resolveSignalSendContext(params) {
674
676
  return {
675
677
  send: resolveOutboundSendDep(params.deps, "signal") ?? (await loadSignalSendRuntime()).sendMessageSignal,
676
678
  maxBytes: resolveChannelMediaMaxBytes({
677
679
  cfg: params.cfg,
678
- resolveChannelLimitMb: ({ cfg, accountId }) => cfg.channels?.signal?.accounts?.[accountId]?.mediaMaxMb ?? cfg.channels?.signal?.mediaMaxMb,
679
- accountId: params.accountId
680
+ resolveChannelLimitMb: () => resolveSignalAccount(params).config.mediaMaxMb
680
681
  })
681
682
  };
682
683
  }
@@ -835,14 +836,15 @@ async function sendFormattedSignalText(ctx) {
835
836
  accountId: ctx.accountId,
836
837
  replyToId
837
838
  });
838
- const deliveryResult = attachChannelToResult("signal", attachSignalVisibleText(await send(to, chunk.text, {
839
+ const result = await send(to, chunk.text, {
839
840
  cfg: ctx.cfg,
840
841
  maxBytes,
841
842
  accountId: ctx.accountId ?? void 0,
842
843
  textMode: "plain",
843
844
  textStyles: chunk.styles,
844
845
  ...replyOptions
845
- }), chunk.text));
846
+ });
847
+ const deliveryResult = attachChannelToResult("signal", attachSignalVisibleText(result, chunk.text));
846
848
  results.push(deliveryResult);
847
849
  await ctx.onDeliveryResult?.(deliveryResult);
848
850
  }
@@ -875,7 +877,7 @@ async function sendFormattedSignalMedia(ctx) {
875
877
  accountId: ctx.accountId,
876
878
  replyToId: ctx.replyToId
877
879
  });
878
- return attachChannelToResult("signal", attachSignalVisibleText(await send(to, formatted.text, {
880
+ const result = await send(to, formatted.text, {
879
881
  cfg: ctx.cfg,
880
882
  mediaUrl: ctx.mediaUrl,
881
883
  ...ctx.mediaAccess ? { mediaAccess: ctx.mediaAccess } : {},
@@ -886,7 +888,8 @@ async function sendFormattedSignalMedia(ctx) {
886
888
  textMode: "plain",
887
889
  textStyles: formatted.styles,
888
890
  ...replyOptions
889
- }), formatted.text));
891
+ });
892
+ return attachChannelToResult("signal", attachSignalVisibleText(result, formatted.text));
890
893
  }
891
894
  async function registerDeliveredSignalApprovalPayloadForReactions(params) {
892
895
  const account = resolveSignalAccount({
@@ -896,7 +899,7 @@ async function registerDeliveredSignalApprovalPayloadForReactions(params) {
896
899
  const targetAuthor = normalizeOptionalString(account.config.account);
897
900
  const targetAuthorUuid = normalizeOptionalString(account.config.accountUuid);
898
901
  if (!targetAuthor && !targetAuthorUuid) return;
899
- const { registerSignalQuestionReactionTargetForDeliveredPayload } = await import("./question-reactions-BaatFqJ7.js").then((n) => n.n);
902
+ const { registerSignalQuestionReactionTargetForDeliveredPayload } = await import("./question-reactions-Bw30cacw.js").then((n) => n.n);
900
903
  registerSignalQuestionReactionTargetForDeliveredPayload({
901
904
  cfg: params.cfg,
902
905
  target: {
@@ -1,2 +1,2 @@
1
- import { t as SignalChannelConfigSchema } from "./config-schema-CkMIK7zp.js";
1
+ import { t as SignalChannelConfigSchema } from "./config-schema-CHihQTOp.js";
2
2
  export { SignalChannelConfigSchema };
@@ -1,2 +1,2 @@
1
- import { t as signalPlugin } from "./channel-zIopSllO.js";
1
+ import { t as signalPlugin } from "./channel-CU23CLyl.js";
2
2
  export { signalPlugin };
@@ -1,6 +1,6 @@
1
1
  import { i as resolveSignalAccount, n as listSignalAccountIds } from "./accounts-DO4HMqaK.js";
2
- import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-zIopSllO.js";
3
- import { i as installSignalCli } from "./install-signal-cli-Cpiyk0k1.js";
2
+ import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-CU23CLyl.js";
3
+ import { i as installSignalCli } from "./install-signal-cli-7tEL37_j.js";
4
4
  import { detectBinary } from "openclaw/plugin-sdk/setup-tools";
5
5
  import { createDetectedBinaryStatus, createSetupTranslator, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
6
6
  //#region extensions/signal/src/setup-surface.ts
@@ -59,7 +59,8 @@ const signalSetupWizard = {
59
59
  accountId
60
60
  }).transport;
61
61
  if (transport.kind !== "managed-native") return;
62
- const cliDetected = await detectBinary((typeof credentialValues.cliPath === "string" ? credentialValues.cliPath : void 0) ?? (transport.kind === "managed-native" ? transport.cliPath : void 0) ?? "signal-cli");
62
+ const currentCliPath = (typeof credentialValues.cliPath === "string" ? credentialValues.cliPath : void 0) ?? (transport.kind === "managed-native" ? transport.cliPath : void 0) ?? "signal-cli";
63
+ const cliDetected = await detectBinary(currentCliPath);
63
64
  if (!await prompter.confirm({
64
65
  message: cliDetected ? t("wizard.signal.reinstallPrompt") : t("wizard.signal.installPrompt"),
65
66
  initialValue: !cliDetected
@@ -19,12 +19,12 @@ import { generateSecureUuid } from "openclaw/plugin-sdk/core";
19
19
  */
20
20
  const DEFAULT_TIMEOUT_MS$1 = 1e4;
21
21
  const DEFAULT_ATTACHMENT_RESPONSE_MAX_BYTES = 1048576;
22
- const SIGNAL_REST_ERROR_RESPONSE_MAX_BYTES = 16 * 1024;
23
- const SIGNAL_REST_SUCCESS_RESPONSE_MAX_BYTES = 16 * 1024 * 1024;
24
- const WS_MAX_PAYLOAD = 1024 * 1024;
22
+ const SIGNAL_REST_ERROR_RESPONSE_MAX_BYTES = 16384;
23
+ const SIGNAL_REST_SUCCESS_RESPONSE_MAX_BYTES = 16777216;
24
+ const WS_MAX_PAYLOAD = 1048576;
25
25
  const WS_HANDSHAKE_MS = 3e4;
26
26
  const WS_SHUTDOWN_DRAIN_TIMEOUT_MS = 1500;
27
- const DEFAULT_SIGNAL_CONTAINER_MAX_ATTACHMENT_BYTES = 8 * 1024 * 1024;
27
+ const DEFAULT_SIGNAL_CONTAINER_MAX_ATTACHMENT_BYTES = 8388608;
28
28
  const CONTAINER_TEXT_STYLE_MARKERS = {
29
29
  BOLD: "**",
30
30
  ITALIC: "*",
@@ -1,4 +1,4 @@
1
- import { a as containerRpcRequest, i as containerCheck, n as signalRpcRequest$1, o as streamContainerEvents, r as streamSignalEvents$1, t as signalCheck$1 } from "./client-CvnR8_XA.js";
1
+ import { a as containerRpcRequest, i as containerCheck, n as signalRpcRequest$1, o as streamContainerEvents, r as streamSignalEvents$1, t as signalCheck$1 } from "./client-DtHac18U.js";
2
2
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
3
3
  //#region extensions/signal/src/client-adapter.ts
4
4
  /**
@@ -1,7 +1,7 @@
1
1
  import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
2
2
  import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId, resolveAccountEntry } from "openclaw/plugin-sdk/account-resolution";
4
- import { ChannelDeliveryStreamingConfigSchema, ChannelSendReadReceiptsSchema, ExecutableTokenSchema, ReplyToModeSchema, buildChannelConfigSchema, buildChannelReactionShape, buildCommonChannelAccountShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
4
+ import { ChannelDeliveryStreamingConfigSchema, ChannelSendReadReceiptsSchema, ExecutableTokenSchema, ReplyToModeSchema, buildChannelAccountSchemaParts, buildChannelConfigSchema, buildChannelReactionShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
5
5
  import { z } from "zod";
6
6
  //#region extensions/signal/src/config-ui-hints.ts
7
7
  const signalChannelConfigUiHints = {
@@ -104,13 +104,13 @@ const SignalGroupEntrySchema = buildGroupEntrySchema({ ingest: z.boolean().optio
104
104
  "systemPrompt"
105
105
  ] });
106
106
  const SignalGroupsSchema = z.record(z.string(), SignalGroupEntrySchema.optional()).optional();
107
+ const { accountShape, rootPolicyShape } = buildChannelAccountSchemaParts({
108
+ omit: ["mentionPatterns"],
109
+ streaming: ChannelDeliveryStreamingConfigSchema.optional(),
110
+ mediaMaxMb: z.number().int().positive().optional()
111
+ });
107
112
  const SignalAccountSchemaBase = z.object({
108
- ...buildCommonChannelAccountShape({
109
- useDefaults: true,
110
- omit: ["mentionPatterns"],
111
- streaming: ChannelDeliveryStreamingConfigSchema.optional(),
112
- mediaMaxMb: z.number().int().positive().optional()
113
- }),
113
+ ...accountShape,
114
114
  account: z.string().optional(),
115
115
  accountUuid: z.string().optional(),
116
116
  transport: SignalTransportSchema.optional(),
@@ -137,6 +137,7 @@ const SignalAccountSchemaBase = z.object({
137
137
  actions: z.object({ reactions: z.boolean().optional() }).strict().optional()
138
138
  }).strict();
139
139
  const SignalConfigSchemaBase = SignalAccountSchemaBase.extend({
140
+ ...rootPolicyShape,
140
141
  accounts: z.record(z.string(), SignalAccountSchemaBase.optional()).optional(),
141
142
  defaultAccount: z.string().optional()
142
143
  });
@@ -197,7 +198,8 @@ function validateSignalContainerAccounts(value, ctx) {
197
198
  if (!account || !channelEnabled || account.enabled === false) continue;
198
199
  const isDefaultAccount = normalizeAccountId(accountId) === DEFAULT_ACCOUNT_ID;
199
200
  if ((isDefaultAccount && value.transport ? value.transport : account.transport)?.kind !== "container" || isDefaultAccount && value.transport) continue;
200
- if (!normalizeOptionalString(account.account === void 0 ? value.account : account.account)) ctx.addIssue({
201
+ const effectiveAccount = account.account === void 0 ? value.account : account.account;
202
+ if (!normalizeOptionalString(effectiveAccount)) ctx.addIssue({
201
203
  code: z.ZodIssueCode.custom,
202
204
  message: "channels.signal account container transport requires an account number on the account or channel",
203
205
  path: [
@@ -1,3 +1,4 @@
1
- import { d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, u as looksLikeSignalTargetId } from "./identity-BQ4OzXXk.js";
2
- import { a as installSignalCliFromRelease, i as installSignalCli, n as downloadToFile, o as looksLikeArchive, r as extractSignalCliArchive, s as pickAsset, t as MAX_SIGNAL_CLI_EXTRACTED_BYTES } from "./install-signal-cli-Cpiyk0k1.js";
3
- export { MAX_SIGNAL_CLI_EXTRACTED_BYTES, downloadToFile, extractSignalCliArchive, installSignalCli, installSignalCliFromRelease, isSignalSenderAllowed, looksLikeArchive, looksLikeSignalTargetId, normalizeSignalMessagingTarget, pickAsset };
1
+ import { n as normalizeSignalMessagingTarget, r as normalizeSignalReactionRecipient, t as looksLikeSignalTargetId } from "./normalize-l_b99hap.js";
2
+ import { i as isSignalSenderAllowed } from "./identity-YXPmgFMu.js";
3
+ import { a as installSignalCliFromRelease, i as installSignalCli, n as downloadToFile, o as looksLikeArchive, r as extractSignalCliArchive, s as pickAsset, t as MAX_SIGNAL_CLI_EXTRACTED_BYTES } from "./install-signal-cli-7tEL37_j.js";
4
+ export { MAX_SIGNAL_CLI_EXTRACTED_BYTES, downloadToFile, extractSignalCliArchive, installSignalCli, installSignalCliFromRelease, isSignalSenderAllowed, looksLikeArchive, looksLikeSignalTargetId, normalizeSignalMessagingTarget, normalizeSignalReactionRecipient, pickAsset };
@@ -428,7 +428,7 @@ function migrateLegacySignalTransportConfigSync(cfg) {
428
428
  };
429
429
  }
430
430
  //#endregion
431
- //#region extensions/signal/doctor-contract-api.ts
431
+ //#region extensions/signal/config-doctor-api.ts
432
432
  const RETIRED_SIGNAL_ACCOUNT_TRANSPORT_FIELDS = [
433
433
  "configPath",
434
434
  "httpUrl",
@@ -1,2 +1,2 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-api-Dnp5eQQJ.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-api-C18u1hW0.js";
2
2
  export { legacyConfigRules, normalizeCompatibilityConfig };
@@ -1,51 +1,6 @@
1
- import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
3
3
  import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
4
- //#region extensions/signal/src/normalize.ts
5
- function normalizeSignalMessagingTarget(raw) {
6
- const trimmed = raw.trim();
7
- if (!trimmed) return;
8
- let normalized = trimmed;
9
- if (normalizeLowercaseStringOrEmpty(normalized).startsWith("signal:")) normalized = normalized.slice(7).trim();
10
- if (!normalized) return;
11
- const lower = normalizeLowercaseStringOrEmpty(normalized);
12
- if (lower.startsWith("group:")) {
13
- const id = normalized.slice(6).trim();
14
- return id ? `group:${id}` : void 0;
15
- }
16
- if (lower.startsWith("username:")) {
17
- const id = normalized.slice(9).trim();
18
- return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
19
- }
20
- if (lower.startsWith("u:")) {
21
- const id = normalized.slice(2).trim();
22
- return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
23
- }
24
- if (lower.startsWith("uuid:")) {
25
- const id = normalized.slice(5).trim();
26
- return id ? normalizeLowercaseStringOrEmpty(id) : void 0;
27
- }
28
- return normalizeLowercaseStringOrEmpty(normalized);
29
- }
30
- const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
31
- const UUID_COMPACT_PATTERN = /^[0-9a-f]{32}$/i;
32
- function looksLikeSignalTargetId(raw, normalized) {
33
- const candidates = normalizeStringEntries([raw, normalized ?? ""]);
34
- for (const candidate of candidates) {
35
- if (/^(signal:)?(group:|username:|u:)/i.test(candidate)) return true;
36
- if (/^(signal:)?uuid:/i.test(candidate)) {
37
- const stripped = candidate.replace(/^signal:/i, "").replace(/^uuid:/i, "").trim();
38
- if (!stripped) continue;
39
- if (UUID_PATTERN.test(stripped) || UUID_COMPACT_PATTERN.test(stripped)) return true;
40
- continue;
41
- }
42
- const withoutSignalPrefix = candidate.replace(/^signal:/i, "").trim();
43
- if (UUID_PATTERN.test(withoutSignalPrefix) || UUID_COMPACT_PATTERN.test(withoutSignalPrefix)) return true;
44
- if (/^\+?\d{3,}$/.test(withoutSignalPrefix)) return true;
45
- }
46
- return false;
47
- }
48
- //#endregion
49
4
  //#region extensions/signal/src/uuid.ts
50
5
  const UUID_HYPHENATED_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
51
6
  const UUID_COMPACT_RE = /^[0-9a-f]{32}$/i;
@@ -143,4 +98,4 @@ function isSignalSenderAllowed(sender, allowFrom) {
143
98
  }).allowed;
144
99
  }
145
100
  //#endregion
146
- export { normalizeSignalAllowRecipient as a, resolveSignalSender as c, normalizeSignalMessagingTarget as d, isSignalSenderAllowed as i, looksLikeUuid as l, formatSignalSenderDisplay as n, resolveSignalPeerId as o, formatSignalSenderId as r, resolveSignalRecipient as s, formatSignalPairingIdLine as t, looksLikeSignalTargetId as u };
101
+ export { normalizeSignalAllowRecipient as a, resolveSignalSender as c, isSignalSenderAllowed as i, looksLikeUuid as l, formatSignalSenderDisplay as n, resolveSignalPeerId as o, formatSignalSenderId as r, resolveSignalRecipient as s, formatSignalPairingIdLine as t };
@@ -12,10 +12,10 @@ import { runPluginCommandWithTimeout } from "openclaw/plugin-sdk/run-command";
12
12
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
13
13
  import { withTempDownloadPath } from "openclaw/plugin-sdk/temp-path";
14
14
  //#region extensions/signal/src/install-signal-cli.ts
15
- const MAX_SIGNAL_CLI_ARCHIVE_BYTES = 256 * 1024 * 1024;
15
+ const MAX_SIGNAL_CLI_ARCHIVE_BYTES = 268435456;
16
16
  /** @internal Exported for testing. */
17
- const MAX_SIGNAL_CLI_EXTRACTED_BYTES = 384 * 1024 * 1024;
18
- const SIGNAL_CLI_DOWNLOAD_TIMEOUT_MS = 5 * 6e4;
17
+ const MAX_SIGNAL_CLI_EXTRACTED_BYTES = 402653184;
18
+ const SIGNAL_CLI_DOWNLOAD_TIMEOUT_MS = 3e5;
19
19
  const SIGNAL_CLI_RELEASE_INFO_TIMEOUT_MS = 3e4;
20
20
  const CONTENT_LENGTH_RE = /^\d+$/;
21
21
  /** @internal Exported for testing. */
@@ -57,7 +57,8 @@ function normalizeReleaseAsset(value) {
57
57
  } : void 0;
58
58
  }
59
59
  function normalizeSignalCliRelease(value) {
60
- const version = normalizeOptionalString(normalizeOptionalString(value.tag_name)?.replace(/^v/, ""));
60
+ const tagName = normalizeOptionalString(value.tag_name);
61
+ const version = normalizeOptionalString(tagName?.replace(/^v/, ""));
61
62
  if (!version || !Array.isArray(value.assets)) return;
62
63
  return {
63
64
  version,
@@ -114,14 +115,17 @@ async function downloadToFile(url, dest, maxRedirects = 5, maxBytes = MAX_SIGNAL
114
115
  }
115
116
  let totalBytes = 0;
116
117
  const body = response.body;
117
- await pipeline(isNodeReadableStream(body) ? body : Readable.fromWeb(body), new Transform({ transform(chunk, _encoding, callback) {
118
+ const readable = isNodeReadableStream(body) ? body : Readable.fromWeb(body);
119
+ const limiter = new Transform({ transform(chunk, _encoding, callback) {
118
120
  totalBytes += chunkByteLength(chunk);
119
121
  if (totalBytes > maxBytes) {
120
122
  callback(/* @__PURE__ */ new Error(`signal-cli archive exceeded the ${maxBytes}-byte download cap.`));
121
123
  return;
122
124
  }
123
125
  callback(null, chunk);
124
- } }), createWriteStream(dest));
126
+ } });
127
+ const out = createWriteStream(dest);
128
+ await pipeline(readable, limiter, out);
125
129
  completed = true;
126
130
  } finally {
127
131
  await release();
@@ -178,7 +182,7 @@ async function installSignalCliViaBrew(runtime) {
178
182
  "install",
179
183
  "signal-cli"
180
184
  ],
181
- timeoutMs: 15 * 6e4
185
+ timeoutMs: 9e5
182
186
  });
183
187
  if (result.code !== 0) return {
184
188
  ok: false,
@@ -1,21 +1,22 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
2
  import { l as normalizeSignalTransportHost } from "./transport-policy-DxvSMHp9.js";
3
3
  import { i as resolveSignalAccount, o as resolveSignalReplyToMode } from "./accounts-DO4HMqaK.js";
4
- 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 } from "./identity-BQ4OzXXk.js";
5
- import { c as resolveSignalReactionLevel, f as isSignalNativeApprovalHandlerConfigured, i as getOptionalSignalRuntime, l as formatSignalMediaText, n as registerSignalReplyContext, o as materializeSignalPresentationFallback } from "./transport-detection-D_M79R5f.js";
6
- import { n as signalRpcRequest, r as streamSignalEvents, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
7
- import { n as sendReactionSignal } from "./reaction-runtime-api-YGD6hhDh.js";
8
- import { i as maybeResolveSignalApprovalReaction, o as registerSignalApprovalReactionTargetForDeliveredPayload, s as resolveSignalApprovalConversationKey, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-cs3Ox9Ow.js";
9
- import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-BaatFqJ7.js";
10
- import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-BNl5folj.js";
4
+ import { n as normalizeSignalMessagingTarget } from "./normalize-l_b99hap.js";
5
+ import { a as normalizeSignalAllowRecipient, c as resolveSignalSender, i as isSignalSenderAllowed, l as looksLikeUuid, n as formatSignalSenderDisplay, o as resolveSignalPeerId, r as formatSignalSenderId, s as resolveSignalRecipient, t as formatSignalPairingIdLine } from "./identity-YXPmgFMu.js";
6
+ import { c as resolveSignalReactionLevel, f as isSignalNativeApprovalHandlerConfigured, i as getOptionalSignalRuntime, l as formatSignalMediaText, n as registerSignalReplyContext, o as materializeSignalPresentationFallback } from "./transport-detection-DROVGqJp.js";
7
+ import { n as signalRpcRequest, r as streamSignalEvents, t as signalCheck } from "./client-adapter-E06RAM6-.js";
8
+ import { n as sendReactionSignal } from "./reaction-runtime-api-BUy1VGT6.js";
9
+ import { i as maybeResolveSignalApprovalReaction, o as registerSignalApprovalReactionTargetForDeliveredPayload, s as resolveSignalApprovalConversationKey, t as addSignalApprovalReactionHintToStructuredPayload } from "./approval-reactions-C5MzjYo0.js";
10
+ import { r as registerSignalQuestionReactionTargetForDeliveredPayload, t as maybeResolveSignalQuestionReaction } from "./question-reactions-Bw30cacw.js";
11
+ import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-G6zfBh13.js";
11
12
  import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
12
13
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
13
- import { canonicalizeBase64, detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
14
14
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
15
15
  import { asPositiveSafeInteger, isRecord, normalizeNullableString, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
16
16
  import { CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
17
17
  import { normalizeE164, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
18
18
  import { buildChannelInboundEventContext, buildMentionRegexes, createChannelInboundDebouncer, filterChannelInboundQuoteContext, formatInboundEnvelope, formatInboundFromLabel, formatInboundMediaUnavailableText, hasVisibleInboundReplyDispatch, logInboundDrop, matchesMentionPatterns, readAgentRunTerminalOutcome, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent, shouldDebounceTextInbound, toHistoryMediaEntries, toInboundMediaFactsWithMetadata } from "openclaw/plugin-sdk/channel-inbound";
19
+ import { canonicalizeBase64, detectMime, estimateBase64DecodedBytes, kindFromMime, saveMediaBuffer } from "openclaw/plugin-sdk/media-runtime";
19
20
  import { collectErrorGraphCandidates, formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
20
21
  import { ensurePortAvailable, extractErrorCode, formatErrorMessage as formatErrorMessage$1, resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
21
22
  import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention } from "openclaw/plugin-sdk/channel-policy";
@@ -1647,10 +1648,10 @@ async function startSignalIngressMonitor(params) {
1647
1648
  createClaimError: (_kind, claim) => new SignalIngressPermanentError("unsupported-event", `Signal ingress row ${claim.id} has an invalid payload`)
1648
1649
  },
1649
1650
  deliver: ([event, parsedPayload], lifecycle) => parsedPayload ? params.dispatch(event, lifecycle, parsedPayload) : void 0,
1650
- onDurableAdmission: async (_event, { facts }) => {
1651
+ onDurableAdmission: async (_event, { facts, isNew }) => {
1651
1652
  const { numberAliasEventId } = facts;
1652
1653
  if (!numberAliasEventId) return;
1653
- if (!await ingressQueue.complete(numberAliasEventId)) await ingressQueue.complete(facts.eventId);
1654
+ if (!await ingressQueue.complete(numberAliasEventId) && isNew) await ingressQueue.complete(facts.eventId);
1654
1655
  },
1655
1656
  pollIntervalMs: SIGNAL_INGRESS_DRAIN_INTERVAL_MS,
1656
1657
  retention: {
@@ -1815,7 +1816,7 @@ function buildSignalReactionSystemEventText(params) {
1815
1816
  const withTarget = params.targetLabel ? `${base} from ${params.targetLabel}` : base;
1816
1817
  return params.groupLabel ? `${withTarget} in ${params.groupLabel}` : withTarget;
1817
1818
  }
1818
- const SIGNAL_ATTACHMENT_RPC_RESPONSE_HEADROOM_BYTES = 64 * 1024;
1819
+ const SIGNAL_ATTACHMENT_RPC_RESPONSE_HEADROOM_BYTES = 65536;
1819
1820
  const SIGNAL_BASE64_OVERHEAD_NUMERATOR = 4;
1820
1821
  const SIGNAL_BASE64_OVERHEAD_DENOMINATOR = 3;
1821
1822
  function deriveSignalAttachmentRpcMaxResponseBytes(maxBytes) {
@@ -1825,7 +1826,7 @@ function deriveSignalAttachmentRpcMaxResponseBytes(maxBytes) {
1825
1826
  async function fetchAttachment(params) {
1826
1827
  const { attachment } = params;
1827
1828
  if (!attachment?.id) return null;
1828
- if (typeof attachment.size === "number" && attachment.size > params.maxBytes) throw new Error(`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / (1024 * 1024)).toFixed(0)}MB limit`);
1829
+ if (typeof attachment.size === "number" && attachment.size > params.maxBytes) throw new Error(`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / 1048576).toFixed(0)}MB limit`);
1829
1830
  const rpcParams = { id: attachment.id };
1830
1831
  if (params.account) rpcParams.account = params.account;
1831
1832
  if (params.groupId) rpcParams.groupId = params.groupId;
@@ -1837,15 +1838,16 @@ async function fetchAttachment(params) {
1837
1838
  transportKind: params.transportKind
1838
1839
  });
1839
1840
  if (!result?.data) return null;
1840
- if (estimateBase64DecodedBytes(result.data) > params.maxBytes) throw new Error(`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / (1024 * 1024)).toFixed(0)}MB limit`);
1841
+ if (estimateBase64DecodedBytes(result.data) > params.maxBytes) throw new Error(`Signal attachment ${attachment.id} exceeds ${(params.maxBytes / 1048576).toFixed(0)}MB limit`);
1841
1842
  const canonicalData = canonicalizeBase64(result.data);
1842
1843
  if (!canonicalData) throw new Error(`Signal attachment ${attachment.id} returned malformed base64 data`);
1843
1844
  const buffer = Buffer.from(canonicalData, "base64");
1844
1845
  const originalFilename = normalizeOptionalString(attachment.filename ?? void 0);
1845
- const saved = await saveMediaBuffer(buffer, normalizeOptionalString(attachment.contentType ?? void 0) ?? await detectMime({
1846
+ const contentType = normalizeOptionalString(attachment.contentType ?? void 0) ?? await detectMime({
1846
1847
  buffer,
1847
1848
  filePath: originalFilename
1848
- }), "inbound", params.maxBytes, originalFilename);
1849
+ });
1850
+ const saved = await saveMediaBuffer(buffer, contentType, "inbound", params.maxBytes, originalFilename);
1849
1851
  return {
1850
1852
  path: saved.path,
1851
1853
  contentType: saved.contentType
@@ -0,0 +1,51 @@
1
+ import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ //#region extensions/signal/src/normalize.ts
3
+ function normalizeSignalReactionRecipient(raw) {
4
+ const withoutSignal = raw.trim().replace(/^signal:/i, "").trim();
5
+ return /^uuid:/i.test(withoutSignal) ? withoutSignal.slice(5).trim() : withoutSignal;
6
+ }
7
+ function normalizeSignalMessagingTarget(raw) {
8
+ const trimmed = raw.trim();
9
+ if (!trimmed) return;
10
+ let normalized = trimmed;
11
+ if (normalizeLowercaseStringOrEmpty(normalized).startsWith("signal:")) normalized = normalized.slice(7).trim();
12
+ if (!normalized) return;
13
+ const lower = normalizeLowercaseStringOrEmpty(normalized);
14
+ if (lower.startsWith("group:")) {
15
+ const id = normalized.slice(6).trim();
16
+ return id ? `group:${id}` : void 0;
17
+ }
18
+ if (lower.startsWith("username:")) {
19
+ const id = normalized.slice(9).trim();
20
+ return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
21
+ }
22
+ if (lower.startsWith("u:")) {
23
+ const id = normalized.slice(2).trim();
24
+ return id ? normalizeLowercaseStringOrEmpty(`username:${id}`) : void 0;
25
+ }
26
+ if (lower.startsWith("uuid:")) {
27
+ const id = normalized.slice(5).trim();
28
+ return id ? normalizeLowercaseStringOrEmpty(id) : void 0;
29
+ }
30
+ return normalizeLowercaseStringOrEmpty(normalized);
31
+ }
32
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
33
+ const UUID_COMPACT_PATTERN = /^[0-9a-f]{32}$/i;
34
+ function looksLikeSignalTargetId(raw, normalized) {
35
+ const candidates = normalizeStringEntries([raw, normalized ?? ""]);
36
+ for (const candidate of candidates) {
37
+ if (/^(signal:)?(group:|username:|u:)/i.test(candidate)) return true;
38
+ if (/^(signal:)?uuid:/i.test(candidate)) {
39
+ const stripped = candidate.replace(/^signal:/i, "").replace(/^uuid:/i, "").trim();
40
+ if (!stripped) continue;
41
+ if (UUID_PATTERN.test(stripped) || UUID_COMPACT_PATTERN.test(stripped)) return true;
42
+ continue;
43
+ }
44
+ const withoutSignalPrefix = candidate.replace(/^signal:/i, "").trim();
45
+ if (UUID_PATTERN.test(withoutSignalPrefix) || UUID_COMPACT_PATTERN.test(withoutSignalPrefix)) return true;
46
+ if (/^\+?\d{3,}$/.test(withoutSignalPrefix)) return true;
47
+ }
48
+ return false;
49
+ }
50
+ //#endregion
51
+ export { normalizeSignalMessagingTarget as n, normalizeSignalReactionRecipient as r, looksLikeSignalTargetId as t };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { t as detectSignalTransport } from "./transport-detection-D_M79R5f.js";
3
- import { n as signalRpcRequest, t as signalCheck } from "./client-adapter-D9SNPaNx.js";
2
+ import { t as detectSignalTransport } from "./transport-detection-DROVGqJp.js";
3
+ import { n as signalRpcRequest, t as signalCheck } from "./client-adapter-E06RAM6-.js";
4
4
  import { runChannelProbe } from "openclaw/plugin-sdk/text-utility-runtime";
5
5
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
6
6
  //#region extensions/signal/src/probe.ts
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { i as resolveSignalTarget } from "./approval-auth-BY6uuApE.js";
3
- import { c as resolveSignalApprovalTargetAuthorKeys, s as resolveSignalApprovalConversationKey } from "./approval-reactions-cs3Ox9Ow.js";
2
+ import { i as resolveSignalTarget } from "./approval-auth-CkljhI65.js";
3
+ import { c as resolveSignalApprovalTargetAuthorKeys, s as resolveSignalApprovalConversationKey } from "./approval-reactions-C5MzjYo0.js";
4
4
  import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
5
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
6
6
  //#region extensions/signal/src/question-reactions.ts
@@ -1,58 +1,34 @@
1
1
  import { i as resolveSignalAccount } from "./accounts-DO4HMqaK.js";
2
- import { n as signalRpcRequest } from "./client-adapter-D9SNPaNx.js";
2
+ import { r as normalizeSignalReactionRecipient } from "./normalize-l_b99hap.js";
3
+ import { n as signalRpcRequest } from "./client-adapter-E06RAM6-.js";
3
4
  import { t as resolveSignalRpcContext } from "./rpc-context-dXSy4NtF.js";
4
- import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
6
6
  //#region extensions/signal/src/send-reactions.ts
7
- function normalizeSignalId(raw) {
8
- const trimmed = raw.trim();
9
- if (!trimmed) return "";
10
- return trimmed.replace(/^signal:/i, "").trim();
11
- }
12
- function normalizeSignalUuid(raw) {
13
- const trimmed = normalizeSignalId(raw);
14
- if (!trimmed) return "";
15
- if (normalizeLowercaseStringOrEmpty(trimmed).startsWith("uuid:")) return trimmed.slice(5).trim();
16
- return trimmed;
17
- }
18
- function resolveTargetAuthorParams(params) {
19
- const candidates = [
20
- params.targetAuthor,
21
- params.targetAuthorUuid,
22
- params.fallback
23
- ];
24
- for (const candidate of candidates) {
25
- const raw = candidate?.trim();
26
- if (!raw) continue;
27
- const normalized = normalizeSignalUuid(raw);
28
- if (normalized) return { targetAuthor: normalized };
29
- }
30
- return {};
31
- }
32
7
  async function sendReactionSignalCore(params) {
8
+ const cfg = requireRuntimeConfig(params.opts.cfg, "Signal reactions");
33
9
  const accountInfo = resolveSignalAccount({
34
- cfg: requireRuntimeConfig(params.opts.cfg, "Signal reactions"),
10
+ cfg,
35
11
  accountId: params.opts.accountId
36
12
  });
37
13
  const { baseUrl, account } = resolveSignalRpcContext(params.opts, accountInfo);
38
- const normalizedRecipient = normalizeSignalUuid(params.recipient);
14
+ const normalizedRecipient = normalizeSignalReactionRecipient(params.recipient);
39
15
  const groupId = params.opts.groupId?.trim();
40
16
  const operation = `Signal reaction${params.remove ? " removal" : ""}`;
41
17
  if (!normalizedRecipient && !groupId) throw new Error(`Recipient or groupId is required for ${operation}`);
42
18
  if (!Number.isFinite(params.targetTimestamp) || params.targetTimestamp <= 0) throw new Error(`Valid targetTimestamp is required for ${operation}`);
43
19
  const normalizedEmoji = params.emoji?.trim();
44
20
  if (!normalizedEmoji) throw new Error(`Emoji is required for ${operation}`);
45
- const targetAuthorParams = resolveTargetAuthorParams({
46
- targetAuthor: params.opts.targetAuthor,
47
- targetAuthorUuid: params.opts.targetAuthorUuid,
48
- fallback: normalizedRecipient
49
- });
50
- if (groupId && !targetAuthorParams.targetAuthor) throw new Error(`targetAuthor is required for group reaction${params.remove ? " removal" : "s"}`);
21
+ const targetAuthor = [
22
+ params.opts.targetAuthor,
23
+ params.opts.targetAuthorUuid,
24
+ normalizedRecipient
25
+ ].map((candidate) => normalizeSignalReactionRecipient(candidate ?? "")).find(Boolean);
26
+ if (groupId && !targetAuthor) throw new Error(`targetAuthor is required for group reaction${params.remove ? " removal" : "s"}`);
51
27
  const requestParams = {
52
28
  emoji: normalizedEmoji,
53
29
  targetTimestamp: params.targetTimestamp,
54
30
  ...params.remove ? { remove: true } : {},
55
- ...targetAuthorParams
31
+ ...targetAuthor ? { targetAuthor } : {}
56
32
  };
57
33
  if (normalizedRecipient) requestParams.recipients = [normalizedRecipient];
58
34
  if (groupId) requestParams.groupIds = [groupId];
@@ -1,2 +1,2 @@
1
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-YGD6hhDh.js";
1
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BUy1VGT6.js";
2
2
  export { removeReactionSignal, sendReactionSignal };
@@ -1,14 +1,14 @@
1
1
  import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-DO4HMqaK.js";
2
- import { d as normalizeSignalMessagingTarget, u as looksLikeSignalTargetId } from "./identity-BQ4OzXXk.js";
3
- import { a as setSignalRuntime, c as resolveSignalReactionLevel, s as signalMessageActions } from "./transport-detection-D_M79R5f.js";
4
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-YGD6hhDh.js";
5
- import { n as SignalConfigSchema } from "./config-schema-CkMIK7zp.js";
6
- import { i as installSignalCli } from "./install-signal-cli-Cpiyk0k1.js";
7
- import { t as monitorSignalProvider } from "./monitor-BLFIkpH0.js";
8
- import { t as sendMessageSignal } from "./send-BNl5folj.js";
9
- import { t as probeSignal } from "./probe-B0E_cXQw.js";
2
+ import { n as normalizeSignalMessagingTarget, t as looksLikeSignalTargetId } from "./normalize-l_b99hap.js";
3
+ import { a as setSignalRuntime, c as resolveSignalReactionLevel, s as signalMessageActions } from "./transport-detection-DROVGqJp.js";
4
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BUy1VGT6.js";
5
+ import { n as SignalConfigSchema } from "./config-schema-CHihQTOp.js";
6
+ import { i as installSignalCli } from "./install-signal-cli-7tEL37_j.js";
7
+ import { t as monitorSignalProvider } from "./monitor-CfRPorq9.js";
8
+ import { t as sendMessageSignal } from "./send-G6zfBh13.js";
9
+ import { t as probeSignal } from "./probe-CiVqVfko.js";
10
+ import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/account-helpers";
10
11
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
11
- import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
12
12
  import { buildBaseAccountStatusSnapshot, buildBaseChannelStatusSummary, collectStatusIssuesFromLastError, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
13
13
  import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
14
14
  import { DEFAULT_ACCOUNT_ID, applyAccountNameToChannelSection, deleteAccountFromConfigSection, emptyPluginConfigSchema, formatPairingApproveHint, getChatChannelMeta, migrateBaseNameToDefaultAccount, normalizeAccountId, setAccountEnabledInConfigSection } from "openclaw/plugin-sdk/core";
@@ -1,12 +1,12 @@
1
1
  import { i as resolveSignalAccount } from "./accounts-DO4HMqaK.js";
2
- import { d as normalizeSignalMessagingTarget } from "./identity-BQ4OzXXk.js";
3
- import { n as registerSignalReplyContext, u as markdownToSignalText } from "./transport-detection-D_M79R5f.js";
4
- import { n as signalRpcRequest } from "./client-adapter-D9SNPaNx.js";
2
+ import { n as normalizeSignalMessagingTarget } from "./normalize-l_b99hap.js";
3
+ import { n as registerSignalReplyContext, u as markdownToSignalText } from "./transport-detection-DROVGqJp.js";
4
+ import { n as signalRpcRequest } from "./client-adapter-E06RAM6-.js";
5
5
  import { t as resolveSignalRpcContext } from "./rpc-context-dXSy4NtF.js";
6
6
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
7
7
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
8
- import { kindFromMime, resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
9
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
9
+ import { kindFromMime, resolveOutboundAttachmentFromUrl } from "openclaw/plugin-sdk/media-runtime";
10
10
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
11
11
  //#region extensions/signal/src/send.ts
12
12
  function assertSignalRecipientDelivery(result, target) {
@@ -28,8 +28,9 @@ function assertSignalRecipientDelivery(result, target) {
28
28
  }
29
29
  async function resolveSignalRpcAccountInfo(opts) {
30
30
  if (!opts.cfg) throw new Error("Signal RPC account resolution requires a resolved runtime config. Load and resolve config at the command or gateway boundary, then pass cfg through the runtime path.");
31
+ const cfg = requireRuntimeConfig(opts.cfg, "Signal RPC account resolution");
31
32
  return resolveSignalAccount({
32
- cfg: requireRuntimeConfig(opts.cfg, "Signal RPC account resolution"),
33
+ cfg,
33
34
  accountId: opts.accountId
34
35
  });
35
36
  }
@@ -111,7 +112,8 @@ function resolveSignalQuoteParams(opts) {
111
112
  };
112
113
  }
113
114
  function isSignalQuoteMetadataRejection(error) {
114
- const normalized = normalizeLowercaseStringOrEmpty(error instanceof Error ? error.message : String(error));
115
+ const message = error instanceof Error ? error.message : String(error);
116
+ const normalized = normalizeLowercaseStringOrEmpty(message);
115
117
  const rpcCode = /^signal rpc (-?\d+):/u.exec(normalized)?.[1];
116
118
  if (rpcCode !== void 0) {
117
119
  if (rpcCode !== "-32602") return false;
@@ -142,7 +144,7 @@ async function sendMessageSignal(to, text, opts) {
142
144
  if (typeof opts.maxBytes === "number") return opts.maxBytes;
143
145
  if (typeof accountInfo.config.mediaMaxMb === "number") return accountInfo.config.mediaMaxMb * 1024 * 1024;
144
146
  if (typeof cfg.agents?.defaults?.mediaMaxMb === "number") return cfg.agents.defaults.mediaMaxMb * 1024 * 1024;
145
- return 8 * 1024 * 1024;
147
+ return 8388608;
146
148
  })();
147
149
  let attachments;
148
150
  if (opts.mediaUrl?.trim()) {
@@ -157,16 +159,18 @@ async function sendMessageSignal(to, text, opts) {
157
159
  kind: kindFromMime(resolved.contentType ?? void 0) ?? "unknown"
158
160
  };
159
161
  }
160
- if (message.trim()) if (textMode === "plain") textStyles = opts.textStyles ?? [];
161
- else {
162
- const tableMode = resolveMarkdownTableMode({
163
- cfg,
164
- channel: "signal",
165
- accountId: accountInfo.accountId
166
- });
167
- const formatted = markdownToSignalText(message, { tableMode });
168
- message = formatted.text;
169
- textStyles = formatted.styles;
162
+ if (message.trim()) {
163
+ if (textMode === "plain") textStyles = opts.textStyles ?? [];
164
+ else {
165
+ const tableMode = resolveMarkdownTableMode({
166
+ cfg,
167
+ channel: "signal",
168
+ accountId: accountInfo.accountId
169
+ });
170
+ const formatted = markdownToSignalText(message, { tableMode });
171
+ message = formatted.text;
172
+ textStyles = formatted.styles;
173
+ }
170
174
  }
171
175
  if (!message.trim() && (!attachments || attachments.length === 0)) throw new Error("Signal send requires text or media");
172
176
  const params = { message };
@@ -1,2 +1,2 @@
1
- import { r as sendTypingSignal, t as sendMessageSignal } from "./send-BNl5folj.js";
1
+ import { r as sendTypingSignal, t as sendMessageSignal } from "./send-G6zfBh13.js";
2
2
  export { sendMessageSignal, sendTypingSignal };
@@ -1,10 +1,9 @@
1
1
  import { u as normalizeSignalTransportUrl } from "./transport-policy-DxvSMHp9.js";
2
2
  import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-DO4HMqaK.js";
3
- import { d as normalizeSignalMessagingTarget } from "./identity-BQ4OzXXk.js";
4
- import { n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-BY6uuApE.js";
5
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-YGD6hhDh.js";
3
+ import { n as normalizeSignalMessagingTarget, r as normalizeSignalReactionRecipient } from "./normalize-l_b99hap.js";
4
+ import { n as signalApprovalAuth, t as getSignalApprovalApprovers } from "./approval-auth-CkljhI65.js";
5
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-BUy1VGT6.js";
6
6
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
7
- import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";
8
7
  import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
9
8
  import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
10
9
  import { resolveReactionLevel } from "openclaw/plugin-sdk/status-helpers";
@@ -15,6 +14,7 @@ import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-s
15
14
  import { shouldSuppressLocalNativeExecApprovalPrompt } from "openclaw/plugin-sdk/approval-native-runtime";
16
15
  import { buildApprovalReactionPendingContentForRequest } from "openclaw/plugin-sdk/approval-reaction-runtime";
17
16
  import { formatMediaPlaceholderText } from "openclaw/plugin-sdk/channel-inbound";
17
+ import { kindFromMime } from "openclaw/plugin-sdk/media-runtime";
18
18
  import { createActionGate, jsonResult, readStringParam, resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
19
19
  import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
20
20
  import { getExecApprovalReplyMetadata } from "openclaw/plugin-sdk/approval-reply-runtime";
@@ -69,7 +69,7 @@ const signalApproval = createApproverRestrictedNativeApprovalCapabilityFromForwa
69
69
  approvalKind,
70
70
  request
71
71
  }),
72
- load: async () => (await import("./approval-handler.runtime-Co6EVTqY.js")).signalApprovalNativeRuntime
72
+ load: async () => (await import("./approval-handler.runtime-C5SsJ5ko.js")).signalApprovalNativeRuntime
73
73
  })
74
74
  });
75
75
  const signalApprovalRouting = signalApproval.routing;
@@ -164,8 +164,9 @@ function markdownToSignalText(markdown, options = {}) {
164
164
  return renderSignalText(markdownToSignalIR(markdown, options));
165
165
  }
166
166
  function markdownToSignalTextChunks(markdown, limit, options = {}) {
167
+ const ir = markdownToSignalIR(markdown, options);
167
168
  return renderMarkdownIRChunksWithinLimit({
168
- ir: markdownToSignalIR(markdown, options),
169
+ ir,
169
170
  limit,
170
171
  assistantTranscriptRoleMessageBoundaries: true,
171
172
  renderChunk: renderSignalText,
@@ -200,11 +201,12 @@ function formatSignalMediaText(media) {
200
201
  * - "extensive": Agent can react liberally
201
202
  */
202
203
  function resolveSignalReactionLevel(params) {
204
+ const account = resolveSignalAccount({
205
+ cfg: params.cfg,
206
+ accountId: params.accountId
207
+ });
203
208
  return resolveReactionLevel({
204
- value: resolveSignalAccount({
205
- cfg: params.cfg,
206
- accountId: params.accountId
207
- }).config.reactionLevel,
209
+ value: account.config.reactionLevel,
208
210
  defaultLevel: "minimal",
209
211
  invalidFallback: "minimal"
210
212
  });
@@ -213,18 +215,8 @@ function resolveSignalReactionLevel(params) {
213
215
  //#region extensions/signal/src/message-actions.ts
214
216
  const providerId = "signal";
215
217
  const GROUP_PREFIX = "group:";
216
- function normalizeSignalReactionRecipient(raw) {
217
- const trimmed = raw.trim();
218
- if (!trimmed) return trimmed;
219
- const withoutSignal = trimmed.replace(/^signal:/i, "").trim();
220
- if (!withoutSignal) return withoutSignal;
221
- if (normalizeLowercaseStringOrEmpty(withoutSignal).startsWith("uuid:")) return withoutSignal.slice(5).trim();
222
- return withoutSignal;
223
- }
224
218
  function resolveSignalReactionTarget(raw) {
225
- const trimmed = raw.trim();
226
- if (!trimmed) return {};
227
- const withoutSignal = trimmed.replace(/^signal:/i, "").trim();
219
+ const withoutSignal = raw.trim().replace(/^signal:/i, "").trim();
228
220
  if (!withoutSignal) return {};
229
221
  if (normalizeLowercaseStringOrEmpty(withoutSignal).startsWith(GROUP_PREFIX)) {
230
222
  const groupId = withoutSignal.slice(6).trim();
@@ -240,17 +232,10 @@ async function mutateSignalReaction(params) {
240
232
  targetAuthor: params.targetAuthor,
241
233
  targetAuthorUuid: params.targetAuthorUuid
242
234
  };
243
- if (params.remove) {
244
- await removeReactionSignal(params.target.recipient ?? "", params.timestamp, params.emoji, options);
245
- return jsonResult({
246
- ok: true,
247
- removed: params.emoji
248
- });
249
- }
250
- await sendReactionSignal(params.target.recipient ?? "", params.timestamp, params.emoji, options);
235
+ await (params.remove ? removeReactionSignal : sendReactionSignal)(params.target.recipient ?? "", params.timestamp, params.emoji, options);
251
236
  return jsonResult({
252
237
  ok: true,
253
- added: params.emoji
238
+ [params.remove ? "removed" : "added"]: params.emoji
254
239
  });
255
240
  }
256
241
  const signalMessageActions = {
@@ -307,27 +292,14 @@ const signalMessageActions = {
307
292
  const remove = typeof params.remove === "boolean" ? params.remove : void 0;
308
293
  const timestamp = parseStrictNonNegativeInteger(messageId);
309
294
  if (timestamp === void 0) throw new Error(`Invalid messageId: ${messageId}. Expected numeric timestamp.`);
310
- if (remove) {
311
- if (!emoji) throw new Error("Emoji required to remove reaction.");
312
- return await mutateSignalReaction({
313
- cfg,
314
- accountId: account.accountId,
315
- target,
316
- timestamp,
317
- emoji,
318
- remove: true,
319
- targetAuthor,
320
- targetAuthorUuid
321
- });
322
- }
323
- if (!emoji) throw new Error("Emoji required to add reaction.");
295
+ if (!emoji) throw new Error(`Emoji required to ${remove ? "remove" : "add"} reaction.`);
324
296
  return await mutateSignalReaction({
325
297
  cfg,
326
298
  accountId: account.accountId,
327
299
  target,
328
300
  timestamp,
329
301
  emoji,
330
- remove: false,
302
+ remove: Boolean(remove),
331
303
  targetAuthor,
332
304
  targetAuthorUuid
333
305
  });
@@ -347,10 +319,11 @@ function materializeSignalPresentationFallback(payload, presentationOverride) {
347
319
  const presentation = presentationOverride ?? normalizeMessagePresentation(payload.presentation);
348
320
  if (!presentation) return payload;
349
321
  const currentText = payload.text?.trim() ?? "";
350
- const presentationFallback = renderMessagePresentationFallbackText({ presentation: Boolean(getExecApprovalReplyMetadata(payload) && currentText) ? {
322
+ const fallbackPresentation = Boolean(getExecApprovalReplyMetadata(payload) && currentText) ? {
351
323
  ...presentation,
352
324
  blocks: presentation.blocks.filter((block) => !isMessagePresentationInteractiveBlock(block))
353
- } : presentation });
325
+ } : presentation;
326
+ const presentationFallback = renderMessagePresentationFallbackText({ presentation: fallbackPresentation });
354
327
  const text = currentText.includes(presentationFallback) ? currentText : [currentText, presentationFallback].filter(Boolean).join("\n\n");
355
328
  const { presentation: _presentation, ...withoutPresentation } = payload;
356
329
  return {
@@ -374,7 +347,7 @@ const { setRuntime: setSignalRuntime, tryGetRuntime: getOptionalSignalRuntime }
374
347
  //#region extensions/signal/src/reply-authors.ts
375
348
  const PERSISTENT_NAMESPACE = "signal.reply-authors.v1";
376
349
  const PERSISTENT_MAX_ENTRIES = 5e3;
377
- const DEFAULT_REPLY_AUTHOR_TTL_MS = 10080 * 60 * 1e3;
350
+ const DEFAULT_REPLY_AUTHOR_TTL_MS = 6048e5;
378
351
  const { memoryReplyContexts } = signalReplyAuthorState;
379
352
  function openSignalReplyAuthorStore() {
380
353
  if (signalReplyAuthorState.persistentStoreDisabled) return;
@@ -545,7 +518,7 @@ const DEFAULT_PROBE_TIMEOUT_MS = 1e4;
545
518
  async function detectSignalTransport(params) {
546
519
  const url = normalizeSignalTransportUrl(params.url);
547
520
  const timeoutMs = params.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
548
- const probes = params.probeNative && params.probeContainer ? void 0 : await import("./transport-probes.runtime-BsJdp0oI.js");
521
+ const probes = params.probeNative && params.probeContainer ? void 0 : await import("./transport-probes.runtime-BMxOPSFh.js");
549
522
  const probeNative = params.probeNative ?? probes?.nativeCheck;
550
523
  const probeContainer = params.probeContainer ?? probes?.containerCheck;
551
524
  if (!probeNative || !probeContainer) throw new Error("Signal transport probes are unavailable");
@@ -1,2 +1,2 @@
1
- import { t as detectSignalTransport } from "./transport-detection-D_M79R5f.js";
1
+ import { t as detectSignalTransport } from "./transport-detection-DROVGqJp.js";
2
2
  export { detectSignalTransport };
@@ -1,2 +1,2 @@
1
- import { i as containerCheck, t as signalCheck } from "./client-CvnR8_XA.js";
1
+ import { i as containerCheck, t as signalCheck } from "./client-DtHac18U.js";
2
2
  export { containerCheck, signalCheck as nativeCheck };
@@ -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",
@@ -543,7 +543,6 @@
543
543
  "type": "boolean"
544
544
  },
545
545
  "dmPolicy": {
546
- "default": "pairing",
547
546
  "type": "string",
548
547
  "enum": [
549
548
  "pairing",
@@ -582,7 +581,6 @@
582
581
  }
583
582
  },
584
583
  "groupPolicy": {
585
- "default": "allowlist",
586
584
  "type": "string",
587
585
  "enum": [
588
586
  "open",
@@ -996,10 +994,6 @@
996
994
  "additionalProperties": false
997
995
  }
998
996
  },
999
- "required": [
1000
- "dmPolicy",
1001
- "groupPolicy"
1002
- ],
1003
997
  "additionalProperties": false
1004
998
  }
1005
999
  },
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@openclaw/signal",
3
- "version": "2026.8.1-beta.3",
3
+ "version": "2026.8.2",
4
4
  "description": "OpenClaw Signal channel plugin",
5
5
  "type": "module",
6
6
  "dependencies": {
7
- "ws": "8.21.1",
7
+ "ws": "8.21.3",
8
8
  "zod": "4.4.3"
9
9
  },
10
10
  "openclaw": {
@@ -93,10 +93,10 @@
93
93
  "allowInvalidConfigRecovery": true
94
94
  },
95
95
  "compat": {
96
- "pluginApi": ">=2026.8.1-beta.3"
96
+ "pluginApi": ">=2026.8.2"
97
97
  },
98
98
  "build": {
99
- "openclawVersion": "2026.8.1-beta.3",
99
+ "openclawVersion": "2026.8.2",
100
100
  "bundledDist": false
101
101
  },
102
102
  "release": {
@@ -118,7 +118,7 @@
118
118
  "README.md"
119
119
  ],
120
120
  "peerDependencies": {
121
- "openclaw": ">=2026.8.1-beta.3"
121
+ "openclaw": ">=2026.8.2"
122
122
  },
123
123
  "peerDependenciesMeta": {
124
124
  "openclaw": {