@workclaw/cli 1.0.315 → 1.0.317

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
@@ -52,12 +52,14 @@ workclaw box
52
52
  **适用场景**:个人电脑或需要用户登录的设备
53
53
 
54
54
  **特点**:
55
+
55
56
  - ✅ 需要用户登录(手机号 + 密码)
56
57
  - ✅ 自动获取 appKey 和 appSecret
57
58
  - ✅ 支持多账号管理
58
59
  - ✅ 自动创建和管理配置
59
60
 
60
61
  **安装流程**:
62
+
61
63
  1. 用户登录(RSA 加密密码)
62
64
  2. 获取绑定配置
63
65
  3. 通过手机号补全配置
@@ -69,12 +71,14 @@ workclaw box
69
71
  **适用场景**:专用设备或无需用户登录的环境
70
72
 
71
73
  **特点**:
74
+
72
75
  - ✅ 无需登录(直接使用 appKey + appSecret)
73
76
  - ✅ 适合批量部署
74
77
  - ✅ 配置文件默认设置为开放策略
75
78
  - ✅ 更快的安装速度
76
79
 
77
80
  **安装流程**:
81
+
78
82
  1. 清理旧版本插件
79
83
  2. 下载并安装插件
80
84
  3. 更新配置文件(`dmPolicy: "open"`)
@@ -96,25 +100,27 @@ npx @workclaw/cli --help
96
100
 
97
101
  ### local 命令参数
98
102
 
99
- | 参数 | 说明 |
100
- | --------------- | --------------------------------------- |
101
- | --phone | 手机号码(登录账号),未填写时会交互式提示输入 |
102
- | --user-pass | 用户密码,未填写时会交互式提示输入 |
103
- | --env | 环境 (test/prod),默认 test,未填写时会交互式提示选择 |
103
+ | 参数 | 说明 |
104
+ | ---------------- | ----------------------------------- |
105
+ | --phone | 手机号码(登录账号),未填写时会交互式提示输入 |
106
+ | --user-pass | 用户密码,未填写时会交互式提示输入 |
107
+ | --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
108
+ | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
104
109
  | --plugin-version | 插件版本号(默认安装最新版) |
105
- | --openclaw-path | OpenClaw 安装目录(默认 ~/.openclaw) |
106
- | --debug | 开启调试日志 |
110
+ | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
111
+ | --debug | 开启调试日志 |
107
112
 
108
113
  ### box 命令参数
109
114
 
110
- | 参数 | 说明 |
111
- | --------------- | --------------------------------------- |
112
- | --app-key | App Key,未填写时会交互式提示输入 |
113
- | --app-secret | App Secret,未填写时会交互式提示输入 |
114
- | --env | 环境 (test/prod),默认 test,未填写时会交互式提示选择 |
115
+ | 参数 | 说明 |
116
+ | ---------------- | ----------------------------------- |
117
+ | --app-key | App Key,未填写时会交互式提示输入 |
118
+ | --app-secret | App Secret,未填写时会交互式提示输入 |
119
+ | --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
120
+ | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
115
121
  | --plugin-version | 插件版本号(默认安装最新版) |
116
- | --openclaw-path | OpenClaw 安装目录(默认 ~/.openclaw) |
117
- | --debug | 开启调试日志 |
122
+ | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
123
+ | --debug | 开启调试日志 |
118
124
 
119
125
  ## 💡 使用示例
120
126
 
@@ -125,16 +131,25 @@ npx @workclaw/cli --help
125
131
  npx @workclaw/cli local
126
132
 
127
133
  # 指定手机号和密码
128
- npx @workclaw/cli local --phone 18111657826 --user-pass yourpassword
134
+ npx @workclaw/cli local --phone your_phone --user-pass your_password
129
135
 
130
136
  # 指定正式环境
131
- npx @workclaw/cli local --env prod --phone 18111657826 --user-pass yourpassword
137
+ npx @workclaw/cli local --env prod --phone your_phone --user-pass your_password
132
138
 
133
139
  # 自定义安装路径
134
- npx @workclaw/cli local --openclaw-path "C:\CustomPath\OpenClaw" --phone 18111657826 --user-pass yourpassword
140
+ npx @workclaw/cli local --openclaw-path "C:\CustomPath\OpenClaw" --phone your_phone --user-pass your_password
135
141
 
136
142
  # 开启调试模式
