@openclaw/signal 2026.7.2-beta.5 → 2026.8.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +7 -7
- package/dist/{approval-handler.runtime-C-XYgcxE.js → approval-handler.runtime-Bi5yNhnj.js} +2 -2
- package/dist/{approval-reactions-DtL47gSK.js → approval-reactions-BulCzhdB.js} +15 -45
- package/dist/{channel-CBIljGCH.js → channel-CzDJMDtX.js} +50 -91
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-B8GXmuol.js → channel.runtime-D12iYzJB.js} +2 -2
- package/dist/{client-BazXTH7O.js → client-CvnR8_XA.js} +31 -34
- package/dist/{client-adapter-mXGeEHQJ.js → client-adapter-D9SNPaNx.js} +13 -6
- package/dist/{config-schema-DLvpQPN5.js → config-schema-CkMIK7zp.js} +4 -7
- package/dist/contract-api.js +1 -1
- package/dist/{doctor-contract-api-DbUCknbC.js → doctor-contract-api-Dnp5eQQJ.js} +46 -54
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{install-signal-cli-qJF7iC4h.js → install-signal-cli-Cpiyk0k1.js} +8 -5
- package/dist/{monitor-CHBkf7lk.js → monitor-DiN2hKnG.js} +177 -126
- package/dist/{probe-Br9abaGp.js → probe-C_THuQzn.js} +23 -7
- package/dist/question-reactions-ByjH5qST.js +80 -0
- package/dist/{reaction-runtime-api-BjeDyKcz.js → reaction-runtime-api-Cf6QHcE5.js} +8 -19
- package/dist/reaction-runtime-api.js +1 -1
- package/dist/runtime-api.js +7 -7
- package/dist/{send-B_Ks4MZr.js → send-BvGgByMd.js} +12 -3
- package/dist/{send.runtime-CbuXycZT.js → send.runtime-CtTBBrjL.js} +1 -1
- package/dist/{transport-detection-Da06-LOL.js → transport-detection-BItHawMq.js} +50 -145
- package/dist/{transport-detection.runtime-D_190UUL.js → transport-detection.runtime-DoiwPcrG.js} +1 -1
- package/dist/{transport-probes.runtime-CV6Qs0Og.js → transport-probes.runtime-BsJdp0oI.js} +1 -1
- package/openclaw.plugin.json +4 -1
- package/package.json +5 -5
- package/dist/approval-resolver-B3m0D2R0.js +0 -16
- package/dist/question-reactions-Ds48FtEu.js +0 -109
|
@@ -1,9 +1,14 @@
|
|
|
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-
|
|
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";
|
|
2
|
+
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
2
3
|
//#region extensions/signal/src/client-adapter.ts
|
|
4
|
+
/**
|
|
5
|
+
* Signal client adapter - unified interface for both native signal-cli and bbernhard container.
|
|
6
|
+
*
|
|
7
|
+
* This adapter provides a single API that routes to the concrete account transport.
|
|
8
|
+
* Exports mirror client.ts names so consumers
|
|
9
|
+
* only need to change their import path.
|
|
10
|
+
*/
|
|
3
11
|
const DEFAULT_TIMEOUT_MS = 1e4;
|
|
4
|
-
function formatErrorMessage(error) {
|
|
5
|
-
return error instanceof Error ? error.message : String(error);
|
|
6
|
-
}
|
|
7
12
|
function usesContainer(kind) {
|
|
8
13
|
return kind === "container";
|
|
9
14
|
}
|
|
@@ -19,7 +24,7 @@ async function signalRpcRequest(method, params, opts) {
|
|
|
19
24
|
*/
|
|
20
25
|
async function signalCheck(baseUrl, timeoutMs = DEFAULT_TIMEOUT_MS, options = {}) {
|
|
21
26
|
try {
|
|
22
|
-
return usesContainer(options.transportKind) ? await containerCheck(baseUrl, timeoutMs) : await signalCheck$1(baseUrl, timeoutMs);
|
|
27
|
+
return usesContainer(options.transportKind) ? await containerCheck(baseUrl, timeoutMs, options.account) : await signalCheck$1(baseUrl, timeoutMs);
|
|
23
28
|
} catch (error) {
|
|
24
29
|
return {
|
|
25
30
|
ok: false,
|
|
@@ -42,6 +47,7 @@ async function streamSignalEvents(params) {
|
|
|
42
47
|
event: "receive",
|
|
43
48
|
data: JSON.stringify(event)
|
|
44
49
|
}),
|
|
50
|
+
onStreamOpen: params.onStreamOpen,
|
|
45
51
|
logger: params.logger
|
|
46
52
|
});
|
|
47
53
|
return streamSignalEvents$1({
|
|
@@ -49,7 +55,8 @@ async function streamSignalEvents(params) {
|
|
|
49
55
|
account: params.account,
|
|
50
56
|
abortSignal: params.abortSignal,
|
|
51
57
|
timeoutMs: params.timeoutMs,
|
|
52
|
-
onEvent: (event) => params.onEvent(event)
|
|
58
|
+
onEvent: (event) => params.onEvent(event),
|
|
59
|
+
onStreamOpen: params.onStreamOpen
|
|
53
60
|
});
|
|
54
61
|
}
|
|
55
62
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
|
|
2
|
-
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
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
4
|
import { ChannelDeliveryStreamingConfigSchema, ChannelSendReadReceiptsSchema, ExecutableTokenSchema, ReplyToModeSchema, buildChannelConfigSchema, buildChannelReactionShape, buildCommonChannelAccountShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -60,15 +60,12 @@ const SIGNAL_RETIRED_TRANSPORT_KEYS = [
|
|
|
60
60
|
"ignoreStories"
|
|
61
61
|
];
|
|
62
62
|
const SignalTransportUrlSchema = z.string().url().regex(/^[Hh][Tt][Tt][Pp][Ss]?:\/\/(?![^/?#]*@)/, "Expected http:// or https:// URL without embedded credentials");
|
|
63
|
-
function isRecord$1(value) {
|
|
64
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
65
|
-
}
|
|
66
63
|
function projectSignalConfigForUpdateValidation(value) {
|
|
67
|
-
if (process.env.OPENCLAW_UPDATE_IN_PROGRESS !== "1" || !isRecord
|
|
64
|
+
if (process.env.OPENCLAW_UPDATE_IN_PROGRESS !== "1" || !isRecord(value)) return value;
|
|
68
65
|
const next = { ...value };
|
|
69
66
|
for (const key of SIGNAL_RETIRED_TRANSPORT_KEYS) delete next[key];
|
|
70
|
-
if (isRecord
|
|
71
|
-
if (!isRecord
|
|
67
|
+
if (isRecord(value.accounts)) next.accounts = Object.fromEntries(Object.entries(value.accounts).map(([accountId, account]) => {
|
|
68
|
+
if (!isRecord(account)) return [accountId, account];
|
|
72
69
|
const nextAccount = { ...account };
|
|
73
70
|
for (const key of SIGNAL_RETIRED_TRANSPORT_KEYS) delete nextAccount[key];
|
|
74
71
|
return [accountId, nextAccount];
|
package/dist/contract-api.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
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-
|
|
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
3
|
export { MAX_SIGNAL_CLI_EXTRACTED_BYTES, downloadToFile, extractSignalCliArchive, installSignalCli, installSignalCliFromRelease, isSignalSenderAllowed, looksLikeArchive, looksLikeSignalTargetId, normalizeSignalMessagingTarget, pickAsset };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { a as isSignalManagedNativeConnectionUrlForBind, c as buildSignalTransportHttpUrl, i as assignSignalManagedNativePort, o as isValidSignalManagedNativePort, r as allocateSignalManagedNativePort, s as resolveLocalSignalTransportPort, u as normalizeSignalTransportUrl } from "./transport-policy-DxvSMHp9.js";
|
|
2
|
+
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
3
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
3
|
-
import { defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
|
|
4
|
+
import { defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
4
5
|
//#region extensions/signal/src/config-compat.ts
|
|
5
6
|
const LEGACY_TRANSPORT_FIELDS = [
|
|
6
7
|
"configPath",
|
|
@@ -18,11 +19,8 @@ const PENDING_LEGACY_INVALID_URL_WARNING = "- channels.signal: legacy httpUrl is
|
|
|
18
19
|
const PENDING_LEGACY_INVALID_HOST_WARNING = "- channels.signal: legacy httpHost is invalid; keep the current config, correct httpHost, then run openclaw doctor --fix.";
|
|
19
20
|
const PENDING_LEGACY_INVALID_PORT_WARNING = "- channels.signal: legacy httpPort must be an integer between 1 and 65535; correct httpPort, then run openclaw doctor --fix.";
|
|
20
21
|
const PENDING_LEGACY_CONTAINER_ACCOUNT_WARNING = "- channels.signal: legacy container transport requires an account number; add channels.signal.account (or the relevant channels.signal.accounts.*.account) and rerun openclaw doctor --fix.";
|
|
21
|
-
function isRecord$1(value) {
|
|
22
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23
|
-
}
|
|
24
22
|
function isSignalTransportConfig(value) {
|
|
25
|
-
if (!isRecord
|
|
23
|
+
if (!isRecord(value)) return false;
|
|
26
24
|
if (value.kind === "managed-native") {
|
|
27
25
|
if (value.httpPort !== void 0 && !isValidSignalManagedNativePort(value.httpPort)) return false;
|
|
28
26
|
if (value.url === void 0) return true;
|
|
@@ -42,16 +40,13 @@ function isSignalTransportConfig(value) {
|
|
|
42
40
|
return false;
|
|
43
41
|
}
|
|
44
42
|
}
|
|
45
|
-
function optionalString(value) {
|
|
46
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
47
|
-
}
|
|
48
43
|
function inherited(entry, parent, key) {
|
|
49
44
|
return Object.hasOwn(entry, key) ? entry[key] : parent[key];
|
|
50
45
|
}
|
|
51
46
|
function legacyBaseUrl(entry, parent) {
|
|
52
|
-
const url =
|
|
47
|
+
const url = normalizeOptionalString(inherited(entry, parent, "httpUrl"));
|
|
53
48
|
if (url) return normalizeSignalTransportUrl(url);
|
|
54
|
-
const host =
|
|
49
|
+
const host = normalizeOptionalString(inherited(entry, parent, "httpHost")) ?? "127.0.0.1";
|
|
55
50
|
const rawPort = inherited(entry, parent, "httpPort");
|
|
56
51
|
return buildSignalTransportHttpUrl(host, typeof rawPort === "number" ? rawPort : 8080);
|
|
57
52
|
}
|
|
@@ -59,11 +54,11 @@ function hasLegacyFields(entry) {
|
|
|
59
54
|
return LEGACY_TRANSPORT_FIELDS.some((field) => Object.hasOwn(entry, field));
|
|
60
55
|
}
|
|
61
56
|
function wasLegacySignalAccountConfigured(entry, parent) {
|
|
62
|
-
return Boolean(
|
|
57
|
+
return Boolean(normalizeOptionalString(inherited(entry, parent, "account")) || normalizeOptionalString(inherited(entry, parent, "configPath")) || normalizeOptionalString(inherited(entry, parent, "httpUrl")) || normalizeOptionalString(inherited(entry, parent, "httpHost")) || normalizeOptionalString(inherited(entry, parent, "cliPath")) || typeof inherited(entry, parent, "httpPort") === "number" || typeof inherited(entry, parent, "autoStart") === "boolean");
|
|
63
58
|
}
|
|
64
59
|
function hasInvalidLegacyHttpUrl(entries, parent) {
|
|
65
60
|
return entries.some((entry) => {
|
|
66
|
-
const httpUrl =
|
|
61
|
+
const httpUrl = normalizeOptionalString(inherited(entry, parent, "httpUrl"));
|
|
67
62
|
if (!httpUrl) return false;
|
|
68
63
|
try {
|
|
69
64
|
normalizeSignalTransportUrl(httpUrl);
|
|
@@ -75,10 +70,10 @@ function hasInvalidLegacyHttpUrl(entries, parent) {
|
|
|
75
70
|
}
|
|
76
71
|
function findInvalidLegacyDerivedEndpoint(entries, parent) {
|
|
77
72
|
for (const entry of entries) {
|
|
78
|
-
if (
|
|
73
|
+
if (normalizeOptionalString(inherited(entry, parent, "httpUrl"))) continue;
|
|
79
74
|
const rawPort = inherited(entry, parent, "httpPort");
|
|
80
75
|
if (rawPort !== void 0 && !isValidSignalManagedNativePort(rawPort)) return "port";
|
|
81
|
-
const host =
|
|
76
|
+
const host = normalizeOptionalString(inherited(entry, parent, "httpHost")) ?? "127.0.0.1";
|
|
82
77
|
try {
|
|
83
78
|
buildSignalTransportHttpUrl(host, typeof rawPort === "number" ? rawPort : 8080);
|
|
84
79
|
} catch {
|
|
@@ -91,19 +86,19 @@ function hasInvalidManagedTransportPort(transports) {
|
|
|
91
86
|
}
|
|
92
87
|
function requiresDetection(entry, parent, apiMode) {
|
|
93
88
|
if (apiMode !== void 0 && apiMode !== "auto") return false;
|
|
94
|
-
return Boolean(
|
|
89
|
+
return Boolean(normalizeOptionalString(inherited(entry, parent, "httpUrl"))) || !resolveLegacyAutoStart(entry, parent);
|
|
95
90
|
}
|
|
96
91
|
function resolveLegacyAutoStart(entry, parent) {
|
|
97
92
|
const autoStart = inherited(entry, parent, "autoStart");
|
|
98
93
|
if (typeof autoStart === "boolean") return autoStart;
|
|
99
|
-
return !
|
|
94
|
+
return !normalizeOptionalString(inherited(entry, parent, "httpUrl"));
|
|
100
95
|
}
|
|
101
96
|
function resolveManagedConnectionUrl(entry, parent) {
|
|
102
|
-
const httpUrl =
|
|
97
|
+
const httpUrl = normalizeOptionalString(inherited(entry, parent, "httpUrl"));
|
|
103
98
|
if (!httpUrl) return;
|
|
104
99
|
const normalizedUrl = normalizeSignalTransportUrl(httpUrl);
|
|
105
100
|
const endpoint = new URL(normalizedUrl);
|
|
106
|
-
const bindHost = (
|
|
101
|
+
const bindHost = (normalizeOptionalString(inherited(entry, parent, "httpHost")) ?? "127.0.0.1").replace(/^\[|\]$/g, "").toLowerCase();
|
|
107
102
|
const rawBindPort = inherited(entry, parent, "httpPort");
|
|
108
103
|
const bindPort = typeof rawBindPort === "number" ? rawBindPort : 8080;
|
|
109
104
|
const endpointHost = endpoint.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
@@ -112,10 +107,10 @@ function resolveManagedConnectionUrl(entry, parent) {
|
|
|
112
107
|
}
|
|
113
108
|
function buildManagedNativeTransport(entry, parent) {
|
|
114
109
|
const value = (key) => inherited(entry, parent, key);
|
|
115
|
-
const configPath =
|
|
116
|
-
const cliPath =
|
|
110
|
+
const configPath = normalizeOptionalString(value("configPath"));
|
|
111
|
+
const cliPath = normalizeOptionalString(value("cliPath"));
|
|
117
112
|
const url = resolveManagedConnectionUrl(entry, parent);
|
|
118
|
-
const httpHost =
|
|
113
|
+
const httpHost = normalizeOptionalString(value("httpHost"));
|
|
119
114
|
const httpPort = value("httpPort");
|
|
120
115
|
const startupTimeoutMs = value("startupTimeoutMs");
|
|
121
116
|
const receiveMode = value("receiveMode");
|
|
@@ -154,7 +149,7 @@ function resolveLegacyTransportWithoutDetection(params) {
|
|
|
154
149
|
async function resolveLegacyTransport(params) {
|
|
155
150
|
const resolved = resolveLegacyTransportWithoutDetection(params);
|
|
156
151
|
if (resolved) return resolved;
|
|
157
|
-
const account =
|
|
152
|
+
const account = normalizeOptionalString(inherited(params.entry, params.parent, "account"));
|
|
158
153
|
try {
|
|
159
154
|
const detected = await params.detect?.({
|
|
160
155
|
url: legacyBaseUrl(params.entry, params.parent),
|
|
@@ -172,11 +167,11 @@ function clearLegacyTransportFields(entry) {
|
|
|
172
167
|
}
|
|
173
168
|
function hasRootSignalAccount(entries) {
|
|
174
169
|
const root = entries[0];
|
|
175
|
-
return entries.length === 1 || Boolean(
|
|
170
|
+
return entries.length === 1 || Boolean(normalizeOptionalString(root?.account)) || isSignalTransportConfig(root?.transport);
|
|
176
171
|
}
|
|
177
172
|
function signalAccountIds(entries) {
|
|
178
|
-
const accounts = isRecord
|
|
179
|
-
return Object.entries(accounts).filter(([, entry]) => isRecord
|
|
173
|
+
const accounts = isRecord(entries[0]?.accounts) ? entries[0].accounts : {};
|
|
174
|
+
return Object.entries(accounts).filter(([, entry]) => isRecord(entry)).map(([accountId]) => accountId);
|
|
180
175
|
}
|
|
181
176
|
function isDefaultSignalAccountId(accountId) {
|
|
182
177
|
return Boolean(accountId?.trim()) && normalizeAccountId(accountId) === DEFAULT_ACCOUNT_ID;
|
|
@@ -186,10 +181,10 @@ function resolveSignalAccountKey(accounts, accountId) {
|
|
|
186
181
|
return Object.keys(accounts).find((key) => Boolean(key.trim()) && normalizeAccountId(key) === normalizedAccountId);
|
|
187
182
|
}
|
|
188
183
|
function nestedDefaultOwnsEffectiveTransport(entries) {
|
|
189
|
-
const accounts = isRecord
|
|
184
|
+
const accounts = isRecord(entries[0]?.accounts) ? entries[0].accounts : {};
|
|
190
185
|
const nestedDefaultKey = resolveSignalAccountKey(accounts, DEFAULT_ACCOUNT_ID);
|
|
191
186
|
const nestedDefault = nestedDefaultKey ? accounts[nestedDefaultKey] : void 0;
|
|
192
|
-
return isRecord
|
|
187
|
+
return isRecord(nestedDefault) && (isSignalTransportConfig(nestedDefault.transport) || hasLegacyFields(nestedDefault));
|
|
193
188
|
}
|
|
194
189
|
function isDiscardedTransportEntry(entries, index) {
|
|
195
190
|
if (index === 0) return !hasRootSignalAccount(entries) || nestedDefaultOwnsEffectiveTransport(entries);
|
|
@@ -204,23 +199,23 @@ function shouldMaterializeTransport(entries, index) {
|
|
|
204
199
|
function clearLegacySignalTransportFieldsForAccount(params) {
|
|
205
200
|
const next = structuredClone(params.cfg);
|
|
206
201
|
const signal = next.channels?.signal;
|
|
207
|
-
if (!isRecord
|
|
202
|
+
if (!isRecord(signal)) return next;
|
|
208
203
|
if (isDefaultSignalAccountId(params.accountId)) {
|
|
209
204
|
clearLegacyTransportFields(signal);
|
|
210
205
|
delete signal.apiMode;
|
|
211
|
-
const accounts = isRecord
|
|
206
|
+
const accounts = isRecord(signal.accounts) ? signal.accounts : void 0;
|
|
212
207
|
const nestedDefaultKey = accounts ? resolveSignalAccountKey(accounts, DEFAULT_ACCOUNT_ID) : void 0;
|
|
213
208
|
const nestedDefault = nestedDefaultKey ? accounts?.[nestedDefaultKey] : void 0;
|
|
214
|
-
if (isRecord
|
|
209
|
+
if (isRecord(nestedDefault)) {
|
|
215
210
|
clearLegacyTransportFields(nestedDefault);
|
|
216
211
|
delete nestedDefault.transport;
|
|
217
212
|
}
|
|
218
213
|
return next;
|
|
219
214
|
}
|
|
220
|
-
const accounts = isRecord
|
|
215
|
+
const accounts = isRecord(signal.accounts) ? signal.accounts : void 0;
|
|
221
216
|
const accountKey = accounts ? resolveSignalAccountKey(accounts, params.accountId) : void 0;
|
|
222
217
|
const account = accountKey ? accounts?.[accountKey] : void 0;
|
|
223
|
-
if (isRecord
|
|
218
|
+
if (isRecord(account)) clearLegacyTransportFields(account);
|
|
224
219
|
return next;
|
|
225
220
|
}
|
|
226
221
|
function allocateMigratedManagedPorts(params) {
|
|
@@ -239,12 +234,12 @@ function allocateMigratedManagedPorts(params) {
|
|
|
239
234
|
const localConnectionPort = resolveLocalSignalTransportPort(transport.url);
|
|
240
235
|
if (localConnectionPort !== void 0) reservedPorts.add(localConnectionPort);
|
|
241
236
|
}
|
|
242
|
-
if (index === canonicalDefaultIndex || isRecord
|
|
237
|
+
if (index === canonicalDefaultIndex || isRecord(params.entries[index]?.transport)) reservedPorts.add(transport.httpPort ?? 8080);
|
|
243
238
|
}
|
|
244
239
|
return params.transports.map((transport, index) => {
|
|
245
240
|
if (!transport || index === 0 && canonicalDefaultIndex !== 0) return transport;
|
|
246
241
|
if (transport.kind !== "managed-native") return transport;
|
|
247
|
-
if (isRecord
|
|
242
|
+
if (isRecord(params.entries[index]?.transport) || index === canonicalDefaultIndex) return transport;
|
|
248
243
|
const rawPreferredPort = params.entries[index]?.httpPort;
|
|
249
244
|
const preferredPort = typeof rawPreferredPort === "number" ? rawPreferredPort : transport.httpPort;
|
|
250
245
|
const httpPort = allocateSignalManagedNativePort({
|
|
@@ -258,10 +253,10 @@ function allocateMigratedManagedPorts(params) {
|
|
|
258
253
|
function applyMigratedSignalTransports(params) {
|
|
259
254
|
const next = structuredClone(params.cfg);
|
|
260
255
|
const nextSignal = next.channels?.signal;
|
|
261
|
-
if (!isRecord
|
|
256
|
+
if (!isRecord(nextSignal)) return;
|
|
262
257
|
const accountIds = signalAccountIds(params.entries);
|
|
263
|
-
const nextAccounts = isRecord
|
|
264
|
-
const nextEntries = [nextSignal, ...Object.values(nextAccounts).filter(isRecord
|
|
258
|
+
const nextAccounts = isRecord(nextSignal.accounts) ? nextSignal.accounts : {};
|
|
259
|
+
const nextEntries = [nextSignal, ...Object.values(nextAccounts).filter(isRecord)];
|
|
265
260
|
const rootIsAccount = hasRootSignalAccount(params.entries);
|
|
266
261
|
const canonicalRootTransport = isSignalTransportConfig(params.entries[0]?.transport) ? params.entries[0].transport : void 0;
|
|
267
262
|
for (const [index, entry] of nextEntries.entries()) {
|
|
@@ -280,37 +275,37 @@ function applyMigratedSignalTransports(params) {
|
|
|
280
275
|
}
|
|
281
276
|
function hasContainerTransportWithoutEffectiveAccount(cfg) {
|
|
282
277
|
const signal = cfg.channels?.signal;
|
|
283
|
-
if (!isRecord
|
|
284
|
-
const accounts = isRecord
|
|
278
|
+
if (!isRecord(signal)) return false;
|
|
279
|
+
const accounts = isRecord(signal.accounts) ? signal.accounts : {};
|
|
285
280
|
const rootTransport = isSignalTransportConfig(signal.transport) ? signal.transport : void 0;
|
|
286
281
|
const defaultKey = resolveSignalAccountKey(accounts, DEFAULT_ACCOUNT_ID);
|
|
287
282
|
const defaultEntry = defaultKey ? accounts[defaultKey] : void 0;
|
|
288
|
-
const defaultAccount = isRecord
|
|
283
|
+
const defaultAccount = isRecord(defaultEntry) && defaultEntry.account !== void 0 ? normalizeOptionalString(defaultEntry.account) : normalizeOptionalString(signal.account);
|
|
289
284
|
const channelEnabled = signal.enabled !== false;
|
|
290
|
-
const defaultEnabled = !isRecord
|
|
285
|
+
const defaultEnabled = !isRecord(defaultEntry) || defaultEntry.enabled !== false;
|
|
291
286
|
if (rootTransport?.kind === "container" && channelEnabled && defaultEnabled && !defaultAccount) return true;
|
|
292
287
|
for (const [accountId, entry] of Object.entries(accounts)) {
|
|
293
|
-
if (!isRecord
|
|
288
|
+
if (!isRecord(entry)) continue;
|
|
294
289
|
if (!channelEnabled || entry.enabled === false) continue;
|
|
295
290
|
const isDefaultAccount = isDefaultSignalAccountId(accountId);
|
|
296
291
|
if ((isDefaultAccount && rootTransport ? rootTransport : isSignalTransportConfig(entry.transport) ? entry.transport : void 0)?.kind !== "container" || isDefaultAccount && rootTransport) continue;
|
|
297
|
-
if (!(entry.account === void 0 ?
|
|
292
|
+
if (!(entry.account === void 0 ? normalizeOptionalString(signal.account) : normalizeOptionalString(entry.account))) return true;
|
|
298
293
|
}
|
|
299
294
|
return false;
|
|
300
295
|
}
|
|
301
296
|
async function migrateLegacySignalTransportConfig(params) {
|
|
302
297
|
const signal = params.cfg.channels?.signal;
|
|
303
|
-
if (!isRecord
|
|
298
|
+
if (!isRecord(signal)) return {
|
|
304
299
|
config: params.cfg,
|
|
305
300
|
changes: []
|
|
306
301
|
};
|
|
307
|
-
const accounts = isRecord
|
|
308
|
-
if (!(Object.hasOwn(signal, "apiMode") || hasLegacyFields(signal) || Object.values(accounts).some((entry) => isRecord
|
|
302
|
+
const accounts = isRecord(signal.accounts) ? signal.accounts : {};
|
|
303
|
+
if (!(Object.hasOwn(signal, "apiMode") || hasLegacyFields(signal) || Object.values(accounts).some((entry) => isRecord(entry) && hasLegacyFields(entry)))) return {
|
|
309
304
|
config: params.cfg,
|
|
310
305
|
changes: []
|
|
311
306
|
};
|
|
312
307
|
const apiMode = signal.apiMode;
|
|
313
|
-
const entries = [signal, ...Object.values(accounts).filter(isRecord
|
|
308
|
+
const entries = [signal, ...Object.values(accounts).filter(isRecord)];
|
|
314
309
|
const legacyResolutionEntries = entries.filter((_, index) => shouldMaterializeTransport(entries, index)).filter((entry) => !isSignalTransportConfig(entry.transport));
|
|
315
310
|
const invalidDerivedEndpoint = findInvalidLegacyDerivedEndpoint(legacyResolutionEntries, signal);
|
|
316
311
|
if (invalidDerivedEndpoint) return {
|
|
@@ -369,16 +364,16 @@ async function migrateLegacySignalTransportConfig(params) {
|
|
|
369
364
|
}
|
|
370
365
|
function migrateLegacySignalTransportConfigSync(cfg) {
|
|
371
366
|
const signal = cfg.channels?.signal;
|
|
372
|
-
if (!isRecord
|
|
367
|
+
if (!isRecord(signal)) return {
|
|
373
368
|
config: cfg,
|
|
374
369
|
changes: []
|
|
375
370
|
};
|
|
376
|
-
const accounts = isRecord
|
|
377
|
-
if (!(Object.hasOwn(signal, "apiMode") || hasLegacyFields(signal) || Object.values(accounts).some((entry) => isRecord
|
|
371
|
+
const accounts = isRecord(signal.accounts) ? signal.accounts : {};
|
|
372
|
+
if (!(Object.hasOwn(signal, "apiMode") || hasLegacyFields(signal) || Object.values(accounts).some((entry) => isRecord(entry) && hasLegacyFields(entry)))) return {
|
|
378
373
|
config: cfg,
|
|
379
374
|
changes: []
|
|
380
375
|
};
|
|
381
|
-
const entries = [signal, ...Object.values(accounts).filter(isRecord
|
|
376
|
+
const entries = [signal, ...Object.values(accounts).filter(isRecord)];
|
|
382
377
|
const legacyResolutionEntries = entries.filter((_, index) => shouldMaterializeTransport(entries, index)).filter((entry) => !isSignalTransportConfig(entry.transport));
|
|
383
378
|
const invalidDerivedEndpoint = findInvalidLegacyDerivedEndpoint(legacyResolutionEntries, signal);
|
|
384
379
|
if (invalidDerivedEndpoint) return {
|
|
@@ -445,9 +440,6 @@ const RETIRED_SIGNAL_ACCOUNT_TRANSPORT_FIELDS = [
|
|
|
445
440
|
"receiveMode",
|
|
446
441
|
"ignoreStories"
|
|
447
442
|
];
|
|
448
|
-
function isRecord(value) {
|
|
449
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
450
|
-
}
|
|
451
443
|
function hasRetiredSignalAccountTransportFields(value) {
|
|
452
444
|
return isRecord(value) && RETIRED_SIGNAL_ACCOUNT_TRANSPORT_FIELDS.some((field) => Object.hasOwn(value, field));
|
|
453
445
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-api-
|
|
1
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-api-Dnp5eQQJ.js";
|
|
2
2
|
export { legacyConfigRules, normalizeCompatibilityConfig };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
3
|
-
import nodePath from "node:path";
|
|
4
3
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
5
4
|
import { CONFIG_DIR, extractArchive, resolveBrewExecutable } from "openclaw/plugin-sdk/setup-tools";
|
|
6
5
|
import { createWriteStream } from "node:fs";
|
|
7
6
|
import fs from "node:fs/promises";
|
|
7
|
+
import path from "node:path";
|
|
8
8
|
import { Readable, Transform } from "node:stream";
|
|
9
9
|
import { pipeline } from "node:stream/promises";
|
|
10
10
|
import { readProviderJsonObjectResponse } from "openclaw/plugin-sdk/provider-http";
|
|
@@ -107,7 +107,10 @@ async function downloadToFile(url, dest, maxRedirects = 5, maxBytes = MAX_SIGNAL
|
|
|
107
107
|
if (rawLength !== null) {
|
|
108
108
|
const trimmedLength = rawLength.trim();
|
|
109
109
|
const declaredLength = CONTENT_LENGTH_RE.test(trimmedLength) ? Number(trimmedLength) : NaN;
|
|
110
|
-
if (Number.isFinite(declaredLength) && declaredLength > maxBytes)
|
|
110
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
111
|
+
await cancelUnusedResponseBody(response);
|
|
112
|
+
throw new Error(`signal-cli archive exceeds the ${maxBytes}-byte download cap (declared ${declaredLength}).`);
|
|
113
|
+
}
|
|
111
114
|
}
|
|
112
115
|
let totalBytes = 0;
|
|
113
116
|
const body = response.body;
|
|
@@ -131,7 +134,7 @@ async function findSignalCliBinary(root) {
|
|
|
131
134
|
if (depth > 3) return;
|
|
132
135
|
const entries = await fs.readdir(dir, { withFileTypes: true }).catch(() => []);
|
|
133
136
|
for (const entry of entries) {
|
|
134
|
-
const full =
|
|
137
|
+
const full = path.join(dir, entry.name);
|
|
135
138
|
if (entry.isDirectory()) await enqueue(full, depth + 1);
|
|
136
139
|
else if (entry.isFile() && entry.name === "signal-cli") candidates.push(full);
|
|
137
140
|
}
|
|
@@ -151,7 +154,7 @@ async function resolveBrewSignalCliPath(brewExe) {
|
|
|
151
154
|
});
|
|
152
155
|
if (result.code === 0 && result.stdout.trim()) {
|
|
153
156
|
const prefix = result.stdout.trim();
|
|
154
|
-
const candidate =
|
|
157
|
+
const candidate = path.join(prefix, "bin", "signal-cli");
|
|
155
158
|
try {
|
|
156
159
|
await fs.access(candidate);
|
|
157
160
|
return candidate;
|
|
@@ -246,7 +249,7 @@ async function installSignalCliFromRelease(runtime) {
|
|
|
246
249
|
}, async (archivePath) => {
|
|
247
250
|
runtime.log(`Downloading signal-cli ${releaseInfo.version} (${asset.name})…`);
|
|
248
251
|
await downloadToFile(asset.browser_download_url, archivePath);
|
|
249
|
-
const installRoot =
|
|
252
|
+
const installRoot = path.join(CONFIG_DIR, "tools", "signal-cli", releaseInfo.version);
|
|
250
253
|
await fs.mkdir(installRoot, { recursive: true });
|
|
251
254
|
if (!looksLikeArchive(normalizeLowercaseStringOrEmpty(asset.name))) return {
|
|
252
255
|
ok: false,
|