@openclaw/signal 2026.7.2-beta.2 → 2026.7.2-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId, t as listEnabledSignalAccounts } from "./accounts-Bz4HtP0g.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-BF8taj7g.js";
3
- import { a as resolveSignalReactionLevel, i as signalMessageActions, o as markdownToSignalText, s as markdownToSignalTextChunks } from "./reply-authors-osU_SY4J.js";
4
- import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-DifyinAU.js";
5
- import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-DK8XZHPe.js";
6
- import { i as installSignalCli, o as looksLikeArchive, r as extractSignalCliArchive, s as pickAsset } from "./install-signal-cli-CtusY3tN.js";
7
- import { t as monitorSignalProvider } from "./monitor-BdzH3U64.js";
8
- import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-BWtA6h3J.js";
9
- import { t as probeSignal } from "./probe-CbWkI24J.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 { a as resolveSignalReactionLevel, i as signalMessageActions, o as markdownToSignalText, s as markdownToSignalTextChunks } from "./reply-authors-DcNqGpX-.js";
4
+ import { n as sendReactionSignal, t as removeReactionSignal } from "./reaction-runtime-api-tPkUVRoL.js";
5
+ import { a as normalizeSignalAccountInput, l as signalSetupAdapter, n as createSignalPluginBase, r as signalSetupWizard, t as signalPlugin, u as resolveSignalOutboundTarget } from "./channel-ChLRPIuC.js";
6
+ import { i as installSignalCli, o as looksLikeArchive, r as extractSignalCliArchive, s as pickAsset } from "./install-signal-cli-l35FqIbP.js";
7
+ import { t as monitorSignalProvider } from "./monitor-D2nTNhM2.js";
8
+ import { n as sendReadReceiptSignal, r as sendTypingSignal, t as sendMessageSignal } from "./send-f6JLstd2.js";
9
+ import { t as probeSignal } from "./probe-sSH6ggyy.js";
10
10
  //#region extensions/signal/src/channel.setup.ts