137
- npx @workclaw/cli local --debug --phone 18111657826 --user-pass yourpassword
143
+ npx @workclaw/cli local --debug --phone your_phone --user-pass your_password
144
+
145
+ # 自定义环境(使用本地后端服务)
146
+ npx @workclaw/cli local --env custom --phone your_phone --user-pass your_password
147
+
148
+ # 自定义环境(命令行直接传入 IP)
149
+ npx @workclaw/cli local --env custom --customIp 192.168.1.100:32005 --phone your_phone --user-pass your_password
150
+
151
+ # 自定义环境(带协议完整地址)
152
+ npx @workclaw/cli local --env custom --customIp http://127.0.0.1:32005 --phone your_phone --user-pass your_password
138
153
  ```
139
154
 
140
155
  ### 盒子设备安装
@@ -154,6 +169,12 @@ npx @workclaw/cli box --openclaw-path "/custom/path" --app-key your-app-key --ap
154
169
 
155
170
  # 开启调试模式
156
171
  npx @workclaw/cli box --debug --app-key your-app-key --app-secret your-app-secret
172
+
173
+ # 自定义环境(使用本地后端服务)
174
+ npx @workclaw/cli box --env custom --app-key your-app-key --app-secret your-app-secret
175
+
176
+ # 自定义环境(命令行直接传入 IP)
177
+ npx @workclaw/cli box --env custom --customIp 192.168.1.100:32005 --app-key your-app-key --app-secret your-app-secret
157
178
  ```
158
179
 
159
180
  ## 🔧 技术实现
@@ -164,11 +185,9 @@ npx @workclaw/cli box --debug --app-key your-app-key --app-secret your-app-secre
164
185
  - 使用 `npm pack` 从 npm 镜像源下载插件包
165
186
  - 默认使用腾讯云 npm 镜像:`https://mirrors.tencent.com/npm/`
166
187
  - 支持重试机制(最多 3 次)
167
-
168
188
  2. **文件解压**
169
189
  - 使用 `tar.extract()` 解压到目标目录
170
190
  - 自动创建必要的目录结构
171
-
172
191
  3. **依赖安装**
173
192
  - 使用 `npm install --omit=dev` 安装生产依赖
174
193
  - 自动跳过开发依赖,减小安装体积
@@ -190,6 +209,7 @@ npx @workclaw/cli box --debug --app-key your-app-key --app-secret your-app-secre
190
209
  ### 路径验证
191
210
 
192
211
  工具会自动验证用户输入的 `--openclaw-path` 参数:
212
+
193
213
  - ✅ 必须是绝对路径
194
214
  - ✅ 不能包含非法字符:`< > : " | ? *`
195
215
 
@@ -198,35 +218,52 @@ npx @workclaw/cli box --debug --app-key your-app-key --app-secret your-app-secre
198
218
  ### Q: 安装失败,提示"网络错误"?
199
219
 
200
220
  **A**: 检查网络连接,可以尝试:
221
+
201
222
  - 使用代理或 VPN
202
223
  - 配置 npm 镜像源:`npm config set registry https://registry.npmmirror.com`
203
224
 
204
225
  ### Q: 提示"路径必须是绝对路径"?
205
226
 
206
227
  **A**: `--openclaw-path` 需要使用绝对路径,例如:
228
+
207
229
  - Windows: `C:\OpenClaw` 或 `C:/OpenClaw`
208
230
  - Linux/macOS: `/opt/openclaw`
209
231
 
210
232
  ### Q: 如何查看详细日志?
211
233
 
212
234
  **A**: 使用 `--debug` 参数:
235
+
213
236
  ```bash
214
- npx @workclaw/cli local --debug --phone 18111657826 --user-pass yourpassword
237
+ npx @workclaw/cli local --debug --phone your_phone --user-pass your_password
215
238
  ```
216
239
 
217
240
  ### Q: 如何指定插件版本?
218
241
 
219
242
  **A**: 使用 `--plugin-version` 参数:
243
+
220
244
  ```bash
221
- npx @workclaw/cli local --plugin-version 1.0.100 --phone 18111657826 --user-pass yourpassword
245
+ npx @workclaw/cli local --plugin-version 1.0.100 --phone your_phone --user-pass your_password
222
246
  ```
223
247
 
224
248
  ### Q: local 和 box 命令有什么区别?
225
249
 
226
- **A**:
250
+ **A**:
251
+
227
252
  - **local**: 需要用户登录,适合个人设备,支持多账号
228
253
  - **box**: 无需登录,直接使用 appKey+appSecret,适合专用设备
229
254
 
