@workclaw/cli 1.0.17 → 1.0.19

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
@@ -21,7 +21,7 @@ npx @workclaw/cli local
21
21
  | 命令 | 说明 |
22
22
  |------|------|
23
23
  | `workclaw local` | 本地账户安装(需要登录) |
24
- | `workclaw box` | 盒子设备安装(无需登录) |
24
+ | `workclaw box` | 盒子设备安装(无需登录,仅支持 Linux) |
25
25
 
26
26
  ### 交互式初始化
27
27
 
@@ -52,14 +52,13 @@ npx @workclaw/cli box
52
52
 
53
53
  #### box 命令参数
54
54
 
55
- | 参数 | 缩写 | 说明 |
56
- | ---------------- | -- | -------------- |
57
- | --scenario | -s | 安装场景 |
55
+ | 参数 | 缩写 | 说明 |
56
+ | ---------------- | -- | ---- |
58
57
  | --env | -e | 环境 (test/prod) |
59
- | --app-key | 无 | App Key |
60
- | --app-secret | 无 | App Secret |
61
- | --plugin-version | 无 | 插件版本号 |
62
- | --debug | 无 | 调试模式 |
58
+ | --app-key | 无 | App Key |
59
+ | --app-secret | 无 | App Secret |
60
+ | --plugin-version | 无 | 插件版本号 |
61
+ | --debug | 无 | 调试模式 |
63
62
 
64
63
  ### 安装场景
65
64
 
@@ -122,7 +121,7 @@ workclaw local --scenario linux-local --phone 13800138000 --user-pass your_passw
122
121
 
123
122
  ### 盒子安装
124
123
 
125
- 盒子安装适用于不需要用户登录的场景,直接使用 AppKey 和 AppSecret 进行安装:
124
+ 盒子安装适用于不需要用户登录的场景,直接使用 AppKey 和 AppSecret 进行安装。**仅支持 Linux 环境**。
126
125
 
127
126
  ```bash
128
127
  # 基本用法
@@ -130,9 +129,6 @@ workclaw box --app-key your_app_key --app-secret your_app_secret
130
129
 
131
130
  # 指定环境
132
131
  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
132
  ```
137
133
 
138
134
  ### 指定插件版本
@@ -29,8 +29,10 @@ const ERROR_CODES$1 = {
29
29
  LOGIN_FAILED: "LOGIN_FAILED",
30
30
  GET_BOUND_CONFIG_FAILED: "GET_BOUND_CONFIG_FAILED",
31
31
  NODE_VERSION_LOW: "NODE_VERSION_LOW",
32
+ NODE_NOT_FOUND: "NODE_NOT_FOUND",
32
33
  NPM_NOT_FOUND: "NPM_NOT_FOUND",
33
- NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED"
34
+ NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED",
35
+ CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED"
34
36
  };
