@workclaw/cli 1.0.23 → 1.0.25
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as fsSync from "node:fs";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
2
3
|
import path, { resolve, dirname } from "node:path";
|
|
3
4
|
import process$1 from "node:process";
|
|
@@ -32,7 +33,9 @@ const ERROR_CODES$1 = {
|
|
|
32
33
|
NODE_NOT_FOUND: "NODE_NOT_FOUND",
|
|
33
34
|
NPM_NOT_FOUND: "NPM_NOT_FOUND",
|
|
34
35
|
NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED",
|
|
35
|
-
CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED"
|
|
36
|
+
CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED",
|
|
37
|
+
HTTP_ERROR: "HTTP_ERROR",
|
|
38
|
+
NETWORK_ERROR: "NETWORK_ERROR"
|
|
36
39
|
};
|
|
37
40
|
let AppError$1 = class AppError extends Error {
|
|
38
41
|
constructor(code, message) {
|
|
@@ -111,20 +114,20 @@ async function httpPost(url, data, config) {
|
|
|
111
114
|
debugLog(`[HTTP POST] 响应状态文本: ${axiosError.response.statusText}`);
|
|
112
115
|
debugLog(`[HTTP POST] 响应数据: ${JSON.stringify(responseData)}`);
|
|
113
116
|
if (typeof responseData === "string") {
|
|
114
|
-
throw new
|
|
117
|
+
throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求失败 (${axiosError.response.status}): ${responseData}`);
|
|
115
118
|
} else if (responseData && typeof responseData === "object" && "message" in responseData) {
|
|
116
|
-
throw new
|
|
119
|
+
throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求失败 (${axiosError.response.status}): ${responseData.message}`);
|
|
117
120
|
} else {
|
|
118
|
-
throw new
|
|
121
|
+
throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求失败 (${axiosError.response.status}): ${axiosError.response.statusText}`);
|
|
119
122
|
}
|
|
120
123
|
} else if (axiosError.request) {
|
|
121
124
|
debugLog(`[HTTP POST] 未收到响应`);
|
|
122
125
|
debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
|
|
123
|
-
throw new
|
|
126
|
+
throw new AppError$1(ERROR_CODES$1.NETWORK_ERROR, `网络错误: ${axiosError.message}`);
|
|
124
127
|
} else {
|
|
125
128
|
debugLog(`[HTTP POST] 请求配置错误`);
|
|
126
129
|
debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
|
|
127
|
-
throw new
|
|
130
|
+
throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求配置错误: ${axiosError.message}`);
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
133
|
}
|
|
@@ -4135,6 +4138,74 @@ class LocalInstaller {
|
|
|
4135
4138
|
}
|
|
4136
4139
|
debugLog("[验证配置] 配置验证通过");
|
|
4137
4140
|
}
|
|
4141
|
+
async installDependencies(targetPath) {
|
|
4142
|
+
this.spinner.prefixText = this.prefixText;
|
|
4143
|
+
this.spinner.text = `${chalk.cyan("安装依赖")} ${chalk.dim("→")} ${chalk.yellow("正在安装...")}`;
|
|
4144
|
+
const checkDependencies = () => {
|
|
4145
|
+
try {
|
|
4146
|
+
const nodeModulesPath = path.join(targetPath, "node_modules");
|
|
4147
|
+
const packageJsonPath = path.join(targetPath, "package.json");
|
|
4148
|
+
try {
|
|
4149
|
+
fsSync.accessSync(nodeModulesPath);
|
|
4150
|
+
} catch {
|
|
4151
|
+
return false;
|
|
4152
|
+
}
|
|
4153
|
+
const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, "utf-8"));
|
|
4154
|
+
const dependencies = Object.keys(packageJson.dependencies || {});
|
|
4155
|
+
for (const dep of dependencies) {
|
|
4156
|
+
const depPath = path.join(nodeModulesPath, dep);
|
|
4157
|
+
if (!fsSync.existsSync(depPath)) {
|
|
4158
|
+
debugLog(`[依赖检查] 缺少依赖: ${dep}`);
|
|
4159
|
+
return false;
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
return true;
|
|
4163
|
+
} catch {
|
|
4164
|
+
return false;
|
|
4165
|
+
}
|
|
4166
|
+
};
|
|
4167
|
+
const runInstall = () => {
|
|
4168
|
+
try {
|
|
4169
|
+
debugLog("[安装依赖] 执行 npm install");
|
|
4170
|
+
execSync("npm install --production", {
|
|
4171
|
+
cwd: targetPath,
|
|
4172
|
+
stdio: "pipe",
|
|
4173
|
+
timeout: 12e4
|
|
4174
|
+
});
|
|
4175
|
+
debugLog("[安装依赖] npm install 执行成功");
|
|
4176
|
+
return true;
|
|
4177
|
+
} catch (error) {
|
|
4178
|
+
const errorMsg = error.stderr?.toString() || error.message || "未知错误";
|
|
4179
|
+
debugLog(`[安装依赖] npm install 失败: ${errorMsg}`);
|
|
4180
|
+
return false;
|
|
4181
|
+
}
|
|
4182
|
+
};
|
|
4183
|
+
if (checkDependencies()) {
|
|
4184
|
+
debugLog("[安装依赖] 依赖检查通过");
|
|
4185
|
+
this.prefixText += chalk.green(`✓ 依赖检查通过
|
|
4186
|
+
`);
|
|
4187
|
+
return;
|
|
4188
|
+
}
|
|
4189
|
+
debugLog("[安装依赖] 依赖检查失败,尝试重新安装...");
|
|
4190
|
+
if (runInstall()) {
|
|
4191
|
+
if (checkDependencies()) {
|
|
4192
|
+
this.prefixText += chalk.green(`✓ 依赖安装成功
|
|
4193
|
+
`);
|
|
4194
|
+
return;
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
debugLog("[安装依赖] 第一次安装失败,尝试完整安装...");
|
|
4198
|
+
if (runInstall()) {
|
|
4199
|
+
if (checkDependencies()) {
|
|
4200
|
+
this.prefixText += chalk.green(`✓ 依赖安装成功
|
|
4201
|
+
`);
|
|
4202
|
+
return;
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
this.prefixText += chalk.red(`✗ 依赖安装失败
|
|
4206
|
+
`);
|
|
4207
|
+
throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, "插件依赖安装失败,请检查网络和 npm 配置");
|
|
4208
|
+
}
|
|
4138
4209
|
async install() {
|
|
4139
4210
|
try {
|
|
4140
4211
|
debugLog("[安装开始]");
|
|
@@ -4279,20 +4350,7 @@ class LocalInstaller {
|
|
|
4279
4350
|
throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
|
|
4280
4351
|
}
|
|
4281
4352
|
debugLog("[下载插件] 插件解压成功");
|
|
4282
|
-
this.
|
|
4283
|
-
this.spinner.text = `${chalk.cyan("下载插件")} ${chalk.dim("→")} ${chalk.yellow("安装依赖")}`;
|
|
4284
|
-
debugLog("[下载插件] 执行 npm install 安装生产环境依赖");
|
|
4285
|
-
try {
|
|
4286
|
-
execSync("npm install --production", {
|
|
4287
|
-
cwd: paths.target,
|
|
4288
|
-
stdio: "pipe",
|
|
4289
|
-
timeout: 12e4
|
|
4290
|
-
});
|
|
4291
|
-
debugLog("[下载插件] npm install 执行成功");
|
|
4292
|
-
} catch (error) {
|
|
4293
|
-
const errorMsg = error.stderr?.toString() || error.message || "未知错误";
|
|
4294
|
-
debugLog(`[下载插件] npm install 可能存在问题: ${errorMsg}`);
|
|
4295
|
-
}
|
|
4353
|
+
await this.installDependencies(paths.target);
|
|
4296
4354
|
this.prefixText += chalk.green(`✓ 插件下载完成
|
|
4297
4355
|
`);
|
|
4298
4356
|
try {
|
|
@@ -4469,9 +4527,14 @@ class LocalInstaller {
|
|
|
4469
4527
|
allowInsecureTls: true,
|
|
4470
4528
|
// 允许原始 JSON 载荷
|
|
4471
4529
|
allowRawJsonPayload: true,
|
|
4530
|
+
// 用户 ID
|
|
4531
|
+
userId: boundConfig.userId,
|
|
4472
4532
|
accounts: {
|
|
4473
4533
|
// 账户配置(agentId 从服务器获取)
|
|
4474
|
-
default: {
|
|
4534
|
+
default: {
|
|
4535
|
+
enabled: true,
|
|
4536
|
+
agentId: boundConfig.agentId
|
|
4537
|
+
}
|
|
4475
4538
|
}
|
|
4476
4539
|
}
|
|
4477
4540
|
},
|
|
@@ -4716,8 +4779,11 @@ const ERROR_CODES = {
|
|
|
4716
4779
|
APP_KEY_REQUIRED: "APP_KEY_REQUIRED",
|
|
4717
4780
|
APP_SECRET_REQUIRED: "APP_SECRET_REQUIRED",
|
|
4718
4781
|
NODE_VERSION_LOW: "NODE_VERSION_LOW",
|
|
4782
|
+
NODE_NOT_FOUND: "NODE_NOT_FOUND",
|
|
4719
4783
|
NPM_NOT_FOUND: "NPM_NOT_FOUND",
|
|
4720
|
-
NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED"
|
|
4784
|
+
NPM_INSTALL_FAILED: "NPM_INSTALL_FAILED",
|
|
4785
|
+
CONFIG_WRITE_FAILED: "CONFIG_WRITE_FAILED",
|
|
4786
|
+
PLUGIN_EXTRACT_FAILED: "PLUGIN_EXTRACT_FAILED"
|
|
4721
4787
|
};
|
|
4722
4788
|
class AppError2 extends Error {
|
|
4723
4789
|
constructor(code, message) {
|
|
@@ -4766,6 +4832,74 @@ class BoxInstaller {
|
|
|
4766
4832
|
}
|
|
4767
4833
|
debugLog("[验证配置] 配置检查通过");
|
|
4768
4834
|
}
|
|
4835
|
+
async installDependencies(targetPath) {
|
|
4836
|
+
this.spinner.prefixText = this.prefixText;
|
|
4837
|
+
this.spinner.text = `${chalk.cyan("安装依赖")} ${chalk.dim("→")} ${chalk.yellow("正在安装...")}`;
|
|
4838
|
+
const checkDependencies = () => {
|
|
4839
|
+
try {
|
|
4840
|
+
const nodeModulesPath = path.join(targetPath, "node_modules");
|
|
4841
|
+
const packageJsonPath = path.join(targetPath, "package.json");
|
|
4842
|
+
try {
|
|
4843
|
+
fsSync.accessSync(nodeModulesPath);
|
|
4844
|
+
} catch {
|
|
4845
|
+
return false;
|
|
4846
|
+
}
|
|
4847
|
+
const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, "utf-8"));
|
|
4848
|
+
const dependencies = Object.keys(packageJson.dependencies || {});
|
|
4849
|
+
for (const dep of dependencies) {
|
|
4850
|
+
const depPath = path.join(nodeModulesPath, dep);
|
|
4851
|
+
if (!fsSync.existsSync(depPath)) {
|
|
4852
|
+
debugLog(`[依赖检查] 缺少依赖: ${dep}`);
|
|
4853
|
+
return false;
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4856
|
+
return true;
|
|
4857
|
+
} catch {
|
|
4858
|
+
return false;
|
|
4859
|
+
}
|
|
4860
|
+
};
|
|
4861
|
+
const runInstall = () => {
|
|
4862
|
+
try {
|
|
4863
|
+
debugLog("[安装依赖] 执行 npm install");
|
|
4864
|
+
execSync("npm install --production", {
|
|
4865
|
+
cwd: targetPath,
|
|
4866
|
+
stdio: "pipe",
|
|
4867
|
+
timeout: 12e4
|
|
4868
|
+
});
|
|
4869
|
+
debugLog("[安装依赖] npm install 执行成功");
|
|
4870
|
+
return true;
|
|
4871
|
+
} catch (error) {
|
|
4872
|
+
const errorMsg = error.stderr?.toString() || error.message || "未知错误";
|
|
4873
|
+
debugLog(`[安装依赖] npm install 失败: ${errorMsg}`);
|
|
4874
|
+
return false;
|
|
4875
|
+
}
|
|
4876
|
+
};
|
|
4877
|
+
if (checkDependencies()) {
|
|
4878
|
+
debugLog("[安装依赖] 依赖检查通过");
|
|
4879
|
+
this.prefixText += chalk.green(`✓ 依赖检查通过
|
|
4880
|
+
`);
|
|
4881
|
+
return;
|
|
4882
|
+
}
|
|
4883
|
+
debugLog("[安装依赖] 依赖检查失败,尝试重新安装...");
|
|
4884
|
+
if (runInstall()) {
|
|
4885
|
+
if (checkDependencies()) {
|
|
4886
|
+
this.prefixText += chalk.green(`✓ 依赖安装成功
|
|
4887
|
+
`);
|
|
4888
|
+
return;
|
|
4889
|
+
}
|
|
4890
|
+
}
|
|
4891
|
+
debugLog("[安装依赖] 第一次安装失败,尝试完整安装...");
|
|
4892
|
+
if (runInstall()) {
|
|
4893
|
+
if (checkDependencies()) {
|
|
4894
|
+
this.prefixText += chalk.green(`✓ 依赖安装成功
|
|
4895
|
+
`);
|
|
4896
|
+
return;
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
this.prefixText += chalk.red(`✗ 依赖安装失败
|
|
4900
|
+
`);
|
|
4901
|
+
throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, "插件依赖安装失败,请检查网络和 npm 配置");
|
|
4902
|
+
}
|
|
4769
4903
|
getPaths() {
|
|
4770
4904
|
const home = getHomeDir();
|
|
4771
4905
|
const openclawDir = path.join(home, ".openclaw");
|
|
@@ -4889,28 +5023,13 @@ class BoxInstaller {
|
|
|
4889
5023
|
debugLog(`[解压插件] 插件解压成功: ${paths.target}`);
|
|
4890
5024
|
this.prefixText += chalk.green(`✓ 插件解压成功
|
|
4891
5025
|
`);
|
|
4892
|
-
this.
|
|
4893
|
-
this.spinner.text = `${chalk.cyan("安装依赖")} ${chalk.dim("→")} ${chalk.yellow("正在安装...")}`;
|
|
4894
|
-
debugLog("[安装依赖] 执行 npm install 安装生产环境依赖");
|
|
4895
|
-
try {
|
|
4896
|
-
execSync("npm install --production", {
|
|
4897
|
-
cwd: paths.target,
|
|
4898
|
-
stdio: "pipe",
|
|
4899
|
-
timeout: 12e4
|
|
4900
|
-
});
|
|
4901
|
-
debugLog("[安装依赖] npm install 执行成功");
|
|
4902
|
-
this.prefixText += chalk.green(`✓ 依赖安装成功
|
|
4903
|
-
`);
|
|
4904
|
-
} catch (error) {
|
|
4905
|
-
const errorMsg = error.stderr?.toString() || error.message || "未知错误";
|
|
4906
|
-
debugLog(`[安装依赖] npm install 可能存在问题: ${errorMsg}`);
|
|
4907
|
-
}
|
|
5026
|
+
await this.installDependencies(paths.target);
|
|
4908
5027
|
await fs.rm(paths.temp, { recursive: true, force: true });
|
|
4909
5028
|
debugLog(`[解压插件] 清理临时文件成功`);
|
|
4910
5029
|
this.prefixText += chalk.green(`✓ 清理临时文件成功
|
|
4911
5030
|
`);
|
|
4912
5031
|
} else {
|
|
4913
|
-
throw new
|
|
5032
|
+
throw new AppError2(ERROR_CODES.PLUGIN_EXTRACT_FAILED, "解压失败:package 目录不存在");
|
|
4914
5033
|
}
|
|
4915
5034
|
} catch (error) {
|
|
4916
5035
|
debugLog(`[解压插件] 解压失败: ${error.message}`);
|
|
@@ -5082,6 +5201,8 @@ class BoxInstaller {
|
|
|
5082
5201
|
allowInsecureTls: true,
|
|
5083
5202
|
// 允许原始 JSON 载荷
|
|
5084
5203
|
allowRawJsonPayload: true,
|
|
5204
|
+
// 用户 ID
|
|
5205
|
+
userId: "",
|
|
5085
5206
|
accounts: {
|
|
5086
5207
|
// 账户配置(agentId 为空表示待分配)
|
|
5087
5208
|
default: { enabled: true, agentId: "" }
|
package/dist/index.js
CHANGED