@openclaw/gateway-protocol 2026.7.2-beta.7 → 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/CHANGELOG.md +5 -1
- package/README.md +1 -1
- package/dist/client-info.d.mts +2 -1
- package/dist/client-info.mjs +5 -5
- package/dist/connect-error-details.d.mts +18 -1
- package/dist/connect-error-details.mjs +61 -21
- package/dist/frame-guards.d.mts +1 -1
- package/dist/frame-guards.mjs +5 -10
- package/dist/{frames-BPnee-QV.d.mts → frames-B9De7i2H.d.mts} +102 -2
- package/dist/{gateway-error-details-Btc09cgL.d.mts → gateway-error-details-BXoMHq1i.d.mts} +17 -4
- package/dist/gateway-error-details.d.mts +2 -2
- package/dist/gateway-error-details.mjs +8 -8
- package/dist/index.d.mts +883 -340
- package/dist/index.mjs +45 -8
- package/dist/protocol-value-normalization-Bexl3yr1.mjs +20 -0
- package/dist/{schema-modules-CJ-akpXK.d.mts → schema-modules-VhRJPNg7.d.mts} +7022 -4824
- package/dist/schema.d.mts +1989 -137
- package/dist/schema.mjs +94 -13
- package/dist/{worktrees-nxd_-Snb.mjs → worktrees-CSLN5mQz.mjs} +4204 -3160
- package/package.json +1 -1
- package/protocol.schema.json +17001 -4602
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,13 @@ version and the additive schema surface. Dates are authoring dates (2026).
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
+
- Add bounded `sessions.patchMany` session mutation orchestration.
|
|
11
|
+
- Preserve required legacy agent-default fields while adding honest `ownership` and `selectionRequired` state to agent lists and initial snapshots.
|
|
10
12
|
- Add semantic `agent` / `system` roster kinds negotiated through the `agent-kind` client capability.
|
|
11
13
|
- Rename structured-question item `id` to `questionId` and flatten keyed answer arrays.
|
|
12
14
|
- Slim worker and session-catalog payloads to the active wire contract.
|
|
13
15
|
- Remove dead protocol surfaces and add since-vintage metadata to retained schemas and methods.
|
|
16
|
+
- Add optional `step` on `SystemAgentChatResult` carrying the full awaited wizard step.
|
|
14
17
|
|
|
15
18
|
## Protocol v4 (current)
|
|
16
19
|
|
|
@@ -126,7 +129,8 @@ Enhancement-only month (no new schema modules):
|
|
|
126
129
|
- Add cron event triggers via polled condition-watcher scripts (#101195) and native
|
|
127
130
|
mobile Automations parity (#106355).
|
|
128
131
|
- Add system-agent conversational onboarding (#99935); rename `crestodian.*` methods to
|
|
129
|
-
`openclaw.chat` / `openclaw.setup.*` (2026-07-14, `a6a0716`)
|
|
132
|
+
`openclaw.chat` / `openclaw.setup.*` (2026-07-14, `a6a0716`); add typed hosted-wizard
|
|
133
|
+
steps and answers to `openclaw.chat` (#114631).
|
|
130
134
|
- Add typed structured questions / `ask_user` with live option cards (#109922, #110242)
|
|
131
135
|
and the questions schema module.
|
|
132
136
|
- Add ui-command / screen-tool Control UI layout control and capability-gated
|
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ Several identifier names coexist because they identify different things:
|
|
|
128
128
|
|
|
129
129
|
Follow each method schema rather than converting fields based on their spelling.
|
|
130
130
|
`sessions.resolve` is the explicit bridge when a caller has a key, raw session ID,
|
|
131
|
-
label, or parent/agent scope.
|
|
131
|
+
label, Control UI short ID, or parent/agent scope.
|
|
132
132
|
|
|
133
133
|
### Intentionally open fields
|
|
134
134
|
|
package/dist/client-info.d.mts
CHANGED
|
@@ -59,7 +59,8 @@ type GatewayClientMode = (typeof GATEWAY_CLIENT_MODES)[keyof typeof GATEWAY_CLIE
|
|
|
59
59
|
type GatewayClientInfo = {
|
|
60
60
|
/** Stable product/client identifier from `GATEWAY_CLIENT_IDS`. */id: GatewayClientId; /** Human-readable label for diagnostics; not used for policy decisions. */
|
|
61
61
|
displayName?: string; /** Client app or package version reported by the connecting process. */
|
|
62
|
-
version: string; /**
|
|
62
|
+
version: string; /** Exact immutable artifact identity when the client can report one. */
|
|
63
|
+
buildId?: string; /** Runtime platform string, such as `darwin`, `ios`, `android`, or `web`. */
|
|
63
64
|
platform: string; /** Optional device family used by native clients for display and routing hints. */
|
|
64
65
|
deviceFamily?: string; /** Native hardware/model identifier when available. */
|
|
65
66
|
modelIdentifier?: string; /** Coarse category from `GATEWAY_CLIENT_MODES` for policy and diagnostics. */
|
package/dist/client-info.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as normalizeOptionalProtocolString } from "./protocol-value-normalization-Bexl3yr1.mjs";
|
|
1
2
|
//#region src/client-info.ts
|
|
2
3
|
/**
|
|
3
4
|
* Shared gateway client identity contract.
|
|
@@ -5,9 +6,8 @@
|
|
|
5
6
|
* These values cross the WebSocket handshake boundary, so additions must stay
|
|
6
7
|
* aligned with protocol schemas and server policy checks.
|
|
7
8
|
*/
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
return raw.trim().toLowerCase() || void 0;
|
|
9
|
+
function normalizeOptionalProtocolLowercaseString(raw) {
|
|
10
|
+
return normalizeOptionalProtocolString(raw)?.toLowerCase();
|
|
11
11
|
}
|
|
12
12
|
/** Canonical client ids accepted in gateway hello/connect payloads. */
|
|
13
13
|
const GATEWAY_CLIENT_IDS = {
|
|
@@ -59,7 +59,7 @@ const GATEWAY_CLIENT_ID_SET = new Set(Object.values(GATEWAY_CLIENT_IDS));
|
|
|
59
59
|
const GATEWAY_CLIENT_MODE_SET = new Set(Object.values(GATEWAY_CLIENT_MODES));
|
|
60
60
|
/** Normalizes untrusted client ids and rejects unknown values. */
|
|
61
61
|
function normalizeGatewayClientId(raw) {
|
|
62
|
-
const normalized =
|
|
62
|
+
const normalized = normalizeOptionalProtocolLowercaseString(raw);
|
|
63
63
|
if (!normalized) return;
|
|
64
64
|
return GATEWAY_CLIENT_ID_SET.has(normalized) ? normalized : void 0;
|
|
65
65
|
}
|
|
@@ -69,7 +69,7 @@ function normalizeGatewayClientName(raw) {
|
|
|
69
69
|
}
|
|
70
70
|
/** Normalizes untrusted client modes and rejects unknown values. */
|
|
71
71
|
function normalizeGatewayClientMode(raw) {
|
|
72
|
-
const normalized =
|
|
72
|
+
const normalized = normalizeOptionalProtocolLowercaseString(raw);
|
|
73
73
|
if (!normalized) return;
|
|
74
74
|
return GATEWAY_CLIENT_MODE_SET.has(normalized) ? normalized : void 0;
|
|
75
75
|
}
|
|
@@ -17,6 +17,7 @@ declare const ConnectErrorDetailCodes: {
|
|
|
17
17
|
readonly AUTH_TAILSCALE_PROXY_MISSING: "AUTH_TAILSCALE_PROXY_MISSING";
|
|
18
18
|
readonly AUTH_TAILSCALE_WHOIS_FAILED: "AUTH_TAILSCALE_WHOIS_FAILED";
|
|
19
19
|
readonly AUTH_TAILSCALE_IDENTITY_MISMATCH: "AUTH_TAILSCALE_IDENTITY_MISMATCH";
|
|
20
|
+
readonly CONTROL_UI_BUILD_MISMATCH: "CONTROL_UI_BUILD_MISMATCH";
|
|
20
21
|
readonly CONTROL_UI_ORIGIN_NOT_ALLOWED: "CONTROL_UI_ORIGIN_NOT_ALLOWED";
|
|
21
22
|
readonly PROTOCOL_MISMATCH: "PROTOCOL_MISMATCH";
|
|
22
23
|
readonly CONTROL_UI_DEVICE_IDENTITY_REQUIRED: "CONTROL_UI_DEVICE_IDENTITY_REQUIRED";
|
|
@@ -70,6 +71,8 @@ declare function resolveAuthConnectErrorDetailCode(reason: string | undefined):
|
|
|
70
71
|
declare function resolveDeviceAuthConnectErrorDetailCode(reason: string | undefined): ConnectErrorDetailCode;
|
|
71
72
|
/** Reads a non-empty detail code from an untrusted error details payload. */
|
|
72
73
|
declare function readConnectErrorDetailCode(details: unknown): string | null;
|
|
74
|
+
/** Read the exact target artifact from an untrusted reload-required rejection. */
|
|
75
|
+
declare function readControlUiBuildMismatchId(details: unknown): string | null;
|
|
73
76
|
/** Extracts normalized retry advice from untrusted connect-error details. */
|
|
74
77
|
declare function readConnectErrorRecoveryAdvice(details: unknown): ConnectErrorRecoveryAdvice;
|
|
75
78
|
/** Normalizes pairing request ids before echoing them in close reasons or UI text. */
|
|
@@ -103,6 +106,20 @@ declare function buildPairingConnectCloseReason(params: {
|
|
|
103
106
|
declare function readPairingConnectErrorDetails(details: unknown): PairingConnectErrorDetails | null;
|
|
104
107
|
/** Parses legacy/string-only pairing-required messages into structured details. */
|
|
105
108
|
declare function readConnectPairingRequiredMessage(message: string | null | undefined): ConnectPairingRequiredDetails | null;
|
|
109
|
+
/** Classifies Gateway connect failures from structured details, with one legacy text fallback. */
|
|
110
|
+
declare function classifyGatewayConnectFailure(input: {
|
|
111
|
+
details?: unknown;
|
|
112
|
+
reason?: string | null;
|
|
113
|
+
message?: string | null;
|
|
114
|
+
}): {
|
|
115
|
+
kind: "pairing-required";
|
|
116
|
+
userMessage: string;
|
|
117
|
+
remediation: string;
|
|
118
|
+
} | {
|
|
119
|
+
remediation?: string | undefined;
|
|
120
|
+
kind: "device-identity-required" | "scope-mismatch" | "rate-limited" | "auth-rejected" | "gateway-rejected" | "unreachable";
|
|
121
|
+
userMessage: string;
|
|
122
|
+
};
|
|
106
123
|
/** Formats pairing-required details into the canonical user-facing message. */
|
|
107
124
|
declare function formatConnectPairingRequiredMessage(details: unknown): string;
|
|
108
125
|
/** Formats connect errors using structured details before falling back to raw messages. */
|
|
@@ -111,4 +128,4 @@ declare function formatConnectErrorMessage(params: {
|
|
|
111
128
|
details?: unknown;
|
|
112
129
|
}): string;
|
|
113
130
|
//#endregion
|
|
114
|
-
export { ConnectErrorDetailCodes, ConnectPairingRequiredDetails, ConnectPairingRequiredReason, buildPairingConnectCloseReason, buildPairingConnectErrorDetails, buildPairingConnectErrorMessage, buildPairingConnectRecoveryTitle, describePairingConnectRequirement, formatConnectErrorMessage, formatConnectPairingRequiredMessage, normalizePairingConnectRequestId, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readConnectPairingRequiredMessage, readPairingConnectErrorDetails, resolveAuthConnectErrorDetailCode, resolveDeviceAuthConnectErrorDetailCode };
|
|
131
|
+
export { ConnectErrorDetailCodes, ConnectPairingRequiredDetails, ConnectPairingRequiredReason, buildPairingConnectCloseReason, buildPairingConnectErrorDetails, buildPairingConnectErrorMessage, buildPairingConnectRecoveryTitle, classifyGatewayConnectFailure, describePairingConnectRequirement, formatConnectErrorMessage, formatConnectPairingRequiredMessage, normalizePairingConnectRequestId, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readConnectPairingRequiredMessage, readControlUiBuildMismatchId, readPairingConnectErrorDetails, resolveAuthConnectErrorDetailCode, resolveDeviceAuthConnectErrorDetailCode };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as normalizeOptionalProtocolString } from "./protocol-value-normalization-Bexl3yr1.mjs";
|
|
1
2
|
//#region src/connect-error-details.ts
|
|
2
3
|
/**
|
|
3
4
|
* Shared gateway connect-error detail helpers.
|
|
@@ -5,13 +6,9 @@
|
|
|
5
6
|
* These details cross client/server boundaries, so readers normalize untrusted
|
|
6
7
|
* payloads before using them in reconnect decisions or user-facing messages.
|
|
7
8
|
*/
|
|
8
|
-
function
|
|
9
|
-
if (typeof value !== "string") return;
|
|
10
|
-
return value.trim() || void 0;
|
|
11
|
-
}
|
|
12
|
-
function normalizeArrayBackedTrimmedStringList(value) {
|
|
9
|
+
function normalizeOptionalConnectDetailStringList(value) {
|
|
13
10
|
if (!Array.isArray(value)) return;
|
|
14
|
-
const values = value.map((entry) =>
|
|
11
|
+
const values = value.map((entry) => normalizeOptionalProtocolString(entry)).filter((entry) => Boolean(entry));
|
|
15
12
|
return values.length > 0 ? values : void 0;
|
|
16
13
|
}
|
|
17
14
|
/** Structured connect-error codes carried in gateway error `details.code`. */
|
|
@@ -32,6 +29,7 @@ const ConnectErrorDetailCodes = {
|
|
|
32
29
|
AUTH_TAILSCALE_PROXY_MISSING: "AUTH_TAILSCALE_PROXY_MISSING",
|
|
33
30
|
AUTH_TAILSCALE_WHOIS_FAILED: "AUTH_TAILSCALE_WHOIS_FAILED",
|
|
34
31
|
AUTH_TAILSCALE_IDENTITY_MISMATCH: "AUTH_TAILSCALE_IDENTITY_MISMATCH",
|
|
32
|
+
CONTROL_UI_BUILD_MISMATCH: "CONTROL_UI_BUILD_MISMATCH",
|
|
35
33
|
CONTROL_UI_ORIGIN_NOT_ALLOWED: "CONTROL_UI_ORIGIN_NOT_ALLOWED",
|
|
36
34
|
PROTOCOL_MISMATCH: "PROTOCOL_MISMATCH",
|
|
37
35
|
CONTROL_UI_DEVICE_IDENTITY_REQUIRED: "CONTROL_UI_DEVICE_IDENTITY_REQUIRED",
|
|
@@ -134,28 +132,36 @@ function readConnectErrorDetailCode(details) {
|
|
|
134
132
|
const code = details.code;
|
|
135
133
|
return typeof code === "string" && code.trim().length > 0 ? code.trim() : null;
|
|
136
134
|
}
|
|
135
|
+
/** Read the exact target artifact from an untrusted reload-required rejection. */
|
|
136
|
+
function readControlUiBuildMismatchId(details) {
|
|
137
|
+
if (readConnectErrorDetailCode(details) !== ConnectErrorDetailCodes.CONTROL_UI_BUILD_MISMATCH) return null;
|
|
138
|
+
const raw = details;
|
|
139
|
+
const gatewayBuildId = normalizeOptionalProtocolString(raw.gatewayBuildId);
|
|
140
|
+
if (!gatewayBuildId || gatewayBuildId.length > 96 || raw.reloadRequired !== true) return null;
|
|
141
|
+
return gatewayBuildId;
|
|
142
|
+
}
|
|
137
143
|
/** Extracts normalized retry advice from untrusted connect-error details. */
|
|
138
144
|
function readConnectErrorRecoveryAdvice(details) {
|
|
139
145
|
if (!details || typeof details !== "object" || Array.isArray(details)) return {};
|
|
140
146
|
const raw = details;
|
|
141
147
|
const canRetryWithDeviceToken = typeof raw.canRetryWithDeviceToken === "boolean" ? raw.canRetryWithDeviceToken : void 0;
|
|
142
|
-
const normalizedNextStep =
|
|
148
|
+
const normalizedNextStep = normalizeOptionalProtocolString(raw.recommendedNextStep) ?? "";
|
|
143
149
|
return {
|
|
144
150
|
canRetryWithDeviceToken,
|
|
145
151
|
recommendedNextStep: CONNECT_RECOVERY_NEXT_STEP_VALUES.has(normalizedNextStep) ? normalizedNextStep : void 0
|
|
146
152
|
};
|
|
147
153
|
}
|
|
148
154
|
function normalizePairingConnectReason(value) {
|
|
149
|
-
const normalized =
|
|
155
|
+
const normalized = normalizeOptionalProtocolString(value) ?? "";
|
|
150
156
|
return CONNECT_PAIRING_REQUIRED_REASON_VALUES.has(normalized) ? normalized : void 0;
|
|
151
157
|
}
|
|
152
158
|
/** Normalizes pairing request ids before echoing them in close reasons or UI text. */
|
|
153
159
|
function normalizePairingConnectRequestId(value) {
|
|
154
|
-
const normalized =
|
|
160
|
+
const normalized = normalizeOptionalProtocolString(value);
|
|
155
161
|
return normalized && PAIRING_CONNECT_REQUEST_ID_PATTERN.test(normalized) ? normalized : void 0;
|
|
156
162
|
}
|
|
157
163
|
function normalizeStringArray(value) {
|
|
158
|
-
return
|
|
164
|
+
return normalizeOptionalConnectDetailStringList(value);
|
|
159
165
|
}
|
|
160
166
|
function createPairingConnectErrorDetails(params) {
|
|
161
167
|
return {
|
|
@@ -191,9 +197,9 @@ function buildPairingConnectRecoveryTitle(reason) {
|
|
|
191
197
|
/** Builds sanitized structured details for a pairing-required connect failure. */
|
|
192
198
|
function buildPairingConnectErrorDetails(params) {
|
|
193
199
|
const requestId = normalizePairingConnectRequestId(params.requestId);
|
|
194
|
-
const remediationHint =
|
|
195
|
-
const deviceId =
|
|
196
|
-
const requestedRole =
|
|
200
|
+
const remediationHint = normalizeOptionalProtocolString(params.remediationHint) ?? buildPairingConnectRemediationHint(params.reason);
|
|
201
|
+
const deviceId = normalizeOptionalProtocolString(params.deviceId);
|
|
202
|
+
const requestedRole = normalizeOptionalProtocolString(params.requestedRole);
|
|
197
203
|
const requestedScopes = normalizeStringArray(params.requestedScopes);
|
|
198
204
|
const approvedRoles = normalizeStringArray(params.approvedRoles);
|
|
199
205
|
const approvedScopes = normalizeStringArray(params.approvedScopes);
|
|
@@ -224,11 +230,11 @@ function readPairingConnectErrorDetails(details) {
|
|
|
224
230
|
const raw = details;
|
|
225
231
|
const reason = normalizePairingConnectReason(raw.reason);
|
|
226
232
|
const requestId = normalizePairingConnectRequestId(raw.requestId);
|
|
227
|
-
const remediationHint =
|
|
228
|
-
const normalizedNextStep =
|
|
233
|
+
const remediationHint = normalizeOptionalProtocolString(raw.remediationHint) ?? buildPairingConnectRemediationHint(reason);
|
|
234
|
+
const normalizedNextStep = normalizeOptionalProtocolString(raw.recommendedNextStep) ?? "";
|
|
229
235
|
const recommendedNextStep = CONNECT_RECOVERY_NEXT_STEP_VALUES.has(normalizedNextStep) ? normalizedNextStep : void 0;
|
|
230
|
-
const deviceId =
|
|
231
|
-
const requestedRole =
|
|
236
|
+
const deviceId = normalizeOptionalProtocolString(raw.deviceId);
|
|
237
|
+
const requestedRole = normalizeOptionalProtocolString(raw.requestedRole);
|
|
232
238
|
const requestedScopes = normalizeStringArray(raw.requestedScopes);
|
|
233
239
|
const approvedRoles = normalizeStringArray(raw.approvedRoles);
|
|
234
240
|
const approvedScopes = normalizeStringArray(raw.approvedScopes);
|
|
@@ -248,7 +254,7 @@ function readPairingConnectErrorDetails(details) {
|
|
|
248
254
|
}
|
|
249
255
|
/** Parses legacy/string-only pairing-required messages into structured details. */
|
|
250
256
|
function readConnectPairingRequiredMessage(message) {
|
|
251
|
-
const normalizedMessage =
|
|
257
|
+
const normalizedMessage = normalizeOptionalProtocolString(message);
|
|
252
258
|
if (!normalizedMessage) return null;
|
|
253
259
|
const normalized = normalizedMessage.trim().toLowerCase();
|
|
254
260
|
let reason;
|
|
@@ -264,6 +270,40 @@ function readConnectPairingRequiredMessage(message) {
|
|
|
264
270
|
reason
|
|
265
271
|
};
|
|
266
272
|
}
|
|
273
|
+
const PAIRING_APPROVAL_REMEDIATION = "Run `openclaw devices approve --latest` to preview the pending request, then rerun the printed `openclaw devices approve <requestId>` command and reconnect (pass the same --url and --token/--password flags if you connected with explicit credentials).";
|
|
274
|
+
const DEVICE_TOKEN_REMEDIATION = "Rotate the paired-device token with `openclaw devices rotate --device <deviceId> --role operator`, then reconnect.";
|
|
275
|
+
const SHARED_TOKEN_REMEDIATION = "Verify `gateway.remote.token` matches `gateway.auth.token`. If a paired-device token is stale, rotate it with `openclaw devices rotate --device <deviceId> --role operator`, then reconnect.";
|
|
276
|
+
const SCOPE_MISMATCH_REMEDIATION = "Review approved scopes with `openclaw devices list`; if an upgrade is pending, preview it with `openclaw devices approve --latest`, approve the printed request, then reconnect.";
|
|
277
|
+
const RATE_LIMITED_REMEDIATION = "Wait for the temporary authentication lockout to expire, then retry.";
|
|
278
|
+
const GATEWAY_CLOSED_MESSAGE_PATTERN = /\bgateway closed \(\d+\):/i;
|
|
279
|
+
/** Classifies Gateway connect failures from structured details, with one legacy text fallback. */
|
|
280
|
+
function classifyGatewayConnectFailure(input) {
|
|
281
|
+
const code = readConnectErrorDetailCode(input.details);
|
|
282
|
+
const message = normalizeOptionalProtocolString(input.message);
|
|
283
|
+
const reason = normalizeOptionalProtocolString(input.reason);
|
|
284
|
+
const userMessage = message ?? reason;
|
|
285
|
+
const classificationText = [message, reason].filter((value) => Boolean(value)).join("\n");
|
|
286
|
+
const normalized = classificationText.toLowerCase();
|
|
287
|
+
const pairing = readPairingConnectErrorDetails(input.details) ?? readConnectPairingRequiredMessage(classificationText);
|
|
288
|
+
if (code === ConnectErrorDetailCodes.PAIRING_REQUIRED || pairing) return {
|
|
289
|
+
kind: "pairing-required",
|
|
290
|
+
userMessage: code === ConnectErrorDetailCodes.PAIRING_REQUIRED ? formatConnectPairingRequiredMessage(input.details) : userMessage ?? "device pairing required",
|
|
291
|
+
remediation: PAIRING_APPROVAL_REMEDIATION
|
|
292
|
+
};
|
|
293
|
+
const deviceIdentityRequired = code === ConnectErrorDetailCodes.DEVICE_IDENTITY_REQUIRED || code === ConnectErrorDetailCodes.CONTROL_UI_DEVICE_IDENTITY_REQUIRED || normalized.includes("device identity required");
|
|
294
|
+
const scopeMismatch = code === ConnectErrorDetailCodes.AUTH_SCOPE_MISMATCH || normalized.includes("scope mismatch");
|
|
295
|
+
const rateLimited = code === ConnectErrorDetailCodes.AUTH_RATE_LIMITED || !code && normalized.includes("too many failed authentication attempts");
|
|
296
|
+
const deviceTokenMismatch = code === ConnectErrorDetailCodes.AUTH_DEVICE_TOKEN_MISMATCH || normalized.includes("device token mismatch");
|
|
297
|
+
const sharedTokenMismatch = code === ConnectErrorDetailCodes.AUTH_TOKEN_MISMATCH || normalized.includes("gateway token mismatch");
|
|
298
|
+
const authRejected = deviceTokenMismatch || sharedTokenMismatch || code?.startsWith("AUTH_") || code?.startsWith("DEVICE_AUTH_");
|
|
299
|
+
const kind = deviceIdentityRequired ? "device-identity-required" : scopeMismatch ? "scope-mismatch" : rateLimited ? "rate-limited" : authRejected ? "auth-rejected" : code || GATEWAY_CLOSED_MESSAGE_PATTERN.test(classificationText) ? "gateway-rejected" : "unreachable";
|
|
300
|
+
const remediation = rateLimited ? RATE_LIMITED_REMEDIATION : scopeMismatch ? SCOPE_MISMATCH_REMEDIATION : deviceTokenMismatch ? DEVICE_TOKEN_REMEDIATION : sharedTokenMismatch ? SHARED_TOKEN_REMEDIATION : void 0;
|
|
301
|
+
return {
|
|
302
|
+
kind,
|
|
303
|
+
userMessage: userMessage ?? (kind === "unreachable" ? "gateway unreachable" : "gateway rejected connection"),
|
|
304
|
+
...remediation ? { remediation } : {}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
267
307
|
/** Formats pairing-required details into the canonical user-facing message. */
|
|
268
308
|
function formatConnectPairingRequiredMessage(details) {
|
|
269
309
|
const pairing = readPairingConnectErrorDetails(details);
|
|
@@ -274,7 +314,7 @@ function formatConnectPairingRequiredMessage(details) {
|
|
|
274
314
|
function formatConnectErrorMessage(params) {
|
|
275
315
|
if (readConnectErrorDetailCode(params.details) === ConnectErrorDetailCodes.PAIRING_REQUIRED) return formatConnectPairingRequiredMessage(params.details);
|
|
276
316
|
if (readConnectErrorDetailCode(params.details) === ConnectErrorDetailCodes.PROTOCOL_MISMATCH) return formatProtocolMismatchMessage(params.message, params.details);
|
|
277
|
-
return
|
|
317
|
+
return normalizeOptionalProtocolString(params.message) ?? "gateway request failed";
|
|
278
318
|
}
|
|
279
319
|
function formatProtocolMismatchMessage(message, details) {
|
|
280
320
|
const raw = details;
|
|
@@ -286,11 +326,11 @@ function formatProtocolMismatchMessage(message, details) {
|
|
|
286
326
|
if (clientMin !== void 0 && clientMax !== void 0) parts.push(clientMin === clientMax ? `Control UI v${clientMin}` : `Control UI v${clientMin}-v${clientMax}`);
|
|
287
327
|
if (expected !== void 0) parts.push(`Gateway v${expected}`);
|
|
288
328
|
if (probeMin !== void 0) parts.push(`probe min v${probeMin}`);
|
|
289
|
-
const normalized =
|
|
329
|
+
const normalized = normalizeOptionalProtocolString(message) ?? "protocol mismatch";
|
|
290
330
|
return parts.length > 0 ? `${normalized}: ${parts.join(", ")}` : normalized;
|
|
291
331
|
}
|
|
292
332
|
function normalizeProtocolNumber(value) {
|
|
293
333
|
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : void 0;
|
|
294
334
|
}
|
|
295
335
|
//#endregion
|
|
296
|
-
export { ConnectErrorDetailCodes, buildPairingConnectCloseReason, buildPairingConnectErrorDetails, buildPairingConnectErrorMessage, buildPairingConnectRecoveryTitle, describePairingConnectRequirement, formatConnectErrorMessage, formatConnectPairingRequiredMessage, normalizePairingConnectRequestId, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readConnectPairingRequiredMessage, readPairingConnectErrorDetails, resolveAuthConnectErrorDetailCode, resolveDeviceAuthConnectErrorDetailCode };
|
|
336
|
+
export { ConnectErrorDetailCodes, buildPairingConnectCloseReason, buildPairingConnectErrorDetails, buildPairingConnectErrorMessage, buildPairingConnectRecoveryTitle, classifyGatewayConnectFailure, describePairingConnectRequirement, formatConnectErrorMessage, formatConnectPairingRequiredMessage, normalizePairingConnectRequestId, readConnectErrorDetailCode, readConnectErrorRecoveryAdvice, readConnectPairingRequiredMessage, readControlUiBuildMismatchId, readPairingConnectErrorDetails, resolveAuthConnectErrorDetailCode, resolveDeviceAuthConnectErrorDetailCode };
|
package/dist/frame-guards.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EventFrame, c as GatewayFrame, f as RequestFrame, m as ResponseFrame, r as ErrorShape, t as ConnectParams, u as HelloOk } from "./frames-
|
|
1
|
+
import { a as EventFrame, c as GatewayFrame, f as RequestFrame, m as ResponseFrame, r as ErrorShape, t as ConnectParams, u as HelloOk } from "./frames-B9De7i2H.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/frame-guards.d.ts
|
|
4
4
|
declare function isGatewayEventFrame(value: unknown): value is EventFrame;
|
package/dist/frame-guards.mjs
CHANGED
|
@@ -1,25 +1,20 @@
|
|
|
1
|
+
import { n as isNonEmptyProtocolString, r as isProtocolRecord } from "./protocol-value-normalization-Bexl3yr1.mjs";
|
|
1
2
|
//#region src/frame-guards.ts
|
|
2
|
-
function isRecord(value) {
|
|
3
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4
|
-
}
|
|
5
|
-
function isNonEmptyString(value) {
|
|
6
|
-
return typeof value === "string" && value.length > 0;
|
|
7
|
-
}
|
|
8
3
|
function isNonNegativeInteger(value) {
|
|
9
4
|
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
10
5
|
}
|
|
11
6
|
function isGatewayErrorShape(value) {
|
|
12
|
-
if (!
|
|
13
|
-
if (!
|
|
7
|
+
if (!isProtocolRecord(value)) return false;
|
|
8
|
+
if (!isNonEmptyProtocolString(value.code) || !isNonEmptyProtocolString(value.message)) return false;
|
|
14
9
|
if (value.retryable !== void 0 && typeof value.retryable !== "boolean") return false;
|
|
15
10
|
return value.retryAfterMs === void 0 || isNonNegativeInteger(value.retryAfterMs);
|
|
16
11
|
}
|
|
17
12
|
function isGatewayEventFrame(value) {
|
|
18
|
-
if (!
|
|
13
|
+
if (!isProtocolRecord(value) || value.type !== "event" || !isNonEmptyProtocolString(value.event)) return false;
|
|
19
14
|
return value.seq === void 0 || isNonNegativeInteger(value.seq);
|
|
20
15
|
}
|
|
21
16
|
function isGatewayResponseFrame(value) {
|
|
22
|
-
if (!
|
|
17
|
+
if (!isProtocolRecord(value) || value.type !== "res" || !isNonEmptyProtocolString(value.id) || typeof value.ok !== "boolean") return false;
|
|
23
18
|
return value.error === void 0 || isGatewayErrorShape(value.error);
|
|
24
19
|
}
|
|
25
20
|
//#endregion
|
|
@@ -4,7 +4,9 @@ import { Static, Type } from "typebox";
|
|
|
4
4
|
declare const GATEWAY_SERVER_CAPS: {
|
|
5
5
|
readonly BOARD_WIDGET_PUT_CANVAS_DOC: "board-widget-put-canvas-doc";
|
|
6
6
|
readonly CHAT_SEND_ROUTING_CONTRACT: "chat-send-routing-contract";
|
|
7
|
+
readonly SYSTEM_AGENT_WIZARD_CANCEL: "openclaw-chat-wizard-cancel";
|
|
7
8
|
readonly SYSTEM_AGENT_SETUP_MODEL_REF: "openclaw-setup-model-ref";
|
|
9
|
+
readonly TASK_SUGGESTIONS_ACCEPT_MODES: "taskSuggestions.acceptModes";
|
|
8
10
|
};
|
|
9
11
|
/**
|
|
10
12
|
* Top-level gateway frame schemas.
|
|
@@ -29,6 +31,7 @@ declare const ConnectParamsSchema: Type.TObject<{
|
|
|
29
31
|
id: Type.TEnum<["webchat-ui", "openclaw-control-ui", "openclaw-browser-copilot", "openclaw-tui", "webchat", "cli", "gateway-client", "openclaw-macos", "openclaw-linux", "openclaw-ios", "openclaw-watchos", "openclaw-android", "node-host", "openclaw-worker", "test", "fingerprint", "openclaw-probe"]>;
|
|
30
32
|
displayName: Type.TOptional<Type.TString>;
|
|
31
33
|
version: Type.TString;
|
|
34
|
+
buildId: Type.TOptional<Type.TString>;
|
|
32
35
|
platform: Type.TString;
|
|
33
36
|
deviceFamily: Type.TOptional<Type.TString>;
|
|
34
37
|
modelIdentifier: Type.TOptional<Type.TString>;
|
|
@@ -36,7 +39,13 @@ declare const ConnectParamsSchema: Type.TObject<{
|
|
|
36
39
|
instanceId: Type.TOptional<Type.TString>;
|
|
37
40
|
}>;
|
|
38
41
|
caps: Type.TOptional<Type.TArray<Type.TString>>;
|
|
39
|
-
commands: Type.TOptional<Type.TArray<Type.TString>>;
|
|
42
|
+
commands: Type.TOptional<Type.TArray<Type.TString>>; /** Additive Computer Use declaration; the owning core contract validates its bounded shape. */
|
|
43
|
+
computerUse: Type.TOptional<Type.TUnknown>; /** Additive node-local worker build identity; presence advertises session hosting. */
|
|
44
|
+
workerRuns: Type.TOptional<Type.TObject<{
|
|
45
|
+
bundleHash: Type.TString;
|
|
46
|
+
openclawVersion: Type.TString;
|
|
47
|
+
protocolFeatures: Type.TArray<Type.TString>;
|
|
48
|
+
}>>;
|
|
40
49
|
permissions: Type.TOptional<Type.TRecord<"^.*$", Type.TBoolean>>;
|
|
41
50
|
pathEnv: Type.TOptional<Type.TString>;
|
|
42
51
|
role: Type.TOptional<Type.TString>;
|
|
@@ -59,12 +68,14 @@ declare const ConnectParamsSchema: Type.TObject<{
|
|
|
59
68
|
locale: Type.TOptional<Type.TString>;
|
|
60
69
|
userAgent: Type.TOptional<Type.TString>;
|
|
61
70
|
}>;
|
|
62
|
-
/** Successful gateway hello response with
|
|
71
|
+
/** Successful gateway hello response with the server protocol and initial state. */
|
|
63
72
|
declare const HelloOkSchema: Type.TObject<{
|
|
64
73
|
type: Type.TLiteral<"hello-ok">;
|
|
65
74
|
protocol: Type.TInteger;
|
|
66
75
|
server: Type.TObject<{
|
|
67
76
|
version: Type.TString;
|
|
77
|
+
buildId: Type.TOptional<Type.TString>;
|
|
78
|
+
controlUiBuildSource: Type.TOptional<Type.TUnion<[Type.TLiteral<"bundled">, Type.TLiteral<"configured">]>>;
|
|
68
79
|
connId: Type.TString;
|
|
69
80
|
}>;
|
|
70
81
|
features: Type.TObject<{
|
|
@@ -104,6 +115,7 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
104
115
|
durationMs: Type.TOptional<Type.TInteger>;
|
|
105
116
|
eventLoop: Type.TOptional<Type.TObject<{
|
|
106
117
|
degraded: Type.TBoolean;
|
|
118
|
+
degradedSinceMs: Type.TOptional<Type.TUnion<[Type.TInteger, Type.TNull]>>;
|
|
107
119
|
reasons: Type.TArray<Type.TUnion<[Type.TLiteral<"event_loop_delay">, Type.TLiteral<"event_loop_utilization">, Type.TLiteral<"cpu">]>>;
|
|
108
120
|
intervalMs: Type.TNumber;
|
|
109
121
|
delayP99Ms: Type.TNumber;
|
|
@@ -147,6 +159,21 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
147
159
|
count: Type.TInteger;
|
|
148
160
|
oldestFailedAt: Type.TOptional<Type.TInteger>;
|
|
149
161
|
}>>;
|
|
162
|
+
ingressFailed: Type.TOptional<Type.TArray<Type.TObject<{
|
|
163
|
+
channelId: Type.TString;
|
|
164
|
+
accountId: Type.TString;
|
|
165
|
+
count: Type.TInteger;
|
|
166
|
+
oldestFailedAt: Type.TOptional<Type.TInteger>;
|
|
167
|
+
}>>>;
|
|
168
|
+
ingressPressure: Type.TOptional<Type.TArray<Type.TObject<{
|
|
169
|
+
channelId: Type.TString;
|
|
170
|
+
accountId: Type.TString;
|
|
171
|
+
laneCount: Type.TInteger;
|
|
172
|
+
pendingCount: Type.TInteger;
|
|
173
|
+
claimedCount: Type.TInteger;
|
|
174
|
+
blockedCount: Type.TInteger;
|
|
175
|
+
oldestReceivedAt: Type.TInteger;
|
|
176
|
+
}>>>;
|
|
150
177
|
}>>;
|
|
151
178
|
modelPricing: Type.TOptional<Type.TObject<{
|
|
152
179
|
state: Type.TUnion<[Type.TLiteral<"ok">, Type.TLiteral<"degraded">, Type.TLiteral<"disabled">]>;
|
|
@@ -178,6 +205,7 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
178
205
|
prompt: Type.TString;
|
|
179
206
|
target: Type.TString;
|
|
180
207
|
model: Type.TOptional<Type.TString>;
|
|
208
|
+
session: Type.TOptional<Type.TString>;
|
|
181
209
|
ackMaxChars: Type.TInteger;
|
|
182
210
|
}>;
|
|
183
211
|
sessions: Type.TObject<{
|
|
@@ -210,6 +238,8 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
210
238
|
stateDir: Type.TOptional<Type.TString>;
|
|
211
239
|
sessionDefaults: Type.TOptional<Type.TObject<{
|
|
212
240
|
defaultAgentId: Type.TString;
|
|
241
|
+
ownership: Type.TOptional<Type.TUnion<[Type.TLiteral<"sole">, Type.TLiteral<"legacy">, Type.TLiteral<"explicit">]>>;
|
|
242
|
+
selectionRequired: Type.TOptional<Type.TBoolean>;
|
|
213
243
|
mainKey: Type.TString;
|
|
214
244
|
mainSessionKey: Type.TString;
|
|
215
245
|
scope: Type.TOptional<Type.TString>;
|
|
@@ -219,6 +249,70 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
219
249
|
currentVersion: Type.TString;
|
|
220
250
|
latestVersion: Type.TString;
|
|
221
251
|
channel: Type.TString;
|
|
252
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
253
|
+
upstreamRef: Type.TOptional<Type.TString>;
|
|
254
|
+
upstreamSha: Type.TOptional<Type.TString>;
|
|
255
|
+
commitsBehind: Type.TOptional<Type.TInteger>;
|
|
256
|
+
commits: Type.TOptional<Type.TArray<Type.TObject<{
|
|
257
|
+
sha: Type.TString;
|
|
258
|
+
subject: Type.TString;
|
|
259
|
+
}>>>;
|
|
260
|
+
}>>;
|
|
261
|
+
updateSchedule: Type.TOptional<Type.TObject<{
|
|
262
|
+
channel: Type.TString;
|
|
263
|
+
autoEnabled: Type.TBoolean;
|
|
264
|
+
install: Type.TOptional<Type.TObject<{
|
|
265
|
+
kind: Type.TUnion<[Type.TLiteral<"package">, Type.TLiteral<"git">, Type.TLiteral<"unknown">]>;
|
|
266
|
+
git: Type.TOptional<Type.TUnion<[Type.TObject<{
|
|
267
|
+
status: Type.TLiteral<"current">;
|
|
268
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
269
|
+
commitAtMs: Type.TOptional<Type.TInteger>;
|
|
270
|
+
installedAtMs: Type.TOptional<Type.TInteger>;
|
|
271
|
+
}>, Type.TObject<{
|
|
272
|
+
status: Type.TLiteral<"behind">;
|
|
273
|
+
commitsBehind: Type.TInteger;
|
|
274
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
275
|
+
commitAtMs: Type.TOptional<Type.TInteger>;
|
|
276
|
+
installedAtMs: Type.TOptional<Type.TInteger>;
|
|
277
|
+
}>, Type.TObject<{
|
|
278
|
+
status: Type.TLiteral<"ahead">;
|
|
279
|
+
commitsAhead: Type.TInteger;
|
|
280
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
281
|
+
commitAtMs: Type.TOptional<Type.TInteger>;
|
|
282
|
+
installedAtMs: Type.TOptional<Type.TInteger>;
|
|
283
|
+
}>, Type.TObject<{
|
|
284
|
+
status: Type.TLiteral<"diverged">;
|
|
285
|
+
commitsAhead: Type.TInteger;
|
|
286
|
+
commitsBehind: Type.TInteger;
|
|
287
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
288
|
+
commitAtMs: Type.TOptional<Type.TInteger>;
|
|
289
|
+
installedAtMs: Type.TOptional<Type.TInteger>;
|
|
290
|
+
}>, Type.TObject<{
|
|
291
|
+
status: Type.TLiteral<"unavailable">;
|
|
292
|
+
reason: Type.TUnion<[Type.TLiteral<"fetch-failed">, Type.TLiteral<"no-upstream">, Type.TLiteral<"no-upstream-sha">, Type.TLiteral<"comparison-failed">, Type.TLiteral<"git-unavailable">]>;
|
|
293
|
+
currentSha: Type.TOptional<Type.TString>;
|
|
294
|
+
commitAtMs: Type.TOptional<Type.TInteger>;
|
|
295
|
+
installedAtMs: Type.TOptional<Type.TInteger>;
|
|
296
|
+
}>]>>;
|
|
297
|
+
}>>;
|
|
298
|
+
target: Type.TOptional<Type.TUnion<[Type.TObject<{
|
|
299
|
+
kind: Type.TLiteral<"package">;
|
|
300
|
+
version: Type.TString;
|
|
301
|
+
}>, Type.TObject<{
|
|
302
|
+
kind: Type.TLiteral<"git">;
|
|
303
|
+
upstreamRef: Type.TString;
|
|
304
|
+
upstreamSha: Type.TString;
|
|
305
|
+
commitsBehind: Type.TInteger;
|
|
306
|
+
}>]>>;
|
|
307
|
+
campaign: Type.TOptional<Type.TObject<{
|
|
308
|
+
id: Type.TString;
|
|
309
|
+
state: Type.TUnion<[Type.TLiteral<"waiting-for-idle">, Type.TLiteral<"countdown">, Type.TLiteral<"applying">]>;
|
|
310
|
+
announcedAtMs: Type.TInteger;
|
|
311
|
+
applyAtMs: Type.TOptional<Type.TInteger>;
|
|
312
|
+
holdUntilMs: Type.TOptional<Type.TInteger>;
|
|
313
|
+
forceAtMs: Type.TInteger;
|
|
314
|
+
updatedAtMs: Type.TInteger;
|
|
315
|
+
}>>;
|
|
222
316
|
}>>;
|
|
223
317
|
}>;
|
|
224
318
|
controlUiTabs: Type.TOptional<Type.TArray<Type.TObject<{
|
|
@@ -243,6 +337,8 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
243
337
|
}>>;
|
|
244
338
|
auth: Type.TObject<{
|
|
245
339
|
deviceToken: Type.TOptional<Type.TString>;
|
|
340
|
+
recoveryMigrationAllowed: Type.TOptional<Type.TLiteral<true>>;
|
|
341
|
+
recoveryScope: Type.TOptional<Type.TString>;
|
|
246
342
|
role: Type.TString;
|
|
247
343
|
scopes: Type.TArray<Type.TString>;
|
|
248
344
|
issuedAtMs: Type.TOptional<Type.TInteger>;
|
|
@@ -257,6 +353,10 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
257
353
|
maxPayload: Type.TInteger;
|
|
258
354
|
maxBufferedBytes: Type.TInteger;
|
|
259
355
|
tickIntervalMs: Type.TInteger;
|
|
356
|
+
attachments: Type.TOptional<Type.TObject<{
|
|
357
|
+
maxBytes: Type.TInteger;
|
|
358
|
+
maxImageBytes: Type.TInteger;
|
|
359
|
+
}>>;
|
|
260
360
|
allowedSessionVisibilities: Type.TOptional<Type.TArray<Type.TUnion<[Type.TLiteral<"shared">, Type.TLiteral<"read-only">, Type.TLiteral<"suggest">, Type.TLiteral<"draft">]>>>;
|
|
261
361
|
hasMultipleSessionSharingIdentities: Type.TOptional<Type.TBoolean>;
|
|
262
362
|
}>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//#region src/gateway-error-details.d.ts
|
|
2
2
|
/** Gateway JSON-RPC style error codes shared by clients and server handlers. */
|
|
3
3
|
declare const ErrorCodes: {
|
|
4
|
-
/**
|
|
5
|
-
readonly NOT_PAIRED: "NOT_PAIRED"; /**
|
|
4
|
+
/** @deprecated Retained for source compatibility; no current server emitter. */readonly NOT_LINKED: "NOT_LINKED"; /** Device exists but still needs an explicit pairing approval. */
|
|
5
|
+
readonly NOT_PAIRED: "NOT_PAIRED"; /** @deprecated Retained for source compatibility; no current server emitter. */
|
|
6
6
|
readonly AGENT_TIMEOUT: "AGENT_TIMEOUT"; /** Request payload failed protocol validation or method preconditions. */
|
|
7
7
|
readonly INVALID_REQUEST: "INVALID_REQUEST"; /** Authenticated caller lacks permission for the requested operation. */
|
|
8
8
|
readonly FORBIDDEN: "FORBIDDEN"; /** Approval resolution referenced a missing or expired approval request. */
|
|
@@ -15,7 +15,9 @@ type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
|
15
15
|
declare const GatewayErrorDetailCodes: {
|
|
16
16
|
readonly MISSING_SCOPE: "MISSING_SCOPE";
|
|
17
17
|
readonly MCP_APP_VIEW_EXPIRED: "MCP_APP_VIEW_EXPIRED";
|
|
18
|
+
readonly USER_PREFS_LIMIT_EXCEEDED: "USER_PREFS_LIMIT_EXCEEDED";
|
|
18
19
|
readonly SESSION_COMPANION_BUSY: "SESSION_COMPANION_BUSY";
|
|
20
|
+
readonly PROJECT_CLONE_FAILED: "PROJECT_CLONE_FAILED";
|
|
19
21
|
readonly UNKNOWN_AGENT_ID: "UNKNOWN_AGENT_ID";
|
|
20
22
|
readonly WIZARD_NOT_FOUND: "WIZARD_NOT_FOUND";
|
|
21
23
|
};
|
|
@@ -28,6 +30,12 @@ type MissingScopeErrorDetails = {
|
|
|
28
30
|
type McpAppViewExpiredErrorDetails = {
|
|
29
31
|
code: typeof GatewayErrorDetailCodes.MCP_APP_VIEW_EXPIRED;
|
|
30
32
|
};
|
|
33
|
+
/** Per-profile preference quota details returned by users.prefs.set. */
|
|
34
|
+
type UserPrefsLimitExceededErrorDetails = {
|
|
35
|
+
code: typeof GatewayErrorDetailCodes.USER_PREFS_LIMIT_EXCEEDED;
|
|
36
|
+
limit: number;
|
|
37
|
+
currentCount: number;
|
|
38
|
+
};
|
|
31
39
|
/** Unknown agent details carried by agent-scoped method validation failures. */
|
|
32
40
|
type UnknownAgentIdErrorDetails = {
|
|
33
41
|
code: typeof GatewayErrorDetailCodes.UNKNOWN_AGENT_ID;
|
|
@@ -37,8 +45,13 @@ type UnknownAgentIdErrorDetails = {
|
|
|
37
45
|
type WizardNotFoundErrorDetails = {
|
|
38
46
|
code: typeof GatewayErrorDetailCodes.WIZARD_NOT_FOUND;
|
|
39
47
|
};
|
|
48
|
+
type ProjectCloneFailureCause = "invalid_url" | "auth_required" | "not_found" | "network" | "target_exists" | "clone_failed";
|
|
49
|
+
type ProjectCloneErrorDetails = {
|
|
50
|
+
code: typeof GatewayErrorDetailCodes.PROJECT_CLONE_FAILED;
|
|
51
|
+
cause: ProjectCloneFailureCause;
|
|
52
|
+
};
|
|
40
53
|
/** Structured details emitted by method-level failures. */
|
|
41
|
-
type GatewayErrorDetails = MissingScopeErrorDetails | McpAppViewExpiredErrorDetails | UnknownAgentIdErrorDetails | WizardNotFoundErrorDetails;
|
|
54
|
+
type GatewayErrorDetails = MissingScopeErrorDetails | McpAppViewExpiredErrorDetails | UserPrefsLimitExceededErrorDetails | ProjectCloneErrorDetails | UnknownAgentIdErrorDetails | WizardNotFoundErrorDetails;
|
|
42
55
|
/** Reads validated missing-scope details from an untrusted protocol payload. */
|
|
43
56
|
declare function readMissingScopeErrorDetails(details: unknown): MissingScopeErrorDetails | null;
|
|
44
57
|
declare function isMcpAppViewExpiredError(error: unknown): boolean;
|
|
@@ -48,4 +61,4 @@ declare function isMcpAppViewExpiredError(error: unknown): boolean;
|
|
|
48
61
|
*/
|
|
49
62
|
declare function readMissingScopeError(error: unknown): MissingScopeErrorDetails | null;
|
|
50
63
|
//#endregion
|
|
51
|
-
export { McpAppViewExpiredErrorDetails as a,
|
|
64
|
+
export { McpAppViewExpiredErrorDetails as a, ProjectCloneFailureCause as c, WizardNotFoundErrorDetails as d, isMcpAppViewExpiredError as f, GatewayErrorDetails as i, UnknownAgentIdErrorDetails as l, readMissingScopeErrorDetails as m, ErrorCodes as n, MissingScopeErrorDetails as o, readMissingScopeError as p, GatewayErrorDetailCodes as r, ProjectCloneErrorDetails as s, ErrorCode as t, UserPrefsLimitExceededErrorDetails as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as McpAppViewExpiredErrorDetails, c as
|
|
2
|
-
export { ErrorCode, ErrorCodes, GatewayErrorDetailCodes, GatewayErrorDetails, McpAppViewExpiredErrorDetails, MissingScopeErrorDetails, UnknownAgentIdErrorDetails, WizardNotFoundErrorDetails, isMcpAppViewExpiredError, readMissingScopeError, readMissingScopeErrorDetails };
|
|
1
|
+
import { a as McpAppViewExpiredErrorDetails, c as ProjectCloneFailureCause, d as WizardNotFoundErrorDetails, f as isMcpAppViewExpiredError, i as GatewayErrorDetails, l as UnknownAgentIdErrorDetails, m as readMissingScopeErrorDetails, n as ErrorCodes, o as MissingScopeErrorDetails, p as readMissingScopeError, r as GatewayErrorDetailCodes, s as ProjectCloneErrorDetails, t as ErrorCode, u as UserPrefsLimitExceededErrorDetails } from "./gateway-error-details-BXoMHq1i.mjs";
|
|
2
|
+
export { ErrorCode, ErrorCodes, GatewayErrorDetailCodes, GatewayErrorDetails, McpAppViewExpiredErrorDetails, MissingScopeErrorDetails, ProjectCloneErrorDetails, ProjectCloneFailureCause, UnknownAgentIdErrorDetails, UserPrefsLimitExceededErrorDetails, WizardNotFoundErrorDetails, isMcpAppViewExpiredError, readMissingScopeError, readMissingScopeErrorDetails };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { t as asProtocolRecord } from "./protocol-value-normalization-Bexl3yr1.mjs";
|
|
1
2
|
//#region src/gateway-error-details.ts
|
|
2
3
|
/** Gateway JSON-RPC style error codes shared by clients and server handlers. */
|
|
3
4
|
const ErrorCodes = {
|
|
4
|
-
/**
|
|
5
|
+
/** @deprecated Retained for source compatibility; no current server emitter. */
|
|
5
6
|
NOT_LINKED: "NOT_LINKED",
|
|
6
7
|
/** Device exists but still needs an explicit pairing approval. */
|
|
7
8
|
NOT_PAIRED: "NOT_PAIRED",
|
|
8
|
-
/**
|
|
9
|
+
/** @deprecated Retained for source compatibility; no current server emitter. */
|
|
9
10
|
AGENT_TIMEOUT: "AGENT_TIMEOUT",
|
|
10
11
|
/** Request payload failed protocol validation or method preconditions. */
|
|
11
12
|
INVALID_REQUEST: "INVALID_REQUEST",
|
|
@@ -20,17 +21,16 @@ const ErrorCodes = {
|
|
|
20
21
|
const GatewayErrorDetailCodes = {
|
|
21
22
|
MISSING_SCOPE: "MISSING_SCOPE",
|
|
22
23
|
MCP_APP_VIEW_EXPIRED: "MCP_APP_VIEW_EXPIRED",
|
|
24
|
+
USER_PREFS_LIMIT_EXCEEDED: "USER_PREFS_LIMIT_EXCEEDED",
|
|
23
25
|
SESSION_COMPANION_BUSY: "SESSION_COMPANION_BUSY",
|
|
26
|
+
PROJECT_CLONE_FAILED: "PROJECT_CLONE_FAILED",
|
|
24
27
|
UNKNOWN_AGENT_ID: "UNKNOWN_AGENT_ID",
|
|
25
28
|
WIZARD_NOT_FOUND: "WIZARD_NOT_FOUND"
|
|
26
29
|
};
|
|
27
30
|
const LEGACY_MISSING_SCOPE_PATTERN = /\bmissing scope:\s*([a-z0-9._-]+)/i;
|
|
28
|
-
function asRecord(value) {
|
|
29
|
-
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
30
|
-
}
|
|
31
31
|
/** Reads validated missing-scope details from an untrusted protocol payload. */
|
|
32
32
|
function readMissingScopeErrorDetails(details) {
|
|
33
|
-
const record =
|
|
33
|
+
const record = asProtocolRecord(details);
|
|
34
34
|
if (record?.code !== GatewayErrorDetailCodes.MISSING_SCOPE) return null;
|
|
35
35
|
const missingScope = typeof record.missingScope === "string" ? record.missingScope.trim() : "";
|
|
36
36
|
const requiredScopes = Array.isArray(record.requiredScopes) ? record.requiredScopes.map((scope) => typeof scope === "string" ? scope.trim() : "") : [];
|
|
@@ -42,14 +42,14 @@ function readMissingScopeErrorDetails(details) {
|
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
44
|
function isMcpAppViewExpiredError(error) {
|
|
45
|
-
return
|
|
45
|
+
return asProtocolRecord(asProtocolRecord(error)?.details)?.code === GatewayErrorDetailCodes.MCP_APP_VIEW_EXPIRED;
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
48
|
* Reads a method-level missing-scope failure, preferring structured details.
|
|
49
49
|
* The message fallback keeps clients compatible with gateways predating structured details.
|
|
50
50
|
*/
|
|
51
51
|
function readMissingScopeError(error) {
|
|
52
|
-
const record =
|
|
52
|
+
const record = asProtocolRecord(error);
|
|
53
53
|
if (!record) return null;
|
|
54
54
|
const structured = readMissingScopeErrorDetails(record.details);
|
|
55
55
|
if (structured) return structured;
|