35
37
  let AppError$1 = class AppError extends Error {
36
38
  constructor(code, message) {
@@ -93,13 +95,38 @@ async function httpPost(url, data, config) {
93
95
  debugLog(`[HTTP POST] 请求地址: ${url}`);
94
96
  debugLog(`[HTTP POST] 请求参数: ${JSON.stringify(data)}`);
95
97
  debugLog(`[HTTP POST] 请求头: ${JSON.stringify(config?.headers || {})}`);
96
- const response = await client.post(url, data, config);
97
- debugLog(`[HTTP POST] 响应状态: ${response.status}`);
98
- debugLog(`[HTTP POST] 响应内容: ${JSON.stringify(response.data)}`);
99
- return {
100
- status: response.status,
101
- data: response.data
102
- };
98
+ try {
99
+ const response = await client.post(url, data, config);
100
+ debugLog(`[HTTP POST] 响应状态: ${response.status}`);
101
+ debugLog(`[HTTP POST] 响应内容: ${JSON.stringify(response.data)}`);
102
+ return {
103
+ status: response.status,
104
+ data: response.data
105
+ };
106
+ } catch (error) {
107
+ const axiosError = error;
108
+ if (axiosError.response) {
109
+ const responseData = axiosError.response.data;
110
+ debugLog(`[HTTP POST] 响应状态: ${axiosError.response.status}`);
111
+ debugLog(`[HTTP POST] 响应状态文本: ${axiosError.response.statusText}`);
112
+ debugLog(`[HTTP POST] 响应数据: ${JSON.stringify(responseData)}`);
113
+ if (typeof responseData === "string") {
114
+ throw new Error(`请求失败 (${axiosError.response.status}): ${responseData}`);
115
+ } else if (responseData && typeof responseData === "object" && "message" in responseData) {
116
+ throw new Error(`请求失败 (${axiosError.response.status}): ${responseData.message}`);
117
+ } else {
118
+ throw new Error(`请求失败 (${axiosError.response.status}): ${axiosError.response.statusText}`);
119
+ }
120
+ } else if (axiosError.request) {
121
+ debugLog(`[HTTP POST] 未收到响应`);
122
+ debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
123
+ throw new Error(`网络错误: ${axiosError.message}`);
124
+ } else {
125
+ debugLog(`[HTTP POST] 请求配置错误`);
126
+ debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
127
+ throw new Error(`请求配置错误: ${axiosError.message}`);
128
+ }
129
+ }
103
130
  }
104
131
  async function login(phone, password, env) {
105
132
  const config = getConfig(env);
@@ -107,18 +134,26 @@ async function login(phone, password, env) {
107
134
  debugLog("[登录] 开始登录...");
108
135
  debugLog(`[登录] 请求地址: ${url}`);
109
136
  debugLog(`[登录] 请求参数: phone=${phone}, password=***`);
110
- const response = await httpPost(url, {
111
- phone,
112
- userPass: password
113
- });
114
- const data = response.data;
115
- debugLog(`[登录] 响应数据: ${JSON.stringify(data)}`);
116
- if (data.code === 200 && data.data?.token) {
117
- debugLog("[登录] 登录成功,获取到 token");
118
- return data.data.token;
137
+ try {
138
+ const response = await httpPost(url, {
139
+ phone,
140
+ userPass: password
141
+ });
142
+ const data = response.data;
143
+ debugLog(`[登录] 响应数据: ${JSON.stringify(data)}`);
144
+ if (data.code === 200 && data.data?.token) {
145
+ debugLog("[登录] 登录成功,获取到 token");
146
+ return data.data.token;
147
+ }
148
+ debugLog("[登录] 登录失败");
149
+ throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, data.message || "登录失败");
150
+ } catch (error) {
151
+ if (error instanceof AppError$1) {
152
+ throw error;
153
+ }
154
+ debugLog(`[登录] 发生错误: ${error.message}`);
155
+ throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, error.message);
119
156
  }
120
- debugLog("[登录] 登录失败");
121
- throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, data.message || "登录失败");
122
157
  }
123
158
  async function fetchBoundConfig(token, phone, env) {
124
159
  const config = getConfig(env);
@@ -127,40 +162,48 @@ async function fetchBoundConfig(token, phone, env) {
127
162
  debugLog(`[获取绑定配置] 请求地址: ${url}`);
128
163
  debugLog(`[获取绑定配置] 请求参数: phone=${phone}, localCode=001`);
129
164
  debugLog(`[获取绑定配置] 请求头: Authorization=${token.substring(0, 20)}...`);
130
- const response = await httpPost(url, {
131
- phone,
132
- localCode: "001"
133
- }, {
134
- headers: {
135
- Authorization: token
165
+ try {
166
+ const response = await httpPost(url, {
167
+ phone,
168
+ localCode: "001"
169
+ }, {
170
+ headers: {
171
+ Authorization: token
172
+ }
173
+ });
174
+ const data = response.data;
175
+ debugLog(`[获取绑定配置] 响应数据: ${JSON.stringify(data)}`);
176
+ if (data.code === 200 && data.data) {
177
+ const boundConfig = {
178
+ appKey: data.data.app_key,
179
+ appSecret: data.data.app_secret,
180
+ userId: data.data.user_id,
181
+ agentId: data.data.agent_id || data.data.agents?.[0]?.id,
182
+ modelApiKey: data.data.model_api_key,
183
+ modelApiBaseUrl: data.data.model_api_base_url
184
+ };
185
+ debugLog("[获取绑定配置] 获取绑定配置成功");
186
+ debugLog(`[获取绑定配置] appKey: ${boundConfig.appKey}`);
187
+ debugLog(`[获取绑定配置] appSecret: ${boundConfig.appSecret ? "***" : "undefined"}`);
188
+ debugLog(`[获取绑定配置] userId: ${boundConfig.userId}`);
189
+ debugLog(`[获取绑定配置] agentId: ${boundConfig.agentId}`);
190
+ debugLog(`[获取绑定配置] modelApiKey: ${boundConfig.modelApiKey || "undefined"}`);
191
+ debugLog(`[获取绑定配置] modelApiBaseUrl: ${boundConfig.modelApiBaseUrl || "undefined"}`);
192
+ if (!boundConfig.appKey || !boundConfig.appSecret || !boundConfig.agentId) {
193
+ debugLog("[获取绑定配置] 缺少必要字段");
194
+ throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, "获取绑定配置失败:缺少必要字段");
195
+ }
196
+ return boundConfig;
136
197
  }
137
- });
138
- const data = response.data;
139
- debugLog(`[获取绑定配置] 响应数据: ${JSON.stringify(data)}`);
140
- if (data.code === 200 && data.data) {
141
- const boundConfig = {
142
- appKey: data.data.app_key,
143
- appSecret: data.data.app_secret,
144
- userId: data.data.user_id,
145
- agentId: data.data.agent_id || data.data.agents?.[0]?.id,
146
- modelApiKey: data.data.model_api_key,
147
- modelApiBaseUrl: data.data.model_api_base_url
148
- };
149
- debugLog("[获取绑定配置] 获取绑定配置成功");
150
- debugLog(`[获取绑定配置] appKey: ${boundConfig.appKey}`);
151
- debugLog(`[获取绑定配置] appSecret: ${boundConfig.appSecret ? "***" : "undefined"}`);
152
- debugLog(`[获取绑定配置] userId: ${boundConfig.userId}`);
153
- debugLog(`[获取绑定配置] agentId: ${boundConfig.agentId}`);
154
- debugLog(`[获取绑定配置] modelApiKey: ${boundConfig.modelApiKey || "undefined"}`);
155
- debugLog(`[获取绑定配置] modelApiBaseUrl: ${boundConfig.modelApiBaseUrl || "undefined"}`);
156
- if (!boundConfig.appKey || !boundConfig.appSecret || !boundConfig.agentId) {
157
- debugLog("[获取绑定配置] 缺少必要字段");
158
- throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, "获取绑定配置失败:缺少必要字段");
198
+ debugLog("[获取绑定配置] 获取绑定配置失败");
199
+ throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, data.message || data.msg || "获取绑定配置失败");
200
+ } catch (error) {
201
+ if (error instanceof AppError$1) {
202
+ throw error;
159
203
  }
160
- return boundConfig;
204
+ debugLog(`[获取绑定配置] 发生错误: ${error.message}`);
205
+ throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, error.message);
161
206
  }
162
- debugLog("[获取绑定配置] 获取绑定配置失败");
163
- throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, data.message || data.msg || "获取绑定配置失败");
164
207
  }
