@workclaw/cli 1.0.313 → 1.0.316
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 +271 -56
- package/dist/box/index.d.ts.map +1 -1
- package/dist/box/installer/installer.d.ts +0 -1
- package/dist/box/installer/installer.d.ts.map +1 -1
- package/dist/box/src/box.d.ts.map +1 -1
- package/dist/box/types/index.d.ts +3 -1
- package/dist/box/types/index.d.ts.map +1 -1
- package/dist/{index-BZh3SXHn.js → index-ChF0VChB.js} +111 -59
- package/dist/index.js +1 -1
- package/dist/local/index.d.ts.map +1 -1
- package/dist/local/installer/installer.d.ts +0 -1
- package/dist/local/installer/installer.d.ts.map +1 -1
- package/dist/local/src/local.d.ts.map +1 -1
- package/dist/local/types/index.d.ts +3 -1
- package/dist/local/types/index.d.ts.map +1 -1
- package/dist/shared/config/index.d.ts +4 -2
- package/dist/shared/config/index.d.ts.map +1 -1
- package/dist/shared/utils/index.d.ts +1 -0
- package/dist/shared/utils/index.d.ts.map +1 -1
- package/dist/shared/utils/path.d.ts +7 -0
- package/dist/shared/utils/path.d.ts.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,80 +2,269 @@
|
|
|
2
2
|
|
|
3
3
|
WorkClaw CLI 是一个用于初始化和配置 WorkClaw 插件的命令行工具。
|
|
4
4
|
|
|
5
|
-
## 特性
|
|
5
|
+
## ✨ 特性
|
|
6
6
|
|
|
7
7
|
- 🚀 **快速初始化** - 一键安装 WorkClaw 插件
|
|
8
8
|
- 🔐 **安全认证** - RSA 加密密码,保护用户隐私
|
|
9
9
|
- 🌐 **多平台支持** - Windows, macOS, Linux
|
|
10
10
|
- 📊 **详细日志** - 完整的请求/响应日志
|
|
11
11
|
- 🎨 **友好界面** - 彩色输出和加载动画
|
|
12
|
+
- 📦 **npm 安装** - 支持自定义安装路径
|
|
13
|
+
- 🔧 **灵活配置** - 支持自定义 OpenClaw 安装目录
|
|
12
14
|
|
|
13
|
-
##
|
|
15
|
+
## 📋 前置要求
|
|
16
|
+
|
|
17
|
+
- **Node.js**: >= 20.0.0
|
|
18
|
+
- **包管理器**: npm / pnpm / yarn(推荐 pnpm)
|
|
19
|
+
|
|
20
|
+
## 🚀 快速开始
|
|
21
|
+
|
|
22
|
+
### 使用 npx(推荐,无需安装)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# 本地账户安装
|
|
26
|
+
npx @workclaw/cli local
|
|
27
|
+
|
|
28
|
+
# 盒子设备安装
|
|
29
|
+
npx @workclaw/cli box
|
|
30
|
+
|
|
31
|
+
# 查看帮助
|
|
32
|
+
npx @workclaw/cli --help
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 全局安装后使用
|
|
14
36
|
|
|
15
37
|
```bash
|
|
38
|
+
# 全局安装
|
|
16
39
|
npm install -g @workclaw/cli
|
|
40
|
+
|
|
41
|
+
# 本地账户安装
|
|
42
|
+
workclaw local
|
|
43
|
+
|
|
44
|
+
# 盒子设备安装
|
|
45
|
+
workclaw box
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 📖 两种安装模式
|
|
49
|
+
|
|
50
|
+
### local 命令 - 本地账户安装
|
|
51
|
+
|
|
52
|
+
**适用场景**:个人电脑或需要用户登录的设备
|
|
53
|
+
|
|
54
|
+
**特点**:
|
|
55
|
+
|
|
56
|
+
- ✅ 需要用户登录(手机号 + 密码)
|
|
57
|
+
- ✅ 自动获取 appKey 和 appSecret
|
|
58
|
+
- ✅ 支持多账号管理
|
|
59
|
+
- ✅ 自动创建和管理配置
|
|
60
|
+
|
|
61
|
+
**安装流程**:
|
|
62
|
+
|
|
63
|
+
1. 用户登录(RSA 加密密码)
|
|
64
|
+
2. 获取绑定配置
|
|
65
|
+
3. 通过手机号补全配置
|
|
66
|
+
4. 下载并安装插件
|
|
67
|
+
5. 更新配置文件
|
|
68
|
+
|
|
69
|
+
### box 命令 - 盒子设备安装
|
|
70
|
+
|
|
71
|
+
**适用场景**:专用设备或无需用户登录的环境
|
|
72
|
+
|
|
73
|
+
**特点**:
|
|
74
|
+
|
|
75
|
+
- ✅ 无需登录(直接使用 appKey + appSecret)
|
|
76
|
+
- ✅ 适合批量部署
|
|
77
|
+
- ✅ 配置文件默认设置为开放策略
|
|
78
|
+
- ✅ 更快的安装速度
|
|
79
|
+
|
|
80
|
+
**安装流程**:
|
|
81
|
+
|
|
82
|
+
1. 清理旧版本插件
|
|
83
|
+
2. 下载并安装插件
|
|
84
|
+
3. 更新配置文件(`dmPolicy: "open"`)
|
|
85
|
+
|
|
86
|
+
## 📖 使用文档
|
|
87
|
+
|
|
88
|
+
### 命令
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 本地账户安装(需要登录)
|
|
92
|
+
npx @workclaw/cli local [options]
|
|
93
|
+
|
|
94
|
+
# 盒子设备安装(无需登录)
|
|
95
|
+
npx @workclaw/cli box [options]
|
|
96
|
+
|
|
97
|
+
# 查看帮助
|
|
98
|
+
npx @workclaw/cli --help
|
|
17
99
|
```
|
|
18
100
|
|
|
19
|
-
|
|
101
|
+
### local 命令参数
|
|
102
|
+
|
|
103
|
+
| 参数 | 说明 |
|
|
104
|
+
| ---------------- | ----------------------------------- |
|
|
105
|
+
| --phone | 手机号码(登录账号),未填写时会交互式提示输入 |
|
|
106
|
+
| --user-pass | 用户密码,未填写时会交互式提示输入 |
|
|
107
|
+
| --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
|
|
108
|
+
| --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
|
|
109
|
+
| --plugin-version | 插件版本号(默认安装最新版) |
|
|
110
|
+
| --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
|
|
111
|
+
| --debug | 开启调试日志 |
|
|
112
|
+
|
|
113
|
+
### box 命令参数
|
|
114
|
+
|
|
115
|
+
| 参数 | 说明 |
|
|
116
|
+
| ---------------- | ----------------------------------- |
|
|
117
|
+
| --app-key | App Key,未填写时会交互式提示输入 |
|
|
118
|
+
| --app-secret | App Secret,未填写时会交互式提示输入 |
|
|
119
|
+
| --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
|
|
120
|
+
| --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
|
|
121
|
+
| --plugin-version | 插件版本号(默认安装最新版) |
|
|
122
|
+
| --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
|
|
123
|
+
| --debug | 开启调试日志 |
|
|
124
|
+
|
|
125
|
+
## 💡 使用示例
|
|
20
126
|
|
|
21
127
|
### 本地账户安装
|
|
22
128
|
|
|
23
129
|
```bash
|
|
24
|
-
|
|
130
|
+
# 交互式安装(会提示输入手机号和密码)
|
|
131
|
+
npx @workclaw/cli local
|
|
132
|
+
|
|
133
|
+
# 指定手机号和密码
|
|
134
|
+
npx @workclaw/cli local --phone your_phone --user-pass your_password
|
|
135
|
+
|
|
136
|
+
# 指定正式环境
|
|
137
|
+
npx @workclaw/cli local --env prod --phone your_phone --user-pass your_password
|
|
138
|
+
|
|
139
|
+
# 自定义安装路径
|
|
140
|
+
npx @workclaw/cli local --openclaw-path "C:\CustomPath\OpenClaw" --phone your_phone --user-pass your_password
|
|
141
|
+
|
|
142
|
+
# 开启调试模式
|
|
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
|
|
25
153
|
```
|
|
26
154
|
|
|
27
155
|
### 盒子设备安装
|
|
28
156
|
|
|
29
157
|
```bash
|
|
30
|
-
|
|
158
|
+
# 交互式安装(会提示输入 AppKey 和 AppSecret)
|
|
159
|
+
npx @workclaw/cli box
|
|
160
|
+
|
|
161
|
+
# 指定参数
|
|
162
|
+
npx @workclaw/cli box --app-key your-app-key --app-secret your-app-secret
|
|
163
|
+
|
|
164
|
+
# 指定正式环境
|
|
165
|
+
npx @workclaw/cli box --env prod --app-key your-app-key --app-secret your-app-secret
|
|
166
|
+
|
|
167
|
+
# 自定义安装路径
|
|
168
|
+
npx @workclaw/cli box --openclaw-path "/custom/path" --app-key your-app-key --app-secret your-app-secret
|
|
169
|
+
|
|
170
|
+
# 开启调试模式
|
|
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
|
|
31
178
|
```
|
|
32
179
|
|
|
33
|
-
##
|
|
180
|
+
## 🔧 技术实现
|
|
34
181
|
|
|
35
|
-
###
|
|
182
|
+
### 安装机制
|
|
183
|
+
|
|
184
|
+
1. **插件下载**
|
|
185
|
+
- 使用 `npm pack` 从 npm 镜像源下载插件包
|
|
186
|
+
- 默认使用腾讯云 npm 镜像:`https://mirrors.tencent.com/npm/`
|
|
187
|
+
- 支持重试机制(最多 3 次)
|
|
188
|
+
2. **文件解压**
|
|
189
|
+
- 使用 `tar.extract()` 解压到目标目录
|
|
190
|
+
- 自动创建必要的目录结构
|
|
191
|
+
3. **依赖安装**
|
|
192
|
+
- 使用 `npm install --omit=dev` 安装生产依赖
|
|
193
|
+
- 自动跳过开发依赖,减小安装体积
|
|
194
|
+
|
|
195
|
+
### 路径结构
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
~/.openclaw/ # 或自定义路径
|
|
199
|
+
├── openclaw.json # 主配置文件
|
|
200
|
+
├── extensions/
|
|
201
|
+
│ └── openclaw-workclaw/ # 插件目录
|
|
202
|
+
│ ├── package.json
|
|
203
|
+
│ ├── dist/
|
|
204
|
+
│ └── ...
|
|
205
|
+
├── workspace/ # 工作空间
|
|
206
|
+
└── .temp/ # 临时文件
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 路径验证
|
|
210
|
+
|
|
211
|
+
工具会自动验证用户输入的 `--openclaw-path` 参数:
|
|
212
|
+
|
|
213
|
+
- ✅ 必须是绝对路径
|
|
214
|
+
- ✅ 不能包含非法字符:`< > : " | ? *`
|
|
215
|
+
|
|
216
|
+
## ❓ 常见问题
|
|
217
|
+
|
|
218
|
+
### Q: 安装失败,提示"网络错误"?
|
|
219
|
+
|
|
220
|
+
**A**: 检查网络连接,可以尝试:
|
|
221
|
+
|
|
222
|
+
- 使用代理或 VPN
|
|
223
|
+
- 配置 npm 镜像源:`npm config set registry https://registry.npmmirror.com`
|
|
224
|
+
|
|
225
|
+
### Q: 提示"路径必须是绝对路径"?
|
|
226
|
+
|
|
227
|
+
**A**: `--openclaw-path` 需要使用绝对路径,例如:
|
|
228
|
+
|
|
229
|
+
- Windows: `C:\OpenClaw` 或 `C:/OpenClaw`
|
|
230
|
+
- Linux/macOS: `/opt/openclaw`
|
|
231
|
+
|
|
232
|
+
### Q: 如何查看详细日志?
|
|
233
|
+
|
|
234
|
+
**A**: 使用 `--debug` 参数:
|
|
36
235
|
|
|
37
236
|
```bash
|
|
38
|
-
|
|
39
|
-
|
|
237
|
+
npx @workclaw/cli local --debug --phone your_phone --user-pass your_password
|
|
238
|
+
```
|
|
40
239
|
|
|
41
|
-
|
|
42
|
-
|
|
240
|
+
### Q: 如何指定插件版本?
|
|
241
|
+
|
|
242
|
+
**A**: 使用 `--plugin-version` 参数:
|
|
43
243
|
|
|
44
|
-
|
|
45
|
-
workclaw --
|
|
244
|
+
```bash
|
|
245
|
+
npx @workclaw/cli local --plugin-version 1.0.100 --phone your_phone --user-pass your_password
|
|
46
246
|
```
|
|
47
247
|
|
|
48
|
-
### local
|
|
248
|
+
### Q: local 和 box 命令有什么区别?
|
|
49
249
|
|
|
50
|
-
|
|
51
|
-
| --------------- | -- | -------------- |
|
|
52
|
-
| --phone | ❌ | 手机号码 |
|
|
53
|
-
| --user-pass | ❌ | 用户密码 |
|
|
54
|
-
| --scenario | ❌ | 安装场景 |
|
|
55
|
-
| --env | ❌ | 环境 (test/prod) |
|
|
56
|
-
| --plugin-version | ❌ | 插件版本号(默认最新版) |
|
|
57
|
-
| --debug | ❌ | 开启调试日志 |
|
|
250
|
+
**A**:
|
|
58
251
|
|
|
59
|
-
|
|
252
|
+
- **local**: 需要用户登录,适合个人设备,支持多账号
|
|
253
|
+
- **box**: 无需登录,直接使用 appKey+appSecret,适合专用设备
|
|
60
254
|
|
|
61
|
-
|
|
62
|
-
| --------------- | -- | -------------- |
|
|
63
|
-
| --app-key | ❌ | App Key |
|
|
64
|
-
| --app-secret | ❌ | App Secret |
|
|
65
|
-
| --env | ❌ | 环境 (test/prod) |
|
|
66
|
-
| --plugin-version | ❌ | 插件版本号(默认最新版) |
|
|
67
|
-
| --debug | ❌ | 开启调试日志 |
|
|
255
|
+
### Q: 什么是自定义环境(custom)?
|
|
68
256
|
|
|
69
|
-
|
|
257
|
+
**A**:
|
|
70
258
|
|
|
71
|
-
|
|
72
|
-
| ------------- | -------------- |
|
|
73
|
-
| windows-local | Windows 本地安装 |
|
|
74
|
-
| mac-local | macOS 本地安装 |
|
|
75
|
-
| linux-local | Linux 本地安装 |
|
|
76
|
-
| linux-box | Linux Box 环境安装 |
|
|
259
|
+
自定义环境允许你连接到自己本地或私有部署的后端服务,适合前后端联调测试场景。使用方式:
|
|
77
260
|
|
|
78
|
-
|
|
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
|
+
|
|
267
|
+
## 🛠 开发
|
|
79
268
|
|
|
80
269
|
### 项目结构
|
|
81
270
|
|
|
@@ -83,12 +272,16 @@ workclaw --help
|
|
|
83
272
|
packages/cli/
|
|
84
273
|
├── src/
|
|
85
274
|
│ ├── bin/ # CLI 入口
|
|
86
|
-
│ ├──
|
|
87
|
-
│ ├──
|
|
88
|
-
│ ├──
|
|
89
|
-
│ ├──
|
|
275
|
+
│ ├── local/ # 本地账户安装模块
|
|
276
|
+
│ │ ├── installer/ # 安装器
|
|
277
|
+
│ │ ├── apis/ # API 调用
|
|
278
|
+
│ │ ├── types/ # 类型定义
|
|
279
|
+
│ │ ├── error/ # 错误处理
|
|
280
|
+
│ │ └── utils/ # 工具函数
|
|
281
|
+
│ ├── box/ # 盒子设备安装模块
|
|
90
282
|
│ ├── shared/ # 共享模块
|
|
91
283
|
│ └── utils/ # 工具函数
|
|
284
|
+
├── package.json
|
|
92
285
|
├── vite.config.ts
|
|
93
286
|
└── README.md
|
|
94
287
|
```
|
|
@@ -96,25 +289,46 @@ packages/cli/
|
|
|
96
289
|
### 构建
|
|
97
290
|
|
|
98
291
|
```bash
|
|
99
|
-
|
|
292
|
+
# 安装依赖
|
|
293
|
+
pnpm install
|
|
294
|
+
|
|
295
|
+
# 构建项目
|
|
296
|
+
pnpm build
|
|
297
|
+
|
|
298
|
+
# 代码检查
|
|
299
|
+
pnpm lint
|
|
300
|
+
|
|
301
|
+
# 自动修复
|
|
302
|
+
pnpm lint:fix
|
|
100
303
|
```
|
|
101
304
|
|
|
102
|
-
## 更新日志
|
|
305
|
+
## 📝 更新日志
|
|
306
|
+
|
|
307
|
+
### v1.0.314 (2026-04-27)
|
|
103
308
|
|
|
104
|
-
|
|
309
|
+
- ✨ 新增自定义环境(custom)- 支持连接私有部署后端服务
|
|
310
|
+
- 🔧 新增 `--customIp` 参数 - 命令行直接传入自定义后端 IP
|
|
311
|
+
- 🎨 优化交互体验 - 仅选择 custom 环境时才提示输入 IP
|
|
312
|
+
- 📝 更新文档 - 添加自定义环境使用说明和示例
|
|
313
|
+
- 🔒 `MODEL_BASE_URL` 保持固定,不随自定义环境改变
|
|
314
|
+
|
|
315
|
+
### v1.0.313 (2026-04-23)
|
|
316
|
+
|
|
317
|
+
- ✨ 新增 `--openclaw-path` 参数 - 支持自定义安装路径
|
|
318
|
+
- 🔧 新增路径验证功能 - 检查绝对路径和非法字符
|
|
319
|
+
- ⚡ 优化安装流程 - 使用 npm pack + tar 替代 openclaw 命令
|
|
320
|
+
- 🔒 移除 `--scenario` 参数 - 自动检测系统环境
|
|
321
|
+
- 📦 更新 npm 镜像源 - 使用腾讯云 npm 镜像
|
|
322
|
+
- 📝 完善文档和错误提示
|
|
323
|
+
|
|
324
|
+
### v1.0.30 (2026-04-08)
|
|
105
325
|
|
|
106
326
|
- ✨ 新增 local 命令 - 本地账户安装(需要登录)
|
|
107
327
|
- ✨ 新增 box 命令 - 盒子设备安装(无需登录)
|
|
108
328
|
- 🔧 重构命令结构,分离 local 和 box 命令
|
|
109
|
-
|
|
110
|
-
### v2.0.0 (2026-04-08)
|
|
111
|
-
|
|
112
|
-
- ✨ 新增 phone + userPass 认证方式
|
|
113
329
|
- 🔒 新增 RSA 密码加密
|
|
114
330
|
- 📝 新增完整请求日志
|
|
115
331
|
- 🎨 优化交互式提示和进度显示
|
|
116
|
-
- 🌐 支持 NPM 安装插件
|
|
117
|
-
- 🔧 统一错误码管理
|
|
118
332
|
|
|
119
333
|
### v1.0.0
|
|
120
334
|
|
|
@@ -122,18 +336,19 @@ npm run build # 构建
|
|
|
122
336
|
- ✨ 支持 appKey + appSecret 认证
|
|
123
337
|
- ✨ 支持多平台安装
|
|
124
338
|
|
|
125
|
-
## 许可证
|
|
339
|
+
## 📄 许可证
|
|
126
340
|
|
|
127
341
|
MIT License
|
|
128
342
|
|
|
129
|
-
## 联系方式
|
|
343
|
+
## 📞 联系方式
|
|
130
344
|
|
|
131
|
-
|
|
132
|
-
- 问题反馈: [Issue Tracker]()
|
|
345
|
+
如有问题,请联系项目维护者。
|
|
133
346
|
|
|
134
|
-
## 致谢
|
|
347
|
+
## 🙏 致谢
|
|
135
348
|
|
|
136
349
|
- [commander](https://github.com/tj/commander.js) - 命令行解析
|
|
137
350
|
- [chalk](https://github.com/chalk/chalk) - 彩色输出
|
|
138
351
|
- [ora](https://github.com/sindresorhus/ora) - 加载动画
|
|
139
352
|
- [axios](https://github.com/axios/axios) - HTTP 客户端
|
|
353
|
+
- [tar](https://github.com/isaacs/node-tar) - tar 文件解压
|
|
354
|
+
|
package/dist/box/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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,
|
|
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;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,
|
|
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,CAgJzE"}
|
|
@@ -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
|
-
|
|
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,
|
|
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"}
|
|
@@ -21,6 +21,19 @@ function debugLog(...args) {
|
|
|
21
21
|
console.log(chalk.gray(`[DEBUG]`), ...args);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
function validateOpenclawPath(openclawPath) {
|
|
25
|
+
debugLog(`[路径验证] 开始验证路径: ${openclawPath}`);
|
|
26
|
+
if (!path.isAbsolute(openclawPath)) {
|
|
27
|
+
debugLog(`[路径验证] 失败: 路径不是绝对路径`);
|
|
28
|
+
throw new Error(`路径必须是绝对路径,当前输入: ${openclawPath}`);
|
|
29
|
+
}
|
|
30
|
+
const invalidChars = /[<>:"|?*]/.test(openclawPath);
|
|
31
|
+
if (invalidChars) {
|
|
32
|
+
debugLog(`[路径验证] 失败: 路径包含特殊字符`);
|
|
33
|
+
throw new Error('路径不能包含特殊字符: < > : " | ? *');
|
|
34
|
+
}
|
|
35
|
+
debugLog(`[路径验证] 通过: ${openclawPath}`);
|
|
36
|
+
}
|
|
24
37
|
const ERROR_CODES$1 = {
|
|
25
38
|
APP_KEY_REQUIRED: "APP_KEY_REQUIRED",
|
|
26
39
|
APP_SECRET_REQUIRED: "APP_SECRET_REQUIRED",
|
|
@@ -76,8 +89,26 @@ const TEST_CONFIG = {
|
|
|
76
89
|
TIMEOUT: 1e4
|
|
77
90
|
}
|
|
78
91
|
};
|
|
79
|
-
function getConfig(env) {
|
|
80
|
-
|
|
92
|
+
function getConfig(env, customIp) {
|
|
93
|
+
if (env === "test") {
|
|
94
|
+
return TEST_CONFIG;
|
|
95
|
+
}
|
|
96
|
+
if (env === "custom") {
|
|
97
|
+
if (!customIp) {
|
|
98
|
+
throw new Error("自定义环境必须提供 customIp");
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
...TEST_CONFIG,
|
|
102
|
+
DEFAULT_BASE_URL: TEST_CONFIG.DEFAULT_BASE_URL.replace("172.168.80.30", customIp),
|
|
103
|
+
DEFAULT_WS_URL: TEST_CONFIG.DEFAULT_WS_URL.replace("172.168.80.30", customIp),
|
|
104
|
+
API: {
|
|
105
|
+
...TEST_CONFIG.API,
|
|
106
|
+
TUZAI_BASE_URL: TEST_CONFIG.API.TUZAI_BASE_URL.replace("172.168.80.30", customIp),
|
|
107
|
+
BASE_URL: TEST_CONFIG.API.BASE_URL.replace("172.168.80.30", customIp)
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return CONFIG;
|
|
81
112
|
}
|
|
82
113
|
function getHomeDir$1() {
|
|
83
114
|
return process$1.env.HOME || process$1.env.USERPROFILE || "";
|
|
@@ -124,31 +155,18 @@ class BoxInstaller {
|
|
|
124
155
|
}
|
|
125
156
|
debugLog("[验证配置] 配置检查通过");
|
|
126
157
|
}
|
|
127
|
-
validateOpenclawPath(openclawPath) {
|
|
128
|
-
debugLog(`[路径验证] 开始验证路径: ${openclawPath}`);
|
|
129
|
-
if (!path.isAbsolute(openclawPath)) {
|
|
130
|
-
debugLog("[路径验证] 失败: 不是绝对路径");
|
|
131
|
-
throw new AppError$1(
|
|
132
|
-
ERROR_CODES$1.INVALID_OPENCLAW_PATH,
|
|
133
|
-
`路径必须是绝对路径,当前输入: ${openclawPath}`
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
const invalidChars = /[<>:"|?*]/.test(openclawPath);
|
|
137
|
-
if (invalidChars) {
|
|
138
|
-
debugLog("[路径验证] 失败: 包含非法字符");
|
|
139
|
-
throw new AppError$1(
|
|
140
|
-
ERROR_CODES$1.INVALID_OPENCLAW_PATH,
|
|
141
|
-
'路径不能包含特殊字符: < > : " | ? *'
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
debugLog("[路径验证] 通过");
|
|
145
|
-
}
|
|
146
158
|
getPaths() {
|
|
147
|
-
const
|
|
159
|
+
const env = this.config.env || "test";
|
|
160
|
+
const config = getConfig(env, this.config.customIp);
|
|
148
161
|
let baseDir;
|
|
149
162
|
if (this.config.openclawPath) {
|
|
150
163
|
debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
|
|
151
|
-
|
|
164
|
+
try {
|
|
165
|
+
validateOpenclawPath(this.config.openclawPath);
|
|
166
|
+
debugLog("[路径验证] 通过");
|
|
167
|
+
} catch (error) {
|
|
168
|
+
throw new AppError$1(ERROR_CODES$1.INVALID_OPENCLAW_PATH, error.message);
|
|
169
|
+
}
|
|
152
170
|
baseDir = this.config.openclawPath;
|
|
153
171
|
} else {
|
|
154
172
|
const home = getHomeDir$1();
|
|
@@ -474,7 +492,7 @@ class BoxInstaller {
|
|
|
474
492
|
// 应用密钥
|
|
475
493
|
appSecret: this.config.appSecret,
|
|
476
494
|
// API 基础 URL
|
|
477
|
-
baseUrl: this.config.
|
|
495
|
+
baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
|
|
478
496
|
// WebSocket URL
|
|
479
497
|
websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
|
|
480
498
|
// 允许不安全的 TLS 连接
|
|
@@ -595,13 +613,14 @@ function checkEnv$1() {
|
|
|
595
613
|
async function createBoxCommand(options) {
|
|
596
614
|
setDebug(!!options.debug);
|
|
597
615
|
debugLog("[盒子安装] 开始处理...");
|
|
598
|
-
debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, debug=${options.debug}`);
|
|
616
|
+
debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, customIp=${options.customIp}, debug=${options.debug}`);
|
|
599
617
|
checkEnv$1();
|
|
600
618
|
debugLog("[盒子安装] 环境检查通过");
|
|
601
619
|
try {
|
|
602
620
|
let env = options.env;
|
|
603
621
|
let appKey = options.appKey;
|
|
604
622
|
let appSecret = options.appSecret;
|
|
623
|
+
let customIp = options.customIp;
|
|
605
624
|
const questions = [];
|
|
606
625
|
if (!env) {
|
|
607
626
|
debugLog("[盒子安装] 需要选择环境");
|
|
@@ -612,7 +631,8 @@ async function createBoxCommand(options) {
|
|
|
612
631
|
default: "test",
|
|
613
632
|
choices: [
|
|
614
633
|
{ name: `${chalk.green("测试环境")} ${chalk.dim("(test)")}`, value: "test" },
|
|
615
|
-
{ name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" }
|
|
634
|
+
{ name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" },
|
|
635
|
+
{ name: `${chalk.yellow("自定义环境")} ${chalk.dim("(custom) - 需要输入后端 IP")}`, value: "custom" }
|
|
616
636
|
]
|
|
617
637
|
});
|
|
618
638
|
} else {
|
|
@@ -658,12 +678,33 @@ async function createBoxCommand(options) {
|
|
|
658
678
|
appKey = appKey || answers.appKey;
|
|
659
679
|
appSecret = appSecret || answers.appSecret;
|
|
660
680
|
}
|
|
661
|
-
|
|
681
|
+
if (env === "custom" && !customIp) {
|
|
682
|
+
debugLog("[盒子安装] 自定义环境需要输入后端 IP");
|
|
683
|
+
const answer = await inquirer.prompt([{
|
|
684
|
+
type: "input",
|
|
685
|
+
name: "customIp",
|
|
686
|
+
message: chalk.cyan("请输入后端 IP:"),
|
|
687
|
+
default: "127.0.0.1",
|
|
688
|
+
validate: (value) => {
|
|
689
|
+
if (!value || value.trim() === "") {
|
|
690
|
+
return chalk.red("后端 IP 不能为空");
|
|
691
|
+
}
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
}]);
|
|
695
|
+
customIp = answer.customIp;
|
|
696
|
+
debugLog("[盒子安装] 获取自定义 customIp");
|
|
697
|
+
} else if (env === "custom" && customIp) {
|
|
698
|
+
debugLog(`[盒子安装] 使用命令行参数: customIp=${customIp}`);
|
|
699
|
+
}
|
|
700
|
+
debugLog(`[盒子安装] 最终参数: env=${env}, customIp=${customIp}, openclawPath=${options.openclawPath}`);
|
|
662
701
|
debugLog("[盒子安装] 创建 BoxInstaller 实例...");
|
|
663
702
|
const installer = new BoxInstaller({
|
|
664
703
|
appKey,
|
|
665
704
|
appSecret,
|
|
666
705
|
env,
|
|
706
|
+
customIp,
|
|
707
|
+
wsUrl: options.wsUrl,
|
|
667
708
|
pluginVersion: options.pluginVersion,
|
|
668
709
|
openclawPath: options.openclawPath
|
|
669
710
|
});
|
|
@@ -700,7 +741,7 @@ async function createBoxCommand(options) {
|
|
|
700
741
|
}
|
|
701
742
|
}
|
|
702
743
|
function registerCommands$1(program2) {
|
|
703
|
-
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);
|
|
744
|
+
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);
|
|
704
745
|
}
|
|
705
746
|
const ERROR_CODES = {
|
|
706
747
|
PHONE_REQUIRED: "PHONE_REQUIRED",
|
|
@@ -4781,35 +4822,21 @@ class LocalInstaller {
|
|
|
4781
4822
|
}
|
|
4782
4823
|
debugLog("[验证配置] 配置验证通过");
|
|
4783
4824
|
}
|
|
4784
|
-
validateOpenclawPath(openclawPath) {
|
|
4785
|
-
debugLog(`[路径验证] 开始验证路径: ${openclawPath}`);
|
|
4786
|
-
if (!path.isAbsolute(openclawPath)) {
|
|
4787
|
-
debugLog("[路径验证] 失败: 不是绝对路径");
|
|
4788
|
-
throw new AppError2(
|
|
4789
|
-
ERROR_CODES.INVALID_OPENCLAW_PATH,
|
|
4790
|
-
`路径必须是绝对路径,当前输入: ${openclawPath}`
|
|
4791
|
-
);
|
|
4792
|
-
}
|
|
4793
|
-
const invalidChars = /[<>:"|?*]/.test(openclawPath);
|
|
4794
|
-
if (invalidChars) {
|
|
4795
|
-
debugLog("[路径验证] 失败: 包含非法字符");
|
|
4796
|
-
throw new AppError2(
|
|
4797
|
-
ERROR_CODES.INVALID_OPENCLAW_PATH,
|
|
4798
|
-
'路径不能包含特殊字符: < > : " | ? *'
|
|
4799
|
-
);
|
|
4800
|
-
}
|
|
4801
|
-
debugLog("[路径验证] 通过");
|
|
4802
|
-
}
|
|
4803
4825
|
async install() {
|
|
4804
4826
|
try {
|
|
4805
4827
|
debugLog("[安装开始]");
|
|
4806
4828
|
this.validateConfig();
|
|
4807
4829
|
const env = this.config.env || "test";
|
|
4808
|
-
const config = getConfig(env);
|
|
4830
|
+
const config = getConfig(env, this.config.customIp);
|
|
4809
4831
|
let baseDir;
|
|
4810
4832
|
if (this.config.openclawPath) {
|
|
4811
4833
|
debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
|
|
4812
|
-
|
|
4834
|
+
try {
|
|
4835
|
+
validateOpenclawPath(this.config.openclawPath);
|
|
4836
|
+
debugLog("[路径验证] 通过");
|
|
4837
|
+
} catch (error) {
|
|
4838
|
+
throw new AppError2(ERROR_CODES.INVALID_OPENCLAW_PATH, error.message);
|
|
4839
|
+
}
|
|
4813
4840
|
baseDir = this.config.openclawPath;
|
|
4814
4841
|
} else {
|
|
4815
4842
|
const homeDir = getHomeDir();
|
|
@@ -4828,8 +4855,8 @@ class LocalInstaller {
|
|
|
4828
4855
|
debugLog(`[路径配置] target=${paths.target}`);
|
|
4829
4856
|
debugLog(`[路径配置] config=${paths.config}`);
|
|
4830
4857
|
debugLog(`[路径配置] workspace=${paths.workspace}`);
|
|
4831
|
-
const token = await this.doLogin(
|
|
4832
|
-
const boundConfig = await this.doFetchBoundConfig(
|
|
4858
|
+
const token = await this.doLogin();
|
|
4859
|
+
const boundConfig = await this.doFetchBoundConfig(token);
|
|
4833
4860
|
await this.doCleanOldFiles(paths.target);
|
|
4834
4861
|
await this.doDownloadFromNpm(paths);
|
|
4835
4862
|
await this.doUpdateConfig(paths, boundConfig, env);
|
|
@@ -4848,7 +4875,8 @@ class LocalInstaller {
|
|
|
4848
4875
|
}
|
|
4849
4876
|
return PLUGIN_PACKAGE_NAME;
|
|
4850
4877
|
}
|
|
4851
|
-
async doLogin(
|
|
4878
|
+
async doLogin() {
|
|
4879
|
+
const env = this.config.env || "test";
|
|
4852
4880
|
this.spinner.prefixText = this.prefixText;
|
|
4853
4881
|
this.spinner.text = chalk.cyan("正在验证账号...");
|
|
4854
4882
|
debugLog(`[用户登录] 手机号: ${this.config.phone}`);
|
|
@@ -4865,7 +4893,8 @@ class LocalInstaller {
|
|
|
4865
4893
|
debugLog("[用户登录] 登录成功");
|
|
4866
4894
|
return token;
|
|
4867
4895
|
}
|
|
4868
|
-
async doFetchBoundConfig(
|
|
4896
|
+
async doFetchBoundConfig(token) {
|
|
4897
|
+
const env = this.config.env || "test";
|
|
4869
4898
|
this.spinner.prefixText = this.prefixText;
|
|
4870
4899
|
this.spinner.text = chalk.cyan("正在获取绑定信息...");
|
|
4871
4900
|
debugLog("[获取配置] 调用绑定配置接口...");
|
|
@@ -5003,7 +5032,7 @@ class LocalInstaller {
|
|
|
5003
5032
|
} catch {
|
|
5004
5033
|
debugLog("[更新配置] 无原有配置");
|
|
5005
5034
|
}
|
|
5006
|
-
const config = getConfig(env);
|
|
5035
|
+
const config = getConfig(env, this.config.customIp);
|
|
5007
5036
|
const newConfig = {
|
|
5008
5037
|
// diagnostics: 诊断配置
|
|
5009
5038
|
diagnostics: {
|
|
@@ -5099,7 +5128,7 @@ class LocalInstaller {
|
|
|
5099
5128
|
connectionMode: "websocket",
|
|
5100
5129
|
appKey: boundConfig.appKey,
|
|
5101
5130
|
appSecret: boundConfig.appSecret,
|
|
5102
|
-
baseUrl: this.config.
|
|
5131
|
+
baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
|
|
5103
5132
|
websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
|
|
5104
5133
|
allowInsecureTls: true,
|
|
5105
5134
|
allowRawJsonPayload: true,
|
|
@@ -5195,13 +5224,14 @@ function checkEnv() {
|
|
|
5195
5224
|
async function createLocalCommand(options) {
|
|
5196
5225
|
setDebug(!!options.debug);
|
|
5197
5226
|
debugLog("[初始化] 开始处理...");
|
|
5198
|
-
debugLog(`[初始化] 参数: env=${options.env}, phone=${options.phone}, debug=${options.debug}`);
|
|
5227
|
+
debugLog(`[初始化] 参数: env=${options.env}, phone=${options.phone}, customIp=${options.customIp}, debug=${options.debug}`);
|
|
5199
5228
|
checkEnv();
|
|
5200
5229
|
debugLog("[初始化] 环境检查通过");
|
|
5201
5230
|
try {
|
|
5202
5231
|
let env = options.env;
|
|
5203
5232
|
let phone = options.phone;
|
|
5204
5233
|
let userPass = options.userPass;
|
|
5234
|
+
let customIp = options.customIp;
|
|
5205
5235
|
const questions = [];
|
|
5206
5236
|
if (!env) {
|
|
5207
5237
|
debugLog("[初始化] 需要选择环境");
|
|
@@ -5212,7 +5242,8 @@ async function createLocalCommand(options) {
|
|
|
5212
5242
|
default: "test",
|
|
5213
5243
|
choices: [
|
|
5214
5244
|
{ name: `${chalk.green("测试环境")} ${chalk.dim("(test)")}`, value: "test" },
|
|
5215
|
-
{ name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" }
|
|
5245
|
+
{ name: `${chalk.red("正式环境")} ${chalk.dim("(prod)")}`, value: "prod" },
|
|
5246
|
+
{ name: `${chalk.yellow("自定义环境")} ${chalk.dim("(custom) - 需要输入后端 IP")}`, value: "custom" }
|
|
5216
5247
|
]
|
|
5217
5248
|
});
|
|
5218
5249
|
} else {
|
|
@@ -5261,12 +5292,33 @@ async function createLocalCommand(options) {
|
|
|
5261
5292
|
phone = phone || answers.phone;
|
|
5262
5293
|
userPass = userPass || answers.userPass;
|
|
5263
5294
|
}
|
|
5264
|
-
|
|
5295
|
+
if (env === "custom" && !customIp) {
|
|
5296
|
+
debugLog("[初始化] 自定义环境需要输入后端 IP");
|
|
5297
|
+
const answer = await inquirer.prompt([{
|
|
5298
|
+
type: "input",
|
|
5299
|
+
name: "customIp",
|
|
5300
|
+
message: chalk.cyan("请输入后端 IP:"),
|
|
5301
|
+
default: "127.0.0.1",
|
|
5302
|
+
validate: (value) => {
|
|
5303
|
+
if (!value || value.trim() === "") {
|
|
5304
|
+
return chalk.red("后端 IP 不能为空");
|
|
5305
|
+
}
|
|
5306
|
+
return true;
|
|
5307
|
+
}
|
|
5308
|
+
}]);
|
|
5309
|
+
customIp = answer.customIp;
|
|
5310
|
+
debugLog("[初始化] 获取自定义 customIp");
|
|
5311
|
+
} else if (env === "custom" && customIp) {
|
|
5312
|
+
debugLog(`[初始化] 使用命令行参数: customIp=${customIp}`);
|
|
5313
|
+
}
|
|
5314
|
+
debugLog(`[初始化] 最终参数: env=${env}, phone=${phone}, customIp=${customIp}, pluginVersion=${options.pluginVersion}, openclawPath=${options.openclawPath}`);
|
|
5265
5315
|
debugLog("[初始化] 创建 LocalInstaller 实例...");
|
|
5266
5316
|
const installer = new LocalInstaller({
|
|
5267
5317
|
phone,
|
|
5268
5318
|
userPass,
|
|
5269
5319
|
env,
|
|
5320
|
+
customIp,
|
|
5321
|
+
wsUrl: options.wsUrl,
|
|
5270
5322
|
pluginVersion: options.pluginVersion,
|
|
5271
5323
|
openclawPath: options.openclawPath
|
|
5272
5324
|
});
|
|
@@ -5303,7 +5355,7 @@ async function createLocalCommand(options) {
|
|
|
5303
5355
|
}
|
|
5304
5356
|
}
|
|
5305
5357
|
function registerCommands(program2) {
|
|
5306
|
-
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);
|
|
5358
|
+
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);
|
|
5307
5359
|
}
|
|
5308
5360
|
const __filename$1 = fileURLToPath(import.meta.url);
|
|
5309
5361
|
const __dirname$1 = dirname(__filename$1);
|
package/dist/index.js
CHANGED
|
@@ -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,
|
|
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;
|
|
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;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,
|
|
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,CAgJ7E"}
|
|
@@ -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
|
-
|
|
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,
|
|
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;
|
|
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,CAsB9E"}
|
|
@@ -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"}
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/path.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAiB/D"}
|