11
11
  const signalSetupPlugin = { ...createSignalPluginBase({
12
12
  setupWizard: signalSetupWizard,
@@ -1,8 +1,8 @@
1
1
  import { r as resolveDefaultSignalAccountId } from "./accounts-Bz4HtP0g.js";
2
- import { d as normalizeSignalMessagingTarget } from "./identity-BF8taj7g.js";
3
- import { o as resolveSignalTarget } from "./runtime-BZ9hnS3a.js";
4
- import { d as unregisterSignalApprovalReactionTarget, i as hasSignalApprovalReactionApprovers, l as resolveSignalApprovalConversationKey, o as registerSignalApprovalReactionTarget, u as resolveSignalApprovalTargetAuthorKeys } from "./approval-reactions-ChcS2rQN.js";
5
- import { r as sendTypingSignal, t as sendMessageSignal } from "./send-BWtA6h3J.js";
2
+ import { d as normalizeSignalMessagingTarget } from "./identity-BQ4OzXXk.js";
3
+ import { o as resolveSignalTarget } from "./runtime-B900w6lc.js";
4
+ import { d as unregisterSignalApprovalReactionTarget, i as hasSignalApprovalReactionApprovers, l as resolveSignalApprovalConversationKey, o as registerSignalApprovalReactionTarget, u as resolveSignalApprovalTargetAuthorKeys } from "./approval-reactions-DcpZRS5-.js";
5
+ import { r as sendTypingSignal, t as sendMessageSignal } from "./send-f6JLstd2.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,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-BF8taj7g.js";
3
- import { i as signalApprovalAuth, o as resolveSignalTarget, r as getSignalApprovalApprovers, t as getOptionalSignalRuntime } from "./runtime-BZ9hnS3a.js";
2
+ import { d as normalizeSignalMessagingTarget, l as looksLikeUuid } from "./identity-BQ4OzXXk.js";
3
+ import { i as signalApprovalAuth, o as resolveSignalTarget, r as getSignalApprovalApprovers, t as getOptionalSignalRuntime } from "./runtime-B900w6lc.js";
4
4
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
5
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,7 +1,7 @@
1
1
  import { a as resolveSignalReplyToMode, i as resolveSignalAccount, n as listSignalAccountIds, r as resolveDefaultSignalAccountId } from "./accounts-Bz4HtP0g.js";
2
- import { c as resolveSignalSender, d as normalizeSignalMessagingTarget, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient, u as looksLikeSignalTargetId } from "./identity-BF8taj7g.js";
3
- import { a as listSignalAliasDirectoryEntries, o as resolveSignalTarget } from "./runtime-BZ9hnS3a.js";
4
- import { a as resolveSignalReactionLevel, i as signalMessageActions, l as shouldSuppressLocalSignalExecApprovalPrompt, n as resolveSignalReplyContextWithPersistence, r as materializeSignalPresentationFallback, s as markdownToSignalTextChunks, u as signalApprovalCapability } from "./reply-authors-osU_SY4J.js";
2
+ import { c as resolveSignalSender, d as normalizeSignalMessagingTarget, l as looksLikeUuid, o as resolveSignalPeerId, s as resolveSignalRecipient, u as looksLikeSignalTargetId } from "./identity-BQ4OzXXk.js";
3
+ import { a as listSignalAliasDirectoryEntries, o as resolveSignalTarget } from "./runtime-B900w6lc.js";
4
+ import { a as resolveSignalReactionLevel, i as signalMessageActions, l as shouldSuppressLocalSignalExecApprovalPrompt, n as resolveSignalReplyContextWithPersistence, r as materializeSignalPresentationFallback, s as markdownToSignalTextChunks, u as signalApprovalCapability } from "./reply-authors-DcNqGpX-.js";
5
5
  import { t as SignalChannelConfigSchema } from "./config-schema-CfVNH0DB.js";
6
6
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
7
7
  import { buildDmGroupAccountAllowlistAdapter } from "openclaw/plugin-sdk/allowlist-config-edit";
@@ -13,6 +13,7 @@ import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
13
13
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
14
14
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
15
15
  import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
16
+ import { questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
16
17
  import { chunkText, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
17
18
  import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
18
19
  import { buildBaseChannelStatusSummary, collectStatusIssuesFromLastError, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
@@ -246,7 +247,7 @@ function createSignalSetupWizardProxy(loadWizard) {
246
247
  //#region extensions/signal/src/shared.ts
247
248
  const SIGNAL_CHANNEL = "signal";
248
249
  async function loadSignalChannelRuntime() {
249
- return await import("./channel.runtime-BbDh5UIr.js");
250
+ return await import("./channel.runtime-ts_U4_q4.js");
250
251
  }
251
252
  const signalSetupWizard = createSignalSetupWizardProxy(async () => (await loadSignalChannelRuntime()).signalSetupWizard);
252
253
  const signalConfigAdapter = {
@@ -332,10 +333,10 @@ function createSignalPluginBase(params) {
332
333
  }
333
334
  //#endregion
334
335
  //#region extensions/signal/src/channel.ts
335
- const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor-BdzH3U64.js").then((n) => n.n));
336
- const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe-CbWkI24J.js").then((n) => n.n));
337
- const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-D4WBNNgn.js"));
338
- const loadSignalApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-ChcS2rQN.js").then((n) => n.r));
336
+ const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor-D2nTNhM2.js").then((n) => n.n));
337
+ const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe-sSH6ggyy.js").then((n) => n.n));
338
+ const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-B_UYsXWd.js"));
339
+ const loadSignalApprovalReactionsModule = createLazyRuntimeModule(() => import("./approval-reactions-DcpZRS5-.js").then((n) => n.r));
339
340
  async function resolveSignalSendContext(params) {
340
341
  return {
341
342
  send: resolveOutboundSendDep(params.deps, "signal") ?? (await loadSignalSendRuntime()).sendMessageSignal,
@@ -566,6 +567,18 @@ async function registerDeliveredSignalApprovalPayloadForReactions(params) {
566
567
  const targetAuthor = normalizeOptionalString(account.config.account);
567
568
  const targetAuthorUuid = normalizeOptionalString(account.config.accountUuid);
568
569
  if (!targetAuthor && !targetAuthorUuid) return;
570
+ const { registerSignalQuestionReactionTargetForDeliveredPayload } = await import("./question-reactions-BFFJNQsu.js").then((n) => n.n);
571
+ registerSignalQuestionReactionTargetForDeliveredPayload({
572
+ cfg: params.cfg,
573
+ target: {
574
+ ...params.target,
575
+ accountId: account.accountId
576
+ },
577
+ payload: params.payload,
578
+ results: params.results,
579
+ targetAuthor,
580
+ targetAuthorUuid
581
+ });
569
582
  const { registerSignalApprovalReactionTargetForDeliveredPayload } = await loadSignalApprovalReactionsModule();
570
583
  registerSignalApprovalReactionTargetForDeliveredPayload({
571
584
  cfg: params.cfg,
@@ -589,6 +602,11 @@ async function renderSignalApprovalPayloadForReactions(params) {
589
602
  if (!targetAuthor && !targetAuthorUuid) return null;
590
603
  const { addSignalApprovalReactionHintToStructuredPayload } = await loadSignalApprovalReactionsModule();
591
604
  const payload = materializeSignalPresentationFallback(params.payload, params.presentation);
605
+ const questionPayload = questionGatewayRuntime.prepareReactionPayloadForDelivery({
606
+ payload: params.payload,
607
+ presentation: params.presentation
608
+ });
609
+ if (questionPayload) return questionPayload;
592
610
  return addSignalApprovalReactionHintToStructuredPayload({
593
611
  cfg: params.ctx.cfg,
594
612
  accountId: params.ctx.accountId ?? void 0,
@@ -1,2 +1,2 @@
1
- import { t as signalPlugin } from "./channel-DK8XZHPe.js";
1
+ import { t as signalPlugin } from "./channel-ChLRPIuC.js";
2
2
  export { signalPlugin };
@@ -1,6 +1,6 @@
1
1
  import { i as resolveSignalAccount, n as listSignalAccountIds } from "./accounts-Bz4HtP0g.js";
2
- import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-DK8XZHPe.js";
3
- import { i as installSignalCli } from "./install-signal-cli-CtusY3tN.js";
2
+ import { c as signalNumberTextInput, i as createSignalCliPathTextInput, o as signalCompletionNote, s as signalDmPolicy } from "./channel-ChLRPIuC.js";
3
+ import { i as installSignalCli } from "./install-signal-cli-l35FqIbP.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
@@ -246,16 +246,27 @@ async function streamContainerEvents(params) {
246
246
  log(`[signal-ws] connecting to ${redactedWsUrl}`);
247
247
  return new Promise((resolve, reject) => {
248
248
  let ws;
249
- let resolved = false;
249
+ let settled = false;
250
+ let eventChain = Promise.resolve();
250
251
  let abortHandler;
251
252
  const cleanup = () => {
252
- if (resolved) return;
253
- resolved = true;
254
253
  if (abortHandler) {
255
254
  params.abortSignal?.removeEventListener("abort", abortHandler);
256
255
  abortHandler = void 0;
257
256
  }
258
257
  };
258
+ const resolveOnce = () => {
259
+ if (settled) return;
260
+ settled = true;
261
+ cleanup();
262
+ resolve();
263
+ };
264
+ const rejectOnce = (error) => {
265
+ if (settled) return;
266
+ settled = true;
267
+ cleanup();
268
+ reject(toLintErrorObject$1(error, "Signal WebSocket receive handler failed"));
269
+ };
259
270
  try {
260
271
  ws = new WebSocket(wsUrl, {
261
272
  maxPayload: WS_MAX_PAYLOAD,
@@ -270,10 +281,20 @@ async function streamContainerEvents(params) {
270
281
  log("[signal-ws] connected");
271
282
  });
272
283
  ws.on("message", (data) => {
284
+ if (settled) return;
273
285
  try {
274
286
  const text = data.toString();
275
287
  const envelope = JSON.parse(text);
276
- if (envelope) params.onEvent(envelope);
288
+ if (envelope) {
289
+ eventChain = eventChain.then(async () => {
290
+ await params.onEvent(envelope);
291
+ });
292
+ eventChain.catch((err) => {
293
+ logError(`[signal-ws] receive handler failed: ${err instanceof Error ? err.message : String(err)}`);
294
+ rejectOnce(err);
295
+ ws.close();
296
+ });
297
+ }
277
298
  } catch (err) {
278
299
  logError(`[signal-ws] parse error: ${err instanceof Error ? err.message : String(err)}`);
279
300
  }
@@ -284,8 +305,7 @@ async function streamContainerEvents(params) {
284
305
  ws.on("close", (code, reason) => {
285
306
  const reasonStr = reason?.toString() || "no reason";
286
307
  log(`[signal-ws] closed (code=${code}, reason=${reasonStr})`);
287
- cleanup();
288
- resolve();
308
+ eventChain.then(resolveOnce, rejectOnce);
289
309
  });
290
310
  ws.on("ping", () => {
291
311
  log("[signal-ws] ping received");
@@ -296,9 +316,8 @@ async function streamContainerEvents(params) {
296
316
  if (params.abortSignal) {
297
317
  abortHandler = () => {
298
318
  log("[signal-ws] aborted, closing connection");
299
- cleanup();
300
319
  ws.close();
301
- resolve();
320
+ resolveOnce();
302
321
  };
303
322
  params.abortSignal.addEventListener("abort", abortHandler, { once: true });
304
323
  }
@@ -805,9 +824,9 @@ async function streamSignalEvents$1(params) {
805
824
  let bufferedBytes = 0;
806
825
  let currentEvent = {};
807
826
  let currentEventDataBytes = 0;
808
- const flushEvent = () => {
827
+ const flushEvent = async () => {
809
828
  if (!currentEvent.data && !currentEvent.event && !currentEvent.id) return;
810
- params.onEvent({
829
+ await params.onEvent({
811
830
  event: currentEvent.event,
812
831
  data: currentEvent.data,
813
832
  id: currentEvent.id
@@ -815,9 +834,9 @@ async function streamSignalEvents$1(params) {
815
834
  currentEvent = {};
816
835
  currentEventDataBytes = 0;
817
836
  };
818
- const processLine = (line) => {
837
+ const processLine = async (line) => {
819
838
  if (line === "") {
820
- flushEvent();
839
+ await flushEvent();
821
840
  return;
822
841
  }
823
842
  if (line.startsWith(":")) return;
@@ -834,13 +853,13 @@ async function streamSignalEvents$1(params) {
834
853
  currentEvent.data = currentEvent.data ? `${currentEvent.data}${segment}` : segment;
835
854
  } else if (field === "id") currentEvent.id = value;
836
855
  };
837
- const drainCompleteLines = () => {
856
+ const drainCompleteLines = async () => {
838
857
  let lineEnd = buffer.indexOf("\n");
839
858
  while (lineEnd !== -1) {
840
859
  let line = buffer.slice(0, lineEnd);
841
860
  buffer = buffer.slice(lineEnd + 1);
842
861
  if (line.endsWith("\r")) line = line.slice(0, -1);
843
- processLine(line);
862
+ await processLine(line);
844
863
  lineEnd = buffer.indexOf("\n");
845
864
  }
846
865
  bufferedBytes = Buffer$1.byteLength(buffer, "utf8");
@@ -851,7 +870,7 @@ async function streamSignalEvents$1(params) {
851
870
  bufferedBytes += value.byteLength;
852
871
  if (bufferedBytes > MAX_SIGNAL_SSE_BUFFER_BYTES) throw new Error("Signal SSE buffer exceeded size limit");
853
872
  buffer += decoder.decode(value, { stream: true });
854
- drainCompleteLines();
873
+ await drainCompleteLines();
855
874
  }
856
875
  const tail = decoder.decode();
857
876
  if (tail) {
@@ -859,11 +878,11 @@ async function streamSignalEvents$1(params) {
859
878
  bufferedBytes = Buffer$1.byteLength(buffer, "utf8");
860
879
  }
861
880
  if (bufferedBytes > MAX_SIGNAL_SSE_BUFFER_BYTES) throw new Error("Signal SSE buffer exceeded size limit");
862
- drainCompleteLines();
881
+ await drainCompleteLines();
863
882
  } finally {
864
883
  cleanup();
865
884
  }
866
- flushEvent();
885
+ await flushEvent();
867
886
  }
868
887
  function toLintErrorObject(value, fallbackMessage) {
869
888
  if (value instanceof Error) return value;
@@ -1,3 +1,3 @@
1
- import { d as normalizeSignalMessagingTarget, i as isSignalSenderAllowed, u as looksLikeSignalTargetId } from "./identity-BF8taj7g.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-CtusY3tN.js";
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-l35FqIbP.js";
3
3
  export { MAX_SIGNAL_CLI_EXTRACTED_BYTES, downloadToFile, extractSignalCliArchive, installSignalCli, installSignalCliFromRelease, isSignalSenderAllowed, looksLikeArchive, looksLikeSignalTargetId, normalizeSignalMessagingTarget, pickAsset };
@@ -1,5 +1,6 @@
1
1
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import { normalizeE164 } from "openclaw/plugin-sdk/text-utility-runtime";
3
+ import { resolveAllowlistMatchByCandidates } from "openclaw/plugin-sdk/allow-from";
3
4
  //#region extensions/signal/src/normalize.ts
4
5
  function normalizeSignalMessagingTarget(raw) {
5
6
  const trimmed = raw.trim();
@@ -122,16 +123,24 @@ function normalizeSignalAllowRecipient(entry) {
122
123
  return parsed.kind === "phone" ? parsed.e164 : parsed.raw;
123
124
  }
124
125
  function isSignalSenderAllowed(sender, allowFrom) {
125
- if (allowFrom.length === 0) return false;
126
- const parsed = allowFrom.map(parseSignalAllowEntry).filter((entry) => entry !== null);
127
- if (parsed.some((entry) => entry.kind === "any")) return true;
126
+ const normalizedAllowFrom = allowFrom.flatMap((entry) => {
127
+ const parsed = parseSignalAllowEntry(entry);
128
+ if (!parsed) return [];
129
+ if (parsed.kind === "any") return ["*"];
130
+ return [parsed.kind === "phone" ? `phone:${parsed.e164}` : `uuid:${parsed.raw}`];
131
+ });
128
132
  const senderE164 = sender.kind === "phone" ? sender.e164 : sender.aliases?.e164;
129
133
  const senderUuid = sender.kind === "uuid" ? sender.raw : sender.aliases?.uuid;
130
- return parsed.some((entry) => {
131
- if (entry.kind === "phone") return senderE164 !== void 0 && entry.e164 === senderE164;
132
- if (entry.kind === "uuid") return senderUuid !== void 0 && entry.raw === senderUuid;
133
- return false;
134
- });
134
+ return resolveAllowlistMatchByCandidates({
135
+ allowList: normalizedAllowFrom,
136
+ candidates: [{
137
+ value: senderE164 ? `phone:${senderE164}` : void 0,
138
+ source: "phone"
139
+ }, {
140
+ value: senderUuid ? `uuid:${senderUuid}` : void 0,
141
+ source: "uuid"
142
+ }]
143
+ }).allowed;
135
144
  }
136
145
  //#endregion
137
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 };
@@ -44,6 +44,9 @@ function chunkByteLength(chunk) {
44
44
  if (chunk instanceof Uint8Array) return chunk.byteLength;
45
45
  return Buffer.byteLength(String(chunk));
46
46
  }
47
+ async function cancelUnusedResponseBody(response) {
48
+ await response.body?.cancel().catch(() => void 0);
49
+ }
47
50
  /**
48
51
  * Pick a native release asset from the official GitHub releases.
49
52
  *
@@ -76,7 +79,10 @@ async function downloadToFile(url, dest, maxRedirects = 5, maxBytes = MAX_SIGNAL
76
79
  auditContext: "signal-cli-install-archive"
77
80
  });
78
81
  try {
79
- if (!response.ok || !response.body) throw new Error(`HTTP ${response.status || "?"} downloading file`);
82
+ if (!response.ok || !response.body) {
83
+ await cancelUnusedResponseBody(response);
84
+ throw new Error(`HTTP ${response.status || "?"} downloading file`);
85
+ }
80
86
  const rawLength = response.headers.get("content-length");
81
87
  if (rawLength !== null) {
82
88
  const trimmedLength = rawLength.trim();
@@ -189,10 +195,13 @@ async function installSignalCliFromRelease(runtime) {
189
195
  });
190
196
  let payload;
191
197
  try {
192
- if (!response.ok) return {
193
- ok: false,
194
- error: `Failed to fetch release info (${response.status})`
195
- };
198
+ if (!response.ok) {
199
+ await cancelUnusedResponseBody(response);
200
+ return {
201
+ ok: false,
202
+ error: `Failed to fetch release info (${response.status})`
203
+ };
204
+ }
196
205
  try {
197
206
  payload = await readProviderJsonResponse(response, "signal.release-info");
198
207
  } catch {