165
208
  var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
166
209
  function int2char(n) {
@@ -4916,34 +4959,17 @@ function checkEnv() {
4916
4959
  }
4917
4960
  async function createBoxCommand(options) {
4918
4961
  setDebug(!!options.debug);
4919
- debugLog("[初始化] 开始处理...");
4920
- debugLog(`[初始化] 参数: scenario=${options.scenario}, env=${options.env}, appKey=${options.appKey}, debug=${options.debug}`);
4962
+ debugLog("[盒子安装] 开始处理...");
4963
+ debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, debug=${options.debug}`);
4921
4964
  checkEnv();
4922
- debugLog("[初始化] 环境检查通过");
4965
+ debugLog("[盒子安装] 环境检查通过");
4923
4966
  try {
4924
- let scenario = options.scenario;
4925
4967
  let env = options.env;
4926
4968
  let appKey = options.appKey;
4927
4969
  let appSecret = options.appSecret;
4928
4970
  const questions = [];
4929
- if (!scenario) {
4930
- debugLog("[初始化] 需要选择安装场景");
4931
- questions.push({
4932
- type: "list",
4933
- name: "scenario",
4934
- message: `${nodeEmoji.get("desktop_computer")} 请选择安装场景:`,
4935
- default: "windows-local",
4936
- choices: [
4937
- { name: `${chalk.green("Windows")} ${chalk.gray("本地安装")}`, value: "windows-local" },
4938
- { name: `${chalk.green("macOS")} ${chalk.gray("本地安装")}`, value: "mac-local" },
4939
- { name: `${chalk.green("Linux")} ${chalk.gray("本地安装")}`, value: "linux-local" }
4940
- ]
4941
- });
4942
- } else {
4943
- debugLog(`[初始化] 使用命令行参数: scenario=${scenario}`);
4944
- }
4945
4971
  if (!env) {
4946
- debugLog("[初始化] 需要选择环境");
4972
+ debugLog("[盒子安装] 需要选择环境");
4947
4973
  questions.push({
4948
4974
  type: "list",
4949
4975
  name: "env",
@@ -4955,10 +4981,10 @@ async function createBoxCommand(options) {
4955
4981
  ]
4956
4982
  });
4957
4983
  } else {
4958
- debugLog(`[初始化] 使用命令行参数: env=${env}`);
4984
+ debugLog(`[盒子安装] 使用命令行参数: env=${env}`);
4959
4985
  }
4960
4986
  if (!appKey) {
4961
- debugLog("[初始化] 需要输入 AppKey");
4987
+ debugLog("[盒子安装] 需要输入 AppKey");
4962
4988
  questions.push({
4963
4989
  type: "input",
4964
4990
  name: "appKey",
@@ -4971,10 +4997,10 @@ async function createBoxCommand(options) {
4971
4997
  }
4972
4998
  });
4973
4999
  } else {
4974
- debugLog("[初始化] 使用命令行参数: appKey");
5000
+ debugLog("[盒子安装] 使用命令行参数: appKey");
4975
5001
  }
4976
5002
  if (!appSecret) {
4977
- debugLog("[初始化] 需要输入 AppSecret");
5003
+ debugLog("[盒子安装] 需要输入 AppSecret");
4978
5004
  questions.push({
4979
5005
  type: "input",
4980
5006
  name: "appSecret",
@@ -4987,29 +5013,26 @@ async function createBoxCommand(options) {
4987
5013
  }
4988
5014
  });
4989
5015
  } else {
4990
- debugLog("[初始化] 使用命令行参数: appSecret");
5016
+ debugLog("[盒子安装] 使用命令行参数: appSecret");
4991
5017
  }
4992
5018
  if (questions.length > 0) {
4993
- debugLog(`[初始化] 开始交互式问答,共 ${questions.length} 个问题`);
5019
+ debugLog(`[盒子安装] 开始交互式问答,共 ${questions.length} 个问题`);
4994
5020
  const answers = await inquirer.prompt(questions);
4995
- debugLog("[初始化] 交互式问答完成");
4996
- scenario = scenario || answers.scenario;
5021
+ debugLog("[盒子安装] 交互式问答完成");
4997
5022
  env = env || answers.env || "test";
4998
5023
  appKey = appKey || answers.appKey;
4999
5024
  appSecret = appSecret || answers.appSecret;
5000
5025
  }
5001
- debugLog(`[初始化] 最终参数: scenario=${scenario}, env=${env}, pluginVersion=${options.pluginVersion}`);
5002
- debugLog("[初始化] 创建 BoxInstaller 实例...");
5026
+ debugLog(`[盒子安装] 最终参数: env=${env}`);
5027
+ debugLog("[盒子安装] 创建 BoxInstaller 实例...");
5003
5028
  const installer = new BoxInstaller({
5004
5029
  appKey,
5005
5030
  appSecret,
5006
- scenario,
5007
- env,
5008
- pluginVersion: options.pluginVersion
5031
+ env
5009
5032
  });
5010
- debugLog("[初始化] 开始安装...");
5033
+ debugLog("[盒子安装] 开始安装...");
5011
5034
  await installer.install();
5012
- debugLog("[初始化] 安装完成");
5035
+ debugLog("[盒子安装] 安装完成");
5013
5036
  console.log(installer.getPrefixText() + boxen(
5014
5037
  `${nodeEmoji.get("tada")} 插件初始化成功!`,
5015
5038
  {
@@ -5023,7 +5046,7 @@ async function createBoxCommand(options) {
5023
5046
  }
5024
5047
  ));
5025
5048
  } catch (error) {
5026
- debugLog(`[初始化] 发生错误: ${error.message}`);
5049
+ debugLog(`[盒子安装] 发生错误: ${error.message}`);
5027
5050
  console.error(boxen(
5028
5051
  `${chalk.yellow(error.message)}`,
5029
5052
  {
@@ -5040,7 +5063,7 @@ async function createBoxCommand(options) {
5040
5063
  }
5041
5064
  }
5042
5065
  function registerCommands(program2) {
5043
- 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);
5066
+ 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);
5044
5067
  }
5045
5068
  const __filename$1 = fileURLToPath(import.meta.url);
5046
5069
  const __dirname$1 = dirname(__filename$1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-39c6v1yS.js").then((cli) => {
2
+ import("./index-K7R_QFg0.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.17",
4
+ "version": "1.0.19",
5
5
  "description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
6
6
  "license": "MIT",
7
7
  "keywords": [