@honor-claw/yoyo 1.1.2 → 1.1.4-beta.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.
Files changed (66) hide show
  1. package/index.ts +25 -25
  2. package/package.json +5 -5
  3. package/src/apis/claw-cloud.ts +124 -124
  4. package/src/apis/helpers.ts +10 -10
  5. package/src/apis/honor-auth.ts +158 -158
  6. package/src/apis/http-client.ts +239 -239
  7. package/src/apis/index.ts +8 -8
  8. package/src/apis/types.ts +77 -73
  9. package/src/cloud-channel/channel.ts +117 -117
  10. package/src/cloud-channel/client.ts +3 -3
  11. package/src/cloud-channel/index.ts +4 -4
  12. package/src/cloud-channel/message-handler.ts +50 -42
  13. package/src/cloud-channel/session-manager.ts +14 -9
  14. package/src/cloud-channel/types.ts +115 -115
  15. package/src/commands/env/impl.ts +58 -58
  16. package/src/commands/env/index.ts +1 -1
  17. package/src/commands/index.ts +30 -30
  18. package/src/commands/login/impl.ts +30 -30
  19. package/src/commands/login/index.ts +1 -1
  20. package/src/commands/logout/index.ts +1 -1
  21. package/src/commands/status/index.ts +194 -194
  22. package/src/gateway-client/client.ts +90 -90
  23. package/src/gateway-client/device/auth.ts +57 -57
  24. package/src/gateway-client/device/builder.ts +105 -105
  25. package/src/gateway-client/device/helpers.ts +40 -40
  26. package/src/gateway-client/device/identity.ts +251 -251
  27. package/src/gateway-client/device/index.ts +40 -40
  28. package/src/gateway-client/device/types.ts +57 -57
  29. package/src/gateway-client/index.ts +5 -5
  30. package/src/gateway-client/protocol-client.ts +49 -34
  31. package/src/honor-auth/browser.ts +2 -2
  32. package/src/honor-auth/callback-server.ts +109 -109
  33. package/src/honor-auth/cloud.ts +57 -57
  34. package/src/honor-auth/config.ts +43 -43
  35. package/src/honor-auth/index.ts +3 -3
  36. package/src/honor-auth/token-manager.ts +90 -90
  37. package/src/honor-auth/types.ts +50 -50
  38. package/src/index.ts +10 -10
  39. package/src/modules/claw-configs/config-manager.ts +409 -409
  40. package/src/modules/claw-configs/hosts.ts +48 -48
  41. package/src/modules/claw-configs/index.ts +8 -8
  42. package/src/modules/claw-configs/provider.ts +394 -394
  43. package/src/modules/claw-configs/types.ts +34 -34
  44. package/src/modules/device/device-info.ts +1 -1
  45. package/src/modules/device/index.ts +3 -3
  46. package/src/modules/device/providers/base.ts +32 -32
  47. package/src/modules/device/providers/pad.ts +107 -107
  48. package/src/modules/device/providers/windows.ts +130 -130
  49. package/src/modules/device/registry.ts +48 -43
  50. package/src/modules/login/impl.ts +31 -26
  51. package/src/modules/login/index.ts +6 -6
  52. package/src/schemas.ts +23 -23
  53. package/src/services/connection/impl.ts +339 -339
  54. package/src/services/connection/status-tracker/events.ts +127 -127
  55. package/src/services/connection/status-tracker/index.ts +31 -31
  56. package/src/services/connection/status-tracker/storage.ts +133 -133
  57. package/src/services/connection/status-tracker/tracker.ts +370 -370
  58. package/src/services/connection/status-tracker/types.ts +131 -131
  59. package/src/services/connection/types.ts +20 -20
  60. package/src/types.ts +64 -64
  61. package/src/utils/id.ts +8 -8
  62. package/src/utils/jwt.ts +37 -37
  63. package/src/utils/logger.ts +20 -20
  64. package/src/utils/proxy.ts +58 -58
  65. package/src/utils/version.ts +29 -29
  66. package/src/utils/ws.ts +21 -21
