@lingyao037/openclaw-lingyao-cli 0.9.5 → 0.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accounts-CzjBLXMH.d.ts → accounts-BykE02r0.d.ts} +1 -1
- package/dist/cli.d.ts +2 -2
- package/dist/index.d.ts +14 -4
- package/dist/index.js +103 -5
- package/dist/index.js.map +1 -1
- package/dist/setup-entry.d.ts +2 -2
- package/dist/setup-entry.js +1 -1
- package/dist/setup-entry.js.map +1 -1
- package/dist/{status-DdIuhIHE.d.ts → status-CVwSoPKi.d.ts} +1 -1
- package/dist/{types-Zbv12l39.d.ts → types-LFC6Wpqo.d.ts} +7 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LingyaoRuntime, g as LingyaoAccount, c as DeviceToken, D as DeviceInfo } from './types-
|
|
1
|
+
import { L as LingyaoRuntime, g as LingyaoAccount, c as DeviceToken, D as DeviceInfo } from './types-LFC6Wpqo.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Account storage and management
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LingyaoRuntime, H as HealthStatus } from './types-
|
|
2
|
-
import { A as AccountManager } from './accounts-
|
|
1
|
+
import { L as LingyaoRuntime, H as HealthStatus } from './types-LFC6Wpqo.js';
|
|
2
|
+
import { A as AccountManager } from './accounts-BykE02r0.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Probe status levels
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { R as ResolvedAccount, L as LingyaoProbeResult } from './status-
|
|
1
|
+
import { R as ResolvedAccount, L as LingyaoProbeResult } from './status-CVwSoPKi.js';
|
|
2
2
|
import * as openclaw_plugin_sdk from 'openclaw/plugin-sdk';
|
|
3
3
|
import { PluginRuntime, ChannelPlugin } from 'openclaw/plugin-sdk';
|
|
4
|
-
import { L as LingyaoRuntime, S as SyncRequest, a as SyncResponse, b as LingyaoMessage, D as DeviceInfo, c as DeviceToken, d as LingyaoConfig, N as NotifyPayload, H as HealthStatus } from './types-
|
|
5
|
-
export { A as AckRequest, e as DiarySyncPayload, F as FailedEntry, f as LINGYAO_SERVER_URL, g as LingyaoAccount, h as LingyaoAccountConfig, M as MemorySyncPayload, i as MessageType, j as NotifyAction, k as NotifyRequest, P as PairingCode, l as PairingConfirmRequest, m as PairingConfirmResponse, n as PollRequest, o as PollResponse, Q as QueuedMessage, T as TokenRefreshRequest, p as TokenRefreshResponse, W as WebSocketConnection } from './types-
|
|
6
|
-
import { A as AccountManager } from './accounts-
|
|
4
|
+
import { L as LingyaoRuntime, S as SyncRequest, a as SyncResponse, b as LingyaoMessage, D as DeviceInfo, c as DeviceToken, d as LingyaoConfig, N as NotifyPayload, H as HealthStatus } from './types-LFC6Wpqo.js';
|
|
5
|
+
export { A as AckRequest, e as DiarySyncPayload, F as FailedEntry, f as LINGYAO_SERVER_URL, g as LingyaoAccount, h as LingyaoAccountConfig, M as MemorySyncPayload, i as MessageType, j as NotifyAction, k as NotifyRequest, P as PairingCode, l as PairingConfirmRequest, m as PairingConfirmResponse, n as PollRequest, o as PollResponse, Q as QueuedMessage, T as TokenRefreshRequest, p as TokenRefreshResponse, W as WebSocketConnection, q as getLingyaoGatewayWsUrl } from './types-LFC6Wpqo.js';
|
|
6
|
+
import { A as AccountManager } from './accounts-BykE02r0.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* 灵爻服务器 HTTP 客户端
|
|
@@ -134,6 +134,11 @@ declare class ServerHttpClient {
|
|
|
134
134
|
* 检查是否已注册
|
|
135
135
|
*/
|
|
136
136
|
isReady(): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Clear local gateway token/session (storage + in-memory). Used when WS handshake
|
|
139
|
+
* fails with 404 or when forcing re-registration with the same gatewayId.
|
|
140
|
+
*/
|
|
141
|
+
clearLocalSession(): Promise<void>;
|
|
137
142
|
/**
|
|
138
143
|
* 从存储恢复会话
|
|
139
144
|
*/
|
|
@@ -218,6 +223,9 @@ type WSClientEvent = {
|
|
|
218
223
|
} | {
|
|
219
224
|
type: "error";
|
|
220
225
|
error: Error;
|
|
226
|
+
} | {
|
|
227
|
+
type: "fatal_handshake";
|
|
228
|
+
reason: "http_404";
|
|
221
229
|
} | {
|
|
222
230
|
type: "message";
|
|
223
231
|
message: WSMessage;
|
|
@@ -259,6 +267,8 @@ declare class LingyaoWSClient {
|
|
|
259
267
|
private connectionId;
|
|
260
268
|
private heartbeatTimer;
|
|
261
269
|
private reconnectTimer;
|
|
270
|
+
/** When set, close handler will not schedule reconnect (e.g. HTTP 404 on upgrade). */
|
|
271
|
+
private suppressReconnect;
|
|
262
272
|
private messageHandlers;
|
|
263
273
|
private logger;
|
|
264
274
|
constructor(runtime: LingyaoRuntime, config: WSClientConfig);
|
package/dist/index.js
CHANGED
|
@@ -409,6 +409,9 @@ import { createHash as createHash2 } from "crypto";
|
|
|
409
409
|
|
|
410
410
|
// src/types.ts
|
|
411
411
|
var LINGYAO_SERVER_URL = "https://api.lingyao.live";
|
|
412
|
+
function getLingyaoGatewayWsUrl() {
|
|
413
|
+
return LINGYAO_SERVER_URL.replace(/^https:/i, "wss:") + "/lyoc/gateway/ws";
|
|
414
|
+
}
|
|
412
415
|
var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
413
416
|
MessageType2["SYNC_DIARY"] = "sync_diary";
|
|
414
417
|
MessageType2["SYNC_MEMORY"] = "sync_memory";
|
|
@@ -445,7 +448,8 @@ var ServerHttpClient = class {
|
|
|
445
448
|
this.storagePrefix = storagePrefix;
|
|
446
449
|
this.config = {
|
|
447
450
|
baseURL: serverConfig.baseURL || "https://api.lingyao.live",
|
|
448
|
-
|
|
451
|
+
// Public API (api.lingyao.live) serves gateway HTTP under /lyoc; local relay also accepts /lyoc (see server getApiPathSuffix).
|
|
452
|
+
apiBase: serverConfig.apiBase || "/lyoc",
|
|
449
453
|
timeout: serverConfig.timeout || 3e4,
|
|
450
454
|
connectionTimeout: serverConfig.connectionTimeout || 5e3
|
|
451
455
|
};
|
|
@@ -525,6 +529,10 @@ var ServerHttpClient = class {
|
|
|
525
529
|
throw new Error("Gateway already registered");
|
|
526
530
|
} else if (status === 400) {
|
|
527
531
|
throw new Error(`Invalid request: ${data?.details || "Unknown error"}`);
|
|
532
|
+
} else if (status === 404) {
|
|
533
|
+
throw new Error(
|
|
534
|
+
"Lingyao gateway register returned 404. Check server URL and /lyoc/gateway/register; the gatewayId may be invalid or the API may not be deployed on this host."
|
|
535
|
+
);
|
|
528
536
|
}
|
|
529
537
|
throw new Error(`Registration failed: ${axiosError.message}`);
|
|
530
538
|
}
|
|
@@ -659,6 +667,26 @@ var ServerHttpClient = class {
|
|
|
659
667
|
isReady() {
|
|
660
668
|
return this.isRegistered && !!this.gatewayToken;
|
|
661
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* Clear local gateway token/session (storage + in-memory). Used when WS handshake
|
|
672
|
+
* fails with 404 or when forcing re-registration with the same gatewayId.
|
|
673
|
+
*/
|
|
674
|
+
async clearLocalSession() {
|
|
675
|
+
this.stopHeartbeat();
|
|
676
|
+
this.gatewayToken = null;
|
|
677
|
+
this.webhookSecret = null;
|
|
678
|
+
this.tokenExpiresAt = 0;
|
|
679
|
+
this.isRegistered = false;
|
|
680
|
+
const keys = ["gatewayToken", "webhookSecret", "tokenExpiresAt", "serverConfig"];
|
|
681
|
+
for (const k of keys) {
|
|
682
|
+
try {
|
|
683
|
+
await this.runtime.storage.delete(this.storageKey(k));
|
|
684
|
+
} catch (e) {
|
|
685
|
+
this.runtime.logger.warn(`Failed to delete storage key ${k}`, e);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
this.runtime.logger.info("Cleared local Lingyao gateway session");
|
|
689
|
+
}
|
|
662
690
|
/**
|
|
663
691
|
* 从存储恢复会话
|
|
664
692
|
*/
|
|
@@ -705,6 +733,9 @@ var ServerHttpClient = class {
|
|
|
705
733
|
|
|
706
734
|
// src/websocket-client.ts
|
|
707
735
|
import WebSocket from "ws";
|
|
736
|
+
function isWebsocketUpgradeNotFoundError(message) {
|
|
737
|
+
return /Unexpected server response:\s*404/i.test(message) || /\b404\b/.test(message);
|
|
738
|
+
}
|
|
708
739
|
var LingyaoWSClient = class {
|
|
709
740
|
config;
|
|
710
741
|
ws = null;
|
|
@@ -712,6 +743,8 @@ var LingyaoWSClient = class {
|
|
|
712
743
|
connectionId = null;
|
|
713
744
|
heartbeatTimer = null;
|
|
714
745
|
reconnectTimer = null;
|
|
746
|
+
/** When set, close handler will not schedule reconnect (e.g. HTTP 404 on upgrade). */
|
|
747
|
+
suppressReconnect = false;
|
|
715
748
|
messageHandlers = /* @__PURE__ */ new Map();
|
|
716
749
|
logger;
|
|
717
750
|
constructor(runtime, config) {
|
|
@@ -734,6 +767,7 @@ var LingyaoWSClient = class {
|
|
|
734
767
|
return;
|
|
735
768
|
}
|
|
736
769
|
this.state = "connecting";
|
|
770
|
+
this.suppressReconnect = false;
|
|
737
771
|
this.emitEvent({ type: "disconnected", code: 0, reason: "Reconnecting" });
|
|
738
772
|
try {
|
|
739
773
|
this.logger.info(`Connecting to Lingyao server: ${this.config.url}`);
|
|
@@ -810,7 +844,16 @@ var LingyaoWSClient = class {
|
|
|
810
844
|
* 处理连接错误
|
|
811
845
|
*/
|
|
812
846
|
handleErrorEvent(error) {
|
|
813
|
-
|
|
847
|
+
const msg = error?.message ?? String(error);
|
|
848
|
+
if (isWebsocketUpgradeNotFoundError(msg)) {
|
|
849
|
+
this.suppressReconnect = true;
|
|
850
|
+
this.logger.error(
|
|
851
|
+
"WebSocket handshake failed with HTTP 404 \u2014 stopping reconnect loop. If the gateway was removed server-side, remove `gatewayId` from channels.lingyao.accounts.* or use a new account id; if the path is wrong, verify wss://\u2026/lyoc/gateway/ws is deployed on api.lingyao.live.",
|
|
852
|
+
{ gatewayId: this.config.gatewayId, message: msg }
|
|
853
|
+
);
|
|
854
|
+
} else {
|
|
855
|
+
this.logger.error("WebSocket error", error);
|
|
856
|
+
}
|
|
814
857
|
this.state = "error";
|
|
815
858
|
this.emitEvent({ type: "error", error });
|
|
816
859
|
}
|
|
@@ -827,6 +870,11 @@ var LingyaoWSClient = class {
|
|
|
827
870
|
this.logger.error("WebSocket closed with 1008 (Invalid Token). Stopping reconnect loop.");
|
|
828
871
|
return;
|
|
829
872
|
}
|
|
873
|
+
if (this.suppressReconnect) {
|
|
874
|
+
this.suppressReconnect = false;
|
|
875
|
+
this.emitEvent({ type: "fatal_handshake", reason: "http_404" });
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
830
878
|
if (code !== 1e3) {
|
|
831
879
|
this.scheduleReconnect();
|
|
832
880
|
}
|
|
@@ -2683,7 +2731,7 @@ var MultiAccountOrchestrator = class {
|
|
|
2683
2731
|
}
|
|
2684
2732
|
await this.registerToServer(state);
|
|
2685
2733
|
const wsClient = new LingyaoWSClient(this.runtime, {
|
|
2686
|
-
url:
|
|
2734
|
+
url: getLingyaoGatewayWsUrl(),
|
|
2687
2735
|
gatewayId,
|
|
2688
2736
|
token: httpClient.getGatewayToken() ?? void 0,
|
|
2689
2737
|
reconnectInterval: 5e3,
|
|
@@ -2905,6 +2953,11 @@ var MultiAccountOrchestrator = class {
|
|
|
2905
2953
|
});
|
|
2906
2954
|
state.errorHandler.handleError(event.error);
|
|
2907
2955
|
break;
|
|
2956
|
+
case "fatal_handshake":
|
|
2957
|
+
if (event.reason === "http_404") {
|
|
2958
|
+
void this.handleWsHandshake404(state);
|
|
2959
|
+
}
|
|
2960
|
+
break;
|
|
2908
2961
|
case "pairing_completed":
|
|
2909
2962
|
this.handlePairingCompleted(state, event);
|
|
2910
2963
|
break;
|
|
@@ -2928,6 +2981,45 @@ var MultiAccountOrchestrator = class {
|
|
|
2928
2981
|
this.runtime.logger.error(`[${state.accountId}] Failed to auto-bind device: ${deviceId}`, error);
|
|
2929
2982
|
}
|
|
2930
2983
|
}
|
|
2984
|
+
/**
|
|
2985
|
+
* After HTTP 404 on WebSocket upgrade: clear local tokens, re-register once, reconnect.
|
|
2986
|
+
* Does not fix wrong server URL or permanently deleted gateway rows (user must fix config).
|
|
2987
|
+
*/
|
|
2988
|
+
async handleWsHandshake404(state) {
|
|
2989
|
+
if (state.wsHandshake404RecoveryAttempted) {
|
|
2990
|
+
this.runtime.logger.error(
|
|
2991
|
+
`[${state.accountId}] Lingyao WebSocket still failing after one recovery attempt. Check that wss://\u2026/lyoc/gateway/ws is deployed; if the gateway was removed, delete \`channels.lingyao.accounts.${state.accountId}.gatewayId\` or use a new account id, then restart.`
|
|
2992
|
+
);
|
|
2993
|
+
return;
|
|
2994
|
+
}
|
|
2995
|
+
state.wsHandshake404RecoveryAttempted = true;
|
|
2996
|
+
const { httpClient, wsClient, accountId } = state;
|
|
2997
|
+
if (!httpClient || !wsClient) {
|
|
2998
|
+
return;
|
|
2999
|
+
}
|
|
3000
|
+
this.runtime.logger.info(`[${accountId}] WS HTTP 404 \u2014 clearing local session and re-registering...`);
|
|
3001
|
+
try {
|
|
3002
|
+
await httpClient.clearLocalSession();
|
|
3003
|
+
const response = await httpClient.register({
|
|
3004
|
+
websocket: true,
|
|
3005
|
+
compression: false,
|
|
3006
|
+
maxMessageSize: 1048576
|
|
3007
|
+
});
|
|
3008
|
+
wsClient.updateToken(response.gatewayToken);
|
|
3009
|
+
await wsClient.connect();
|
|
3010
|
+
this.runtime.logger.info(`[${accountId}] Re-register OK; WebSocket reconnect issued.`);
|
|
3011
|
+
} catch (error) {
|
|
3012
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
3013
|
+
if (msg.includes("already registered")) {
|
|
3014
|
+
this.runtime.logger.error(
|
|
3015
|
+
`[${accountId}] Re-register failed: gateway still registered on server but local session was cleared. Remove or change \`gatewayId\` under this account, or reset the gateway on lingyao.live, then restart OpenClaw.`,
|
|
3016
|
+
error
|
|
3017
|
+
);
|
|
3018
|
+
} else {
|
|
3019
|
+
this.runtime.logger.error(`[${accountId}] WS 404 recovery (clear + register) failed`, error);
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
2931
3023
|
/**
|
|
2932
3024
|
* Handle invalid token by re-registering the gateway and reconnecting WS
|
|
2933
3025
|
*/
|
|
@@ -3164,7 +3256,7 @@ var LingyaoChannel = class {
|
|
|
3164
3256
|
try {
|
|
3165
3257
|
await this.registerToServer();
|
|
3166
3258
|
this.wsClient = new LingyaoWSClient(this.runtime, {
|
|
3167
|
-
url:
|
|
3259
|
+
url: getLingyaoGatewayWsUrl(),
|
|
3168
3260
|
gatewayId: this.gatewayId,
|
|
3169
3261
|
token: this.serverClient?.getGatewayToken() ?? void 0,
|
|
3170
3262
|
reconnectInterval: 5e3,
|
|
@@ -3313,6 +3405,11 @@ var LingyaoChannel = class {
|
|
|
3313
3405
|
)
|
|
3314
3406
|
);
|
|
3315
3407
|
break;
|
|
3408
|
+
case "fatal_handshake":
|
|
3409
|
+
this.runtime.logger.error(
|
|
3410
|
+
"Lingyao WebSocket upgrade failed (HTTP 404). Use the OpenClaw plugin path for automatic recovery, or clear gateway session / gatewayId in config."
|
|
3411
|
+
);
|
|
3412
|
+
break;
|
|
3316
3413
|
}
|
|
3317
3414
|
}
|
|
3318
3415
|
/**
|
|
@@ -3702,7 +3799,7 @@ async function createPlugin(runtime, config = {}) {
|
|
|
3702
3799
|
}
|
|
3703
3800
|
var pluginMetadata = {
|
|
3704
3801
|
name: "lingyao",
|
|
3705
|
-
version: "0.9.
|
|
3802
|
+
version: "0.9.6",
|
|
3706
3803
|
description: "Lingyao Channel Plugin - bidirectional sync via lingyao.live server relay",
|
|
3707
3804
|
type: "channel",
|
|
3708
3805
|
capabilities: {
|
|
@@ -3738,6 +3835,7 @@ export {
|
|
|
3738
3835
|
createPlugin,
|
|
3739
3836
|
index_default as default,
|
|
3740
3837
|
getDefaultConfig,
|
|
3838
|
+
getLingyaoGatewayWsUrl,
|
|
3741
3839
|
initializeLingyaoRuntime,
|
|
3742
3840
|
lingyaoPlugin,
|
|
3743
3841
|
pluginMetadata,
|