255
+ ### Q: 什么是自定义环境(custom)?
256
+
257
+ **A**:
258
+
259
+ 自定义环境允许你连接到自己本地或私有部署的后端服务,适合前后端联调测试场景。使用方式:
260
+
261
+ 1. 选择 `custom` 环境
262
+ 2. 输入你的后端 IP 地址(支持 `192.168.1.100:32005` 或 `http://127.0.0.1:32005` 格式)
263
+ 3. 工具会自动适配协议和路径
264
+
265
+ `MODEL_BASE_URL` 始终保持为固定值,不会随自定义环境改变。
266
+
230
267
  ## 🛠 开发
231
268
 
232
269
  ### 项目结构
@@ -267,6 +304,14 @@ pnpm lint:fix
267
304
 
268
305
  ## 📝 更新日志
269
306
 
307
+ ### v1.0.314 (2026-04-27)
308
+
309
+ - ✨ 新增自定义环境(custom)- 支持连接私有部署后端服务
310
+ - 🔧 新增 `--customIp` 参数 - 命令行直接传入自定义后端 IP
311
+ - 🎨 优化交互体验 - 仅选择 custom 环境时才提示输入 IP
312
+ - 📝 更新文档 - 添加自定义环境使用说明和示例
313
+ - 🔒 `MODEL_BASE_URL` 保持固定,不随自定义环境改变
314
+
270
315
  ### v1.0.313 (2026-04-23)
271
316
 
272
317
  - ✨ 新增 `--openclaw-path` 参数 - 支持自定义安装路径
