@workclaw/cli 1.0.31 → 1.0.312
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/dist/box/installer/installer.d.ts +1 -0
- package/dist/box/installer/installer.d.ts.map +1 -1
- package/dist/{index-BBOjut3R.js → index-CVmebGfl.js} +198 -65
- package/dist/index.js +1 -1
- package/dist/local/installer/installer.d.ts +1 -0
- package/dist/local/installer/installer.d.ts.map +1 -1
- package/package.json +4 -2
|
@@ -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;
|
|
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;IAmBhB,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"}
|
|
@@ -9,6 +9,7 @@ import chalk from "chalk";
|
|
|
9
9
|
import inquirer from "inquirer";
|
|
10
10
|
import semver from "semver";
|
|
11
11
|
import fs from "node:fs/promises";
|
|
12
|
+
import tar from "tar";
|
|
12
13
|
import ora from "ora";
|
|
13
14
|
import axios from "axios";
|
|
14
15
|
import "node:os";
|
|
@@ -146,6 +147,12 @@ class BoxInstaller {
|
|
|
146
147
|
getPrefixText() {
|
|
147
148
|
return this.prefixText;
|
|
148
149
|
}
|
|
150
|
+
getPackageName() {
|
|
151
|
+
if (this.config.pluginVersion) {
|
|
152
|
+
return `${PLUGIN_PACKAGE_NAME$1}@${this.config.pluginVersion}`;
|
|
153
|
+
}
|
|
154
|
+
return PLUGIN_PACKAGE_NAME$1;
|
|
155
|
+
}
|
|
149
156
|
async install() {
|
|
150
157
|
try {
|
|
151
158
|
debugLog("[盒子安装] 开始安装...");
|
|
@@ -190,25 +197,97 @@ class BoxInstaller {
|
|
|
190
197
|
}
|
|
191
198
|
}
|
|
192
199
|
async doDownloadFromNpm() {
|
|
193
|
-
|
|
194
|
-
this.prefixText
|
|
195
|
-
|
|
200
|
+
const paths = this.getPaths();
|
|
201
|
+
this.spinner.prefixText = this.prefixText;
|
|
202
|
+
this.spinner.text = chalk.cyan("正在准备安装目录...");
|
|
203
|
+
debugLog("[下载插件] 创建扩展目录...");
|
|
204
|
+
await fs.mkdir(paths.extensions, { recursive: true });
|
|
205
|
+
debugLog(`[下载插件] 扩展目录: ${paths.extensions}`);
|
|
206
|
+
const tempDir = path.join(paths.temp, `install-${Date.now()}`);
|
|
207
|
+
debugLog(`[下载插件] 创建临时目录: ${tempDir}`);
|
|
208
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
196
209
|
this.spinner.prefixText = this.prefixText;
|
|
197
|
-
this.spinner.text = chalk.cyan("
|
|
210
|
+
this.spinner.text = chalk.cyan("正在下载插件...");
|
|
211
|
+
debugLog("[下载插件] 执行 npm pack 下载源码包");
|
|
212
|
+
debugLog(`[下载插件] 工作目录: ${tempDir}`);
|
|
213
|
+
const maxRetries = 3;
|
|
214
|
+
let lastError = "";
|
|
215
|
+
let tarballPath = "";
|
|
216
|
+
for (let i = 1; i <= maxRetries; i++) {
|
|
217
|
+
this.spinner.prefixText = this.prefixText;
|
|
218
|
+
this.spinner.text = chalk.cyan(`正在下载 (${i}/${maxRetries})...`);
|
|
219
|
+
debugLog(`[下载插件] 第 ${i} 次尝试下载 tarball...`);
|
|
220
|
+
try {
|
|
221
|
+
const packageName = this.getPackageName();
|
|
222
|
+
debugLog(`[下载插件] 下载包名: ${packageName}`);
|
|
223
|
+
this.spinner.text = chalk.cyan("正在从 npm 获取插件...");
|
|
224
|
+
const output = await execAsync$1(
|
|
225
|
+
`npm pack ${packageName} --registry=https://mirrors.tencent.com/npm/ --ignore-scripts --quiet`,
|
|
226
|
+
{ cwd: tempDir, timeout: 12e4 }
|
|
227
|
+
);
|
|
228
|
+
const lines = output.trim().split("\n").filter((line) => line.trim());
|
|
229
|
+
const filename = lines[lines.length - 1] || "";
|
|
230
|
+
tarballPath = path.join(tempDir, filename);
|
|
231
|
+
debugLog(`[下载插件] tarball 下载成功: ${tarballPath}`);
|
|
232
|
+
break;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
lastError = error.message || "未知错误";
|
|
235
|
+
debugLog(`[下载插件] 第 ${i} 次尝试失败: ${lastError}`);
|
|
236
|
+
if (i < maxRetries) {
|
|
237
|
+
this.spinner.text = chalk.cyan(`下载失败,3秒后重试...`);
|
|
238
|
+
debugLog("[下载插件] 等待 3 秒后重试...");
|
|
239
|
+
await new Promise((resolve2) => setTimeout(resolve2, 3e3));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (!tarballPath || !await fs.access(tarballPath).then(() => true).catch(() => false)) {
|
|
244
|
+
throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, `tarball 下载失败: ${lastError}`);
|
|
245
|
+
}
|
|
246
|
+
this.spinner.prefixText = this.prefixText;
|
|
247
|
+
this.spinner.text = chalk.cyan("正在解压插件...");
|
|
248
|
+
debugLog(`[下载插件] 创建插件目录: ${paths.target}`);
|
|
249
|
+
await fs.mkdir(paths.target, { recursive: true });
|
|
250
|
+
debugLog(`[下载插件] 解压 tarball 到: ${paths.target}`);
|
|
198
251
|
try {
|
|
199
|
-
await
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
`);
|
|
252
|
+
await tar.extract({
|
|
253
|
+
file: tarballPath,
|
|
254
|
+
cwd: paths.target,
|
|
255
|
+
strip: 1
|
|
256
|
+
});
|
|
257
|
+
debugLog("[下载插件] tarball 解压成功");
|
|
206
258
|
} catch (error) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
259
|
+
throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, `tarball 解压失败: ${error.message}`);
|
|
260
|
+
}
|
|
261
|
+
const pluginPath = path.join(paths.target, "package.json");
|
|
262
|
+
const pluginExists = await fs.access(pluginPath).then(() => true).catch(() => false);
|
|
263
|
+
if (!pluginExists) {
|
|
264
|
+
throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
|
|
265
|
+
}
|
|
266
|
+
debugLog("[下载插件] 插件解压成功");
|
|
267
|
+
this.spinner.prefixText = this.prefixText;
|
|
268
|
+
this.spinner.text = chalk.cyan("正在安装依赖...");
|
|
269
|
+
debugLog("[下载插件] 执行 npm install 安装生产环境依赖");
|
|
270
|
+
try {
|
|
271
|
+
await execAsync$1("npm install --omit=dev --ignore-scripts --quiet", {
|
|
272
|
+
cwd: paths.target,
|
|
273
|
+
timeout: 12e4
|
|
274
|
+
});
|
|
275
|
+
debugLog("[下载插件] npm install 执行成功");
|
|
276
|
+
} catch (error) {
|
|
277
|
+
const errorMsg = error.message || "";
|
|
278
|
+
if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) {
|
|
279
|
+
debugLog("[下载插件] npm install 有警告但可能成功,继续流程");
|
|
280
|
+
} else {
|
|
281
|
+
debugLog(`[下载插件] npm install 失败: ${errorMsg}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
this.prefixText += chalk.green(` ✓ 插件安装完成
|
|
210
285
|
`);
|
|
211
|
-
|
|
286
|
+
try {
|
|
287
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
288
|
+
debugLog("[下载插件] 清理临时目录完成");
|
|
289
|
+
} catch {
|
|
290
|
+
debugLog("[下载插件] 清理临时目录失败(忽略)");
|
|
212
291
|
}
|
|
213
292
|
}
|
|
214
293
|
async doUpdateConfig(paths) {
|
|
@@ -444,7 +523,19 @@ class BoxInstaller {
|
|
|
444
523
|
redactPatterns: ["sk-.*"]
|
|
445
524
|
},
|
|
446
525
|
// plugins: 插件配置
|
|
447
|
-
plugins: {
|
|
526
|
+
plugins: {
|
|
527
|
+
allow: [config.PLUGIN_NAME],
|
|
528
|
+
installs: {
|
|
529
|
+
[config.PLUGIN_NAME]: {
|
|
530
|
+
source: "npm",
|
|
531
|
+
spec: PLUGIN_PACKAGE_NAME$1,
|
|
532
|
+
installPath: paths.target
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
entries: {
|
|
536
|
+
[config.PLUGIN_NAME]: { enabled: true }
|
|
537
|
+
}
|
|
538
|
+
}
|
|
448
539
|
};
|
|
449
540
|
const finalConfig = deepMerge$1(originalConfig, newConfig);
|
|
450
541
|
this.updateSpinner("正在写入配置...");
|
|
@@ -4692,6 +4783,12 @@ class LocalInstaller {
|
|
|
4692
4783
|
getPrefixText() {
|
|
4693
4784
|
return this.prefixText;
|
|
4694
4785
|
}
|
|
4786
|
+
getPackageName() {
|
|
4787
|
+
if (this.config.pluginVersion) {
|
|
4788
|
+
return `${PLUGIN_PACKAGE_NAME}@${this.config.pluginVersion}`;
|
|
4789
|
+
}
|
|
4790
|
+
return PLUGIN_PACKAGE_NAME;
|
|
4791
|
+
}
|
|
4695
4792
|
async doLogin(env) {
|
|
4696
4793
|
this.spinner.prefixText = this.prefixText;
|
|
4697
4794
|
this.spinner.text = chalk.cyan("正在验证账号...");
|
|
@@ -4740,60 +4837,96 @@ class LocalInstaller {
|
|
|
4740
4837
|
}
|
|
4741
4838
|
async doDownloadFromNpm(paths) {
|
|
4742
4839
|
this.spinner.prefixText = this.prefixText;
|
|
4743
|
-
this.spinner.text = chalk.cyan("
|
|
4744
|
-
debugLog("[
|
|
4840
|
+
this.spinner.text = chalk.cyan("正在准备安装目录...");
|
|
4841
|
+
debugLog("[下载插件] 创建扩展目录...");
|
|
4745
4842
|
await fs.mkdir(paths.extensions, { recursive: true });
|
|
4746
|
-
debugLog(`[
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
`pnpm add ${PLUGIN_PACKAGE_NAME}`,
|
|
4762
|
-
{ cwd: paths.target, timeout: 12e4 }
|
|
4763
|
-
);
|
|
4764
|
-
const nodeModulesPath = path.join(paths.target, "node_modules", PLUGIN_PACKAGE_NAME);
|
|
4765
|
-
const files = await fs.readdir(nodeModulesPath);
|
|
4766
|
-
for (const file of files) {
|
|
4767
|
-
const srcPath = path.join(nodeModulesPath, file);
|
|
4768
|
-
const destPath = path.join(paths.target, file);
|
|
4769
|
-
await fs.rename(srcPath, destPath);
|
|
4770
|
-
}
|
|
4771
|
-
await fs.rm(path.join(paths.target, "node_modules"), { recursive: true, force: true });
|
|
4772
|
-
await fs.unlink(path.join(paths.target, "package.json"));
|
|
4773
|
-
if (await fs.access(path.join(paths.target, "pnpm-lock.yaml")).then(() => true).catch(() => false)) {
|
|
4774
|
-
await fs.unlink(path.join(paths.target, "pnpm-lock.yaml"));
|
|
4775
|
-
}
|
|
4776
|
-
debugLog("[安装插件] pnpm 安装完成");
|
|
4777
|
-
this.prefixText += chalk.green(` ✓ 插件安装完成
|
|
4778
|
-
`);
|
|
4779
|
-
} catch (error) {
|
|
4780
|
-
const errorMsg = error.message || "未知错误";
|
|
4781
|
-
debugLog(`[安装插件] 安装失败: ${errorMsg}`);
|
|
4782
|
-
debugLog("[安装插件] 尝试使用 openclaw 安装...");
|
|
4843
|
+
debugLog(`[下载插件] 扩展目录: ${paths.extensions}`);
|
|
4844
|
+
const tempDir = path.join(paths.temp, `install-${Date.now()}`);
|
|
4845
|
+
debugLog(`[下载插件] 创建临时目录: ${tempDir}`);
|
|
4846
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
4847
|
+
this.spinner.prefixText = this.prefixText;
|
|
4848
|
+
this.spinner.text = chalk.cyan("正在下载插件...");
|
|
4849
|
+
debugLog("[下载插件] 执行 npm pack 下载源码包");
|
|
4850
|
+
debugLog(`[下载插件] 工作目录: ${tempDir}`);
|
|
4851
|
+
const maxRetries = 3;
|
|
4852
|
+
let lastError = "";
|
|
4853
|
+
let tarballPath = "";
|
|
4854
|
+
for (let i = 1; i <= maxRetries; i++) {
|
|
4855
|
+
this.spinner.prefixText = this.prefixText;
|
|
4856
|
+
this.spinner.text = chalk.cyan(`正在下载 (${i}/${maxRetries})...`);
|
|
4857
|
+
debugLog(`[下载插件] 第 ${i} 次尝试下载 tarball...`);
|
|
4783
4858
|
try {
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4859
|
+
const packageName = this.getPackageName();
|
|
4860
|
+
debugLog(`[下载插件] 下载包名: ${packageName}`);
|
|
4861
|
+
this.spinner.text = chalk.cyan("正在从 npm 获取插件...");
|
|
4862
|
+
const output = await execAsync(
|
|
4863
|
+
`npm pack ${packageName} --registry=https://mirrors.tencent.com/npm/ --ignore-scripts --quiet`,
|
|
4864
|
+
{ cwd: tempDir, timeout: 12e4 }
|
|
4787
4865
|
);
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4866
|
+
const lines = output.trim().split("\n").filter((line) => line.trim());
|
|
4867
|
+
const filename = lines[lines.length - 1] || "";
|
|
4868
|
+
tarballPath = path.join(tempDir, filename);
|
|
4869
|
+
debugLog(`[下载插件] tarball 下载成功: ${tarballPath}`);
|
|
4870
|
+
break;
|
|
4871
|
+
} catch (error) {
|
|
4872
|
+
lastError = error.message || "未知错误";
|
|
4873
|
+
debugLog(`[下载插件] 第 ${i} 次尝试失败: ${lastError}`);
|
|
4874
|
+
if (i < maxRetries) {
|
|
4875
|
+
this.spinner.text = chalk.cyan(`下载失败,3秒后重试...`);
|
|
4876
|
+
debugLog("[下载插件] 等待 3 秒后重试...");
|
|
4877
|
+
await new Promise((resolve2) => setTimeout(resolve2, 3e3));
|
|
4878
|
+
}
|
|
4795
4879
|
}
|
|
4796
4880
|
}
|
|
4881
|
+
if (!tarballPath || !await fs.access(tarballPath).then(() => true).catch(() => false)) {
|
|
4882
|
+
throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `tarball 下载失败: ${lastError}`);
|
|
4883
|
+
}
|
|
4884
|
+
this.spinner.prefixText = this.prefixText;
|
|
4885
|
+
this.spinner.text = chalk.cyan("正在解压插件...");
|
|
4886
|
+
debugLog(`[下载插件] 创建插件目录: ${paths.target}`);
|
|
4887
|
+
await fs.mkdir(paths.target, { recursive: true });
|
|
4888
|
+
debugLog(`[下载插件] 解压 tarball 到: ${paths.target}`);
|
|
4889
|
+
try {
|
|
4890
|
+
await tar.extract({
|
|
4891
|
+
file: tarballPath,
|
|
4892
|
+
cwd: paths.target,
|
|
4893
|
+
strip: 1
|
|
4894
|
+
});
|
|
4895
|
+
debugLog("[下载插件] tarball 解压成功");
|
|
4896
|
+
} catch (error) {
|
|
4897
|
+
throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `tarball 解压失败: ${error.message}`);
|
|
4898
|
+
}
|
|
4899
|
+
const pluginPath = path.join(paths.target, "package.json");
|
|
4900
|
+
const pluginExists = await fs.access(pluginPath).then(() => true).catch(() => false);
|
|
4901
|
+
if (!pluginExists) {
|
|
4902
|
+
throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
|
|
4903
|
+
}
|
|
4904
|
+
debugLog("[下载插件] 插件解压成功");
|
|
4905
|
+
this.spinner.prefixText = this.prefixText;
|
|
4906
|
+
this.spinner.text = chalk.cyan("正在安装依赖...");
|
|
4907
|
+
debugLog("[下载插件] 执行 npm install 安装生产环境依赖");
|
|
4908
|
+
try {
|
|
4909
|
+
await execAsync("npm install --omit=dev --ignore-scripts --quiet", {
|
|
4910
|
+
cwd: paths.target,
|
|
4911
|
+
timeout: 12e4
|
|
4912
|
+
});
|
|
4913
|
+
debugLog("[下载插件] npm install 执行成功");
|
|
4914
|
+
} catch (error) {
|
|
4915
|
+
const errorMsg = error.message || "";
|
|
4916
|
+
if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) {
|
|
4917
|
+
debugLog("[下载插件] npm install 有警告但可能成功,继续流程");
|
|
4918
|
+
} else {
|
|
4919
|
+
debugLog(`[下载插件] npm install 失败: ${errorMsg}`);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
this.prefixText += chalk.green(` ✓ 插件安装完成
|
|
4923
|
+
`);
|
|
4924
|
+
try {
|
|
4925
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
4926
|
+
debugLog("[下载插件] 清理临时目录完成");
|
|
4927
|
+
} catch {
|
|
4928
|
+
debugLog("[下载插件] 清理临时目录失败(忽略)");
|
|
4929
|
+
}
|
|
4797
4930
|
}
|
|
4798
4931
|
async doUpdateConfig(paths, boundConfig, env) {
|
|
4799
4932
|
this.spinner.prefixText = this.prefixText;
|
package/dist/index.js
CHANGED
|
@@ -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;
|
|
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;IAoC9B,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;YAOR,OAAO;YAoBP,kBAAkB;YAalB,eAAe;YAmBf,iBAAiB;YAmHjB,cAAc;CA+M7B"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workclaw/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.312",
|
|
5
5
|
"description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@types/semver": "^7.7.0",
|
|
30
|
+
"@types/tar": "^6.1.13",
|
|
30
31
|
"axios": "^1.7.9",
|
|
31
32
|
"boxen": "^8.0.1",
|
|
32
33
|
"chalk": "^5.6.2",
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"inquirer": "^12.7.0",
|
|
35
36
|
"jsencrypt": "^3.5.4",
|
|
36
37
|
"ora": "^8.2.0",
|
|
37
|
-
"semver": "^7.7.1"
|
|
38
|
+
"semver": "^7.7.1",
|
|
39
|
+
"tar": "^6.2.1"
|
|
38
40
|
}
|
|
39
41
|
}
|