@workclaw/cli 1.0.18 → 1.0.20

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
@@ -1,165 +1,161 @@
1
- # WorkClaw CLI
2
-
3
- WorkClaw CLI 是一个用于初始化和配置 WorkClaw 插件的命令行工具。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- # 使用 npm 安装
9
- npm install -g @workclaw/cli
10
-
11
- # 使用 npx 直接运行(无需安装)
12
- npx @workclaw/cli local
13
- ```
14
-
15
- ## 使用
16
-
17
- ### 命令
18
-
19
- 本 CLI 提供两个命令:
20
-
21
- | 命令 | 说明 |
22
- |------|------|
23
- | `workclaw local` | 本地账户安装(需要登录) |
24
- | `workclaw box` | 盒子设备安装(无需登录) |
25
-
26
- ### 交互式初始化
27
-
28
- ```bash
29
- # 本地安装(需要手机号密码)
30
- workclaw local
31
- # 或使用 npx
32
- npx @workclaw/cli local
33
-
34
- # 盒子安装(需要 AppKey 和 AppSecret)
35
- workclaw box
36
- # 或使用 npx
37
- npx @workclaw/cli box
38
- ```
39
-
40
- ### 命令行参数
41
-
42
- #### local 命令参数
43
-
44
- | 参数 | 缩写 | 说明 |
45
- | ---------------- | -- | -------------- |
46
- | --scenario | -s | 安装场景 |
47
- | --env | -e | 环境 (test/prod) |
48
- | --phone | 无 | 手机号码 |
49
- | --user-pass | 无 | 用户密码 |
50
- | --plugin-version | 无 | 插件版本号 |
51
- | --debug | 无 | 调试模式 |
52
-
53
- #### box 命令参数
54
-
55
- | 参数 | 缩写 | 说明 |
56
- | ---------------- | -- | -------------- |
57
- | --scenario | -s | 安装场景 |
58
- | --env | -e | 环境 (test/prod) |
59
- | --app-key | 无 | App Key |
60
- | --app-secret | 无 | App Secret |
61
- | --plugin-version | 无 | 插件版本号 |
62
- | --debug | 无 | 调试模式 |
63
-
64
- ### 安装场景
65
-
66
- | 场景 | 说明 |
67
- | ------------- | ------------ |
68
- | windows-local | Windows 本地安装 |
69
- | mac-local | macOS 本地安装 |
70
- | linux-local | Linux 本地安装 |
71
-
72
- ### 环境
73
-
74
- | 环境 | 说明 |
75
- | ---- | ---- |
76
- | test | 测试环境 |
77
- | prod | 正式环境 |
78
-
79
- ## 示例
80
-
81
- ### 本地安装
82
-
83
- #### 交互式安装(推荐新手使用)
84
-
85
- ```bash
86
- # 全局安装后运行
87
- workclaw local
88
-
89
- # 或使用 npx 直接运行
90
- npx @workclaw/cli local
91
- ```
92
-
93
- #### 仅指定手机号和密码
94
-
95
- ```bash
96
- workclaw local --phone 13800138000 --user-pass your_password
97
- ```
98
-
99
- #### 完整参数指定
100
-
101
- ```bash
102
- workclaw local --scenario windows-local --env test --phone 13800138000 --user-pass your_password
103
- ```
104
-
105
- #### 使用正式环境
106
-
107
- ```bash
108
- workclaw local --env prod --phone 13800138000 --user-pass your_password
109
- ```
110
-
111
- #### macOS 安装
112
-
113
- ```bash
114
- workclaw local --scenario mac-local --phone 13800138000 --user-pass your_password
115
- ```
116
-
117
- #### Linux 安装
118
-
119
- ```bash
120
- workclaw local --scenario linux-local --phone 13800138000 --user-pass your_password
121
- ```
122
-
123
- ### 盒子安装
124
-
125
- 盒子安装适用于不需要用户登录的场景,直接使用 AppKey 和 AppSecret 进行安装:
126
-
127
- ```bash
128
- # 基本用法
129
- workclaw box --app-key your_app_key --app-secret your_app_secret
130
-
131
- # 指定环境
132
- workclaw box --app-key your_app_key --app-secret your_app_secret --env prod
133
-
134
- # 指定场景
135
- workclaw box --app-key your_app_key --app-secret your_app_secret --scenario linux-local
136
- ```
137
-
138
- ### 指定插件版本
139
-
140
- 可以使用 `--plugin-version` 参数安装指定版本的插件(默认安装最新版):
141
-
142
- ```bash
143
- # 安装指定版本
144
- workclaw local --phone 13800138000 --user-pass your_password --plugin-version 1.0.0
145
- workclaw box --app-key your_app_key --app-secret your_app_secret --plugin-version 1.0.0
146
- ```
147
-
148
- ### 调试模式
149
-
150
- 当安装失败时,可以使用 `--debug` 参数查看详细日志:
151
-
152
- ```bash
153
- # 本地安装 + 调试模式
154
- workclaw local --phone 13800138000 --user-pass your_password --debug
155
-
156
- # 盒子安装 + 调试模式
157
- workclaw box --app-key your_app_key --app-secret your_app_secret --debug
158
-
159
- # 完整参数 + 调试模式
160
- workclaw local --scenario windows-local --env test --phone 13800138000 --user-pass your_password --debug
161
- ```
162
-
163
- ## 许可证
164
-
165
- MIT License
1
+ # WorkClaw CLI
2
+
3
+ WorkClaw CLI 是一个用于初始化和配置 WorkClaw 插件的命令行工具。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ # 使用 npm 安装
9
+ npm install -g @workclaw/cli
10
+
11
+ # 使用 npx 直接运行(无需安装)
12
+ npx @workclaw/cli local
13
+ ```
14
+
15
+ ## 使用
16
+
17
+ ### 命令
18
+
19
+ 本 CLI 提供两个命令:
20
+
21
+ | 命令 | 说明 |
22
+ |------|------|
23
+ | `workclaw local` | 本地账户安装(需要登录) |
24
+ | `workclaw box` | 盒子设备安装(无需登录,仅支持 Linux) |
25
+
26
+ ### 交互式初始化
27
+
28
+ ```bash
29
+ # 本地安装(需要手机号密码)
30
+ workclaw local
31
+ # 或使用 npx
32
+ npx @workclaw/cli local
33
+
34
+ # 盒子安装(需要 AppKey 和 AppSecret)
35
+ workclaw box
36
+ # 或使用 npx
37
+ npx @workclaw/cli box
38
+ ```
39
+
40
+ ### 命令行参数
41
+
42
+ #### local 命令参数
43
+
44
+ | 参数 | 缩写 | 说明 |
45
+ | ---------------- | -- | -------------- |
46
+ | --scenario | -s | 安装场景 |
47
+ | --env | -e | 环境 (test/prod) |
48
+ | --phone | 无 | 手机号码 |
49
+ | --user-pass | 无 | 用户密码 |
50
+ | --plugin-version | 无 | 插件版本号 |
51
+ | --debug | 无 | 调试模式 |
52
+
53
+ #### box 命令参数
54
+
55
+ | 参数 | 缩写 | 说明 |
56
+ | ---------------- | -- | ---- |
57
+ | --env | -e | 环境 (test/prod) |
58
+ | --app-key | | App Key |
59
+ | --app-secret | 无 | App Secret |
60
+ | --plugin-version | 无 | 插件版本号 |
61
+ | --debug | 无 | 调试模式 |
62
+
63
+ ### 安装场景
64
+
65
+ | 场景 | 说明 |
66
+ | ------------- | ------------ |
67
+ | windows-local | Windows 本地安装 |
68
+ | mac-local | macOS 本地安装 |
69
+ | linux-local | Linux 本地安装 |
70
+
71
+ ### 环境
72
+
73
+ | 环境 | 说明 |
74
+ | ---- | ---- |
75
+ | test | 测试环境 |
76
+ | prod | 正式环境 |
77
+
78
+ ## 示例
79
+
80
+ ### 本地安装
81
+
82
+ #### 交互式安装(推荐新手使用)
83
+
84
+ ```bash
85
+ # 全局安装后运行
86
+ workclaw local
87
+
88
+ # 或使用 npx 直接运行
89
+ npx @workclaw/cli local
90
+ ```
91
+
92
+ #### 仅指定手机号和密码
93
+
94
+ ```bash
95
+ workclaw local --phone 13800138000 --user-pass your_password
96
+ ```
97
+
98
+ #### 完整参数指定
99
+
100
+ ```bash
101
+ workclaw local --scenario windows-local --env test --phone 13800138000 --user-pass your_password
102
+ ```
103
+
104
+ #### 使用正式环境
105
+
106
+ ```bash
107
+ workclaw local --env prod --phone 13800138000 --user-pass your_password
108
+ ```
109
+
110
+ #### macOS 安装
111
+
112
+ ```bash
113
+ workclaw local --scenario mac-local --phone 13800138000 --user-pass your_password
114
+ ```
115
+
116
+ #### Linux 安装
117
+
118
+ ```bash
119
+ workclaw local --scenario linux-local --phone 13800138000 --user-pass your_password
120
+ ```
121
+
122
+ ### 盒子安装
123
+
124
+ 盒子安装适用于不需要用户登录的场景,直接使用 AppKey 和 AppSecret 进行安装。**仅支持 Linux 环境**。
125
+
126
+ ```bash
127
+ # 基本用法
128
+ workclaw box --app-key your_app_key --app-secret your_app_secret
129
+
130
+ # 指定环境
131
+ workclaw box --app-key your_app_key --app-secret your_app_secret --env prod
132
+ ```
133
+
134
+ ### 指定插件版本
135
+
136
+ 可以使用 `--plugin-version` 参数安装指定版本的插件(默认安装最新版):
137
+
138
+ ```bash
139
+ # 安装指定版本
140
+ workclaw local --phone 13800138000 --user-pass your_password --plugin-version 1.0.0
141
+ workclaw box --app-key your_app_key --app-secret your_app_secret --plugin-version 1.0.0
142
+ ```
143
+
144
+ ### 调试模式
145
+
146
+ 当安装失败时,可以使用 `--debug` 参数查看详细日志:
147
+
148
+ ```bash
149
+ # 本地安装 + 调试模式
150
+ workclaw local --phone 13800138000 --user-pass your_password --debug
151
+
152
+ # 盒子安装 + 调试模式
153
+ workclaw box --app-key your_app_key --app-secret your_app_secret --debug
154
+
155
+ # 完整参数 + 调试模式
156
+ workclaw local --scenario windows-local --env test --phone 13800138000 --user-pass your_password --debug
157
+ ```
158
+
159
+ ## 许可证
160
+
161
+ MIT License
@@ -4099,6 +4099,19 @@ function getHomeDir$1() {
4099
4099
  return process$1.env.HOME || process$1.env.USERPROFILE || "";
4100
4100
  }