@@ -306,3 +351,4 @@ MIT License
306
351
  - [ora](https://github.com/sindresorhus/ora) - 加载动画
307
352
  - [axios](https://github.com/axios/axios) - HTTP 客户端
308
353
  - [tar](https://github.com/isaacs/node-tar) - tar 文件解压
354
+
@@ -11,6 +11,7 @@ export declare const ERROR_CODES: {
11
11
  readonly CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED";
12
12
  readonly PLUGIN_EXTRACT_FAILED: "PLUGIN_EXTRACT_FAILED";
13
13
  readonly INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH";
14
+ readonly INVALID_ARGUMENT: "INVALID_ARGUMENT";
14
15
  };
15
16
  export type ErrorCode = keyof typeof ERROR_CODES;
16
17
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/box/error/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAUpD,CAAA;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACtB,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/box/error/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;CAWd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAWpD,CAAA;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACtB,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/box/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/box/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/box/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,UAAU,CAAA;AAqDhE,qBAAa,YAAY;IAIX,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,kBAAkB;IAI9C,cAAc,IAAI,IAAI;IAatB,OAAO,CAAC,QAAQ;IAiChB,OAAO,CAAC,aAAa;IAMrB,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;IAOhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA0BhB,eAAe;YA0Bf,iBAAiB;YAoHjB,cAAc;CAiR7B"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/box/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAsDhE,qBAAa,YAAY;IAIX,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,kBAAkB;IAI9C,cAAc,IAAI,IAAI;IAyBtB,OAAO,CAAC,QAAQ;IAkChB,OAAO,CAAC,aAAa;IAMrB,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;IAOhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA0BhB,eAAe;YA0Bf,iBAAiB;YAoHjB,cAAc;CAiR7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/box/src/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAgC1C,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAuHzE"}
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../src/box/src/box.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAgC1C,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoJzE"}
@@ -3,13 +3,15 @@ export interface BoxOptions {
3
3
  env?: string;
4
4
  appKey?: string;
5
5
  appSecret?: string;
6
+ customIp?: string;
7
+ wsUrl?: string;
6
8
  pluginVersion?: string;
7
9
  openclawPath?: string;
8
10
  debug?: boolean;
9
11
  }
10
12
  export interface BoxInstallerConfig {
11
13
  env: Environment;
12
- baseUrl?: string;
14
+ customIp?: string;
13
15
  wsUrl?: string;
14
16
  appKey: string;
15
17
  appSecret: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/box/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,WAAW,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/box/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -8,6 +8,7 @@ import boxen from "boxen";
8
8
  import chalk from "chalk";
9
9
  import inquirer from "inquirer";
10
10
  import semver from "semver";
11
+ import { z as z$1 } from "zod";
11
12
  import fs from "node:fs/promises";
12
13
  import tar from "tar";
13
14
  import ora from "ora";
@@ -34,13 +35,17 @@ function validateOpenclawPath(openclawPath) {
34
35
  }
35
36
  debugLog(`[路径验证] 通过: ${openclawPath}`);
36
37
  }
38
+ const ipv4Schema = z$1.ipv4({
39
+ message: "请输入正确的 IP 地址格式,例如: 192.168.1.100"
40
+ });
37
41
  const ERROR_CODES$1 = {
38
42
  APP_KEY_REQUIRED: "APP_KEY_REQUIRED",
39
43
  APP_SECRET_REQUIRED: "APP_SECRET_REQUIRED",
40
44
  NODE_VERSION_LOW: "NODE_VERSION_LOW",
41
45
  NPM_NOT_FOUND: "NPM_NOT_FOUND",
42
46
  NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED",
43
- INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH"
47
+ INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH",
48
+ INVALID_ARGUMENT: "INVALID_ARGUMENT"
44
49
  };
45
50
  let AppError$1 = class AppError extends Error {
46
51
  constructor(code, message) {
@@ -89,8 +94,27 @@ const TEST_CONFIG = {
89
94
  TIMEOUT: 1e4
90
95
  }
91
96
  };
92
- function getConfig(env) {
93
- return env === "test" ? TEST_CONFIG : CONFIG;
97
+ function getConfig(env, customIp) {
98
+ if (env === "test") {
99
+ return TEST_CONFIG;
100
+ }
101
+ if (env === "custom") {
102
+ if (!customIp) {
103
+ throw new Error("自定义环境必须提供 customIp");
104
+ }
105
+ const replaceIp = (url) => url.replace("172.168.80.30", customIp);
106
+ return {
107
+ ...TEST_CONFIG,
108
+ DEFAULT_BASE_URL: replaceIp(TEST_CONFIG.DEFAULT_BASE_URL),
109
+ DEFAULT_WS_URL: replaceIp(TEST_CONFIG.DEFAULT_WS_URL),
110
+ API: {
111
+ ...TEST_CONFIG.API,
112
+ TUZAI_BASE_URL: replaceIp(TEST_CONFIG.API.TUZAI_BASE_URL),
113
+ BASE_URL: replaceIp(TEST_CONFIG.API.BASE_URL)
114
+ }
115
+ };
116
+ }
117
+ return CONFIG;
94
118
  }
95
119
  function getHomeDir$1() {
96
120
  return process$1.env.HOME || process$1.env.USERPROFILE || "";
@@ -135,10 +159,22 @@ class BoxInstaller {
135
159
  if (!this.config.appSecret) {
136
160
  throw new AppError$1(ERROR_CODES$1.APP_SECRET_REQUIRED, "AppSecret 不能为空,请使用 --app-secret 参数");
137
161
  }
162
+ if (this.config.env === "custom") {
163
+ debugLog("[验证配置] 检查自定义环境 IP...");
164
+ if (!this.config.customIp) {
165
+ throw new AppError$1(ERROR_CODES$1.INVALID_ARGUMENT, "自定义环境必须提供 --customIp 参数");
166
+ }
167
+ const result = ipv4Schema.safeParse(this.config.customIp);
168
+ if (!result.success) {
169
+ throw new AppError$1(ERROR_CODES$1.INVALID_ARGUMENT, result.error.issues[0].message);
170
+ }
171
+ debugLog("[验证配置] 自定义环境 IP 验证通过");
172
+ }
138
173
  debugLog("[验证配置] 配置检查通过");
139
174
  }
140
175
  getPaths() {
141
- const config = getConfig(this.config.env);
176
+ const env = this.config.env || "test";
177
+ const config = getConfig(env, this.config.customIp);
142
178
  let baseDir;
143
179
  if (this.config.openclawPath) {
144
180
  debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
@@ -473,7 +509,7 @@ class BoxInstaller {
473
509
  // 应用密钥
474
510
  appSecret: this.config.appSecret,
475
511
  // API 基础 URL
476
- baseUrl: this.config.baseUrl || config.DEFAULT_BASE_URL,
512
+ baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
477
513
  // WebSocket URL
478
514
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
479
515
  // 允许不安全的 TLS 连接
@@ -594,13 +630,14 @@ function checkEnv$1() {
594
630
  async function createBoxCommand(options) {
595
631
  setDebug(!!options.debug);
596
632
  debugLog("[盒子安装] 开始处理...");
597
- debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, debug=${options.debug}`);
633
+ debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, customIp=${options.customIp}, debug=${options.debug}`);
598
634
  checkEnv$1();
599
635
  debugLog("[盒子安装] 环境检查通过");
600
636
  try {
601
637
  let env = options.env;
602
638
  let appKey = options.appKey;
603
639
  let appSecret = options.appSecret;
640
+ let customIp = options.customIp;
604
641
  const questions = [];
605
642
  if (!env) {
606
643
  debugLog("[盒子安装] 需要选择环境");
@@ -611,7 +648,8 @@ async function createBoxCommand(options) {
611
648
  default: "test",
612
649
  choices: [
613
650
  { name: `${chalk.green("测试环境")} ${chalk.dim("(test)")}`, value: "test" },
614
- { name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" }
651
+ { name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" },
652
+ { name: `${chalk.yellow("自定义环境")} ${chalk.dim("(custom) - 需要输入后端 IP")}`, value: "custom" }
615
653
  ]
616
654
  });
617
655
  } else {
@@ -657,12 +695,37 @@ async function createBoxCommand(options) {
657
695
  appKey = appKey || answers.appKey;
658
696
  appSecret = appSecret || answers.appSecret;
659
697
  }
660
- debugLog(`[盒子安装] 最终参数: env=${env}, openclawPath=${options.openclawPath}`);
698
+ if (env === "custom" && !customIp) {
699
+ debugLog("[盒子安装] 自定义环境需要输入后端 IP");
700
+ const answer = await inquirer.prompt([{
701
+ type: "input",
702
+ name: "customIp",
703
+ message: chalk.cyan("请输入后端 IP:"),
704
+ default: "127.0.0.1",
705
+ validate: (value) => {
706
+ if (!value || value.trim() === "") {
707
+ return chalk.red("后端 IP 不能为空");
708
+ }
709
+ const result = ipv4Schema.safeParse(value);
710
+ if (!result.success) {
711
+ return chalk.yellow(result.error.issues[0].message);
712
+ }
713
+ return true;
714
+ }
715
+ }]);
716
+ customIp = answer.customIp;
717
+ debugLog("[盒子安装] 获取自定义 customIp");
718
+ } else if (env === "custom" && customIp) {
719
+ debugLog(`[盒子安装] 使用命令行参数: customIp=${customIp}`);
720
+ }
721
+ debugLog(`[盒子安装] 最终参数: env=${env}, customIp=${customIp}, openclawPath=${options.openclawPath}`);
661
722
  debugLog("[盒子安装] 创建 BoxInstaller 实例...");
662
723
  const installer = new BoxInstaller({
663
724
  appKey,
664
725
  appSecret,
665
726
  env,
727
+ customIp,
728
+ wsUrl: options.wsUrl,
666
729
  pluginVersion: options.pluginVersion,
667
730
  openclawPath: options.openclawPath
668
731
  });
@@ -699,7 +762,7 @@ async function createBoxCommand(options) {
699
762
  }
700
763
  }
701
764
  function registerCommands$1(program2) {
702
- program2.command("box").description("盒子设备安装(无需登录)").option("-e, --env <env>", "环境 (test/prod)").option("--app-key <appKey>", "App Key").option("--app-secret <appSecret>", "App Secret").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").action(createBoxCommand);
765
+ program2.command("box").description("盒子设备安装(无需登录)").option("-e, --env <env>", "环境 (test/prod/custom)").option("--app-key <appKey>", "App Key").option("--app-secret <appSecret>", "App Secret").option("--base-url <url>", "自定义后端基础 URL(仅 custom 环境生效)").option("--ws-url <url>", "自定义 WebSocket URL(仅 custom 环境生效,默认自动从 base-url 转换)").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").action(createBoxCommand);
703
766
  }
704
767
  const ERROR_CODES = {
705
768
  PHONE_REQUIRED: "PHONE_REQUIRED",
@@ -713,7 +776,8 @@ const ERROR_CODES = {
713
776
  CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED",
714
777
  HTTP_ERROR: "HTTP_ERROR",
715
778
  NETWORK_ERROR: "NETWORK_ERROR",
716
- INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH"
779
+ INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH",
780
+ INVALID_ARGUMENT: "INVALID_ARGUMENT"
717
781
  };
718
782
  class AppError2 extends Error {
719
783
  constructor(code, message) {
@@ -4778,6 +4842,17 @@ class LocalInstaller {
4778
4842
  if (!this.config.userPass) {
4779
4843
  throw new AppError2(ERROR_CODES.USER_PASS_REQUIRED, "用户密码不能为空,请使用 --user-pass 参数");
4780
4844
  }
4845
+ if (this.config.env === "custom") {
4846
+ debugLog("[验证配置] 检查自定义环境 IP...");
4847
+ if (!this.config.customIp) {
4848
+ throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, "自定义环境必须提供 --customIp 参数");
4849
+ }
4850
+ const result = ipv4Schema.safeParse(this.config.customIp);
4851
+ if (!result.success) {
4852
+ throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, result.error.issues[0].message);
4853
+ }
4854
+ debugLog("[验证配置] 自定义环境 IP 验证通过");
4855
+ }
4781
4856
  debugLog("[验证配置] 配置验证通过");
4782
4857
  }
4783
4858
  async install() {
@@ -4785,7 +4860,7 @@ class LocalInstaller {
4785
4860
  debugLog("[安装开始]");
4786
4861
  this.validateConfig();
4787
4862
  const env = this.config.env || "test";
4788
- const config = getConfig(env);
4863
+ const config = getConfig(env, this.config.customIp);
4789
4864
  let baseDir;
4790
4865
  if (this.config.openclawPath) {
4791
4866
  debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
@@ -4813,8 +4888,8 @@ class LocalInstaller {
4813
4888
  debugLog(`[路径配置] target=${paths.target}`);
4814
4889
  debugLog(`[路径配置] config=${paths.config}`);
4815
4890
  debugLog(`[路径配置] workspace=${paths.workspace}`);
4816
- const token = await this.doLogin(env);
4817
- const boundConfig = await this.doFetchBoundConfig(env, token);
4891
+ const token = await this.doLogin();
4892
+ const boundConfig = await this.doFetchBoundConfig(token);
4818
4893
  await this.doCleanOldFiles(paths.target);
4819
4894
  await this.doDownloadFromNpm(paths);
4820
4895
  await this.doUpdateConfig(paths, boundConfig, env);
@@ -4833,7 +4908,8 @@ class LocalInstaller {
4833
4908
  }
4834
4909
  return PLUGIN_PACKAGE_NAME;
4835
4910
  }
4836
- async doLogin(env) {
4911
+ async doLogin() {
4912
+ const env = this.config.env || "test";
4837
4913
  this.spinner.prefixText = this.prefixText;
4838
4914
  this.spinner.text = chalk.cyan("正在验证账号...");
4839
4915
  debugLog(`[用户登录] 手机号: ${this.config.phone}`);
@@ -4850,7 +4926,8 @@ class LocalInstaller {
4850
4926
  debugLog("[用户登录] 登录成功");
4851
4927
  return token;
4852
4928
  }
4853
- async doFetchBoundConfig(env, token) {
4929
+ async doFetchBoundConfig(token) {
4930
+ const env = this.config.env || "test";
4854
4931
  this.spinner.prefixText = this.prefixText;
4855
4932
  this.spinner.text = chalk.cyan("正在获取绑定信息...");
4856
4933
  debugLog("[获取配置] 调用绑定配置接口...");
@@ -4988,7 +5065,7 @@ class LocalInstaller {
4988
5065
  } catch {
4989
5066
  debugLog("[更新配置] 无原有配置");
4990
5067
  }
4991
- const config = getConfig(env);
5068
+ const config = getConfig(env, this.config.customIp);
4992
5069
  const newConfig = {
4993
5070
  // diagnostics: 诊断配置
4994
5071
  diagnostics: {
@@ -5084,7 +5161,7 @@ class LocalInstaller {
5084
5161
  connectionMode: "websocket",
5085
5162
  appKey: boundConfig.appKey,
5086
5163
  appSecret: boundConfig.appSecret,
5087
- baseUrl: this.config.baseUrl || config.DEFAULT_BASE_URL,
5164
+ baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
5088
5165
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
5089
5166
  allowInsecureTls: true,
5090
5167
  allowRawJsonPayload: true,
@@ -5180,13 +5257,14 @@ function checkEnv() {
5180
5257
  async function createLocalCommand(options) {
5181
5258
  setDebug(!!options.debug);
5182
5259
  debugLog("[初始化] 开始处理...");
5183
- debugLog(`[初始化] 参数: env=${options.env}, phone=${options.phone}, debug=${options.debug}`);
5260
+ debugLog(`[初始化] 参数: env=${options.env}, phone=${options.phone}, customIp=${options.customIp}, debug=${options.debug}`);
5184
5261
  checkEnv();
5185
5262
  debugLog("[初始化] 环境检查通过");
5186
5263
  try {
5187
5264
  let env = options.env;
5188
5265
  let phone = options.phone;
5189
5266
  let userPass = options.userPass;
5267
+ let customIp = options.customIp;
5190
5268
  const questions = [];
5191
5269
  if (!env) {
5192
5270
  debugLog("[初始化] 需要选择环境");
@@ -5197,7 +5275,8 @@ async function createLocalCommand(options) {
5197
5275
  default: "test",
5198
5276
  choices: [
5199
5277
  { name: `${chalk.green("测试环境")} ${chalk.dim("(test)")}`, value: "test" },
5200
- { name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" }
5278
+ { name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" },
5279
+ { name: `${chalk.yellow("自定义环境")} ${chalk.dim("(custom) - 需要输入后端 IP")}`, value: "custom" }
5201
5280
  ]
5202
5281
  });
5203
5282
  } else {
@@ -5246,12 +5325,37 @@ async function createLocalCommand(options) {
5246
5325
  phone = phone || answers.phone;
5247
5326
  userPass = userPass || answers.userPass;
5248
5327
  }
5249
- debugLog(`[初始化] 最终参数: env=${env}, phone=${phone}, pluginVersion=${options.pluginVersion}, openclawPath=${options.openclawPath}`);
5328
+ if (env === "custom" && !customIp) {
5329
+ debugLog("[初始化] 自定义环境需要输入后端 IP");
5330
+ const answer = await inquirer.prompt([{
5331
+ type: "input",
5332
+ name: "customIp",
5333
+ message: chalk.cyan("请输入后端 IP:"),
5334
+ default: "127.0.0.1",
5335
+ validate: (value) => {
5336
+ if (!value || value.trim() === "") {
5337
+ return chalk.red("后端 IP 不能为空");
5338
+ }
5339
+ const result = ipv4Schema.safeParse(value);
5340
+ if (!result.success) {
5341
+ return chalk.yellow(result.error.issues[0].message);
5342
+ }
5343
+ return true;
5344
+ }
5345
+ }]);
5346
+ customIp = answer.customIp;
5347
+ debugLog("[初始化] 获取自定义 customIp");
5348
+ } else if (env === "custom" && customIp) {
5349
+ debugLog(`[初始化] 使用命令行参数: customIp=${customIp}`);
5350
+ }
5351
+ debugLog(`[初始化] 最终参数: env=${env}, phone=${phone}, customIp=${customIp}, pluginVersion=${options.pluginVersion}, openclawPath=${options.openclawPath}`);
5250
5352
  debugLog("[初始化] 创建 LocalInstaller 实例...");
5251
5353
  const installer = new LocalInstaller({
5252
5354
  phone,
5253
5355
  userPass,
5254
5356
  env,
5357
+ customIp,
5358
+ wsUrl: options.wsUrl,
5255
5359
  pluginVersion: options.pluginVersion,
5256
5360
  openclawPath: options.openclawPath
5257
5361
  });
@@ -5288,7 +5392,7 @@ async function createLocalCommand(options) {
5288
5392
  }
5289
5393
  }
5290
5394
  function registerCommands(program2) {
5291
- program2.command("local").description("本地账户安装(需要登录)").option("-e, --env <env>", "环境 (test/prod)").option("--phone <phone>", "手机号码").option("--user-pass <userPass>", "用户密码").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").action(createLocalCommand);
5395
+ program2.command("local").description("本地账户安装(需要登录)").option("-e, --env <env>", "环境 (test/prod/custom)").option("--phone <phone>", "手机号码").option("--user-pass <userPass>", "用户密码").option("--base-url <url>", "自定义后端基础 URL(仅 custom 环境生效)").option("--ws-url <url>", "自定义 WebSocket URL(仅 custom 环境生效,默认自动从 base-url 转换)").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").action(createLocalCommand);
5292
5396
  }
5293
5397
  const __filename$1 = fileURLToPath(import.meta.url);
5294
5398
  const __dirname$1 = dirname(__filename$1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-CkTwizLH.js").then((cli) => {
2
+ import("./index-B5TYzGeQ.js").then((cli) => {
3
3
  cli.default();
4
4
  });
@@ -14,6 +14,7 @@ export declare const ERROR_CODES: {
14
14
  readonly HTTP_ERROR: "HTTP_ERROR";
15
15
  readonly NETWORK_ERROR: "NETWORK_ERROR";
16
16
  readonly INVALID_OPENCLAW_PATH: "INVALID_OPENCLAW_PATH";
17
+ readonly INVALID_ARGUMENT: "INVALID_ARGUMENT";
17
18
  };
18
19
  export type ErrorCode = keyof typeof ERROR_CODES;
19
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/error/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAad,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAapD,CAAA;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACtB,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/error/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAcd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAcpD,CAAA;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IAExB,IAAI,EAAE,SAAS;gBAAf,IAAI,EAAE,SAAS,EACtB,OAAO,EAAE,MAAM;CAKlB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/local/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA6B,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAuD/E,qBAAa,cAAc;IAIb,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,oBAAoB;IAIhD,cAAc,IAAI,IAAI;IAYhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD9B,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;YAOR,OAAO;YAoBP,kBAAkB;YAalB,eAAe;YAmBf,iBAAiB;YAmHjB,cAAc;CA+M7B"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/local/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA6B,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAuD/E,qBAAa,cAAc;IAIb,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,oBAAoB;IAIhD,cAAc,IAAI,IAAI;IAyBhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD9B,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;YAOR,OAAO;YAqBP,kBAAkB;YAclB,eAAe;YAmBf,iBAAiB;YAmHjB,cAAc;CA+M7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/local/src/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAgC5C,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuH7E"}
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/local/src/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAgC5C,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoJ7E"}
@@ -3,13 +3,15 @@ export interface LocalOptions {
3
3
  env?: string;
4
4
  phone?: string;
5
5
  userPass?: string;
6
+ customIp?: string;
7
+ wsUrl?: string;
6
8
  pluginVersion?: string;
7
9
  openclawPath?: string;
8
10
  debug?: boolean;
9
11
  }
10
12
  export interface LocalInstallerConfig {
11
13
  env?: Environment;
12
- baseUrl?: string;
14
+ customIp?: string;
13
15
  wsUrl?: string;
14
16
  phone: string;
15
17
  userPass: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,WAAW,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 环境类型
3
3
  */
4
- export type Environment = 'test' | 'prod';
4
+ export type Environment = 'test' | 'prod' | 'custom';
5
5
  /**
6
6
  * 配置接口
7
7
  */
@@ -44,6 +44,8 @@ export declare const CONFIG: ConfigInterface;
44
44
  export declare const TEST_CONFIG: ConfigInterface;
45
45
  /**
46
46
  * 根据环境获取配置
47
+ * @param env - 环境
48
+ * @param customIp - 自定义环境的 IP 地址,仅当 env 为 custom 时使用
47
49
  */
48
- export declare function getConfig(env: Environment): ConfigInterface;
50
+ export declare function getConfig(env: Environment, customIp?: string): ConfigInterface;
49
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAA;AAEzC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,oBAAoB;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW;IACX,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,WAAW;IACX,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa;IACb,GAAG,EAAE;QACH,cAAc,EAAE,MAAM,CAAA;QACtB,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,eAmBpB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,eAmBzB,CAAA;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,eAAe,CAE3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,eAAe;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,oBAAoB;IACpB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW;IACX,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAA;QAChB,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,WAAW;IACX,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,aAAa;IACb,GAAG,EAAE;QACH,cAAc,EAAE,MAAM,CAAA;QACtB,QAAQ,EAAE,MAAM,CAAA;QAChB,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,eAmBpB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,eAmBzB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAuB9E"}
@@ -2,4 +2,5 @@ export { debugLog, isDebugMode, setDebug } from './debug';
2
2
  export { createLogger, logger } from './logger';
3
3
  export type { Logger } from './logger';
4
4
  export { validateOpenclawPath } from './path';
5
+ export { ipv4Schema } from './validate';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,6 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * IPv4 地址 schema
4
+ */
5
+ export declare const ipv4Schema: z.ZodIPv4;
6
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;GAEG;AACH,eAAO,MAAM,UAAU,WAErB,CAAA"}
@@ -7,6 +7,8 @@ export declare const ERROR_CODES: {
7
7
  readonly MISSING_AGENT_ID: 2003;
8
8
  readonly MISSING_APP_KEY: 2004;
9
9
  readonly MISSING_APP_SECRET: 2005;
10
+ readonly INVALID_ARGUMENT: 2006;
11
+ readonly INVALID_OPENCLAW_PATH: 2007;
10
12
  readonly LOGIN_FAILED: 3001;
11
13
  readonly GET_BOUND_CONFIG_FAILED: 3002;
12
14
  readonly FETCH_CONFIG_FAILED: 3003;
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;CAyBd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAEpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;gBAEL,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAO/D,MAAM,IAAI,YAAY;IAQtB,QAAQ,IAAI,MAAM;CAGnB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAEzF"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;CA2Bd,CAAA;AAEV,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,OAAO,WAAW,CAAC,CAAA;AAEpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;gBAEL,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;IAO/D,MAAM,IAAI,YAAY;IAQtB,QAAQ,IAAI,MAAM;CAGnB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUlD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAEzF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workclaw/cli",
3
3
  "type": "module",
4
- "version": "1.0.315",
4
+ "version": "1.0.317",
5
5
  "description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
6
6
  "license": "MIT",
7
7
  "keywords": [
@@ -36,6 +36,7 @@
36
36
  "jsencrypt": "^3.5.4",
37
37
  "ora": "^8.2.0",
38
38
  "semver": "^7.7.1",
39
- "tar": "^6.2.1"
39
+ "tar": "^6.2.1",
40
+ "zod": "^4.3.6"
40
41
  }
41
42
  }