@@ -1,131 +1,131 @@
1
- /**
2
- * 状态跟踪类型定义
3
- * 定义连接状态的完整数据结构
4
- */
5
-
6
- /**
7
- * 连接状态类型
8
- */
9
- export type ConnectionStatus = 'idle' | 'connecting' | 'connected';
10
-
11
- /**
12
- * Gateway连接信息
13
- */
14
- export interface GatewayConnectionInfo {
15
- sessionId: string;
16
- hardwareDeviceId: string;
17
- connectedAt: string;
18
- deviceInfo: any;
19
- }
20
-
21
- /**
22
- * 物理设备信息
23
- */
24
- export interface PhysicalDeviceInfo {
25
- hardwareDeviceId: string;
26
- sessions: number;
27
- lastActiveAt: string;
28
- deviceInfo?: any;
29
- }
30
-
31
- /**
32
- * 云侧Socket状态信息
33
- */
34
- export interface CloudSocketStatus {
35
- connected: boolean;
36
- connectedAt: string | null;
37
- lastDisconnectedAt: string | null;
38
- retryCount: number;
39
- lastError: string | null;
40
- url: string;
41
- readyState: number;
42
- }
43
-
44
- /**
45
- * Gateway连接统计
46
- */
47
- export interface GatewayStatus {
48
- totalConnections: number;
49
- activeConnections: number;
50
- connections: GatewayConnectionInfo[];
51
- }
52
-
53
- /**
54
- * 物理设备统计
55
- */
56
- export interface DevicesStatus {
57
- totalDevices: number;
58
- uniqueHardwareDevices: number;
59
- devices: PhysicalDeviceInfo[];
60
- }
61
-
62
- /**
63
- * 连接历史统计
64
- */
65
- export interface ConnectionHistory {
66
- connectionCount: number;
67
- disconnectionCount: number;
68
- lastConnectionAt: string | null;
69
- lastDisconnectionAt: string | null;
70
- }
71
-
72
- /**
73
- * 完整的连接状态数据
74
- */
75
- export interface ConnectionStatusData {
76
- // 基础状态
77
- status: ConnectionStatus;
78
- updatedAt: string;
79
-
80
- // 云侧Socket
81
- cloudSocket: CloudSocketStatus;
82
-
83
- // Gateway连接
84
- gateway: GatewayStatus;
85
-
86
- // 物理设备
87
- devices: DevicesStatus;
88
-
89
- // 连接历史
90
- history: ConnectionHistory;
91
- }
92
-
93
- /**
94
- * 空的连接状态数据(初始化用)
95
- */
96
- export function createEmptyStatusData(): ConnectionStatusData {
97
- const now = new Date().toISOString();
98
- return {
99
- status: 'idle',
100
- updatedAt: now,
101
-
102
- cloudSocket: {
103
- connected: false,
104
- connectedAt: null,
105
- lastDisconnectedAt: null,
106
- retryCount: 0,
107
- lastError: null,
108
- url: '',
109
- readyState: 3, // WebSocket.CLOSED
110
- },
111
-
112
- gateway: {
113
- totalConnections: 0,
114
- activeConnections: 0,
115
- connections: [],
116
- },
117
-
118
- devices: {
119
- totalDevices: 0,
120
- uniqueHardwareDevices: 0,
121
- devices: [],
122
- },
123
-
124
- history: {
125
- connectionCount: 0,
126
- disconnectionCount: 0,
127
- lastConnectionAt: null,
128
- lastDisconnectionAt: null,
129
- },
130
- };
131
- }
1
+ /**
2
+ * 状态跟踪类型定义
3
+ * 定义连接状态的完整数据结构
4
+ */
5
+
6
+ /**
7
+ * 连接状态类型
8
+ */
9
+ export type ConnectionStatus = 'idle' | 'connecting' | 'connected';
10
+
11
+ /**
12
+ * Gateway连接信息
13
+ */
14
+ export interface GatewayConnectionInfo {
15
+ sessionId: string;
16
+ hardwareDeviceId: string;
17
+ connectedAt: string;
18
+ deviceInfo: any;
19
+ }
20
+
21
+ /**
22
+ * 物理设备信息
23
+ */
24
+ export interface PhysicalDeviceInfo {
25
+ hardwareDeviceId: string;
26
+ sessions: number;
27
+ lastActiveAt: string;
28
+ deviceInfo?: any;
29
+ }
30
+
31
+ /**
32
+ * 云侧Socket状态信息
33
+ */
34
+ export interface CloudSocketStatus {
35
+ connected: boolean;
36
+ connectedAt: string | null;
37
+ lastDisconnectedAt: string | null;
38
+ retryCount: number;
39
+ lastError: string | null;
40
+ url: string;
41
+ readyState: number;
42
+ }
43
+
44
+ /**
45
+ * Gateway连接统计
46
+ */
47
+ export interface GatewayStatus {
48
+ totalConnections: number;
49
+ activeConnections: number;
50
+ connections: GatewayConnectionInfo[];
51
+ }
52
+
53
+ /**
54
+ * 物理设备统计
55
+ */
56
+ export interface DevicesStatus {
57
+ totalDevices: number;
58
+ uniqueHardwareDevices: number;
59
+ devices: PhysicalDeviceInfo[];
60
+ }
61
+
62
+ /**
63
+ * 连接历史统计
64
+ */
65
+ export interface ConnectionHistory {
66
+ connectionCount: number;
67
+ disconnectionCount: number;
68
+ lastConnectionAt: string | null;
69
+ lastDisconnectionAt: string | null;
70
+ }
71
+
72
+ /**
73
+ * 完整的连接状态数据
74
+ */
75
+ export interface ConnectionStatusData {
76
+ // 基础状态
77
+ status: ConnectionStatus;
78
+ updatedAt: string;
79
+
80
+ // 云侧Socket
81
+ cloudSocket: CloudSocketStatus;
82
+
83
+ // Gateway连接
84
+ gateway: GatewayStatus;
85
+
86
+ // 物理设备
87
+ devices: DevicesStatus;
88
+
89
+ // 连接历史
90
+ history: ConnectionHistory;
91
+ }
92
+
93
+ /**
94
+ * 空的连接状态数据(初始化用)
95
+ */
96
+ export function createEmptyStatusData(): ConnectionStatusData {
97
+ const now = new Date().toISOString();
98
+ return {
99
+ status: 'idle',
100
+ updatedAt: now,
101
+
102
+ cloudSocket: {
103
+ connected: false,
104
+ connectedAt: null,
105
+ lastDisconnectedAt: null,
106
+ retryCount: 0,
107
+ lastError: null,
108
+ url: '',
109
+ readyState: 3, // WebSocket.CLOSED
110
+ },
111
+
112
+ gateway: {
113
+ totalConnections: 0,
114
+ activeConnections: 0,
115
+ connections: [],
116
+ },
117
+
118
+ devices: {
119
+ totalDevices: 0,
120
+ uniqueHardwareDevices: 0,
121
+ devices: [],
122
+ },
123
+
124
+ history: {
125
+ connectionCount: 0,
126
+ disconnectionCount: 0,
127
+ lastConnectionAt: null,
128
+ lastDisconnectionAt: null,
129
+ },
130
+ };
131
+ }
@@ -1,20 +1,20 @@
1
- import { ClawChannel } from "../../cloud-channel/channel.js";
2
- import { DeviceInfo, HonorUserInfo } from "../../types.js";
3
-
4
- /**
5
- * 连接状态
6
- */
7
- export type ConnectionStatus = "idle" | "connecting" | "connected";
8
-
9
- /**
10
- * 全局连接管理状态
11
- */
12
- export interface ClawConnection {
13
- channel: ClawChannel | null;
14
- status: ConnectionStatus;
15
- }
16
-
17
- export interface ClawConnectionConfig {
18
- deviceInfo: DeviceInfo;
19
- userInfo: HonorUserInfo;
20
- }
1
+ import { ClawChannel } from "../../cloud-channel/channel.js";
2
+ import { DeviceInfo, HonorUserInfo } from "../../types.js";
3
+
4
+ /**
5
+ * 连接状态
6
+ */
7
+ export type ConnectionStatus = "idle" | "connecting" | "connected";
8
+
9
+ /**
10
+ * 全局连接管理状态
11
+ */
12
+ export interface ClawConnection {
13
+ channel: ClawChannel | null;
14
+ status: ConnectionStatus;
15
+ }
16
+
17
+ export interface ClawConnectionConfig {
18
+ deviceInfo: DeviceInfo;
19
+ userInfo: HonorUserInfo;
20
+ }
package/src/types.ts CHANGED
@@ -1,64 +1,64 @@
1
- import { z } from "zod";
2
- import { YoyoPluginConfigSchema } from "./schemas.js";
3
- import { OpenClawConfig } from "openclaw/plugin-sdk";
4
-
5
- /**
6
- * 设备类型枚举
7
- */
8
- export type DeviceType = "phone" | "pad" | "pc";
9
-
10
- /**
11
- * 设备信息
12
- */
13
- export interface DeviceInfo {
14
- deviceId: string;
15
- deviceName: string;
16
- /**
17
- * phone、pad、pc
18
- */
19
- deviceType: DeviceType;
20
- deviceModel: string;
21
- /**
22
- * 品牌信息
23
- */
24
- brand: string;
25
- port: number;
26
- }
27
-
28
- /**
29
- * 设备角色
30
- */
31
- export type DeviceRole = "yoyoclaw" | "node";
32
-
33
- /**
34
- * 用户信息
35
- */
36
- export interface HonorUserInfo {
37
- userId?: string;
38
- token?: string;
39
- userName?: string;
40
- }
41
-
42
- /**
43
- * 插件配置类型(存储在 openclaw.json 的 plugins.entries.yoyoclaw.config)
44
- * 从schemas.ts中的YoyoPluginConfigSchema推断而来
45
- */
46
- export type YoyoPluginConfig = z.infer<typeof YoyoPluginConfigSchema>;
47
-
48
- /**
49
- * 设备信息
50
- */
51
- export interface ClawDeviceInfo extends DeviceInfo {
52
- /**
53
- * 当前设备的连接状态
54
- */
55
- status?: number;
56
- /**
57
- * 当前用户的角色信息
58
- */
59
- role: DeviceRole;
60
- /**
61
- * 扩展信息,当前claw的配置token信息
62
- */
63
- bizExtInfo?: Pick<OpenClawConfig["gateway"]["auth"], 'token' |'password'>;
64
- }
1
+ import { z } from "zod";
2
+ import { YoyoPluginConfigSchema } from "./schemas.js";
3
+ import { OpenClawConfig } from "openclaw/plugin-sdk";
4
+
5
+ /**
6
+ * 设备类型枚举
7
+ */
8
+ export type DeviceType = "phone" | "pad" | "pc";
9
+
10
+ /**
11
+ * 设备信息
12
+ */
13
+ export interface DeviceInfo {
14
+ deviceId: string;
15
+ deviceName: string;
16
+ /**
17
+ * phone、pad、pc
18
+ */
19
+ deviceType: DeviceType;
20
+ deviceModel: string;
21
+ /**
22
+ * 品牌信息
23
+ */
24
+ brand: string;
25
+ port: number;
26
+ }
27
+
28
+ /**
29
+ * 设备角色
30
+ */
31
+ export type DeviceRole = "yoyoclaw" | "node";
32
+
33
+ /**
34
+ * 用户信息
35
+ */
36
+ export interface HonorUserInfo {
37
+ userId?: string;
38
+ token?: string;
39
+ userName?: string;
40
+ }
41
+
42
+ /**
43
+ * 插件配置类型(存储在 openclaw.json 的 plugins.entries.yoyoclaw.config)
44
+ * 从schemas.ts中的YoyoPluginConfigSchema推断而来
45
+ */
46
+ export type YoyoPluginConfig = z.infer<typeof YoyoPluginConfigSchema>;
47
+
48
+ /**
49
+ * 设备信息
50
+ */
51
+ export interface ClawDeviceInfo extends DeviceInfo {
52
+ /**
53
+ * 当前设备的连接状态
54
+ */
55
+ status?: number;
56
+ /**
57
+ * 当前用户的角色信息
58
+ */
59
+ role: DeviceRole;
60
+ /**
61
+ * 扩展信息,当前claw的配置token信息
62
+ */
63
+ bizExtInfo?: Pick<NonNullable<NonNullable<OpenClawConfig['gateway']>['auth']>, 'token' |'password'>;
64
+ }
package/src/utils/id.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { customAlphabet } from 'nanoid';
2
-
3
- const Alphabet = '0123456789abcdefghijklmnopqrstuvwxyz';
4
- const uuidGenerator = customAlphabet(Alphabet, 32);
5
-
6
- export function uuid(size?: number) {
7
- return uuidGenerator(size);
8
- }
1
+ import { customAlphabet } from 'nanoid';
2
+
3
+ const Alphabet = '0123456789abcdefghijklmnopqrstuvwxyz';
4
+ const uuidGenerator = customAlphabet(Alphabet, 32);
5
+
6
+ export function uuid(size?: number) {
7
+ return uuidGenerator(size);
8
+ }
package/src/utils/jwt.ts CHANGED
@@ -1,37 +1,37 @@
1
- /**
2
- * JWT Token 生成工具
3
- */
4
-
5
- import jwt from 'jsonwebtoken';
6
-
7
- const SECRET = 'EIAMTDO~_IFR@XKKA+OKSK%ZUHPIF%Z!';
8
- const EXPIRATION_MS = 604800; // 7天
9
-
10
- interface JwtClaims {
11
- rt: string;
12
- }
13
-
14
- /**
15
- * 生成 JWT Token
16
- * @param userId 用户ID
17
- * @returns JWT Token 字符串
18
- */
19
- export function generateAuthorization(userId: string): string {
20
- try {
21
-
22
- const claims: JwtClaims = {
23
- rt: 'rtValue',
24
- };
25
-
26
- const payload = {
27
- ...claims,
28
- sub: userId,
29
- iat: Math.floor(Date.now() / 1000),
30
- exp: Math.floor((Date.now() + EXPIRATION_MS) / 1000),
31
- };
32
-
33
- return jwt.sign(payload, SECRET, { algorithm: 'HS256' });
34
- } catch (error) {
35
- throw new Error(`generateAuthorization error: ${error instanceof Error ? error.message : String(error)}`);
36
- }
37
- }
1
+ /**
2
+ * JWT Token 生成工具
3
+ */
4
+
5
+ import jwt from 'jsonwebtoken';
6
+
7
+ const SECRET = 'EIAMTDO~_IFR@XKKA+OKSK%ZUHPIF%Z!';
8
+ const EXPIRATION_MS = 604800; // 7天
9
+
10
+ interface JwtClaims {
11
+ rt: string;
12
+ }
13
+
14
+ /**
15
+ * 生成 JWT Token
16
+ * @param userId 用户ID
17
+ * @returns JWT Token 字符串
18
+ */
19
+ export function generateAuthorization(userId: string): string {
20
+ try {
21
+
22
+ const claims: JwtClaims = {
23
+ rt: 'rtValue',
24
+ };
25
+
26
+ const payload = {
27
+ ...claims,
28
+ sub: userId,
29
+ iat: Math.floor(Date.now() / 1000),
30
+ exp: Math.floor((Date.now() + EXPIRATION_MS) / 1000),
31
+ };
32
+
33
+ return jwt.sign(payload, SECRET, { algorithm: 'HS256' });
34
+ } catch (error) {
35
+ throw new Error(`generateAuthorization error: ${error instanceof Error ? error.message : String(error)}`);
36
+ }
37
+ }
@@ -1,20 +1,20 @@
1
- import { type PluginLogger } from "openclaw/plugin-sdk";
2
-
3
- let logger: PluginLogger | null = null;
4
-
5
- export function setClawLogger(next: PluginLogger) {
6
- logger = next;
7
- }
8
-
9
- export function useClawLogger(): PluginLogger {
10
- if (!logger) {
11
- // 返回console兜底实现
12
- return {
13
- debug: console.debug,
14
- info: console.log,
15
- warn: console.warn,
16
- error: console.error,
17
- };
18
- }
19
- return logger;
20
- }
1
+ import { type PluginLogger } from "openclaw/plugin-sdk";
2
+
3
+ let logger: PluginLogger | null = null;
4
+
5
+ export function setClawLogger(next: PluginLogger) {
6
+ logger = next;
7
+ }
8
+
9
+ export function useClawLogger(): PluginLogger {
10
+ if (!logger) {
11
+ // 返回console兜底实现
12
+ return {
13
+ debug: console.debug,
14
+ info: console.log,
15
+ warn: console.warn,
16
+ error: console.error,
17
+ };
18
+ }
19
+ return logger;
20
+ }
@@ -1,58 +1,58 @@
1
- /**
2
- * 代理工具类
3
- * 提供统一的代理配置获取逻辑
4
- */
5
-
6
- import { HttpProxyAgent } from 'http-proxy-agent';
7
- import { HttpsProxyAgent } from 'https-proxy-agent';
8
-
9
- /**
10
- * 获取代理 URL
11
- * 优先级:配置的 proxy > HTTP_PROXY/http_proxy > HTTPS_PROXY/https_proxy
12
- * @param proxy 配置的代理地址
13
- * @returns 代理 URL
14
- */
15
- export function getProxyUrl(proxy?: string): string | undefined {
16
- return (
17
- proxy ||
18
- process.env.HTTP_PROXY ||
19
- process.env.http_proxy ||
20
- process.env.HTTPS_PROXY ||
21
- process.env.https_proxy
22
- );
23
- }
24
-
25
- /**
26
- * 检查是否需要使用代理
27
- * @param proxyUrl 代理 URL
28
- * @param disableProxy 是否禁用代理
29
- * @returns 是否需要使用代理
30
- */
31
- export function shouldUseProxy(proxyUrl?: string, disableProxy?: boolean): boolean {
32
- return !disableProxy && !!proxyUrl;
33
- }
34
-
35
- /**
36
- * 创建 WebSocket 代理 Agent
37
- * @param url WebSocket URL
38
- * @param proxy 代理地址
39
- * @returns 代理 Agent
40
- */
41
- export function createWebSocketProxyAgent(
42
- url: string,
43
- proxy?: string
44
- ): HttpProxyAgent<string> | HttpsProxyAgent<string> | undefined {
45
- const proxyUrl = getProxyUrl(proxy);
46
-
47
- if (!proxyUrl) {
48
- return undefined;
49
- }
50
-
51
- if (url.startsWith('wss://')) {
52
- return new HttpsProxyAgent(proxyUrl);
53
- } else if (url.startsWith('ws://')) {
54
- return new HttpProxyAgent(proxyUrl);
55
- }
56
-
57
- return undefined;
58
- }
1
+ /**
2
+ * 代理工具类
3
+ * 提供统一的代理配置获取逻辑
4
+ */
5
+
6
+ import { HttpProxyAgent } from 'http-proxy-agent';
7
+ import { HttpsProxyAgent } from 'https-proxy-agent';
8
+
9
+ /**
10
+ * 获取代理 URL
11
+ * 优先级:配置的 proxy > HTTP_PROXY/http_proxy > HTTPS_PROXY/https_proxy
12
+ * @param proxy 配置的代理地址
13
+ * @returns 代理 URL
14
+ */
15
+ export function getProxyUrl(proxy?: string): string | undefined {
16
+ return (
17
+ proxy ||
18
+ process.env.HTTP_PROXY ||
19
+ process.env.http_proxy ||
20
+ process.env.HTTPS_PROXY ||
21
+ process.env.https_proxy
22
+ );
23
+ }
24
+
25
+ /**
26
+ * 检查是否需要使用代理
27
+ * @param proxyUrl 代理 URL
28
+ * @param disableProxy 是否禁用代理
29
+ * @returns 是否需要使用代理
30
+ */
31
+ export function shouldUseProxy(proxyUrl?: string, disableProxy?: boolean): boolean {
32
+ return !disableProxy && !!proxyUrl;
33
+ }
34
+
35
+ /**
36
+ * 创建 WebSocket 代理 Agent
37
+ * @param url WebSocket URL
38
+ * @param proxy 代理地址
39
+ * @returns 代理 Agent
40
+ */
41
+ export function createWebSocketProxyAgent(
42
+ url: string,
43
+ proxy?: string
44
+ ): HttpProxyAgent<string> | HttpsProxyAgent<string> | undefined {
45
+ const proxyUrl = getProxyUrl(proxy);
46
+
47
+ if (!proxyUrl) {
48
+ return undefined;
49
+ }
50
+
51
+ if (url.startsWith('wss://')) {
52
+ return new HttpsProxyAgent(proxyUrl);
53
+ } else if (url.startsWith('ws://')) {
54
+ return new HttpProxyAgent(proxyUrl);
55
+ }
56
+
57
+ return undefined;
58
+ }