@openclaw/gateway-client 2026.9.1-beta.1 → 2026.9.1

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/README.md CHANGED
@@ -25,13 +25,26 @@ separate from the Gateway's current wire protocol number reported in `hello-ok`.
25
25
 
26
26
  ## Install
27
27
 
28
+ Use the verified stable release with exact pins:
29
+
28
30
  ```bash
29
- npm install @openclaw/gateway-client @openclaw/gateway-protocol
31
+ npm install --save-exact @openclaw/gateway-client@2026.8.1 @openclaw/gateway-protocol@2026.8.1
30
32
  ```
31
33
 
32
- Node consumers use the `ws` transport included as a runtime dependency. Browser
33
- consumers provide their platform WebSocket through the browser-safe protocol
34
- client surface.
34
+ See the canonical [installation guide](https://docs.openclaw.ai/gateway/clients#install-the-packages)
35
+ for package/wire-version rules and recovery from reserved `0.0.0` artifacts.
36
+ Test it with the Gateway version you deploy; the root `openclaw` CLI has its own
37
+ package versions and dist-tags.
38
+
39
+ This release declares Node.js `>=22.19.0`. Node consumers use the `ws` transport
40
+ included as a runtime dependency. Browser consumers provide their platform
41
+ WebSocket through the browser-safe protocol client surface.
42
+
43
+ For device-authenticated Node connections, supply `deviceIdentity` (or
44
+ `hostDeps.loadOrCreateDeviceIdentity`) and the `hostDeps.signDevicePayload` and
45
+ `hostDeps.publicKeyRawBase64UrlFromPem` callbacks. The host also owns device-token
46
+ storage through `GatewayClientHostDeps`; the package does not load OpenClaw's
47
+ local identity or credentials automatically.
35
48
 
36
49
  ## Entry points
37
50
 
@@ -80,9 +93,16 @@ The client waits for the Gateway's `connect.challenge` event before sending its
80
93
  does not fall back to a pre-challenge handshake. `onHelloOk` fires only after the
81
94
  Gateway accepts a compatible connection, so requests should wait for that callback.
82
95
 
83
- For remote connections, use `wss://`. Plaintext `ws://` is allowed by default
84
- only for loopback addresses. Authentication material and Gateway traffic must
85
- not cross an untrusted network without transport security.
96
+ This loopback example uses the default `gateway-client` / `backend` identity.
97
+ It is not a device-pairing example. UI clients should declare their actual `mode`
98
+ and supply the device-auth host callbacks described above; see
99
+ [device identity and pairing](https://docs.openclaw.ai/gateway/protocol#device-identity-and-pairing).
100
+
101
+ For remote connections, prefer `wss://`. The Node client also accepts plaintext
102
+ `ws://` by default for loopback, private/link-local/CGNAT IP addresses, and
103
+ `.local` or `.ts.net` hostnames. This allowlist does not provide encryption:
104
+ authentication material and Gateway traffic must not cross an untrusted network
105
+ without transport security.
86
106
 
87
107
  ## Browser clients
88
108
 
@@ -1,7 +1,7 @@
1
- import { A as gatewayCredentialScope, C as reduceSessionProjection, D as normalizeSessionProjectionRunId, E as SessionMessageIdentity, M as buildDeviceAuthPayload, N as buildDeviceAuthPayloadV3, O as readSessionMessageIdentity, P as normalizeDeviceMetadataForAuth, S as reconcileSessionProjectionSnapshot, T as SessionMessageEnvelope, _ as SessionProjectionState, a as GatewaySessionMessageSubscriptionOptions, b as isLocallyOptimisticSessionMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionGatewayRunEvent, f as SessionProjectionRun, g as SessionProjectionSnapshotOptions, h as SessionProjectionScope, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as gatewayOriginScope, k as readSessionMessageSequence, l as SessionProjectionEntry, m as SessionProjectionRunTransition, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionRunStatus, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as createSessionProjection, w as reduceSessionProjectionRunEvent, x as projectLiveSessionMessage, y as hasSessionProjectionAcceptedFinal } from "./session-subscriptions-DNKXLO-Z.mjs";
1
+ import { A as readSessionMessageSequence, C as reduceSessionProjection, D as normalizeSessionProjectionRunId, E as SessionMessageIdentity, F as normalizeDeviceMetadataForAuth, M as gatewayOriginScope, N as buildDeviceAuthPayload, O as readAssistantStreamSegmentIdentity, P as buildDeviceAuthPayloadV3, S as reconcileSessionProjectionSnapshot, T as SessionMessageEnvelope, _ as SessionProjectionState, a as GatewaySessionMessageSubscriptionOptions, b as isLocallyOptimisticSessionMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionGatewayRunEvent, f as SessionProjectionRun, g as SessionProjectionSnapshotOptions, h as SessionProjectionScope, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as gatewayCredentialScope, k as readSessionMessageIdentity, l as SessionProjectionEntry, m as SessionProjectionRunTransition, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionRunStatus, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as createSessionProjection, w as reduceSessionProjectionRunEvent, x as projectLiveSessionMessage, y as hasSessionProjectionAcceptedFinal } from "./session-subscriptions-D2UdeJ0u.mjs";
2
2
  import { a as GatewayBrowserDeviceTokenStore, c as resolveGatewayConnectScopes, i as GatewayBrowserDeviceTokenRecord, l as selectGatewayConnectAuth, n as GatewayBrowserDeviceAuthPlan, o as GatewayConnectAuthSelection, r as GatewayBrowserDeviceIdentity, s as buildGatewayConnectAuth, t as GatewayBrowserDeviceAuthLifecycle, u as shouldRetryGatewayWithDeviceToken } from "./browser-device-auth-DoPo-sPB.mjs";
3
- import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-r0jkQ1XE.mjs";
4
- import { a as GatewayProtocolTiming, i as GatewayProtocolSocketHandlers, n as GatewayProtocolCloseContext, o as GatewayProtocolRequestTiming, r as GatewayProtocolSocket, t as GatewayProtocolClient } from "./protocol-client-C-viHJgO.mjs";
3
+ import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-B5gBmLgq.mjs";
4
+ import { a as GatewayProtocolTiming, i as GatewayProtocolSocketHandlers, n as GatewayProtocolCloseContext, o as GatewayProtocolRequestTiming, r as GatewayProtocolSocket, t as GatewayProtocolClient } from "./protocol-client-DbX7wQED.mjs";
5
5
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
6
6
  import { ConnectParams, ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol";
7
7
  export * from "@openclaw/gateway-protocol/connect-error-details";
@@ -10,7 +10,7 @@ export * from "@openclaw/gateway-protocol/gateway-error-details";
10
10
  export * from "@openclaw/gateway-protocol/startup-unavailable";
11
11
  export * from "@openclaw/gateway-protocol/version";
12
12
  //#region packages/gateway-client/src/reconnect-policy.d.ts
13
- declare function shouldPauseGatewayReconnect(params: {
13
+ export declare function shouldPauseGatewayReconnect(params: {
14
14
  details?: unknown;
15
15
  deviceTokenRetryPending?: boolean;
16
16
  tokenMismatchIsTerminal?: boolean;
@@ -18,4 +18,4 @@ declare function shouldPauseGatewayReconnect(params: {
18
18
  clientVersionMismatchIsTerminal?: boolean;
19
19
  }): boolean;
20
20
  //#endregion
21
- export { type ConnectParams, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, type ErrorShape, type EventFrame, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayConnectAuthSelection, GatewayProtocolClient, type GatewayProtocolCloseContext, GatewayProtocolRequestError, type GatewayProtocolRequestOptions, GatewayProtocolRequestTimeoutError, type GatewayProtocolRequestTiming, type GatewayProtocolSocket, type GatewayProtocolSocketHandlers, type GatewayProtocolTiming, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, type HelloOk, type SessionMessageEnvelope, type SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
21
+ export { type ConnectParams, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, type ErrorShape, type EventFrame, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayConnectAuthSelection, GatewayProtocolClient, type GatewayProtocolCloseContext, GatewayProtocolRequestError, type GatewayProtocolRequestOptions, GatewayProtocolRequestTimeoutError, type GatewayProtocolRequestTiming, type GatewayProtocolSocket, type GatewayProtocolSocketHandlers, type GatewayProtocolTiming, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, type HelloOk, type SessionMessageEnvelope, type SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken };
package/dist/browser.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import { C as buildGatewayConnectAuth, D as buildDeviceAuthPayload, E as shouldRetryGatewayWithDeviceToken, O as buildDeviceAuthPayloadV3, S as GatewayBrowserDeviceAuthLifecycle, T as selectGatewayConnectAuth, _ as GatewayProtocolClient, a as createSessionProjection, b as gatewayCredentialScope, c as projectLiveSessionMessage, d as reduceSessionProjectionRunEvent, f as normalizeSessionProjectionRunId, g as shouldPauseGatewayReconnect, i as resetGatewaySessionMessageSubscriptionCoordinator, k as normalizeDeviceMetadataForAuth, l as reconcileSessionProjectionSnapshot, m as readSessionMessageSequence, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as readSessionMessageIdentity, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjection, v as GatewayProtocolRequestError, w as resolveGatewayConnectScopes, x as gatewayOriginScope, y as GatewayProtocolRequestTimeoutError } from "./session-subscriptions-Uxa34zU5.mjs";
1
+ import { A as buildDeviceAuthPayloadV3, C as gatewayOriginScope, D as selectGatewayConnectAuth, E as resolveGatewayConnectScopes, O as shouldRetryGatewayWithDeviceToken, S as gatewayCredentialScope, T as buildGatewayConnectAuth, _ as shouldPauseGatewayReconnect, a as createSessionProjection, b as GatewayProtocolRequestTimeoutError, c as projectLiveSessionMessage, d as reduceSessionProjectionRunEvent, f as normalizeSessionProjectionRunId, h as readSessionMessageSequence, i as resetGatewaySessionMessageSubscriptionCoordinator, j as normalizeDeviceMetadataForAuth, k as buildDeviceAuthPayload, l as reconcileSessionProjectionSnapshot, m as readSessionMessageIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as readAssistantStreamSegmentIdentity, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjection, v as GatewayProtocolClient, w as GatewayBrowserDeviceAuthLifecycle, y as GatewayProtocolRequestError } from "./session-subscriptions-DT0ZioFT.mjs";
2
2
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, resolveSafeTimeoutDelayMs } from "./timeouts.mjs";
3
3
  export * from "@openclaw/gateway-protocol/connect-error-details";
4
4
  export * from "@openclaw/gateway-protocol/client-info";
5
5
  export * from "@openclaw/gateway-protocol/gateway-error-details";
6
6
  export * from "@openclaw/gateway-protocol/startup-unavailable";
7
7
  export * from "@openclaw/gateway-protocol/version";
8
- export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayProtocolClient, GatewayProtocolRequestError, GatewayProtocolRequestTimeoutError, GatewaySessionMessageSubscriptionCoordinator, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
8
+ export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayProtocolClient, GatewayProtocolRequestError, GatewayProtocolRequestTimeoutError, GatewaySessionMessageSubscriptionCoordinator, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveGatewayConnectScopes, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldPauseGatewayReconnect, shouldRetryGatewayWithDeviceToken };
package/dist/index.d.mts CHANGED
@@ -1,16 +1,17 @@
1
- import { A as gatewayCredentialScope, C as reduceSessionProjection, D as normalizeSessionProjectionRunId, E as SessionMessageIdentity, M as buildDeviceAuthPayload, N as buildDeviceAuthPayloadV3, O as readSessionMessageIdentity, P as normalizeDeviceMetadataForAuth, S as reconcileSessionProjectionSnapshot, T as SessionMessageEnvelope, _ as SessionProjectionState, a as GatewaySessionMessageSubscriptionOptions, b as isLocallyOptimisticSessionMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionGatewayRunEvent, f as SessionProjectionRun, g as SessionProjectionSnapshotOptions, h as SessionProjectionScope, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as gatewayOriginScope, k as readSessionMessageSequence, l as SessionProjectionEntry, m as SessionProjectionRunTransition, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionRunStatus, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as createSessionProjection, w as reduceSessionProjectionRunEvent, x as projectLiveSessionMessage, y as hasSessionProjectionAcceptedFinal } from "./session-subscriptions-DNKXLO-Z.mjs";
1
+ import { A as readSessionMessageSequence, C as reduceSessionProjection, D as normalizeSessionProjectionRunId, E as SessionMessageIdentity, F as normalizeDeviceMetadataForAuth, M as gatewayOriginScope, N as buildDeviceAuthPayload, O as readAssistantStreamSegmentIdentity, P as buildDeviceAuthPayloadV3, S as reconcileSessionProjectionSnapshot, T as SessionMessageEnvelope, _ as SessionProjectionState, a as GatewaySessionMessageSubscriptionOptions, b as isLocallyOptimisticSessionMessage, c as resetGatewaySessionMessageSubscriptionCoordinator, d as SessionProjectionGatewayRunEvent, f as SessionProjectionRun, g as SessionProjectionSnapshotOptions, h as SessionProjectionScope, i as GatewaySessionMessageSubscriptionCoordinatorOptions, j as gatewayCredentialScope, k as readSessionMessageIdentity, l as SessionProjectionEntry, m as SessionProjectionRunTransition, n as GatewaySessionMessageSubscription, o as getGatewaySessionMessageSubscriptionCoordinator, p as SessionProjectionRunStatus, r as GatewaySessionMessageSubscriptionCoordinator, s as releaseGatewaySessionMessageSubscription, t as GatewaySessionMessageRequestClient, u as SessionProjectionEvent, v as createSessionProjection, w as reduceSessionProjectionRunEvent, x as projectLiveSessionMessage, y as hasSessionProjectionAcceptedFinal } from "./session-subscriptions-D2UdeJ0u.mjs";
2
2
  import { a as GatewayBrowserDeviceTokenStore, c as resolveGatewayConnectScopes, i as GatewayBrowserDeviceTokenRecord, l as selectGatewayConnectAuth, n as GatewayBrowserDeviceAuthPlan, o as GatewayConnectAuthSelection, r as GatewayBrowserDeviceIdentity, s as buildGatewayConnectAuth, t as GatewayBrowserDeviceAuthLifecycle, u as shouldRetryGatewayWithDeviceToken } from "./browser-device-auth-DoPo-sPB.mjs";
3
+ import { i as isGatewayProtocolResponseError } from "./protocol-request-B5gBmLgq.mjs";
3
4
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
4
- import { _ as GatewayClientRequestTimeoutError, a as startGatewayClientWithReadinessWait, b as GatewayClientRequestError, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestOptions, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayReconnectPausedInfo, y as isGatewayConnectAssemblyError } from "./readiness-CJ1QsCtR.mjs";
5
+ import { _ as GatewayClientRequestTimeoutError, a as startGatewayClientWithReadinessWait, b as GatewayClientRequestError, c as waitForEventLoopReady, d as GatewayClient, f as GatewayClientCloseInfo, g as GatewayClientRequestOptions, h as GatewayClientOptions, i as startGatewayClientWhenEventLoopReady, l as DeviceAuthTokenRecord, m as GatewayClientHostDeps, n as GatewayClientStartReadinessOptions, o as EventLoopReadyOptions, p as GatewayClientConnectionMetadata, r as GatewayClientStartable, s as EventLoopReadyResult, t as EventLoopReadyWaiter, u as DeviceIdentity, v as GatewayReconnectPausedInfo, y as isGatewayConnectAssemblyError } from "./readiness-5KjCokrl.mjs";
5
6
  import { GatewayScopeUpgrade, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome } from "./scope-upgrade.mjs";
6
7
  //#region packages/gateway-client/src/cloudflare-access.d.ts
7
- declare const CF_ACCESS_CLIENT_ID_HEADER = "CF-Access-Client-Id";
8
- declare const CF_ACCESS_CLIENT_SECRET_HEADER = "CF-Access-Client-Secret";
9
- type CloudflareAccessCredentials = Readonly<{
8
+ export declare const CF_ACCESS_CLIENT_ID_HEADER = "CF-Access-Client-Id";
9
+ export declare const CF_ACCESS_CLIENT_SECRET_HEADER = "CF-Access-Client-Secret";
10
+ export type CloudflareAccessCredentials = Readonly<{
10
11
  clientId: string;
11
12
  clientSecret: string;
12
13
  }>;
13
14
  /** Build only the two headers Cloudflare Access defines for service-token auth. */
14
- declare function buildCloudflareAccessHeaders(credentials: CloudflareAccessCredentials): Record<string, string>;
15
+ export declare function buildCloudflareAccessHeaders(credentials: CloudflareAccessCredentials): Record<string, string>;
15
16
  //#endregion
16
- export { CF_ACCESS_CLIENT_ID_HEADER, CF_ACCESS_CLIENT_SECRET_HEADER, CloudflareAccessCredentials, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, DeviceAuthTokenRecord, DeviceIdentity, EventLoopReadyOptions, EventLoopReadyResult, EventLoopReadyWaiter, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayClient, GatewayClientCloseInfo, GatewayClientConnectionMetadata, GatewayClientHostDeps, GatewayClientOptions, GatewayClientRequestError, GatewayClientRequestOptions, GatewayClientRequestTimeoutError, GatewayClientStartReadinessOptions, GatewayClientStartable, GatewayConnectAuthSelection, GatewayReconnectPausedInfo, GatewayScopeUpgrade, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome, type SessionMessageEnvelope, type SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, addSafeTimeoutDelayGraceMs, buildCloudflareAccessHeaders, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
17
+ export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, DeviceAuthTokenRecord, DeviceIdentity, EventLoopReadyOptions, EventLoopReadyResult, EventLoopReadyWaiter, GatewayBrowserDeviceAuthLifecycle, GatewayBrowserDeviceAuthPlan, GatewayBrowserDeviceIdentity, GatewayBrowserDeviceTokenRecord, GatewayBrowserDeviceTokenStore, GatewayClient, GatewayClientCloseInfo, GatewayClientConnectionMetadata, GatewayClientHostDeps, GatewayClientOptions, GatewayClientRequestError, GatewayClientRequestOptions, GatewayClientRequestTimeoutError, GatewayClientStartReadinessOptions, GatewayClientStartable, GatewayConnectAuthSelection, GatewayReconnectPausedInfo, GatewayScopeUpgrade, GatewaySessionMessageRequestClient, GatewaySessionMessageSubscription, GatewaySessionMessageSubscriptionCoordinator, GatewaySessionMessageSubscriptionCoordinatorOptions, GatewaySessionMessageSubscriptionOptions, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome, type SessionMessageEnvelope, type SessionMessageIdentity, SessionProjectionEntry, SessionProjectionEvent, SessionProjectionGatewayRunEvent, SessionProjectionRun, SessionProjectionRunStatus, SessionProjectionRunTransition, SessionProjectionScope, SessionProjectionSnapshotOptions, SessionProjectionState, addSafeTimeoutDelayGraceMs, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isGatewayProtocolResponseError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as buildGatewayConnectAuth, D as buildDeviceAuthPayload, E as shouldRetryGatewayWithDeviceToken, O as buildDeviceAuthPayloadV3, S as GatewayBrowserDeviceAuthLifecycle, T as selectGatewayConnectAuth, _ as GatewayProtocolClient, a as createSessionProjection, b as gatewayCredentialScope, c as projectLiveSessionMessage, d as reduceSessionProjectionRunEvent, f as normalizeSessionProjectionRunId, g as shouldPauseGatewayReconnect, h as isRecord, i as resetGatewaySessionMessageSubscriptionCoordinator, k as normalizeDeviceMetadataForAuth, l as reconcileSessionProjectionSnapshot, m as readSessionMessageSequence, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as readSessionMessageIdentity, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjection, v as GatewayProtocolRequestError, w as resolveGatewayConnectScopes, x as gatewayOriginScope, y as GatewayProtocolRequestTimeoutError } from "./session-subscriptions-Uxa34zU5.mjs";
1
+ import { A as buildDeviceAuthPayloadV3, C as gatewayOriginScope, D as selectGatewayConnectAuth, E as resolveGatewayConnectScopes, O as shouldRetryGatewayWithDeviceToken, S as gatewayCredentialScope, T as buildGatewayConnectAuth, _ as shouldPauseGatewayReconnect, a as createSessionProjection, b as GatewayProtocolRequestTimeoutError, c as projectLiveSessionMessage, d as reduceSessionProjectionRunEvent, f as normalizeSessionProjectionRunId, g as isRecord, h as readSessionMessageSequence, i as resetGatewaySessionMessageSubscriptionCoordinator, j as normalizeDeviceMetadataForAuth, k as buildDeviceAuthPayload, l as reconcileSessionProjectionSnapshot, m as readSessionMessageIdentity, n as getGatewaySessionMessageSubscriptionCoordinator, o as hasSessionProjectionAcceptedFinal, p as readAssistantStreamSegmentIdentity, r as releaseGatewaySessionMessageSubscription, s as isLocallyOptimisticSessionMessage, t as GatewaySessionMessageSubscriptionCoordinator, u as reduceSessionProjection, v as GatewayProtocolClient, w as GatewayBrowserDeviceAuthLifecycle, x as isGatewayProtocolResponseError, y as GatewayProtocolRequestError } from "./session-subscriptions-DT0ZioFT.mjs";
2
2
  import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
3
3
  import { rawDataToString } from "./websocket-data.mjs";
4
4
  import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-CrWxd4TI.mjs";
@@ -10,6 +10,7 @@ import { MIN_CLIENT_PROTOCOL_VERSION, MIN_NODE_PROTOCOL_VERSION, MIN_PROBE_PROTO
10
10
  import { randomUUID } from "node:crypto";
11
11
  import { WebSocket } from "ws";
12
12
  import ipaddr from "ipaddr.js";
13
+ import { TLSSocket } from "node:tls";
13
14
  //#region packages/normalization-core/src/string-coerce.ts
14
15
  /** Trims string input and returns null for non-strings or empty strings. */
15
16
  function normalizeNullableString(value) {
@@ -484,6 +485,7 @@ function isSecureWebSocketUrl(rawUrl, options) {
484
485
  }
485
486
  }
486
487
  var GatewayWebSocketTransportConfigurationError = class extends Error {};
488
+ var GatewayWebSocketTlsPinError = class extends Error {};
487
489
  function resolveGatewayWebSocketTransport(params) {
488
490
  const usesTls = isWssUrl(params.url);
489
491
  if (params.tlsFingerprint && !usesTls) throw new GatewayWebSocketTransportConfigurationError("gateway tls fingerprint requires wss:// gateway url");
@@ -499,30 +501,37 @@ function resolveGatewayWebSocketTransport(params) {
499
501
  const expectedFingerprint = params.tlsFingerprint ? normalizeTlsFingerprint(params.tlsFingerprint) : void 0;
500
502
  if (params.tlsFingerprint && !expectedFingerprint) throw new GatewayWebSocketTransportConfigurationError("gateway tls fingerprint must be a SHA-256 fingerprint");
501
503
  const options = { ...params.options };
502
- if (usesTls && expectedFingerprint) {
503
- options.rejectUnauthorized = false;
504
- options.checkServerIdentity = (_hostValue, cert) => {
505
- const fingerprintValue = typeof cert === "object" && cert && "fingerprint256" in cert ? cert.fingerprint256 ?? "" : "";
506
- const canonicalFingerprint = normalizeTlsFingerprint(typeof fingerprintValue === "string" ? fingerprintValue : "");
507
- const fingerprint = canonicalFingerprint ? normalize(canonicalFingerprint) : "";
508
- const expected = normalize(expectedFingerprint);
509
- if (!fingerprint) return /* @__PURE__ */ new Error("Missing server TLS fingerprint");
510
- if (fingerprint !== expected) return /* @__PURE__ */ new Error("Server TLS fingerprint mismatch");
511
- };
512
- }
513
- return {
514
- options,
515
- validateSocket: (socket) => {
516
- if (!params.tlsFingerprint) return null;
517
- const expected = expectedFingerprint ? normalize(expectedFingerprint) : "";
518
- if (!expected) return /* @__PURE__ */ new Error("gateway tls fingerprint missing");
519
- const rawSocket = socket["_socket"];
520
- if (!rawSocket || typeof rawSocket.getPeerCertificate !== "function") return /* @__PURE__ */ new Error("gateway tls fingerprint unavailable");
521
- const canonicalFingerprint = normalizeTlsFingerprint(rawSocket.getPeerCertificate()?.fingerprint256 ?? "");
522
- const fingerprint = canonicalFingerprint ? normalize(canonicalFingerprint) : "";
523
- if (!fingerprint) return /* @__PURE__ */ new Error("gateway tls fingerprint unavailable");
524
- return fingerprint === expected ? null : /* @__PURE__ */ new Error("gateway tls fingerprint mismatch");
525
- }
504
+ if (usesTls && expectedFingerprint) applyGatewayWebSocketTlsPin(options, expectedFingerprint, normalize);
505
+ return { options };
506
+ }
507
+ function applyGatewayWebSocketTlsPin(options, expectedFingerprint, normalize = normalizeTlsFingerprint) {
508
+ options.rejectUnauthorized = false;
509
+ const headers = { ...options.headers };
510
+ const deferredHeaders = Object.entries(headers).filter(([key]) => key.toLowerCase() === "expect");
511
+ for (const [key] of deferredHeaders) delete headers[key];
512
+ options.headers = headers;
513
+ options.finishRequest = (request) => {
514
+ request.once("socket", (socket) => {
515
+ if (!(socket instanceof TLSSocket)) {
516
+ request.destroy(new GatewayWebSocketTlsPinError("gateway tls fingerprint unavailable"));
517
+ return;
518
+ }
519
+ const validatePin = () => {
520
+ if (request.destroyed) return;
521
+ const canonicalFingerprint = normalizeTlsFingerprint(socket.getPeerCertificate()?.fingerprint256);
522
+ const fingerprint = canonicalFingerprint ? normalize(canonicalFingerprint) : "";
523
+ if (!fingerprint || fingerprint !== normalize(expectedFingerprint)) {
524
+ request.destroy(new GatewayWebSocketTlsPinError(fingerprint ? "gateway tls fingerprint mismatch" : "gateway tls fingerprint unavailable"));
525
+ return;
526
+ }
527
+ for (const [key, value] of deferredHeaders) if (value !== void 0) request.setHeader(key, value);
528
+ request.end();
529
+ };
530
+ if (socket.secureConnecting) {
531
+ socket.once("secureConnect", validatePin);
532
+ request.once("close", () => socket.off("secureConnect", validatePin));
533
+ } else validatePin();
534
+ });
526
535
  };
527
536
  }
528
537
  //#endregion
@@ -550,7 +559,7 @@ function resolveHostDeps(overrides) {
550
559
  }
551
560
  const DEFAULT_GATEWAY_CLIENT_URL = "ws://127.0.0.1:18789";
552
561
  const DEFAULT_CLIENT_VERSION = "0.0.0";
553
- const MAX_UPGRADE_ERROR_BODY_BYTES = 2 * 1024;
562
+ const MAX_UPGRADE_ERROR_BODY_BYTES = 2048;
554
563
  const UPGRADE_ERROR_BODY_TIMEOUT_MS = 1e3;
555
564
  async function readUpgradeErrorBody(response) {
556
565
  return await new Promise((resolve) => {
@@ -767,7 +776,7 @@ var GatewayClient = class {
767
776
  env: this.opts.env,
768
777
  normalizeTlsFingerprint: this.deps.normalizeTlsFingerprint,
769
778
  options: {
770
- maxPayload: 25 * 1024 * 1024,
779
+ maxPayload: 26214400,
771
780
  handshakeTimeout: handshakeTimeoutMs,
772
781
  ...this.opts.origin ? { origin: this.opts.origin } : {},
773
782
  ...edgeAuthHeaders ? {
@@ -796,14 +805,8 @@ var GatewayClient = class {
796
805
  this.transportValidated = false;
797
806
  let upgradeError;
798
807
  ws.on("open", () => {
799
- handlers.open();
800
- const tlsError = transport.validateSocket(ws);
801
- if (tlsError) {
802
- handlers.error(tlsError);
803
- ws.close(1008, tlsError.message);
804
- return;
805
- }
806
808
  this.transportValidated = true;
809
+ handlers.open();
807
810
  });
808
811
  ws.on("message", (data) => handlers.message(rawDataToString(data)));
809
812
  ws.on("close", (code, reason) => {
@@ -1340,4 +1343,4 @@ function buildCloudflareAccessHeaders(credentials) {
1340
1343
  };
1341
1344
  }
1342
1345
  //#endregion
1343
- export { CF_ACCESS_CLIENT_ID_HEADER, CF_ACCESS_CLIENT_SECRET_HEADER, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewayClientRequestTimeoutError, GatewayScopeUpgrade, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildCloudflareAccessHeaders, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
1346
+ export { CF_ACCESS_CLIENT_ID_HEADER, CF_ACCESS_CLIENT_SECRET_HEADER, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewayClientRequestTimeoutError, GatewayScopeUpgrade, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildCloudflareAccessHeaders, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isGatewayProtocolResponseError, isLocallyOptimisticSessionMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
@@ -1,4 +1,4 @@
1
- import { n as GatewayProtocolRequestOptions, t as GatewayProtocolRequestError } from "./protocol-request-r0jkQ1XE.mjs";
1
+ import { n as GatewayProtocolRequestOptions, t as GatewayProtocolRequestError } from "./protocol-request-B5gBmLgq.mjs";
2
2
  import { ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol";
3
3
  //#region packages/gateway-client/src/pending-request.d.ts
4
4
  type GatewayProtocolRequestTiming = {
@@ -1,5 +1,7 @@
1
1
  import { ErrorShape } from "@openclaw/gateway-protocol";
2
2
  //#region packages/gateway-client/src/protocol-request.d.ts
3
+ /** Distinguishes correlated Gateway responses from locally constructed transport errors. */
4
+ declare function isGatewayProtocolResponseError(error: unknown): error is GatewayProtocolRequestError;
3
5
  type GatewayProtocolRequestOptions = {
4
6
  timeoutMs?: number | null;
5
7
  expectFinal?: boolean;
@@ -13,6 +15,7 @@ declare class GatewayProtocolRequestError extends Error {
13
15
  readonly details?: unknown;
14
16
  readonly retryable: boolean;
15
17
  readonly retryAfterMs?: number;
18
+ readonly responsePayload?: unknown;
16
19
  constructor(error: Partial<ErrorShape>);
17
20
  }
18
21
  /** A local transport deadline, distinct from a Gateway's authoritative rejection. */
@@ -28,4 +31,4 @@ declare class GatewayProtocolRequestTimeoutError extends Error {
28
31
  }, message?: string);
29
32
  }
30
33
  //#endregion
31
- export { GatewayProtocolRequestOptions as n, GatewayProtocolRequestTimeoutError as r, GatewayProtocolRequestError as t };
34
+ export { isGatewayProtocolResponseError as i, GatewayProtocolRequestOptions as n, GatewayProtocolRequestTimeoutError as r, GatewayProtocolRequestError as t };
@@ -1,5 +1,5 @@
1
- import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-r0jkQ1XE.mjs";
2
- import "./protocol-client-C-viHJgO.mjs";
1
+ import { n as GatewayProtocolRequestOptions, r as GatewayProtocolRequestTimeoutError, t as GatewayProtocolRequestError } from "./protocol-request-B5gBmLgq.mjs";
2
+ import "./protocol-client-DbX7wQED.mjs";
3
3
  import { ConnectParams, ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol/frame-guards";
4
4
  import { GatewayClientMode, GatewayClientName } from "@openclaw/gateway-protocol/client-info";
5
5
  //#region packages/gateway-client/src/request-error.d.ts
@@ -1,2 +1,2 @@
1
- import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-CJ1QsCtR.mjs";
1
+ import { a as startGatewayClientWithReadinessWait, i as startGatewayClientWhenEventLoopReady, n as GatewayClientStartReadinessOptions, r as GatewayClientStartable, t as EventLoopReadyWaiter } from "./readiness-5KjCokrl.mjs";
2
2
  export { EventLoopReadyWaiter, GatewayClientStartReadinessOptions, GatewayClientStartable, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait };
@@ -1,12 +1,12 @@
1
1
  import { a as GatewayBrowserDeviceTokenStore } from "./browser-device-auth-DoPo-sPB.mjs";
2
- import { n as GatewayProtocolRequestOptions } from "./protocol-request-r0jkQ1XE.mjs";
2
+ import { n as GatewayProtocolRequestOptions } from "./protocol-request-B5gBmLgq.mjs";
3
3
  //#region packages/gateway-client/src/scope-upgrade.d.ts
4
- type ScopeUpgradeBinding = {
4
+ export type ScopeUpgradeBinding = {
5
5
  clientId: string;
6
6
  deviceId: string;
7
7
  role: string;
8
8
  };
9
- type ScopeUpgradeOutcome = {
9
+ export type ScopeUpgradeOutcome = {
10
10
  status: "approved";
11
11
  requestId: string;
12
12
  scopes: string[];
@@ -14,14 +14,14 @@ type ScopeUpgradeOutcome = {
14
14
  status: "rejected" | "expired";
15
15
  requestId: string;
16
16
  };
17
- type ScopeUpgradeOptions = {
17
+ export type ScopeUpgradeOptions = {
18
18
  binding: ScopeUpgradeBinding;
19
19
  scopes: readonly string[];
20
20
  onPending?: (requestId: string) => void;
21
21
  };
22
22
  type UpgradeRequester = (method: string, params?: unknown, options?: GatewayProtocolRequestOptions) => Promise<unknown>;
23
23
  /** Runs one browser device scope upgrade and owns rotated-token persistence. */
24
- declare class GatewayScopeUpgrade {
24
+ export declare class GatewayScopeUpgrade {
25
25
  private readonly deps;
26
26
  private active?;
27
27
  constructor(deps: {
@@ -33,5 +33,4 @@ declare class GatewayScopeUpgrade {
33
33
  cancelScopeUpgrade(): void;
34
34
  private runUpgrade;
35
35
  }
36
- //#endregion
37
- export { GatewayScopeUpgrade, ScopeUpgradeBinding, ScopeUpgradeOptions, ScopeUpgradeOutcome };
36
+ //#endregion
@@ -1,4 +1,4 @@
1
- import { n as GatewayProtocolRequestOptions } from "./protocol-request-r0jkQ1XE.mjs";
1
+ import { n as GatewayProtocolRequestOptions } from "./protocol-request-B5gBmLgq.mjs";
2
2
  //#region packages/gateway-client/src/device-auth.d.ts
3
3
  declare function normalizeDeviceMetadataForAuth(value?: string | null): string;
4
4
  type DeviceAuthPayloadParams = {
@@ -26,6 +26,8 @@ declare function gatewayCredentialScope(gatewayUrl: string): string;
26
26
  //#endregion
27
27
  //#region packages/gateway-client/src/session-projection-message-identity.d.ts
28
28
  type SessionMessageEnvelope = {
29
+ /** An unsequenced continuation follows this row; null denotes an unsequenced boundary. */
30
+ afterSequence?: number | null;
29
31
  messageId?: unknown;
30
32
  messageSeq?: unknown;
31
33
  clientRunId?: unknown;
@@ -37,6 +39,8 @@ type SessionMessageIdentity = {
37
39
  id: string | null;
38
40
  sequence: number | null;
39
41
  idempotencyKey: string | null;
42
+ /** User submission identity stays stable when a queued turn acquires a new execution run. */
43
+ sendId: string | null;
40
44
  runId: string | null;
41
45
  isImported: boolean;
42
46
  externalSource: string | null;
@@ -47,6 +51,11 @@ declare function readSessionMessageSequence(message: unknown, envelope?: Session
47
51
  declare function normalizeSessionProjectionRunId(value: unknown): string | null;
48
52
  /** Persisted row facts win; assistant run ownership comes from its authoritative producer. */
49
53
  declare function readSessionMessageIdentity(message: unknown, envelope?: SessionMessageEnvelope): SessionMessageIdentity | null;
54
+ /** A commentary item's display identity is separate from the transcript row that later owns it. */
55
+ declare function readAssistantStreamSegmentIdentity(message: unknown): {
56
+ itemId: string;
57
+ runId?: string;
58
+ } | undefined;
50
59
  //#endregion
51
60
  //#region packages/gateway-client/src/session-projection.d.ts
52
61
  type SessionProjectionScope = {
@@ -81,6 +90,7 @@ type SessionProjectionRunTransition = {
81
90
  type SessionProjectionEntry = {
82
91
  message: unknown;
83
92
  identity: SessionMessageIdentity | null;
93
+ afterSequence?: number | null;
84
94
  live: boolean;
85
95
  pending: boolean;
86
96
  pendingRunId: string | null;
@@ -177,4 +187,4 @@ declare function getGatewaySessionMessageSubscriptionCoordinator(client: Gateway
177
187
  declare function resetGatewaySessionMessageSubscriptionCoordinator(client: GatewaySessionMessageRequestClient): void;
178
188
  declare function releaseGatewaySessionMessageSubscription(subscription: GatewaySessionMessageSubscription): Promise<void>;
179
189
  //#endregion
180
- export { gatewayCredentialScope as A, reduceSessionProjection as C, normalizeSessionProjectionRunId as D, SessionMessageIdentity as E, buildDeviceAuthPayload as M, buildDeviceAuthPayloadV3 as N, readSessionMessageIdentity as O, normalizeDeviceMetadataForAuth as P, reconcileSessionProjectionSnapshot as S, SessionMessageEnvelope as T, SessionProjectionState as _, GatewaySessionMessageSubscriptionOptions as a, isLocallyOptimisticSessionMessage as b, resetGatewaySessionMessageSubscriptionCoordinator as c, SessionProjectionGatewayRunEvent as d, SessionProjectionRun as f, SessionProjectionSnapshotOptions as g, SessionProjectionScope as h, GatewaySessionMessageSubscriptionCoordinatorOptions as i, gatewayOriginScope as j, readSessionMessageSequence as k, SessionProjectionEntry as l, SessionProjectionRunTransition as m, GatewaySessionMessageSubscription as n, getGatewaySessionMessageSubscriptionCoordinator as o, SessionProjectionRunStatus as p, GatewaySessionMessageSubscriptionCoordinator as r, releaseGatewaySessionMessageSubscription as s, GatewaySessionMessageRequestClient as t, SessionProjectionEvent as u, createSessionProjection as v, reduceSessionProjectionRunEvent as w, projectLiveSessionMessage as x, hasSessionProjectionAcceptedFinal as y };
190
+ export { readSessionMessageSequence as A, reduceSessionProjection as C, normalizeSessionProjectionRunId as D, SessionMessageIdentity as E, normalizeDeviceMetadataForAuth as F, gatewayOriginScope as M, buildDeviceAuthPayload as N, readAssistantStreamSegmentIdentity as O, buildDeviceAuthPayloadV3 as P, reconcileSessionProjectionSnapshot as S, SessionMessageEnvelope as T, SessionProjectionState as _, GatewaySessionMessageSubscriptionOptions as a, isLocallyOptimisticSessionMessage as b, resetGatewaySessionMessageSubscriptionCoordinator as c, SessionProjectionGatewayRunEvent as d, SessionProjectionRun as f, SessionProjectionSnapshotOptions as g, SessionProjectionScope as h, GatewaySessionMessageSubscriptionCoordinatorOptions as i, gatewayCredentialScope as j, readSessionMessageIdentity as k, SessionProjectionEntry as l, SessionProjectionRunTransition as m, GatewaySessionMessageSubscription as n, getGatewaySessionMessageSubscriptionCoordinator as o, SessionProjectionRunStatus as p, GatewaySessionMessageSubscriptionCoordinator as r, releaseGatewaySessionMessageSubscription as s, GatewaySessionMessageRequestClient as t, SessionProjectionEvent as u, createSessionProjection as v, reduceSessionProjectionRunEvent as w, projectLiveSessionMessage as x, hasSessionProjectionAcceptedFinal as y };
@@ -433,6 +433,11 @@ var GatewayEventListeners = class {
433
433
  };
434
434
  //#endregion
435
435
  //#region packages/gateway-client/src/protocol-request.ts
436
+ const gatewayResponseErrors = /* @__PURE__ */ new WeakSet();
437
+ /** Distinguishes correlated Gateway responses from locally constructed transport errors. */
438
+ function isGatewayProtocolResponseError(error) {
439
+ return error instanceof Error && gatewayResponseErrors.has(error);
440
+ }
436
441
  var GatewayProtocolRequestError = class extends Error {
437
442
  constructor(error) {
438
443
  super(error.message ?? "request failed");
@@ -444,6 +449,15 @@ var GatewayProtocolRequestError = class extends Error {
444
449
  this.retryAfterMs = error.retryAfterMs;
445
450
  }
446
451
  };
452
+ /** Preserve response metadata after custom factories without adding it to error JSON. */
453
+ function retainGatewayResponsePayload(error, payload) {
454
+ gatewayResponseErrors.add(error);
455
+ Object.defineProperty(error, "responsePayload", {
456
+ value: payload,
457
+ enumerable: false,
458
+ configurable: true
459
+ });
460
+ }
447
461
  /** A local transport deadline, distinct from a Gateway's authoritative rejection. */
448
462
  var GatewayProtocolRequestTimeoutError = class extends Error {
449
463
  constructor(params, message = `gateway request timed out after ${params.timeoutMs}ms: ${params.method}`) {
@@ -544,7 +558,7 @@ var GatewayPendingRequests = class {
544
558
  const pending = this.pending.get(frame.id);
545
559
  if (!pending) return;
546
560
  const status = frame.payload?.status;
547
- if (pending.expectFinal && status === "accepted") {
561
+ if (frame.ok && pending.expectFinal && status === "accepted") {
548
562
  if (!pending.acceptedNotified) {
549
563
  pending.acceptedNotified = true;
550
564
  this.invoke("accepted", () => pending.onAccepted?.(frame.payload));
@@ -559,7 +573,9 @@ var GatewayPendingRequests = class {
559
573
  return;
560
574
  }
561
575
  this.finishTiming(frame.id, pending, false, frame.error?.code);
562
- pending.reject(this.opts.createRequestError?.(frame.error ?? {}) ?? new GatewayProtocolRequestError(frame.error ?? {}));
576
+ const error = this.opts.createRequestError?.(frame.error ?? {}) ?? new GatewayProtocolRequestError(frame.error ?? {});
577
+ retainGatewayResponsePayload(error, frame.payload);
578
+ pending.reject(error);
563
579
  }
564
580
  flush(error) {
565
581
  const retired = [...this.pending];
@@ -825,7 +841,7 @@ var GatewayProtocolClient = class {
825
841
  this.recordTiming("request-sent", generation, plan);
826
842
  this.connectRequestSent = true;
827
843
  this.request("connect", this.opts.buildConnectParams(plan)).then((hello) => {
828
- if (!this.isActive(socket, generation)) return;
844
+ if (!this.isActive(socket, generation) || !socket.isOpen()) return;
829
845
  this.helloReceived = true;
830
846
  this.clearHandshakeTimer();
831
847
  this.connectFailure = void 0;
@@ -986,6 +1002,7 @@ const NON_RECOVERABLE_AUTH_ERRORS = /* @__PURE__ */ new Set([
986
1002
  ConnectErrorDetailCodes.AUTH_DEVICE_TOKEN_MISMATCH,
987
1003
  ConnectErrorDetailCodes.AUTH_SCOPE_MISMATCH,
988
1004
  ConnectErrorDetailCodes.AUTH_IDENTITY_HEADER_REQUIRED,
1005
+ ConnectErrorDetailCodes.AUTH_VERIFIED_USER_REQUIRED,
989
1006
  ConnectErrorDetailCodes.CONTROL_UI_BUILD_MISMATCH,
990
1007
  ConnectErrorDetailCodes.PAIRING_REQUIRED,
991
1008
  ConnectErrorDetailCodes.CONTROL_UI_DEVICE_IDENTITY_REQUIRED,
@@ -1044,12 +1061,14 @@ function readSessionMessageIdentity(message, envelope) {
1044
1061
  const isCliAssistant = role === "assistant" && readSessionProjectionString(record.api)?.toLowerCase() === "cli";
1045
1062
  const canonicalPersistedRunId = isCliAssistant && persistedRunId?.startsWith("cli-assistant:") ? readSessionProjectionString(persistedRunId.slice(14)) : persistedRunId;
1046
1063
  const optimisticRunId = metadata && Object.keys(metadata).every((key) => key === "idempotencyKey") ? canonicalPersistedRunId : null;
1064
+ const runId = role === "assistant" ? metadataRunId ?? envelopeRunId ?? (isCliAssistant || !mirroredMessage ? canonicalPersistedRunId : null) ?? optimisticRunId : metadataRunId ?? canonicalPersistedRunId ?? envelopeRunId;
1047
1065
  return {
1048
1066
  role,
1049
1067
  id: readSessionProjectionString(metadata?.id) ?? readSessionProjectionString(envelope?.messageId),
1050
1068
  sequence: readSessionMessageSequence(message, envelope),
1051
1069
  idempotencyKey,
1052
- runId: role === "assistant" ? metadataRunId ?? envelopeRunId ?? (isCliAssistant || !mirroredMessage ? canonicalPersistedRunId : null) ?? optimisticRunId : metadataRunId ?? canonicalPersistedRunId ?? envelopeRunId,
1070
+ sendId: role === "user" ? persistedRunId ?? runId : null,
1071
+ runId,
1053
1072
  isImported: Boolean(importedFrom || cliSessionId || externalId),
1054
1073
  externalSource: importedFrom && cliSessionId && externalId ? JSON.stringify([
1055
1074
  importedFrom,
@@ -1058,6 +1077,18 @@ function readSessionMessageIdentity(message, envelope) {
1058
1077
  ]) : null
1059
1078
  };
1060
1079
  }
1080
+ /** A commentary item's display identity is separate from the transcript row that later owns it. */
1081
+ function readAssistantStreamSegmentIdentity(message) {
1082
+ const record = asNullableRecord(message);
1083
+ if (readSessionProjectionString(record?.role)?.toLowerCase() !== "assistant") return;
1084
+ const fallback = asNullableRecord(record?.openclawStreamFallback);
1085
+ const itemId = readSessionProjectionString(fallback?.itemId);
1086
+ const runId = readSessionMessageIdentity(message)?.runId ?? readSessionProjectionString(record?.runId) ?? readSessionProjectionString(fallback?.runId);
1087
+ return itemId ? {
1088
+ itemId,
1089
+ ...runId ? { runId } : {}
1090
+ } : void 0;
1091
+ }
1061
1092
  //#endregion
1062
1093
  //#region packages/gateway-client/src/session-projection-run-event.ts
1063
1094
  function readNonemptyString(value) {
@@ -1123,6 +1154,7 @@ function createEntry(message, options) {
1123
1154
  return {
1124
1155
  message,
1125
1156
  identity,
1157
+ afterSequence: options?.envelope?.afterSequence,
1126
1158
  live: options?.live === true,
1127
1159
  pending: pendingRunId !== null,
1128
1160
  pendingRunId
@@ -1174,15 +1206,19 @@ function entryMatches(left, right, allowSnapshotPromotion = false) {
1174
1206
  const durableEntry = left.identity?.id ? left : right.identity?.id ? right : null;
1175
1207
  const provisionalEntry = durableEntry === left ? right : durableEntry === right ? left : null;
1176
1208
  const durableMetadata = asNullableRecord(asNullableRecord(durableEntry?.message)?.["__openclaw"]);
1177
- if (durableEntry?.live && provisionalEntry?.live && durableEntry.identity?.role === "assistant" && provisionalEntry.identity?.role === "assistant" && !durableEntry.identity.isImported && !provisionalEntry.identity.isImported && !provisionalEntry.identity.id && durableEntry.identity.runId && durableEntry.identity.runId === provisionalEntry.identity.runId && (readSessionProjectionString(durableMetadata?.mirrorOrigin) === null || durableMetadata?.runTerminal === true)) return true;
1209
+ if (durableEntry?.identity?.role === "assistant" && provisionalEntry?.identity?.role === "assistant" && !durableEntry.identity.isImported && !provisionalEntry.identity.isImported && !provisionalEntry.identity.id) {
1210
+ const durableSegment = readAssistantStreamSegmentIdentity(durableEntry.message);
1211
+ const provisionalSegment = readAssistantStreamSegmentIdentity(provisionalEntry.message);
1212
+ if (provisionalEntry.identity.sequence === null && durableSegment?.runId && durableSegment.runId === provisionalSegment?.runId && durableSegment.itemId === provisionalSegment.itemId) return true;
1213
+ if (provisionalEntry.live && provisionalEntry.identity.sequence === null && (provisionalEntry.afterSequence === void 0 || provisionalEntry.afterSequence !== null && durableEntry.identity.sequence !== null && durableEntry.identity.sequence > provisionalEntry.afterSequence) && durableEntry.identity.runId && durableEntry.identity.runId === provisionalEntry.identity.runId && (readSessionProjectionString(durableMetadata?.mirrorOrigin) === null || durableMetadata?.runTerminal === true)) return true;
1214
+ }
1178
1215
  const persisted = left.identity;
1179
1216
  const observed = right.identity;
1180
- const persistedMetadata = asNullableRecord(asNullableRecord(left.message)?.["__openclaw"]);
1181
- if (allowSnapshotPromotion && right.live && persisted && observed && persisted.role === observed.role && !persisted.isImported && !observed.isImported && persisted.id && !observed.id && (persisted.sequence !== null && persisted.sequence === observed.sequence || persisted.role === "assistant" && observed.sequence === null && persisted.runId !== null && persisted.runId === observed.runId && (readSessionProjectionString(persistedMetadata?.mirrorOrigin) === null || persistedMetadata?.runTerminal === true))) return true;
1217
+ if (allowSnapshotPromotion && right.live && persisted && observed && persisted.role === observed.role && !persisted.isImported && !observed.isImported && persisted.id && !observed.id && persisted.sequence !== null && persisted.sequence === observed.sequence) return true;
1182
1218
  if (left.pending && right.pending) return Boolean(left.identity?.role === right.identity?.role && left.pendingRunId && left.pendingRunId === right.pendingRunId);
1183
1219
  const pending = left.pending ? left : right.pending ? right : null;
1184
1220
  const authoritative = pending === left ? right : pending === right ? left : null;
1185
- return Boolean(pending && authoritative && pending.identity && authoritative.identity && pending.identity.role === authoritative.identity.role && !pending.identity.isImported && !authoritative.identity.isImported && pending.pendingRunId && pending.pendingRunId === authoritative.identity.runId && (pending.identity.sequence === null || authoritative.identity.sequence === null || pending.identity.sequence === authoritative.identity.sequence));
1221
+ return Boolean(pending && authoritative && pending.identity && authoritative.identity && pending.identity.role === authoritative.identity.role && !pending.identity.isImported && !authoritative.identity.isImported && pending.pendingRunId && pending.pendingRunId === (authoritative.identity.sendId ?? authoritative.identity.runId) && (pending.identity.sequence === null || authoritative.identity.sequence === null || pending.identity.sequence === authoritative.identity.sequence));
1186
1222
  }
1187
1223
  function withEntries(state, entries) {
1188
1224
  return {
@@ -1197,10 +1233,24 @@ function insertEntry(entries, incoming, runs) {
1197
1233
  const candidate = entry.identity?.sequence;
1198
1234
  return candidate !== void 0 && candidate !== null && candidate > sequence;
1199
1235
  });
1200
- if (nextIndex < 0 && incoming.identity?.role === "user" && incoming.identity.runId) {
1236
+ if (sequence !== void 0 && sequence !== null && nextIndex < 0) nextIndex = entries.length;
1237
+ if (incoming.identity?.role === "user" && incoming.identity.runId) {
1201
1238
  const runId = incoming.identity.runId;
1202
1239
  const terminalMessage = runs?.[runId]?.message;
1203
- nextIndex = entries.findIndex((entry) => entry.identity?.role === "assistant" && (entry.identity.runId === runId || entry.message === terminalMessage));
1240
+ const belongsToRun = (entry) => entry.identity?.role === "assistant" && (entry.identity.runId === runId || entry.message === terminalMessage);
1241
+ if (sequence !== void 0 && sequence !== null) {
1242
+ const before = [];
1243
+ const replies = [];
1244
+ for (const entry of entries.slice(0, nextIndex)) (entry.identity?.sequence === null && belongsToRun(entry) ? replies : before).push(entry);
1245
+ return [
1246
+ ...before,
1247
+ incoming,
1248
+ ...replies,
1249
+ ...entries.slice(nextIndex)
1250
+ ];
1251
+ }
1252
+ const terminalIndex = entries.findIndex(belongsToRun);
1253
+ if (terminalIndex >= 0 && (nextIndex < 0 || terminalIndex < nextIndex)) nextIndex = terminalIndex;
1204
1254
  }
1205
1255
  return nextIndex < 0 ? [...entries, incoming] : [
1206
1256
  ...entries.slice(0, nextIndex),
@@ -1215,12 +1265,13 @@ function projectLiveSessionMessage(state, message, envelope, scope = {}) {
1215
1265
  live: true
1216
1266
  });
1217
1267
  if (!incoming.identity) return state;
1218
- const existingIndex = state.entries.findIndex((entry) => entryMatches(entry, incoming));
1219
- if (existingIndex < 0) return withEntries(state, insertEntry(state.entries, incoming, state.runs));
1220
- const existing = state.entries[existingIndex];
1221
- if (existing && existing.message === message && existing.live && !existing.pending) return state;
1222
- if (existing && !existing.pending && existing.identity?.id && !incoming.identity.id) return state;
1223
- if (existing?.pending && incoming.identity.sequence !== null) {
1268
+ const matches = state.entries.filter((entry) => entryMatches(entry, incoming));
1269
+ const existing = matches.find((entry) => sameTranscriptIdentity(entry.identity, incoming.identity)) ?? (matches.length === 1 ? matches[0] : void 0);
1270
+ if (!existing) return withEntries(state, insertEntry(state.entries, incoming, state.runs));
1271
+ const existingIndex = state.entries.indexOf(existing);
1272
+ if (existing.message === message && existing.live && !existing.pending) return state;
1273
+ if (!existing.pending && existing.identity?.id && !incoming.identity.id) return state;
1274
+ if (incoming.identity.sequence !== null && (existing.pending || existing.identity?.sequence === null)) {
1224
1275
  const sequence = incoming.identity.sequence;
1225
1276
  return withEntries(state, state.entries.some(({ identity }, index) => identity?.sequence != null && (index < existingIndex ? identity.sequence > sequence : identity.sequence < sequence)) ? insertEntry(state.entries.filter((_, index) => index !== existingIndex), incoming, state.runs) : state.entries.toSpliced(existingIndex, 1, incoming));
1226
1277
  }
@@ -1639,4 +1690,4 @@ function releaseGatewaySessionMessageSubscription(subscription) {
1639
1690
  return sessionMessageSubscriptionOwners.get(subscription)?.coordinator.release(subscription) ?? Promise.resolve();
1640
1691
  }
1641
1692
  //#endregion
1642
- export { buildGatewayConnectAuth as C, buildDeviceAuthPayload as D, shouldRetryGatewayWithDeviceToken as E, buildDeviceAuthPayloadV3 as O, GatewayBrowserDeviceAuthLifecycle as S, selectGatewayConnectAuth as T, GatewayProtocolClient as _, createSessionProjection as a, gatewayCredentialScope as b, projectLiveSessionMessage as c, reduceSessionProjectionRunEvent as d, normalizeSessionProjectionRunId as f, shouldPauseGatewayReconnect as g, isRecord as h, resetGatewaySessionMessageSubscriptionCoordinator as i, normalizeDeviceMetadataForAuth as k, reconcileSessionProjectionSnapshot as l, readSessionMessageSequence as m, getGatewaySessionMessageSubscriptionCoordinator as n, hasSessionProjectionAcceptedFinal as o, readSessionMessageIdentity as p, releaseGatewaySessionMessageSubscription as r, isLocallyOptimisticSessionMessage as s, GatewaySessionMessageSubscriptionCoordinator as t, reduceSessionProjection as u, GatewayProtocolRequestError as v, resolveGatewayConnectScopes as w, gatewayOriginScope as x, GatewayProtocolRequestTimeoutError as y };
1693
+ export { buildDeviceAuthPayloadV3 as A, gatewayOriginScope as C, selectGatewayConnectAuth as D, resolveGatewayConnectScopes as E, shouldRetryGatewayWithDeviceToken as O, gatewayCredentialScope as S, buildGatewayConnectAuth as T, shouldPauseGatewayReconnect as _, createSessionProjection as a, GatewayProtocolRequestTimeoutError as b, projectLiveSessionMessage as c, reduceSessionProjectionRunEvent as d, normalizeSessionProjectionRunId as f, isRecord as g, readSessionMessageSequence as h, resetGatewaySessionMessageSubscriptionCoordinator as i, normalizeDeviceMetadataForAuth as j, buildDeviceAuthPayload as k, reconcileSessionProjectionSnapshot as l, readSessionMessageIdentity as m, getGatewaySessionMessageSubscriptionCoordinator as n, hasSessionProjectionAcceptedFinal as o, readAssistantStreamSegmentIdentity as p, releaseGatewaySessionMessageSubscription as r, isLocallyOptimisticSessionMessage as s, GatewaySessionMessageSubscriptionCoordinator as t, reduceSessionProjection as u, GatewayProtocolClient as v, GatewayBrowserDeviceAuthLifecycle as w, isGatewayProtocolResponseError as x, GatewayProtocolRequestError as y };
@@ -1,43 +1,42 @@
1
1
  //#region packages/gateway-client/src/timeouts.d.ts
2
2
  /** Maximum delay Node timers can represent without overflow warnings. */
3
- declare const MAX_SAFE_TIMEOUT_DELAY_MS = 2147483647;
3
+ export declare const MAX_SAFE_TIMEOUT_DELAY_MS = 2147483647;
4
4
  /** Default server-side window for gateway preauth handshakes. */
5
- declare const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 15000;
5
+ export declare const DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS = 15000;
6
6
  /** Starts the browser-safe deadline that covers Gateway connect preparation and hello. */
7
- declare function startGatewayConnectTimeout(onTimeout: () => void): ReturnType<typeof setTimeout>;
7
+ export declare function startGatewayConnectTimeout(onTimeout: () => void): ReturnType<typeof setTimeout>;
8
8
  /** Clears either pending Gateway handshake phase without retaining its timer. */
9
- declare function clearGatewayConnectTimeout(timer: ReturnType<typeof setTimeout> | null): null;
9
+ export declare function clearGatewayConnectTimeout(timer: ReturnType<typeof setTimeout> | null): null;
10
10
  /** Default deadline for a single non-streaming Gateway request. */
11
- declare const DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS = 30000;
11
+ export declare const DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS = 30000;
12
12
  /** Minimum client watchdog delay for connect challenge setup. */
13
- declare const MIN_CONNECT_CHALLENGE_TIMEOUT_MS = 250;
13
+ export declare const MIN_CONNECT_CHALLENGE_TIMEOUT_MS = 250;
14
14
  /** Default maximum client watchdog delay, aligned with the preauth server timeout. */
15
- declare const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = 15000;
15
+ export declare const MAX_CONNECT_CHALLENGE_TIMEOUT_MS = 15000;
16
16
  /** Clamps arbitrary timer delays to Node's safe range and an optional floor. */
17
- declare function resolveSafeTimeoutDelayMs(delayMs: number, opts?: {
17
+ export declare function resolveSafeTimeoutDelayMs(delayMs: number, opts?: {
18
18
  minMs?: number;
19
19
  }): number;
20
20
  /** Adds grace time while preserving safe timer bounds if inputs overflow or are invalid. */
21
- declare function addSafeTimeoutDelayGraceMs(delayMs: number, graceMs: number, opts?: {
21
+ export declare function addSafeTimeoutDelayGraceMs(delayMs: number, graceMs: number, opts?: {
22
22
  minMs?: number;
23
23
  }): number;
24
24
  /** Resolves optional timeout values through a fallback and safe timer clamp. */
25
- declare function resolveFiniteTimeoutDelayMs(delayMs: number | null | undefined, fallbackMs: number, opts?: {
25
+ export declare function resolveFiniteTimeoutDelayMs(delayMs: number | null | undefined, fallbackMs: number, opts?: {
26
26
  minMs?: number;
27
27
  }): number;
28
28
  /** Clamps connect challenge watchdog timeouts to the gateway-supported range. */
29
- declare function clampConnectChallengeTimeoutMs(timeoutMs: number, maxTimeoutMs?: number): number;
29
+ export declare function clampConnectChallengeTimeoutMs(timeoutMs: number, maxTimeoutMs?: number): number;
30
30
  /** Reads the connect challenge watchdog override from the process environment. */
31
- declare function getConnectChallengeTimeoutMsFromEnv(env?: NodeJS.ProcessEnv): number | undefined;
31
+ export declare function getConnectChallengeTimeoutMsFromEnv(env?: NodeJS.ProcessEnv): number | undefined;
32
32
  /** Resolves the client watchdog timeout using explicit, env, then preauth defaults. */
33
- declare function resolveConnectChallengeTimeoutMs(timeoutMs?: number | null, params?: {
33
+ export declare function resolveConnectChallengeTimeoutMs(timeoutMs?: number | null, params?: {
34
34
  env?: NodeJS.ProcessEnv;
35
35
  configuredTimeoutMs?: number | null;
36
36
  }): number;
37
37
  /** Resolves the server preauth timeout from env, explicit config, or default. */
38
- declare function resolvePreauthHandshakeTimeoutMs(params?: {
38
+ export declare function resolvePreauthHandshakeTimeoutMs(params?: {
39
39
  env?: NodeJS.ProcessEnv;
40
40
  configuredTimeoutMs?: number | null;
41
41
  }): number;
42
- //#endregion
43
- export { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout };
42
+ //#endregion
@@ -1,5 +1,4 @@
1
1
  import { RawData } from "ws";
2
2
  //#region packages/gateway-client/src/websocket-data.d.ts
3
- declare function rawDataToString(data: RawData, encoding?: BufferEncoding): string;
4
- //#endregion
5
- export { rawDataToString };
3
+ export declare function rawDataToString(data: RawData, encoding?: BufferEncoding): string;
4
+ //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/gateway-client",
3
- "version": "2026.9.1-beta.1",
3
+ "version": "2026.9.1",
4
4
  "description": "Reference WebSocket client for the OpenClaw Gateway protocol",
5
5
  "keywords": [
6
6
  "client",
@@ -62,9 +62,9 @@
62
62
  }
63
63
  },
64
64
  "dependencies": {
65
+ "@openclaw/gateway-protocol": "2026.9.1",
65
66
  "ipaddr.js": "2.5.0",
66
- "ws": "8.21.3",
67
- "@openclaw/gateway-protocol": "2026.9.1-beta.1"
67
+ "ws": "8.21.3"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@openclaw/normalization-core": "0.0.0-private"