@openclaw/gateway-protocol 2026.8.1-beta.2 → 2026.8.1-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/CHANGELOG.md +1 -0
- package/dist/client-info.mjs +1 -1
- package/dist/connect-error-details.d.mts +5 -0
- package/dist/connect-error-details.mjs +37 -5
- package/dist/frame-guards.d.mts +1 -1
- package/dist/frame-guards.mjs +5 -4
- package/dist/{frames-B9De7i2H.d.mts → frames-BKvowx_k.d.mts} +7 -4
- package/dist/{gateway-error-details-BXoMHq1i.d.mts → gateway-error-details-DR-CyzeW.d.mts} +28 -2
- package/dist/gateway-error-details.d.mts +2 -2
- package/dist/gateway-error-details.mjs +39 -5
- package/dist/index.d.mts +403 -36
- package/dist/index.mjs +85 -12
- package/dist/protocol-value-normalization-DcAoxLUs.mjs +12 -0
- package/dist/record-coerce-BKHrZ46I.mjs +11 -0
- package/dist/{schema-modules-VhRJPNg7.d.mts → schema-modules-CriS_x5c.d.mts} +16556 -15252
- package/dist/schema.d.mts +1019 -74
- package/dist/schema.mjs +69 -3
- package/dist/{worktrees-CSLN5mQz.mjs → worktrees-D1V7ClOO.mjs} +2958 -2152
- package/package.json +4 -1
- package/protocol.schema.json +7629 -976
- package/dist/protocol-value-normalization-Bexl3yr1.mjs +0 -20
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,7 @@ version and the additive schema surface. Dates are authoring dates (2026).
|
|
|
14
14
|
- Slim worker and session-catalog payloads to the active wire contract.
|
|
15
15
|
- Remove dead protocol surfaces and add since-vintage metadata to retained schemas and methods.
|
|
16
16
|
- Add optional `step` on `SystemAgentChatResult` carrying the full awaited wizard step.
|
|
17
|
+
- Project plugin tab `placement` in `hello-ok` so active plugins can target native Control UI routes.
|
|
17
18
|
|
|
18
19
|
## Protocol v4 (current)
|
|
19
20
|
|
package/dist/client-info.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as normalizeOptionalProtocolString } from "./protocol-value-normalization-DcAoxLUs.mjs";
|
|
2
2
|
//#region src/client-info.ts
|
|
3
3
|
/**
|
|
4
4
|
* Shared gateway client identity contract.
|
|
@@ -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 AUTH_IDENTITY_HEADER_REQUIRED: "AUTH_IDENTITY_HEADER_REQUIRED";
|
|
20
21
|
readonly CONTROL_UI_BUILD_MISMATCH: "CONTROL_UI_BUILD_MISMATCH";
|
|
21
22
|
readonly CONTROL_UI_ORIGIN_NOT_ALLOWED: "CONTROL_UI_ORIGIN_NOT_ALLOWED";
|
|
22
23
|
readonly PROTOCOL_MISMATCH: "PROTOCOL_MISMATCH";
|
|
@@ -115,6 +116,10 @@ declare function classifyGatewayConnectFailure(input: {
|
|
|
115
116
|
kind: "pairing-required";
|
|
116
117
|
userMessage: string;
|
|
117
118
|
remediation: string;
|
|
119
|
+
} | {
|
|
120
|
+
kind: "identity-proxy";
|
|
121
|
+
userMessage: string;
|
|
122
|
+
remediation: string;
|
|
118
123
|
} | {
|
|
119
124
|
remediation?: string | undefined;
|
|
120
125
|
kind: "device-identity-required" | "scope-mismatch" | "rate-limited" | "auth-rejected" | "gateway-rejected" | "unreachable";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as isRecord } from "./record-coerce-BKHrZ46I.mjs";
|
|
2
|
+
import { n as normalizeOptionalProtocolString } from "./protocol-value-normalization-DcAoxLUs.mjs";
|
|
2
3
|
//#region src/connect-error-details.ts
|
|
3
4
|
/**
|
|
4
5
|
* Shared gateway connect-error detail helpers.
|
|
@@ -29,6 +30,7 @@ const ConnectErrorDetailCodes = {
|
|
|
29
30
|
AUTH_TAILSCALE_PROXY_MISSING: "AUTH_TAILSCALE_PROXY_MISSING",
|
|
30
31
|
AUTH_TAILSCALE_WHOIS_FAILED: "AUTH_TAILSCALE_WHOIS_FAILED",
|
|
31
32
|
AUTH_TAILSCALE_IDENTITY_MISMATCH: "AUTH_TAILSCALE_IDENTITY_MISMATCH",
|
|
33
|
+
AUTH_IDENTITY_HEADER_REQUIRED: "AUTH_IDENTITY_HEADER_REQUIRED",
|
|
32
34
|
CONTROL_UI_BUILD_MISMATCH: "CONTROL_UI_BUILD_MISMATCH",
|
|
33
35
|
CONTROL_UI_ORIGIN_NOT_ALLOWED: "CONTROL_UI_ORIGIN_NOT_ALLOWED",
|
|
34
36
|
PROTOCOL_MISMATCH: "PROTOCOL_MISMATCH",
|
|
@@ -95,6 +97,7 @@ const CONNECT_PAIRING_REQUIRED_MESSAGE_BY_REASON = {
|
|
|
95
97
|
};
|
|
96
98
|
/** Maps internal auth failure reasons to public connect-error detail codes. */
|
|
97
99
|
function resolveAuthConnectErrorDetailCode(reason) {
|
|
100
|
+
if (reason?.startsWith("trusted_proxy_missing_header_")) return ConnectErrorDetailCodes.AUTH_IDENTITY_HEADER_REQUIRED;
|
|
98
101
|
switch (reason) {
|
|
99
102
|
case "token_missing": return ConnectErrorDetailCodes.AUTH_TOKEN_MISSING;
|
|
100
103
|
case "token_mismatch": return ConnectErrorDetailCodes.AUTH_TOKEN_MISMATCH;
|
|
@@ -128,13 +131,14 @@ function resolveDeviceAuthConnectErrorDetailCode(reason) {
|
|
|
128
131
|
}
|
|
129
132
|
/** Reads a non-empty detail code from an untrusted error details payload. */
|
|
130
133
|
function readConnectErrorDetailCode(details) {
|
|
131
|
-
if (!
|
|
134
|
+
if (!isRecord(details)) return null;
|
|
132
135
|
const code = details.code;
|
|
133
136
|
return typeof code === "string" && code.trim().length > 0 ? code.trim() : null;
|
|
134
137
|
}
|
|
135
138
|
/** Read the exact target artifact from an untrusted reload-required rejection. */
|
|
136
139
|
function readControlUiBuildMismatchId(details) {
|
|
137
|
-
|
|
140
|
+
const code = readConnectErrorDetailCode(details);
|
|
141
|
+
if (code !== ConnectErrorDetailCodes.PROTOCOL_MISMATCH && code !== ConnectErrorDetailCodes.CONTROL_UI_BUILD_MISMATCH) return null;
|
|
138
142
|
const raw = details;
|
|
139
143
|
const gatewayBuildId = normalizeOptionalProtocolString(raw.gatewayBuildId);
|
|
140
144
|
if (!gatewayBuildId || gatewayBuildId.length > 96 || raw.reloadRequired !== true) return null;
|
|
@@ -142,7 +146,7 @@ function readControlUiBuildMismatchId(details) {
|
|
|
142
146
|
}
|
|
143
147
|
/** Extracts normalized retry advice from untrusted connect-error details. */
|
|
144
148
|
function readConnectErrorRecoveryAdvice(details) {
|
|
145
|
-
if (!
|
|
149
|
+
if (!isRecord(details)) return {};
|
|
146
150
|
const raw = details;
|
|
147
151
|
const canRetryWithDeviceToken = typeof raw.canRetryWithDeviceToken === "boolean" ? raw.canRetryWithDeviceToken : void 0;
|
|
148
152
|
const normalizedNextStep = normalizeOptionalProtocolString(raw.recommendedNextStep) ?? "";
|
|
@@ -226,7 +230,7 @@ function buildPairingConnectCloseReason(params) {
|
|
|
226
230
|
/** Reads and backfills pairing-required details from an untrusted details object. */
|
|
227
231
|
function readPairingConnectErrorDetails(details) {
|
|
228
232
|
if (readConnectErrorDetailCode(details) !== ConnectErrorDetailCodes.PAIRING_REQUIRED) return null;
|
|
229
|
-
if (!
|
|
233
|
+
if (!isRecord(details)) return null;
|
|
230
234
|
const raw = details;
|
|
231
235
|
const reason = normalizePairingConnectReason(raw.reason);
|
|
232
236
|
const requestId = normalizePairingConnectRequestId(raw.requestId);
|
|
@@ -275,7 +279,29 @@ const DEVICE_TOKEN_REMEDIATION = "Rotate the paired-device token with `openclaw
|
|
|
275
279
|
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
280
|
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
281
|
const RATE_LIMITED_REMEDIATION = "Wait for the temporary authentication lockout to expire, then retry.";
|
|
282
|
+
const IDENTITY_PROXY_REMEDIATION = "An identity-aware proxy rejected the WebSocket upgrade. Configure gateway.remote.edgeAuth for the configured Gateway origin, then reconnect. See https://docs.openclaw.ai/gateway/remote#gateway-behind-an-identity-aware-proxy.";
|
|
283
|
+
const CLOUDFLARE_ACCESS_REMEDIATION = "Cloudflare Access detected: configure its token header or service-token headers in gateway.remote.edgeAuth.";
|
|
284
|
+
const IDENTITY_PROXY_HTTP_STATUSES = /* @__PURE__ */ new Set([
|
|
285
|
+
301,
|
|
286
|
+
302,
|
|
287
|
+
303,
|
|
288
|
+
307,
|
|
289
|
+
308,
|
|
290
|
+
401,
|
|
291
|
+
403
|
|
292
|
+
]);
|
|
278
293
|
const GATEWAY_CLOSED_MESSAGE_PATTERN = /\bgateway closed \(\d+\):/i;
|
|
294
|
+
function readIdentityProxyRejection(details) {
|
|
295
|
+
if (!isRecord(details)) return null;
|
|
296
|
+
if (details.reason !== "websocket-upgrade-rejected" || typeof details.httpStatus !== "number" || !IDENTITY_PROXY_HTTP_STATUSES.has(details.httpStatus)) return null;
|
|
297
|
+
const location = normalizeOptionalProtocolString(details.location);
|
|
298
|
+
if (!location) return { cloudflareAccess: false };
|
|
299
|
+
try {
|
|
300
|
+
return { cloudflareAccess: new URL(location).hostname.toLowerCase().replace(/\.+$/u, "").endsWith(".cloudflareaccess.com") };
|
|
301
|
+
} catch {
|
|
302
|
+
return { cloudflareAccess: false };
|
|
303
|
+
}
|
|
304
|
+
}
|
|
279
305
|
/** Classifies Gateway connect failures from structured details, with one legacy text fallback. */
|
|
280
306
|
function classifyGatewayConnectFailure(input) {
|
|
281
307
|
const code = readConnectErrorDetailCode(input.details);
|
|
@@ -290,6 +316,12 @@ function classifyGatewayConnectFailure(input) {
|
|
|
290
316
|
userMessage: code === ConnectErrorDetailCodes.PAIRING_REQUIRED ? formatConnectPairingRequiredMessage(input.details) : userMessage ?? "device pairing required",
|
|
291
317
|
remediation: PAIRING_APPROVAL_REMEDIATION
|
|
292
318
|
};
|
|
319
|
+
const identityProxy = readIdentityProxyRejection(input.details);
|
|
320
|
+
if (identityProxy) return {
|
|
321
|
+
kind: "identity-proxy",
|
|
322
|
+
userMessage: userMessage ?? "identity-aware proxy rejected websocket upgrade",
|
|
323
|
+
remediation: identityProxy.cloudflareAccess ? `${IDENTITY_PROXY_REMEDIATION}\n${CLOUDFLARE_ACCESS_REMEDIATION}` : IDENTITY_PROXY_REMEDIATION
|
|
324
|
+
};
|
|
293
325
|
const deviceIdentityRequired = code === ConnectErrorDetailCodes.DEVICE_IDENTITY_REQUIRED || code === ConnectErrorDetailCodes.CONTROL_UI_DEVICE_IDENTITY_REQUIRED || normalized.includes("device identity required");
|
|
294
326
|
const scopeMismatch = code === ConnectErrorDetailCodes.AUTH_SCOPE_MISMATCH || normalized.includes("scope mismatch");
|
|
295
327
|
const rateLimited = code === ConnectErrorDetailCodes.AUTH_RATE_LIMITED || !code && normalized.includes("too many failed authentication attempts");
|
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-BKvowx_k.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,20 +1,21 @@
|
|
|
1
|
-
import { n as
|
|
1
|
+
import { n as isRecord } from "./record-coerce-BKHrZ46I.mjs";
|
|
2
|
+
import { t as isNonEmptyProtocolString } from "./protocol-value-normalization-DcAoxLUs.mjs";
|
|
2
3
|
//#region src/frame-guards.ts
|
|
3
4
|
function isNonNegativeInteger(value) {
|
|
4
5
|
return typeof value === "number" && Number.isInteger(value) && value >= 0;
|
|
5
6
|
}
|
|
6
7
|
function isGatewayErrorShape(value) {
|
|
7
|
-
if (!
|
|
8
|
+
if (!isRecord(value)) return false;
|
|
8
9
|
if (!isNonEmptyProtocolString(value.code) || !isNonEmptyProtocolString(value.message)) return false;
|
|
9
10
|
if (value.retryable !== void 0 && typeof value.retryable !== "boolean") return false;
|
|
10
11
|
return value.retryAfterMs === void 0 || isNonNegativeInteger(value.retryAfterMs);
|
|
11
12
|
}
|
|
12
13
|
function isGatewayEventFrame(value) {
|
|
13
|
-
if (!
|
|
14
|
+
if (!isRecord(value) || value.type !== "event" || !isNonEmptyProtocolString(value.event)) return false;
|
|
14
15
|
return value.seq === void 0 || isNonNegativeInteger(value.seq);
|
|
15
16
|
}
|
|
16
17
|
function isGatewayResponseFrame(value) {
|
|
17
|
-
if (!
|
|
18
|
+
if (!isRecord(value) || value.type !== "res" || !isNonEmptyProtocolString(value.id) || typeof value.ok !== "boolean") return false;
|
|
18
19
|
return value.error === void 0 || isGatewayErrorShape(value.error);
|
|
19
20
|
}
|
|
20
21
|
//#endregion
|
|
@@ -4,6 +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 GATEWAY_RESTART_TARGET_SAFE: "gateway-restart-target-safe-v1";
|
|
8
|
+
readonly NODE_WORKER_BUNDLE_RETENTION: "node-worker-bundle-retention-v1";
|
|
9
|
+
readonly NODE_WORKER_BUNDLE_STATUS: "node-worker-bundle-status-v1";
|
|
7
10
|
readonly SYSTEM_AGENT_WIZARD_CANCEL: "openclaw-chat-wizard-cancel";
|
|
8
11
|
readonly SYSTEM_AGENT_SETUP_MODEL_REF: "openclaw-setup-model-ref";
|
|
9
12
|
readonly TASK_SUGGESTIONS_ACCEPT_MODES: "taskSuggestions.acceptModes";
|
|
@@ -40,11 +43,12 @@ declare const ConnectParamsSchema: Type.TObject<{
|
|
|
40
43
|
}>;
|
|
41
44
|
caps: Type.TOptional<Type.TArray<Type.TString>>;
|
|
42
45
|
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>; /**
|
|
46
|
+
computerUse: Type.TOptional<Type.TUnknown>; /** @deprecated Accepted for the shipped v1 node-host envelope; current hosts use runner inventory. */
|
|
44
47
|
workerRuns: Type.TOptional<Type.TObject<{
|
|
45
48
|
bundleHash: Type.TString;
|
|
46
49
|
openclawVersion: Type.TString;
|
|
47
50
|
protocolFeatures: Type.TArray<Type.TString>;
|
|
51
|
+
bundlePrewarm: Type.TOptional<Type.TInteger>;
|
|
48
52
|
}>>;
|
|
49
53
|
permissions: Type.TOptional<Type.TRecord<"^.*$", Type.TBoolean>>;
|
|
50
54
|
pathEnv: Type.TOptional<Type.TString>;
|
|
@@ -238,6 +242,7 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
238
242
|
stateDir: Type.TOptional<Type.TString>;
|
|
239
243
|
sessionDefaults: Type.TOptional<Type.TObject<{
|
|
240
244
|
defaultAgentId: Type.TString;
|
|
245
|
+
modelConfigured: Type.TOptional<Type.TBoolean>;
|
|
241
246
|
ownership: Type.TOptional<Type.TUnion<[Type.TLiteral<"sole">, Type.TLiteral<"legacy">, Type.TLiteral<"explicit">]>>;
|
|
242
247
|
selectionRequired: Type.TOptional<Type.TBoolean>;
|
|
243
248
|
mainKey: Type.TString;
|
|
@@ -322,6 +327,7 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
322
327
|
description: Type.TOptional<Type.TString>;
|
|
323
328
|
icon: Type.TOptional<Type.TString>;
|
|
324
329
|
path: Type.TOptional<Type.TString>;
|
|
330
|
+
placement: Type.TOptional<Type.TString>;
|
|
325
331
|
requiresGatewayAuth: Type.TOptional<Type.TBoolean>;
|
|
326
332
|
group: Type.TOptional<Type.TUnion<[Type.TLiteral<"control">, Type.TLiteral<"agent">]>>;
|
|
327
333
|
order: Type.TOptional<Type.TNumber>;
|
|
@@ -332,9 +338,6 @@ declare const HelloOkSchema: Type.TObject<{
|
|
|
332
338
|
label: Type.TString;
|
|
333
339
|
}>>>;
|
|
334
340
|
pluginSurfaceUrls: Type.TOptional<Type.TRecord<"^.*$", Type.TString>>;
|
|
335
|
-
deviceAuthMigration: Type.TOptional<Type.TObject<{
|
|
336
|
-
pending: Type.TLiteral<true>;
|
|
337
|
-
}>>;
|
|
338
341
|
auth: Type.TObject<{
|
|
339
342
|
deviceToken: Type.TOptional<Type.TString>;
|
|
340
343
|
recoveryMigrationAllowed: Type.TOptional<Type.TLiteral<true>>;
|
|
@@ -13,14 +13,22 @@ declare const ErrorCodes: {
|
|
|
13
13
|
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
14
14
|
/** Stable discriminants for structured method-level failures. */
|
|
15
15
|
declare const GatewayErrorDetailCodes: {
|
|
16
|
+
readonly CRON_JOB_NOT_FOUND: "CRON_JOB_NOT_FOUND";
|
|
16
17
|
readonly MISSING_SCOPE: "MISSING_SCOPE";
|
|
17
18
|
readonly MCP_APP_VIEW_EXPIRED: "MCP_APP_VIEW_EXPIRED";
|
|
19
|
+
readonly OUTBOUND_DELIVERY_QUEUED: "OUTBOUND_DELIVERY_QUEUED";
|
|
18
20
|
readonly USER_PREFS_LIMIT_EXCEEDED: "USER_PREFS_LIMIT_EXCEEDED";
|
|
19
21
|
readonly SESSION_COMPANION_BUSY: "SESSION_COMPANION_BUSY";
|
|
22
|
+
readonly SKILL_PROPOSAL_REVISION_CHANGED: "SKILL_PROPOSAL_REVISION_CHANGED";
|
|
20
23
|
readonly PROJECT_CLONE_FAILED: "PROJECT_CLONE_FAILED";
|
|
21
24
|
readonly UNKNOWN_AGENT_ID: "UNKNOWN_AGENT_ID";
|
|
22
25
|
readonly WIZARD_NOT_FOUND: "WIZARD_NOT_FOUND";
|
|
23
26
|
};
|
|
27
|
+
/** Missing cron automation identified by its exact store key. */
|
|
28
|
+
type CronJobNotFoundErrorDetails = {
|
|
29
|
+
code: typeof GatewayErrorDetailCodes.CRON_JOB_NOT_FOUND;
|
|
30
|
+
jobId: string;
|
|
31
|
+
};
|
|
24
32
|
/** Missing operator-scope details shared by WebSocket and HTTP responses. */
|
|
25
33
|
type MissingScopeErrorDetails = {
|
|
26
34
|
code: typeof GatewayErrorDetailCodes.MISSING_SCOPE;
|
|
@@ -30,6 +38,9 @@ type MissingScopeErrorDetails = {
|
|
|
30
38
|
type McpAppViewExpiredErrorDetails = {
|
|
31
39
|
code: typeof GatewayErrorDetailCodes.MCP_APP_VIEW_EXPIRED;
|
|
32
40
|
};
|
|
41
|
+
type OutboundDeliveryQueuedErrorDetails = {
|
|
42
|
+
code: typeof GatewayErrorDetailCodes.OUTBOUND_DELIVERY_QUEUED;
|
|
43
|
+
};
|
|
33
44
|
/** Per-profile preference quota details returned by users.prefs.set. */
|
|
34
45
|
type UserPrefsLimitExceededErrorDetails = {
|
|
35
46
|
code: typeof GatewayErrorDetailCodes.USER_PREFS_LIMIT_EXCEEDED;
|
|
@@ -50,8 +61,23 @@ type ProjectCloneErrorDetails = {
|
|
|
50
61
|
code: typeof GatewayErrorDetailCodes.PROJECT_CLONE_FAILED;
|
|
51
62
|
cause: ProjectCloneFailureCause;
|
|
52
63
|
};
|
|
64
|
+
/** Optimistic-concurrency mismatch for an operator-reviewed Skill Workshop draft. */
|
|
65
|
+
type SkillProposalRevisionChangedErrorDetails = {
|
|
66
|
+
code: typeof GatewayErrorDetailCodes.SKILL_PROPOSAL_REVISION_CHANGED;
|
|
67
|
+
expectedRevisionHash: string;
|
|
68
|
+
currentRevisionHash: string;
|
|
69
|
+
};
|
|
53
70
|
/** Structured details emitted by method-level failures. */
|
|
54
|
-
type GatewayErrorDetails = MissingScopeErrorDetails | McpAppViewExpiredErrorDetails | UserPrefsLimitExceededErrorDetails | ProjectCloneErrorDetails | UnknownAgentIdErrorDetails | WizardNotFoundErrorDetails;
|
|
71
|
+
type GatewayErrorDetails = CronJobNotFoundErrorDetails | MissingScopeErrorDetails | McpAppViewExpiredErrorDetails | OutboundDeliveryQueuedErrorDetails | UserPrefsLimitExceededErrorDetails | SkillProposalRevisionChangedErrorDetails | ProjectCloneErrorDetails | UnknownAgentIdErrorDetails | WizardNotFoundErrorDetails;
|
|
72
|
+
/** Reads a typed cron lookup miss without parsing operator-facing prose. */
|
|
73
|
+
declare function readCronJobNotFoundError(error: unknown): CronJobNotFoundErrorDetails | null;
|
|
74
|
+
/** Builds the canonical stale-draft details shared by Skill Workshop RPCs. */
|
|
75
|
+
declare function buildSkillProposalRevisionChangedErrorDetails(params: {
|
|
76
|
+
expectedRevisionHash: string;
|
|
77
|
+
currentRevisionHash: string;
|
|
78
|
+
}): SkillProposalRevisionChangedErrorDetails;
|
|
79
|
+
/** Reads a stale Skill Workshop decision without parsing operator-facing prose. */
|
|
80
|
+
declare function readSkillProposalRevisionChangedError(error: unknown): SkillProposalRevisionChangedErrorDetails | null;
|
|
55
81
|
/** Reads validated missing-scope details from an untrusted protocol payload. */
|
|
56
82
|
declare function readMissingScopeErrorDetails(details: unknown): MissingScopeErrorDetails | null;
|
|
57
83
|
declare function isMcpAppViewExpiredError(error: unknown): boolean;
|
|
@@ -61,4 +87,4 @@ declare function isMcpAppViewExpiredError(error: unknown): boolean;
|
|
|
61
87
|
*/
|
|
62
88
|
declare function readMissingScopeError(error: unknown): MissingScopeErrorDetails | null;
|
|
63
89
|
//#endregion
|
|
64
|
-
export {
|
|
90
|
+
export { readCronJobNotFoundError as _, GatewayErrorDetails as a, readSkillProposalRevisionChangedError as b, OutboundDeliveryQueuedErrorDetails as c, SkillProposalRevisionChangedErrorDetails as d, UnknownAgentIdErrorDetails as f, isMcpAppViewExpiredError as g, buildSkillProposalRevisionChangedErrorDetails as h, GatewayErrorDetailCodes as i, ProjectCloneErrorDetails as l, WizardNotFoundErrorDetails as m, ErrorCode as n, McpAppViewExpiredErrorDetails as o, UserPrefsLimitExceededErrorDetails as p, ErrorCodes as r, MissingScopeErrorDetails as s, CronJobNotFoundErrorDetails as t, ProjectCloneFailureCause as u, readMissingScopeError as v, readMissingScopeErrorDetails as y };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { ErrorCode, ErrorCodes, GatewayErrorDetailCodes, GatewayErrorDetails, McpAppViewExpiredErrorDetails, MissingScopeErrorDetails, ProjectCloneErrorDetails, ProjectCloneFailureCause, UnknownAgentIdErrorDetails, UserPrefsLimitExceededErrorDetails, WizardNotFoundErrorDetails, isMcpAppViewExpiredError, readMissingScopeError, readMissingScopeErrorDetails };
|
|
1
|
+
import { _ as readCronJobNotFoundError, a as GatewayErrorDetails, b as readSkillProposalRevisionChangedError, c as OutboundDeliveryQueuedErrorDetails, d as SkillProposalRevisionChangedErrorDetails, f as UnknownAgentIdErrorDetails, g as isMcpAppViewExpiredError, h as buildSkillProposalRevisionChangedErrorDetails, i as GatewayErrorDetailCodes, l as ProjectCloneErrorDetails, m as WizardNotFoundErrorDetails, n as ErrorCode, o as McpAppViewExpiredErrorDetails, p as UserPrefsLimitExceededErrorDetails, r as ErrorCodes, s as MissingScopeErrorDetails, t as CronJobNotFoundErrorDetails, u as ProjectCloneFailureCause, v as readMissingScopeError, y as readMissingScopeErrorDetails } from "./gateway-error-details-DR-CyzeW.mjs";
|
|
2
|
+
export { CronJobNotFoundErrorDetails, ErrorCode, ErrorCodes, GatewayErrorDetailCodes, GatewayErrorDetails, McpAppViewExpiredErrorDetails, MissingScopeErrorDetails, OutboundDeliveryQueuedErrorDetails, ProjectCloneErrorDetails, ProjectCloneFailureCause, SkillProposalRevisionChangedErrorDetails, UnknownAgentIdErrorDetails, UserPrefsLimitExceededErrorDetails, WizardNotFoundErrorDetails, buildSkillProposalRevisionChangedErrorDetails, isMcpAppViewExpiredError, readCronJobNotFoundError, readMissingScopeError, readMissingScopeErrorDetails, readSkillProposalRevisionChangedError };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as
|
|
1
|
+
import { t as asNullableRecord } from "./record-coerce-BKHrZ46I.mjs";
|
|
2
2
|
//#region src/gateway-error-details.ts
|
|
3
3
|
/** Gateway JSON-RPC style error codes shared by clients and server handlers. */
|
|
4
4
|
const ErrorCodes = {
|
|
@@ -19,18 +19,52 @@ const ErrorCodes = {
|
|
|
19
19
|
};
|
|
20
20
|
/** Stable discriminants for structured method-level failures. */
|
|
21
21
|
const GatewayErrorDetailCodes = {
|
|
22
|
+
CRON_JOB_NOT_FOUND: "CRON_JOB_NOT_FOUND",
|
|
22
23
|
MISSING_SCOPE: "MISSING_SCOPE",
|
|
23
24
|
MCP_APP_VIEW_EXPIRED: "MCP_APP_VIEW_EXPIRED",
|
|
25
|
+
OUTBOUND_DELIVERY_QUEUED: "OUTBOUND_DELIVERY_QUEUED",
|
|
24
26
|
USER_PREFS_LIMIT_EXCEEDED: "USER_PREFS_LIMIT_EXCEEDED",
|
|
25
27
|
SESSION_COMPANION_BUSY: "SESSION_COMPANION_BUSY",
|
|
28
|
+
SKILL_PROPOSAL_REVISION_CHANGED: "SKILL_PROPOSAL_REVISION_CHANGED",
|
|
26
29
|
PROJECT_CLONE_FAILED: "PROJECT_CLONE_FAILED",
|
|
27
30
|
UNKNOWN_AGENT_ID: "UNKNOWN_AGENT_ID",
|
|
28
31
|
WIZARD_NOT_FOUND: "WIZARD_NOT_FOUND"
|
|
29
32
|
};
|
|
30
33
|
const LEGACY_MISSING_SCOPE_PATTERN = /\bmissing scope:\s*([a-z0-9._-]+)/i;
|
|
34
|
+
const SHA256_PATTERN = /^[a-fA-F0-9]{64}$/;
|
|
35
|
+
/** Reads a typed cron lookup miss without parsing operator-facing prose. */
|
|
36
|
+
function readCronJobNotFoundError(error) {
|
|
37
|
+
const details = asNullableRecord(asNullableRecord(error)?.details);
|
|
38
|
+
if (details?.code !== GatewayErrorDetailCodes.CRON_JOB_NOT_FOUND) return null;
|
|
39
|
+
const jobId = typeof details.jobId === "string" ? details.jobId.trim() : "";
|
|
40
|
+
return jobId ? {
|
|
41
|
+
code: GatewayErrorDetailCodes.CRON_JOB_NOT_FOUND,
|
|
42
|
+
jobId
|
|
43
|
+
} : null;
|
|
44
|
+
}
|
|
45
|
+
/** Builds the canonical stale-draft details shared by Skill Workshop RPCs. */
|
|
46
|
+
function buildSkillProposalRevisionChangedErrorDetails(params) {
|
|
47
|
+
return {
|
|
48
|
+
code: GatewayErrorDetailCodes.SKILL_PROPOSAL_REVISION_CHANGED,
|
|
49
|
+
expectedRevisionHash: params.expectedRevisionHash,
|
|
50
|
+
currentRevisionHash: params.currentRevisionHash
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Reads a stale Skill Workshop decision without parsing operator-facing prose. */
|
|
54
|
+
function readSkillProposalRevisionChangedError(error) {
|
|
55
|
+
const details = asNullableRecord(asNullableRecord(error)?.details);
|
|
56
|
+
if (details?.code !== GatewayErrorDetailCodes.SKILL_PROPOSAL_REVISION_CHANGED) return null;
|
|
57
|
+
const expectedRevisionHash = typeof details.expectedRevisionHash === "string" ? details.expectedRevisionHash : "";
|
|
58
|
+
const currentRevisionHash = typeof details.currentRevisionHash === "string" ? details.currentRevisionHash : "";
|
|
59
|
+
if (!SHA256_PATTERN.test(expectedRevisionHash) || !SHA256_PATTERN.test(currentRevisionHash)) return null;
|
|
60
|
+
return buildSkillProposalRevisionChangedErrorDetails({
|
|
61
|
+
expectedRevisionHash,
|
|
62
|
+
currentRevisionHash
|
|
63
|
+
});
|
|
64
|
+
}
|
|
31
65
|
/** Reads validated missing-scope details from an untrusted protocol payload. */
|
|
32
66
|
function readMissingScopeErrorDetails(details) {
|
|
33
|
-
const record =
|
|
67
|
+
const record = asNullableRecord(details);
|
|
34
68
|
if (record?.code !== GatewayErrorDetailCodes.MISSING_SCOPE) return null;
|
|
35
69
|
const missingScope = typeof record.missingScope === "string" ? record.missingScope.trim() : "";
|
|
36
70
|
const requiredScopes = Array.isArray(record.requiredScopes) ? record.requiredScopes.map((scope) => typeof scope === "string" ? scope.trim() : "") : [];
|
|
@@ -42,14 +76,14 @@ function readMissingScopeErrorDetails(details) {
|
|
|
42
76
|
};
|
|
43
77
|
}
|
|
44
78
|
function isMcpAppViewExpiredError(error) {
|
|
45
|
-
return
|
|
79
|
+
return asNullableRecord(asNullableRecord(error)?.details)?.code === GatewayErrorDetailCodes.MCP_APP_VIEW_EXPIRED;
|
|
46
80
|
}
|
|
47
81
|
/**
|
|
48
82
|
* Reads a method-level missing-scope failure, preferring structured details.
|
|
49
83
|
* The message fallback keeps clients compatible with gateways predating structured details.
|
|
50
84
|
*/
|
|
51
85
|
function readMissingScopeError(error) {
|
|
52
|
-
const record =
|
|
86
|
+
const record = asNullableRecord(error);
|
|
53
87
|
if (!record) return null;
|
|
54
88
|
const structured = readMissingScopeErrorDetails(record.details);
|
|
55
89
|
if (structured) return structured;
|
|
@@ -64,4 +98,4 @@ function readMissingScopeError(error) {
|
|
|
64
98
|
} : null;
|
|
65
99
|
}
|
|
66
100
|
//#endregion
|
|
67
|
-
export { ErrorCodes, GatewayErrorDetailCodes, isMcpAppViewExpiredError, readMissingScopeError, readMissingScopeErrorDetails };
|
|
101
|
+
export { ErrorCodes, GatewayErrorDetailCodes, buildSkillProposalRevisionChangedErrorDetails, isMcpAppViewExpiredError, readCronJobNotFoundError, readMissingScopeError, readMissingScopeErrorDetails, readSkillProposalRevisionChangedError };
|