4101
4101
  const PLUGIN_PACKAGE_NAME$1 = "@workclaw/openclaw-workclaw";
4102
+ function deepMerge$1(target, source) {
4103
+ const result = { ...target };
4104
+ for (const key in source) {
4105
+ const sourceValue = source[key];
4106
+ const targetValue = target[key];
4107
+ if (sourceValue !== void 0 && sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
4108
+ result[key] = deepMerge$1(targetValue, sourceValue);
4109
+ } else if (sourceValue !== void 0) {
4110
+ result[key] = sourceValue;
4111
+ }
4112
+ }
4113
+ return result;
4114
+ }
4102
4115
  class LocalInstaller {
4103
4116
  constructor(config) {
4104
4117
  this.config = config;
@@ -4292,104 +4305,176 @@ class LocalInstaller {
4292
4305
  debugLog("[更新配置] 无原有配置");
4293
4306
  }
4294
4307
  const config = getConfig(env);
4295
- const finalConfig = {
4296
- ...originalConfig,
4308
+ const newConfig = {
4309
+ // diagnostics: 诊断配置
4297
4310
  diagnostics: {
4311
+ // 启用诊断功能
4298
4312
  enabled: true,
4313
+ // 启用所有诊断标志 ['*'] 表示全部,[] 表示禁用所有
4299
4314
  flags: ["*"]
4300
4315
  },
4316
+ // browser: 浏览器配置
4301
4317
  browser: {
4318
+ // 禁用浏览器工具
4302
4319
  enabled: false
4303
4320
  },
4321
+ // models: 模型配置
4304
4322
  models: {
4323
+ // 配置合并模式:'merge' 合并 | 'replace' 替换
4305
4324
  mode: "merge",
4306
4325
  providers: {
4307
4326
  "siliconflow-minimax": {
4327
+ // 模型 API 基础地址
4308
4328
  baseUrl: boundConfig.modelApiBaseUrl || config.MODEL_BASE_URL,
4329
+ // API 密钥(从服务器获取)
4309
4330
  apiKey: boundConfig.modelApiKey,
4331
+ // API 类型:'openai-completions' | 'openai-chat' 等
4310
4332
  api: "openai-completions",
4333
+ // 是否使用 Authorization header 认证
4311
4334
  authHeader: true,
4312
4335
  models: [{
4336
+ // 模型 ID(provider/model 格式)
4313
4337
  id: "Pro/MiniMaxAI/MiniMax-M2.5",
4338
+ // 模型显示名称
4314
4339
  name: "MiniMax-M2.5",
4340
+ // 是否启用推理能力
4315
4341
  reasoning: false,
4342
+ // 支持的输入类型:['text'] | ['text', 'image']
4316
4343
  input: ["text"],
4344
+ // 价格(0 表示免费或未设置)
4317
4345
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
4346
+ // 上下文窗口大小(token)
4318
4347
  contextWindow: 2e5,
4348
+ // 最大输出 token 数
4319
4349
  maxTokens: 65536
4320
4350
  }]
4321
4351
  }
4322
4352
  }
4323
4353
  },
4354
+ // agents: 代理配置
4324
4355
  agents: {
4325
4356
  defaults: {
4357
+ // 默认使用的模型
4326
4358
  model: { primary: "siliconflow-minimax/Pro/MiniMaxAI/MiniMax-M2.5" },
4327
4359
  models: {
4328
4360
  "siliconflow-minimax/Pro/MiniMaxAI/MiniMax-M2.5": {
4361
+ // 模型别名,用于显示
4329
4362
  alias: "Pro/MiniMaxAI/MiniMax-M2.5"
4330
4363
  }
4331
4364
  },
4365
+ // 工作区目录路径
4332
4366
  workspace: paths.workspace,
4367
+ // 会话压缩模式:'safeguard' 保守模式
4333
4368
  compaction: { mode: "safeguard" },
4369
+ // 详细程度:'full' | 'short' | 'off'
4334
4370
  verboseDefault: "full",
4371
+ // 最大并发任务数
4335
4372
  maxConcurrent: 4,
4373
+ // 子代理最大并发数
4336
4374
  subagents: { maxConcurrent: 8 }
4337
4375
  },
4376
+ // 代理列表
4338
4377
  list: [{ id: "main", workspace: paths.workspace }]
4339
4378
  },
4379
+ // tools: 工具配置
4340
4380
  tools: {
4381
+ // 禁用的工具列表(优先于 allow)
4341
4382
  deny: ["image", "web_search", "web_fetch"],
4383
+ // 图像分析工具
4342
4384
  media: { image: { enabled: false } },
4385
+ // 网络搜索和抓取工具
4343
4386
  web: { search: { enabled: false }, fetch: { enabled: false } },
4387
+ // 提升权限工具(host=gateway)
4344
4388
  elevated: { enabled: true, allowFrom: { webchat: ["*"] } },
4389
+ // exec 工具安全级别:'deny' | 'allowlist' | 'full'
4345
4390
  exec: { security: "full" }
4346
4391
  },
4392
+ // bindings: 绑定配置
4347
4393
  bindings: [{
4394
+ // 绑定的代理 ID
4348
4395
  agentId: "main",
4396
+ // 匹配的通道和账户
4349
4397
  match: { channel: "openclaw-workclaw", accountId: "default" }
4350
4398
  }],
4351
- messages: { ackReactionScope: "group-mentions" },
4399
+ // messages: 消息配置
4400
+ messages: {
4401
+ // 消息确认范围
4402
+ ackReactionScope: "group-mentions"
4403
+ },
4404
+ // commands: 命令配置
4352
4405
  commands: {
4406
+ // 本机命令:'auto' | 'on' | 'off'
4353
4407
  native: "auto",
4408
+ // 本机技能:'auto' | 'on' | 'off'
4354
4409
  nativeSkills: "auto",
4410
+ // 是否允许重启命令
4355
4411
  restart: true,
4412
+ // 所有者显示格式:'raw' | 'name' | 'hidden'
4356
4413
  ownerDisplay: "raw"
4357
4414
  },
4358
- session: { dmScope: "per-account-channel-peer" },
4415
+ // session: 会话配置
4416
+ session: {
4417
+ // DM 作用域
4418
+ dmScope: "per-account-channel-peer"
4419
+ },
4420
+ // hooks: 钩子配置
4359
4421
  hooks: {
4360
4422
  internal: {
4423
+ // 启用内部钩子
4361
4424
  enabled: true,
4362
4425
  entries: {
4426
+ // 启动 Markdown 钩子
4363
4427
  "boot-md": { enabled: true },
4428
+ // 引导额外文件钩子
4364
4429
  "bootstrap-extra-files": { enabled: true },
4430
+ // 命令日志钩子
4365
4431
  "command-logger": { enabled: true },
4432
+ // 会话记忆钩子
4366
4433
  "session-memory": { enabled: true }
4367
4434
  }
4368
4435
  }
4369
4436
  },
4437
+ // channels: 通道配置
4370
4438
  channels: {
4371
4439
  "openclaw-workclaw": {
4440
+ // 启用通道
4372
4441
  enabled: true,
4442
+ // 连接模式:'websocket' | 'http'
4373
4443
  connectionMode: "websocket",
4444
+ // WebSocket 连接策略
4374
4445
  wsConnectionStrategy: "per-appKey",
4446
+ // 应用密钥(从服务器获取)
4375
4447
  appKey: boundConfig.appKey,
4448
+ // 应用密钥(从服务器获取)
4376
4449
  appSecret: boundConfig.appSecret,
4450
+ // API 基础 URL
4377
4451
  baseUrl: this.config.baseUrl || config.DEFAULT_BASE_URL,
4452
+ // WebSocket URL
4378
4453
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
4454
+ // 允许不安全的 TLS 连接
4379
4455
  allowInsecureTls: true,
4456
+ // 允许原始 JSON 载荷
4380
4457
  allowRawJsonPayload: true,
4381
4458
  accounts: {
4459
+ // 账户配置(agentId 从服务器获取)
4382
4460
  default: { enabled: true, agentId: boundConfig.agentId }
4383
4461
  }
4384
4462
  }
4385
4463
  },
4464
+ // gateway: 网关配置
4386
4465
  gateway: {
4466
+ // 网关模式:'local' | 'hosted'
4387
4467
  mode: "local",
4468
+ // 网关端口
4388
4469
  port: 18789,
4470
+ // 绑定地址:'loopback' | 'lan' | 'all'
4389
4471
  bind: "loopback",
4472
+ // 认证模式
4390
4473
  auth: { mode: "token", token: "" },
4474
+ // Tailscale 配置
4391
4475
  tailscale: { mode: "off", resetOnExit: false },
4392
4476
  nodes: {
4477
+ // 节点上禁止的命令
4393
4478
  denyCommands: [
4394
4479
  "camera.snap",
4395
4480
  "camera.clip",
@@ -4402,45 +4487,56 @@ class LocalInstaller {
4402
4487
  ]
4403
4488
  },
4404
4489
  controlUi: {
4490
+ // 允许不安全认证
4405
4491
  allowInsecureAuth: true,
4492
+ // 禁用设备认证(仅用于开发)
4406
4493
  dangerouslyDisableDeviceAuth: true,
4494
+ // 允许 Host 头源回退
4407
4495
  dangerouslyAllowHostHeaderOriginFallback: true,
4496
+ // 允许的源
4408
4497
  allowedOrigins: ["http://localhost:18789", "http://127.0.0.1:18789"]
4409
4498
  }
4410
4499
  },
4411
- skills: { load: { watch: true } },
4500
+ // skills: 技能配置
4501
+ skills: {
4502
+ // 技能加载监视模式
4503
+ load: { watch: true }
4504
+ },
4505
+ // logging: 日志配置
4412
4506
  logging: {
4507
+ // 日志级别:'debug' | 'info' | 'warn' | 'error'
4413
4508
  level: "info",
4509
+ // 控制台日志级别
4414
4510
  consoleLevel: "info",
4511
+ // 控制台样式:'pretty' | 'basic' | 'raw'
4415
4512
  consoleStyle: "pretty",
4513
+ // 敏感信息脱敏:'off' | 'keys' | 'all'
4416
4514
  redactSensitive: "off",
4515
+ // 日志文件路径(空表示不写入文件)
4417
4516
  file: "",
4517
+ // 脱敏模式(正则表达式)
4418
4518
  redactPatterns: ["sk-.*"]
4419
4519
  },
4520
+ // plugins: 插件配置
4420
4521
  plugins: {
4522
+ // 允许的插件列表
4421
4523
  allow: [config.PLUGIN_NAME],
4524
+ // 插件安装跟踪
4422
4525
  installs: {
4423
4526
  [config.PLUGIN_NAME]: {
4424
- source: "npm",
4425
- npm: PLUGIN_PACKAGE_NAME$1,
4527
+ // npm 包名
4528
+ installSource: PLUGIN_PACKAGE_NAME$1,
4529
+ // 安装路径
4426
4530
  installPath: paths.target
4427
4531
  }
4428
4532
  },
4533
+ // 插件条目启用状态
4429
4534
  entries: {
4430
4535
  [config.PLUGIN_NAME]: { enabled: true }
4431
4536
  }
4432
- },
4433
- wizard: {
4434
- lastRunAt: "",
4435
- lastRunVersion: "",
4436
- lastRunCommand: "",
4437
- lastRunMode: ""
4438
- },
4439
- meta: {
4440
- lastTouchedVersion: "",
4441
- lastTouchedAt: ""
4442
4537
  }
4443
4538
  };
4539
+ const finalConfig = deepMerge$1(originalConfig, newConfig);
4444
4540
  debugLog("[更新配置] 写入配置文件...");
4445
4541
  await fs.writeFile(paths.config, JSON.stringify(finalConfig, null, 2), "utf-8");
4446
4542
  this.prefixText += chalk.green(`✓ 配置文件更新成功
@@ -4614,6 +4710,19 @@ function getHomeDir() {
4614
4710
  return process$1.env.HOME || process$1.env.USERPROFILE || "";
4615
4711
  }
4616
4712
  const PLUGIN_PACKAGE_NAME = "@workclaw/openclaw-workclaw";
4713
+ function deepMerge(target, source) {
4714
+ const result = { ...target };
4715
+ for (const key in source) {
4716
+ const sourceValue = source[key];
4717
+ const targetValue = target[key];
4718
+ if (sourceValue !== void 0 && sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
4719
+ result[key] = deepMerge(targetValue, sourceValue);
4720
+ } else if (sourceValue !== void 0) {
4721
+ result[key] = sourceValue;
4722
+ }
4723
+ }
4724
+ return result;
4725
+ }
4617
4726
  class BoxInstaller {
4618
4727
  constructor(config) {
4619
4728
  this.config = config;
@@ -4635,76 +4744,80 @@ class BoxInstaller {
4635
4744
  if (!this.config.appSecret) {
4636
4745
  throw new AppError2(ERROR_CODES.APP_SECRET_REQUIRED, "AppSecret 不能为空,请使用 --app-secret 参数");
4637
4746
  }
4638
- debugLog("[验证配置] 配置验证通过");
4747
+ debugLog("[验证配置] 配置检查通过");
4748
+ }
4749
+ getPaths() {
4750
+ const home = getHomeDir();
4751
+ const openclawDir = path.join(home, ".openclaw");
4752
+ const extensionsDir = path.join(openclawDir, "extensions");
4753
+ const targetDir = path.join(extensionsDir, "openclaw-workclaw");
4754
+ const configFile = path.join(openclawDir, "openclaw.json");
4755
+ const workspaceDir = path.join(openclawDir, "workspace");
4756
+ const tempDir = path.join(openclawDir, ".temp");
4757
+ return {
4758
+ home,
4759
+ extensions: extensionsDir,
4760
+ target: targetDir,
4761
+ config: configFile,
4762
+ workspace: workspaceDir,
4763
+ temp: tempDir
4764
+ };
4765
+ }
4766
+ updateSpinner(text) {
4767
+ this.spinner.prefixText = this.prefixText;
4768
+ this.spinner.text = `${chalk.cyan("安装进度")} ${chalk.dim("→")} ${chalk.yellow(text)}`;
4769
+ debugLog(`[Spinner] ${text}`);
4770
+ }
4771
+ getPrefixText() {
4772
+ return this.prefixText;
4639
4773
  }
4640
4774
  async install() {
4641
4775
  try {
4642
- debugLog("[安装开始]");
4776
+ debugLog("[盒子安装] 开始安装...");
4643
4777
  this.validateConfig();
4644
- const env = this.config.env || "test";
4645
- const config = getConfig(env);
4646
- const homeDir = getHomeDir();
4647
- const paths = {
4648
- home: path.join(homeDir, config.DIRS.OPENCLAW),
4649
- extensions: path.join(homeDir, config.DIRS.OPENCLAW, config.DIRS.EXTENSIONS),
4650
- target: path.join(homeDir, config.DIRS.OPENCLAW, config.DIRS.EXTENSIONS, config.PLUGIN_NAME),
4651
- config: path.join(homeDir, config.DIRS.OPENCLAW, config.DIRS.CONFIG_FILE),
4652
- workspace: path.join(homeDir, config.DIRS.OPENCLAW, config.DIRS.WORKSPACE),
4653
- temp: path.join(homeDir, config.DIRS.OPENCLAW, config.DIRS.TEMP)
4654
- };
4655
- debugLog(`[路径配置] home=${paths.home}`);
4656
- debugLog(`[路径配置] extensions=${paths.extensions}`);
4657
- debugLog(`[路径配置] target=${paths.target}`);
4658
- debugLog(`[路径配置] config=${paths.config}`);
4659
- debugLog(`[路径配置] workspace=${paths.workspace}`);
4660
- await this.doCleanOldFiles(paths.target);
4778
+ this.updateSpinner("验证配置完成");
4779
+ const paths = this.getPaths();
4780
+ await this.doCleanOldFiles(paths);
4781
+ this.updateSpinner("清理旧版本完成");
4661
4782
  await this.doDownloadFromNpm(paths);
4662
- await this.doUpdateConfig(paths, env);
4783
+ this.updateSpinner("下载插件完成");
4784
+ await this.doUpdateConfig(paths);
4785
+ this.updateSpinner("更新配置完成");
4663
4786
  this.spinner.stop();
4787
+ debugLog("[盒子安装] 安装完成");
4664
4788
  } catch (error) {
4665
4789
  this.spinner.stop();
4790
+ debugLog(`[盒子安装] 安装失败: ${error.message}`);
4666
4791
  throw error;
4667
4792
  }
4668
4793
  }
4669
- getPrefixText() {
4670
- return this.prefixText;
4671
- }
4672
- async doCleanOldFiles(targetPath) {
4673
- this.spinner.prefixText = this.prefixText;
4674
- this.spinner.text = `${chalk.cyan("清理旧版本")} ${chalk.dim("→")} ${chalk.yellow("检查目录...")}`;
4675
- debugLog(`[清理旧版本] 检查目录: ${targetPath}`);
4794
+ async doCleanOldFiles(paths) {
4795
+ debugLog("[清理旧版本] 开始清理旧版本...");
4796
+ this.prefixText += chalk.green(`✓ 开始清理旧版本
4797
+ `);
4676
4798
  try {
4677
- await fs.access(targetPath);
4678
- debugLog("[清理旧版本] 发现旧版本,开始清理...");
4679
- this.spinner.prefixText = this.prefixText;
4680
- this.spinner.text = `${chalk.cyan("清理旧版本")} ${chalk.dim("→")} ${chalk.yellow("正在清理...")}`;
4681
- await fs.rm(targetPath, { recursive: true, force: true });
4682
- this.prefixText += chalk.green(`✓ 旧版本清理完成
4799
+ await fs.access(paths.target);
4800
+ debugLog("[清理旧版本] 删除旧版本目录...");
4801
+ await fs.rm(paths.target, { recursive: true, force: true });
4802
+ this.prefixText += chalk.green(`✓ 旧版本清理成功
4683
4803
  `);
4684
- debugLog("[清理旧版本] 清理完成");
4804
+ debugLog("[清理旧版本] 旧版本清理成功");
4685
4805
  } catch {
4686
- this.prefixText += chalk.green(`✓ 未发现旧版本
4806
+ debugLog("[清理旧版本] 无旧版本需要清理");
4807
+ this.prefixText += chalk.green(`✓ 无旧版本需要清理
4687
4808
  `);
4688
- debugLog("[清理旧版本] 未发现旧版本");
4809
+ }
4810
+ try {
4811
+ await fs.access(paths.temp);
4812
+ await fs.rm(paths.temp, { recursive: true, force: true });
4813
+ } catch {
4814
+ debugLog("[清理旧版本] 无临时目录需要清理");
4689
4815
  }
4690
4816
  }
4691
4817
  async doDownloadFromNpm(paths) {
4692
- this.spinner.prefixText = this.prefixText;
4693
- this.spinner.text = `${chalk.cyan("下载插件")} ${chalk.dim("→")} ${chalk.yellow("准备目录")}`;
4694
- debugLog("[下载插件] 创建扩展目录...");
4695
- await fs.mkdir(paths.extensions, { recursive: true });
4696
- debugLog(`[下载插件] 扩展目录: ${paths.extensions}`);
4697
- const tempDir = path.join(paths.temp, `install-${Date.now()}`);
4698
- debugLog(`[下载插件] 创建临时目录: ${tempDir}`);
4699
- await fs.mkdir(tempDir, { recursive: true });
4700
- this.spinner.prefixText = this.prefixText;
4701
- this.spinner.text = `${chalk.cyan("下载插件")} ${chalk.dim("→")} ${chalk.yellow("下载 tarball")}`;
4702
- debugLog("[下载插件] 执行 npm pack 下载源码包");
4703
- debugLog(`[下载插件] 工作目录: ${tempDir}`);
4704
- const tarballPath = await this.downloadTarball(tempDir);
4705
- await this.extractTarball(tarballPath, paths, tempDir);
4706
- }
4707
- async downloadTarball(tempDir) {
4818
+ debugLog("[下载插件] 开始下载插件...");
4819
+ this.prefixText += chalk.green(`✓ 开始下载插件
4820
+ `);
4708
4821
  const maxRetries = 3;
4709
4822
  let lastError = "";
4710
4823
  let tarballPath = "";
@@ -4716,10 +4829,10 @@ class BoxInstaller {
4716
4829
  const { execSync: execSync2 } = await import("node:child_process");
4717
4830
  const output = execSync2(
4718
4831
  `npm pack ${packageName} --registry=https://mirrors.tencent.com/npm/ --ignore-scripts`,
4719
- { cwd: tempDir, encoding: "utf-8", timeout: 6e4 }
4832
+ { cwd: paths.temp, encoding: "utf-8", timeout: 6e4 }
4720
4833
  );
4721
4834
  const filename = output.trim().split("\n").pop() || "";
4722
- tarballPath = path.join(tempDir, filename);
4835
+ tarballPath = path.join(paths.temp, filename);
4723
4836
  debugLog(`[下载插件] tarball 下载成功: ${tarballPath}`);
4724
4837
  break;
4725
4838
  } catch (error) {
@@ -4731,50 +4844,49 @@ class BoxInstaller {
4731
4844
  }
4732
4845
  }
4733
4846
  }
4734
- if (!tarballPath || !await fs.access(tarballPath).then(() => true).catch(() => false)) {
4735
- throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `tarball 下载失败: ${lastError}`);
4847
+ if (!tarballPath) {
4848
+ this.prefixText += chalk.red(`✗ 下载失败
4849
+ `);
4850
+ throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `插件下载失败: ${lastError}`);
4736
4851
  }
4737
- return tarballPath;
4852
+ this.prefixText += chalk.green(`✓ 插件下载成功
4853
+ `);
4854
+ await this.extractTarball(tarballPath, paths);
4738
4855
  }
4739
- async extractTarball(tarballPath, paths, tempDir) {
4740
- this.spinner.prefixText = this.prefixText;
4741
- this.spinner.text = `${chalk.cyan("下载插件")} ${chalk.dim("→")} ${chalk.yellow("解压 tarball")}`;
4742
- debugLog(`[下载插件] 创建插件目录: ${paths.target}`);
4743
- await fs.mkdir(paths.target, { recursive: true });
4744
- debugLog(`[下载插件] 解压 tarball 到: ${paths.target}`);
4856
+ async extractTarball(tarballPath, paths) {
4857
+ debugLog("[解压插件] 开始解压 tarball...");
4745
4858
  try {
4859
+ await fs.mkdir(paths.temp, { recursive: true });
4746
4860
  await tar.extract({
4747
4861
  file: tarballPath,
4748
- cwd: paths.target,
4749
- strip: 1
4862
+ cwd: paths.temp
4750
4863
  });
4751
- debugLog("[下载插件] tarball 解压成功");
4864
+ const packageDir = path.join(paths.temp, "package");
4865
+ const stat = await fs.stat(packageDir);
4866
+ if (stat.isDirectory()) {
4867
+ await fs.mkdir(paths.extensions, { recursive: true });
4868
+ await fs.cp(packageDir, paths.target, { recursive: true });
4869
+ debugLog(`[解压插件] 插件解压成功: ${paths.target}`);
4870
+ this.prefixText += chalk.green(`✓ 插件解压成功
4871
+ `);
4872
+ await fs.rm(paths.temp, { recursive: true, force: true });
4873
+ debugLog(`[解压插件] 清理临时文件成功`);
4874
+ this.prefixText += chalk.green(`✓ 清理临时文件成功
4875
+ `);
4876
+ } else {
4877
+ throw new Error("解压失败:package 目录不存在");
4878
+ }
4752
4879
  } catch (error) {
4753
- throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `tarball 解压失败: ${error.message}`);
4754
- }
4755
- const pluginPath = path.join(paths.target, "package.json");
4756
- const pluginExists = await fs.access(pluginPath).then(() => true).catch(() => false);
4757
- if (!pluginExists) {
4758
- throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
4759
- }
4760
- debugLog("[下载插件] 插件解压成功");
4761
- this.prefixText += chalk.green(`✓ 插件下载完成
4880
+ debugLog(`[解压插件] 解压失败: ${error.message}`);
4881
+ this.prefixText += chalk.red(`✗ 解压失败
4762
4882
  `);
4763
- try {
4764
- await fs.rm(tempDir, { recursive: true, force: true });
4765
- debugLog("[下载插件] 清理临时目录完成");
4766
- } catch {
4767
- debugLog("[下载插件] 清理临时目录失败(忽略)");
4883
+ throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `插件解压失败: ${error.message}`);
4768
4884
  }
4769
4885
  }
4770
- async doUpdateConfig(paths, env) {
4771
- this.spinner.prefixText = this.prefixText;
4772
- this.spinner.text = `${chalk.cyan("更新配置")} ${chalk.dim("→")} ${chalk.yellow("写入配置文件")}`;
4773
- debugLog("[更新配置] 创建目录...");
4774
- await fs.mkdir(paths.home, { recursive: true });
4775
- await fs.mkdir(paths.workspace, { recursive: true });
4776
- debugLog("[更新配置] 目录创建完成");
4777
- debugLog("[更新配置] 读取原有配置...");
4886
+ async doUpdateConfig(paths) {
4887
+ debugLog("[更新配置] 开始更新配置...");
4888
+ this.prefixText += chalk.green(`✓ 开始更新配置
4889
+ `);
4778
4890
  let originalConfig = {};
4779
4891
  try {
4780
4892
  const content = await fs.readFile(paths.config, "utf-8");
@@ -4783,105 +4895,179 @@ class BoxInstaller {
4783
4895
  } catch {
4784
4896
  debugLog("[更新配置] 无原有配置");
4785
4897
  }
4786
- const config = getConfig(env);
4787
- const finalConfig = {
4788
- ...originalConfig,
4898
+ const config = getConfig(this.config.env);
4899
+ const newConfig = {
4900
+ // diagnostics: 诊断配置
4789
4901
  diagnostics: {
4902
+ // 启用诊断功能
4790
4903
  enabled: true,
4904
+ // 启用所有诊断标志 ['*'] 表示全部,[] 表示禁用所有
4791
4905
  flags: ["*"]
4792
4906
  },
4907
+ // browser: 浏览器配置
4793
4908
  browser: {
4909
+ // 禁用浏览器工具
4794
4910
  enabled: false
4795
4911
  },
4912
+ // models: 模型配置
4796
4913
  models: {
4914
+ // 配置合并模式:'merge' 合并 | 'replace' 替换
4797
4915
  mode: "merge",
4798
4916
  providers: {
4799
4917
  "siliconflow-minimax": {
4918
+ // 模型 API 基础地址
4800
4919
  baseUrl: config.MODEL_BASE_URL,
4920
+ // API 密钥(留空,由外部提供)
4801
4921
  apiKey: "",
4922
+ // API 类型:'openai-completions' | 'openai-chat' 等
4802
4923
  api: "openai-completions",
4924
+ // 是否使用 Authorization header 认证
4803
4925
  authHeader: true,
4804
4926
  models: [{
4927
+ // 模型 ID(provider/model 格式)
4805
4928
  id: "Pro/MiniMaxAI/MiniMax-M2.5",
4929
+ // 模型显示名称
4806
4930
  name: "MiniMax-M2.5",
4931
+ // 是否启用推理能力
4807
4932
  reasoning: false,
4933
+ // 支持的输入类型:['text'] | ['text', 'image']
4808
4934
  input: ["text"],
4935
+ // 价格(0 表示免费或未设置)
4809
4936
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
4937
+ // 上下文窗口大小(token)
4810
4938
  contextWindow: 2e5,
4939
+ // 最大输出 token 数
4811
4940
  maxTokens: 65536
4812
4941
  }]
4813
4942
  }
4814
4943
  }
4815
4944
  },
4945
+ // agents: 代理配置
4816
4946
  agents: {
4817
4947
  defaults: {
4948
+ // 默认使用的模型
4818
4949
  model: { primary: "siliconflow-minimax/Pro/MiniMaxAI/MiniMax-M2.5" },
4819
4950
  models: {
4820
4951
  "siliconflow-minimax/Pro/MiniMaxAI/MiniMax-M2.5": {
4952
+ // 模型别名,用于显示
4821
4953
  alias: "Pro/MiniMaxAI/MiniMax-M2.5"
4822
4954
  }
4823
4955
  },
4956
+ // 工作区目录路径
4824
4957
  workspace: paths.workspace,
4958
+ // 会话压缩模式:'safeguard' 保守模式
4825
4959
  compaction: { mode: "safeguard" },
4960
+ // 详细程度:'full' | 'short' | 'off'
4826
4961
  verboseDefault: "full",
4962
+ // 最大并发任务数
4827
4963
  maxConcurrent: 4,
4964
+ // 子代理最大并发数
4828
4965
  subagents: { maxConcurrent: 8 }
4829
4966
  },
4967
+ // 代理列表
4830
4968
  list: [{ id: "main", workspace: paths.workspace }]
4831
4969
  },
4970
+ // tools: 工具配置
4832
4971
  tools: {
4972
+ // 禁用的工具列表(优先于 allow)
4833
4973
  deny: ["image", "web_search", "web_fetch"],
4974
+ // 图像分析工具
4834
4975
  media: { image: { enabled: false } },
4976
+ // 网络搜索和抓取工具
4835
4977
  web: { search: { enabled: false }, fetch: { enabled: false } },
4978
+ // 提升权限工具(host=gateway)
4836
4979
  elevated: { enabled: true, allowFrom: { webchat: ["*"] } },
4980
+ // exec 工具安全级别:'deny' | 'allowlist' | 'full'
4837
4981
  exec: { security: "full" }
4838
4982
  },
4983
+ // bindings: 绑定配置
4839
4984
  bindings: [{
4985
+ // 绑定的代理 ID
4840
4986
  agentId: "main",
4987
+ // 匹配的通道和账户
4841
4988
  match: { channel: "openclaw-workclaw", accountId: "default" }
4842
4989
  }],
4843
- messages: { ackReactionScope: "group-mentions" },
4990
+ // messages: 消息配置
4991
+ messages: {
4992
+ // 消息确认范围
4993
+ ackReactionScope: "group-mentions"
4994
+ },
4995
+ // commands: 命令配置
4844
4996
  commands: {
4997
+ // 本机命令:'auto' | 'on' | 'off'
4845
4998
  native: "auto",
4999
+ // 本机技能:'auto' | 'on' | 'off'
4846
5000
  nativeSkills: "auto",
5001
+ // 是否允许重启命令
4847
5002
  restart: true,
5003
+ // 所有者显示格式:'raw' | 'name' | 'hidden'
4848
5004
  ownerDisplay: "raw"
4849
5005
  },
4850
- session: { dmScope: "per-account-channel-peer" },
5006
+ // session: 会话配置
5007
+ session: {
5008
+ // DM 作用域
5009
+ dmScope: "per-account-channel-peer"
5010
+ },
5011
+ // hooks: 钩子配置
4851
5012
  hooks: {
4852
5013
  internal: {
5014
+ // 启用内部钩子
4853
5015
  enabled: true,
4854
5016
  entries: {
5017
+ // 启动 Markdown 钩子
4855
5018
  "boot-md": { enabled: true },
5019
+ // 引导额外文件钩子
4856
5020
  "bootstrap-extra-files": { enabled: true },
5021
+ // 命令日志钩子
4857
5022
  "command-logger": { enabled: true },
5023
+ // 会话记忆钩子
4858
5024
  "session-memory": { enabled: true }
4859
5025
  }
4860
5026
  }
4861
5027
  },
5028
+ // channels: 通道配置
4862
5029
  channels: {
4863
5030
  "openclaw-workclaw": {
5031
+ // 启用通道
4864
5032
  enabled: true,
5033
+ // 连接模式:'websocket' | 'http'
4865
5034
  connectionMode: "websocket",
5035
+ // WebSocket 连接策略
4866
5036
  wsConnectionStrategy: "per-appKey",
5037
+ // 应用密钥
4867
5038
  appKey: this.config.appKey,
5039
+ // 应用密钥
4868
5040
  appSecret: this.config.appSecret,
5041
+ // API 基础 URL
4869
5042
  baseUrl: this.config.baseUrl || config.DEFAULT_BASE_URL,
5043
+ // WebSocket URL
4870
5044
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
5045
+ // 允许不安全的 TLS 连接
4871
5046
  allowInsecureTls: true,
5047
+ // 允许原始 JSON 载荷
4872
5048
  allowRawJsonPayload: true,
4873
5049
  accounts: {
5050
+ // 账户配置(agentId 为空表示待分配)
4874
5051
  default: { enabled: true, agentId: "" }
4875
5052
  }
4876
5053
  }
4877
5054
  },
5055
+ // gateway: 网关配置
4878
5056
  gateway: {
5057
+ // 网关模式:'local' | 'hosted'
4879
5058
  mode: "local",
5059
+ // 网关端口
4880
5060
  port: 18789,
5061
+ // 绑定地址:'loopback' | 'lan' | 'all'
4881
5062
  bind: "loopback",
4882
- auth: { mode: "token", token: "" },
5063
+ // 认证模式(token字段未设置,是因为需要使用原始配置的token
5064
+ auth: {
5065
+ mode: "token"
5066
+ },
5067
+ // Tailscale 配置
4883
5068
  tailscale: { mode: "off", resetOnExit: false },
4884
5069
  nodes: {
5070
+ // 节点上禁止的命令
4885
5071
  denyCommands: [
4886
5072
  "camera.snap",
4887
5073
  "camera.clip",
@@ -4894,45 +5080,56 @@ class BoxInstaller {
4894
5080
  ]
4895
5081
  },
4896
5082
  controlUi: {
5083
+ // 允许不安全认证
4897
5084
  allowInsecureAuth: true,
5085
+ // 禁用设备认证(仅用于开发)
4898
5086
  dangerouslyDisableDeviceAuth: true,
5087
+ // 允许 Host 头源回退
4899
5088
  dangerouslyAllowHostHeaderOriginFallback: true,
5089
+ // 允许的源
4900
5090
  allowedOrigins: ["http://localhost:18789", "http://127.0.0.1:18789"]
4901
5091
  }
4902
5092
  },
4903
- skills: { load: { watch: true } },
5093
+ // skills: 技能配置
5094
+ skills: {
5095
+ // 技能加载监视模式
5096
+ load: { watch: true }
5097
+ },
5098
+ // logging: 日志配置
4904
5099
  logging: {
5100
+ // 日志级别:'debug' | 'info' | 'warn' | 'error'
4905
5101
  level: "info",
5102
+ // 控制台日志级别
4906
5103
  consoleLevel: "info",
5104
+ // 控制台样式:'pretty' | 'basic' | 'raw'
4907
5105
  consoleStyle: "pretty",
5106
+ // 敏感信息脱敏:'off' | 'keys' | 'all'
4908
5107
  redactSensitive: "off",
5108
+ // 日志文件路径(空表示不写入文件)
4909
5109
  file: "",
5110
+ // 脱敏模式(正则表达式)
4910
5111
  redactPatterns: ["sk-.*"]
4911
5112
  },
5113
+ // plugins: 插件配置
4912
5114
  plugins: {
5115
+ // 允许的插件列表
4913
5116
  allow: [config.PLUGIN_NAME],
5117
+ // 插件安装跟踪
4914
5118
  installs: {
4915
5119
  [config.PLUGIN_NAME]: {
4916
- source: "npm",
4917
- npm: "@workclaw/openclaw-workclaw",
5120
+ // npm 包名
5121
+ installSource: PLUGIN_PACKAGE_NAME,
5122
+ // 安装路径
4918
5123
  installPath: paths.target
4919
5124
  }
4920
5125
  },
5126
+ // 插件条目启用状态
4921
5127
  entries: {
4922
5128
  [config.PLUGIN_NAME]: { enabled: true }
4923
5129
  }
4924
- },
4925
- wizard: {
4926
- lastRunAt: "",
4927
- lastRunVersion: "",
4928
- lastRunCommand: "",
4929
- lastRunMode: ""
4930
- },
4931
- meta: {
4932
- lastTouchedVersion: "",
4933
- lastTouchedAt: ""
4934
5130
  }
4935
5131
  };
5132
+ const finalConfig = deepMerge(originalConfig, newConfig);
4936
5133
  debugLog("[更新配置] 写入配置文件...");
4937
5134
  await fs.writeFile(paths.config, JSON.stringify(finalConfig, null, 2), "utf-8");
4938
5135
  this.prefixText += chalk.green(`✓ 配置文件更新成功
@@ -4959,34 +5156,17 @@ function checkEnv() {
4959
5156
  }
4960
5157
  async function createBoxCommand(options) {
4961
5158
  setDebug(!!options.debug);
4962
- debugLog("[初始化] 开始处理...");
4963
- debugLog(`[初始化] 参数: scenario=${options.scenario}, env=${options.env}, appKey=${options.appKey}, debug=${options.debug}`);
5159
+ debugLog("[盒子安装] 开始处理...");
5160
+ debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, debug=${options.debug}`);
4964
5161
  checkEnv();
4965
- debugLog("[初始化] 环境检查通过");
5162
+ debugLog("[盒子安装] 环境检查通过");
4966
5163
  try {
4967
- let scenario = options.scenario;
4968
5164
  let env = options.env;
4969
5165
  let appKey = options.appKey;
4970
5166
  let appSecret = options.appSecret;
4971
5167
  const questions = [];
4972
- if (!scenario) {
4973
- debugLog("[初始化] 需要选择安装场景");
4974
- questions.push({
4975
- type: "list",
4976
- name: "scenario",
4977
- message: `${nodeEmoji.get("desktop_computer")} 请选择安装场景:`,
4978
- default: "windows-local",
4979
- choices: [
4980
- { name: `${chalk.green("Windows")} ${chalk.gray("本地安装")}`, value: "windows-local" },
4981
- { name: `${chalk.green("macOS")} ${chalk.gray("本地安装")}`, value: "mac-local" },
4982
- { name: `${chalk.green("Linux")} ${chalk.gray("本地安装")}`, value: "linux-local" }
4983
- ]
4984
- });
4985
- } else {
4986
- debugLog(`[初始化] 使用命令行参数: scenario=${scenario}`);
4987
- }
4988
5168
  if (!env) {
4989
- debugLog("[初始化] 需要选择环境");
5169
+ debugLog("[盒子安装] 需要选择环境");
4990
5170
  questions.push({
4991
5171
  type: "list",
4992
5172
  name: "env",
@@ -4998,10 +5178,10 @@ async function createBoxCommand(options) {
4998
5178
  ]
4999
5179
  });
5000
5180
  } else {
5001
- debugLog(`[初始化] 使用命令行参数: env=${env}`);
5181
+ debugLog(`[盒子安装] 使用命令行参数: env=${env}`);
5002
5182
  }
5003
5183
  if (!appKey) {
5004
- debugLog("[初始化] 需要输入 AppKey");
5184
+ debugLog("[盒子安装] 需要输入 AppKey");
5005
5185
  questions.push({
5006
5186
  type: "input",
5007
5187
  name: "appKey",
@@ -5014,10 +5194,10 @@ async function createBoxCommand(options) {
5014
5194
  }
5015
5195
  });
5016
5196
  } else {
5017
- debugLog("[初始化] 使用命令行参数: appKey");
5197
+ debugLog("[盒子安装] 使用命令行参数: appKey");
5018
5198
  }
5019
5199
  if (!appSecret) {
5020
- debugLog("[初始化] 需要输入 AppSecret");
5200
+ debugLog("[盒子安装] 需要输入 AppSecret");
5021
5201
  questions.push({
5022
5202
  type: "input",
5023
5203
  name: "appSecret",
@@ -5030,29 +5210,26 @@ async function createBoxCommand(options) {
5030
5210
  }
5031
5211
  });
5032
5212
  } else {
5033
- debugLog("[初始化] 使用命令行参数: appSecret");
5213
+ debugLog("[盒子安装] 使用命令行参数: appSecret");
5034
5214
  }
5035
5215
  if (questions.length > 0) {
5036
- debugLog(`[初始化] 开始交互式问答,共 ${questions.length} 个问题`);
5216
+ debugLog(`[盒子安装] 开始交互式问答,共 ${questions.length} 个问题`);
5037
5217
  const answers = await inquirer.prompt(questions);
5038
- debugLog("[初始化] 交互式问答完成");
5039
- scenario = scenario || answers.scenario;
5218
+ debugLog("[盒子安装] 交互式问答完成");
5040
5219
  env = env || answers.env || "test";
5041
5220
  appKey = appKey || answers.appKey;
5042
5221
  appSecret = appSecret || answers.appSecret;
5043
5222
  }
5044
- debugLog(`[初始化] 最终参数: scenario=${scenario}, env=${env}, pluginVersion=${options.pluginVersion}`);
5045
- debugLog("[初始化] 创建 BoxInstaller 实例...");
5223
+ debugLog(`[盒子安装] 最终参数: env=${env}`);
5224
+ debugLog("[盒子安装] 创建 BoxInstaller 实例...");
5046
5225
  const installer = new BoxInstaller({
5047
5226
  appKey,
5048
5227
  appSecret,
5049
- scenario,
5050
- env,
5051
- pluginVersion: options.pluginVersion
5228
+ env
5052
5229
  });
5053
- debugLog("[初始化] 开始安装...");
5230
+ debugLog("[盒子安装] 开始安装...");
5054
5231
  await installer.install();
5055
- debugLog("[初始化] 安装完成");
5232
+ debugLog("[盒子安装] 安装完成");
5056
5233
  console.log(installer.getPrefixText() + boxen(
5057
5234
  `${nodeEmoji.get("tada")} 插件初始化成功!`,
5058
5235
  {
@@ -5066,7 +5243,7 @@ async function createBoxCommand(options) {
5066
5243
  }
5067
5244
  ));
5068
5245
  } catch (error) {
5069
- debugLog(`[初始化] 发生错误: ${error.message}`);
5246
+ debugLog(`[盒子安装] 发生错误: ${error.message}`);
5070
5247
  console.error(boxen(
5071
5248
  `${chalk.yellow(error.message)}`,
5072
5249
  {
@@ -5083,7 +5260,7 @@ async function createBoxCommand(options) {
5083
5260
  }
5084
5261
  }
5085
5262
  function registerCommands(program2) {
5086
- program2.command("box").description("盒子设备安装(无需登录)").option("-s, --scenario <scenario>", "安装场景").option("-e, --env <env>", "环境 (test/prod)").option("--app-key <appKey>", "App Key").option("--app-secret <appSecret>", "App Secret").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--debug", "开启调试日志").action(createBoxCommand);
5263
+ 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("--debug", "开启调试日志").action(createBoxCommand);
5087
5264
  }
5088
5265
  const __filename$1 = fileURLToPath(import.meta.url);
5089
5266
  const __dirname$1 = dirname(__filename$1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-DrOcptQl.js").then((cli) => {
2
+ import("./index-CznpA35l.js").then((cli) => {
3
3
  cli.default();
4
4
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workclaw/cli",
3
3
  "type": "module",
4
- "version": "1.0.18",
4
+ "version": "1.0.20",
5
5
  "description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
6
6
  "license": "MIT",
7
7
  "keywords": [