@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.
@@ -8,6 +8,7 @@ export declare class BoxInstaller {
8
8
  private getPaths;
9
9
  private updateSpinner;
10
10
  getPrefixText(): string;
11
+ private getPackageName;
11
12
  install(): Promise<void>;
12
13
  private doCleanOldFiles;
13
14
  private doDownloadFromNpm;
@@ -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;AAoDhE,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;IAIjB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA0BhB,eAAe;YA0Bf,iBAAiB;YAuBjB,cAAc;CAqQ7B"}
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
- debugLog("[安装插件] 开始安装插件...");
194
- this.prefixText += chalk.green(` ✓ 开始安装插件
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 execAsync$1(
200
- `openclaw plugins install ${PLUGIN_PACKAGE_NAME$1} --dangerously-force-unsafe-install --pin`,
201
- { timeout: 12e4 }
202
- );
203
- debugLog("[安装插件] openclaw plugins install 执行成功");
204
- this.prefixText += chalk.green(` ✓ 插件安装完成
205
- `);
252
+ await tar.extract({
253
+ file: tarballPath,
254
+ cwd: paths.target,
255
+ strip: 1
256
+ });
257
+ debugLog("[下载插件] tarball 解压成功");
206
258
  } catch (error) {
207
- const errorMsg = error.message || "未知错误";
208
- debugLog(`[安装插件] 安装失败: ${errorMsg}`);
209
- this.prefixText += chalk.red(`✗ 安装失败
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
- throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, `插件安装失败: ${errorMsg}`);
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(`[安装插件] 扩展目录: ${paths.extensions}`);
4747
- debugLog("[安装插件] 直接使用 pnpm npm 安装...");
4748
- try {
4749
- await fs.mkdir(paths.target, { recursive: true });
4750
- const packageJson = {
4751
- name: "temp-install",
4752
- version: "1.0.0",
4753
- private: true
4754
- };
4755
- await fs.writeFile(
4756
- path.join(paths.target, "package.json"),
4757
- JSON.stringify(packageJson, null, 2)
4758
- );
4759
- debugLog(`[安装插件] 执行 pnpm add ${PLUGIN_PACKAGE_NAME}`);
4760
- await execAsync(
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
- await execAsync(
4785
- `openclaw plugins install ${PLUGIN_PACKAGE_NAME} --dangerously-force-unsafe-install`,
4786
- { timeout: 12e4 }
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
- debugLog("[安装插件] openclaw plugins install 执行成功");
4789
- this.prefixText += chalk.green(` ✓ 插件安装完成
4790
- `);
4791
- } catch (fallbackError) {
4792
- const fallbackErrorMsg = fallbackError.message || "未知错误";
4793
- debugLog(`[安装插件] openclaw 安装也失败: ${fallbackErrorMsg}`);
4794
- throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `插件安装失败: ${fallbackErrorMsg}`);
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,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-BBOjut3R.js").then((cli) => {
2
+ import("./index-CVmebGfl.js").then((cli) => {
3
3
  cli.default();
4
4
  });
@@ -7,6 +7,7 @@ export declare class LocalInstaller {
7
7
  validateConfig(): void;
8
8
  install(): Promise<void>;
9
9
  getPrefixText(): string;
10
+ private getPackageName;
10
11
  private doLogin;
11
12
  private doFetchBoundConfig;
12
13
  private doCleanOldFiles;
@@ -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;AAsD/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;YAIT,OAAO;YAoBP,kBAAkB;YAalB,eAAe;YAmBf,iBAAiB;YA2EjB,cAAc;CA+M7B"}
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.31",
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
  }