@workclaw/cli 1.0.322 → 1.0.323

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.
@@ -24,8 +24,6 @@ function setDebug(enabled) {
24
24
  debug.disable();
25
25
  }
26
26
  }
27
- function debugLog(...args) {
28
- }
29
27
  const ERROR_CODES$1 = {
30
28
  PHONE_REQUIRED: "PHONE_REQUIRED",
31
29
  USER_PASS_REQUIRED: "USER_PASS_REQUIRED",
@@ -49,14 +47,18 @@ let AppError$1 = class AppError extends Error {
49
47
  }
50
48
  };
51
49
  function checkEnv() {
50
+ debug.log("[环境检查] 检测 Node.js 版本...");
52
51
  const nodeVersion = execSync("node --version", { stdio: "pipe" }).toString().trim();
52
+ debug.log(`[环境检查] Node.js 版本: ${nodeVersion}`);
53
53
  if (!semver.gte(nodeVersion, "18.0.0")) {
54
54
  throw new AppError$1(ERROR_CODES$1.NODE_VERSION_LOW, `Node.js 版本需要 >= 18.0.0,当前版本: ${nodeVersion}`);
55
55
  }
56
+ debug.log("[环境检查] Node.js 版本检查通过");
57
+ debug.log("[环境检查] 检测 npm...");
56
58
  try {
57
59
  const npmVersion = execSync("npm --version", { stdio: "pipe" }).toString().trim();
58
- debugLog(`[环境检查] npm 版本: ${npmVersion}`);
59
- debugLog("[环境检查] npm 检测通过");
60
+ debug.log(`[环境检查] npm 版本: ${npmVersion}`);
61
+ debug.log("[环境检查] npm 检测通过");
60
62
  } catch {
61
63
  throw new AppError$1(ERROR_CODES$1.NPM_NOT_FOUND, "未检测到 npm,请先安装 Node.js 和 npm");
62
64
  }
@@ -100,11 +102,13 @@ const wsUrlSchema = z$1.string().url({
100
102
  }).optional();
101
103
  z$1.boolean();
102
104
  function validateOpenclawPath(openclawPath) {
105
+ debug.log(`[路径验证] 开始验证路径: ${openclawPath}`);
103
106
  const result = openclawPathSchema.safeParse(openclawPath);
104
107
  if (!result.success) {
105
- debugLog(`[路径验证] 失败: ${result.error.issues[0].message}`);
108
+ debug.log(`[路径验证] 失败: ${result.error.issues[0].message}`);
106
109
  throw new Error(result.error.issues[0].message);
107
110
  }
111
+ debug.log(`[路径验证] 通过: ${openclawPath}`);
108
112
  }
109
113
  const CONFIG = {
110
114
  PLUGIN_NAME: "openclaw-workclaw",
@@ -226,6 +230,7 @@ class BoxInstaller {
226
230
  spinner;
227
231
  prefixText = "";
228
232
  validateConfig() {
233
+ debug.log("[验证配置] 检查 appKey 和 appSecret...");
229
234
  if (!this.config.appKey) {
230
235
  throw new AppError2(ERROR_CODES.APP_KEY_REQUIRED, "AppKey 不能为空,请使用 --app-key 参数");
231
236
  }
@@ -233,6 +238,7 @@ class BoxInstaller {
233
238
  throw new AppError2(ERROR_CODES.APP_SECRET_REQUIRED, "AppSecret 不能为空,请使用 --app-secret 参数");
234
239
  }
235
240
  if (this.config.env === "custom") {
241
+ debug.log("[验证配置] 检查自定义环境 IP...");
236
242
  if (!this.config.customIp) {
237
243
  throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, "自定义环境必须提供 --customIp 参数");
238
244
  }
@@ -240,18 +246,20 @@ class BoxInstaller {
240
246
  if (!result.success) {
241
247
  throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, result.error.issues[0].message);
242
248
  }
249
+ debug.log("[验证配置] 自定义环境 IP 验证通过");
243
250
  }
251
+ debug.log("[验证配置] 配置检查通过");
244
252
  }
245
253
  getPaths() {
246
254
  const env = this.config.env || "test";
247
- debugLog(`[getConfig] env=${env}, customIp=${this.config.customIp}`);
255
+ debug.log(`[getConfig] env=${env}, customIp=${this.config.customIp}`);
248
256
  const config = getConfig(env, this.config.customIp);
249
257
  let baseDir;
250
258
  if (this.config.openclawPath) {
251
- debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
259
+ debug.log(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
252
260
  try {
253
261
  validateOpenclawPath(this.config.openclawPath);
254
- debugLog("[路径验证] 通过");
262
+ debug.log("[路径验证] 通过");
255
263
  } catch (error) {
256
264
  throw new AppError2(ERROR_CODES.INVALID_OPENCLAW_PATH, error.message);
257
265
  }
@@ -277,6 +285,7 @@ class BoxInstaller {
277
285
  updateSpinner(text) {
278
286
  this.spinner.prefixText = this.prefixText;
279
287
  this.spinner.text = chalk.cyan(text);
288
+ debug.log(`[Spinner] ${text}`);
280
289
  }
281
290
  getPrefixText() {
282
291
  return this.prefixText;
@@ -289,7 +298,7 @@ class BoxInstaller {
289
298
  }
290
299
  async install() {
291
300
  try {
292
- debugLog("[盒子安装] 开始安装...");
301
+ debug.log("[盒子安装] 开始安装...");
293
302
  this.validateConfig();
294
303
  this.prefixText += chalk.green(` ✓ 配置验证完成
295
304
  `);
@@ -299,25 +308,27 @@ class BoxInstaller {
299
308
  await this.doDownloadFromNpm();
300
309
  await this.doUpdateConfig(paths);
301
310
  this.spinner.stop();
302
- debugLog("[盒子安装] 安装完成");
311
+ debug.log("[盒子安装] 安装完成");
303
312
  } catch (error) {
304
313
  this.spinner.stop();
305
- debugLog(`[盒子安装] 安装失败: ${error.message}`);
314
+ debug.log(`[盒子安装] 安装失败: ${error.message}`);
306
315
  throw error;
307
316
  }
308
317
  }
309
318
  async doCleanOldFiles(paths) {
319
+ debug.log("[清理旧版本] 开始清理旧版本...");
310
320
  this.prefixText += chalk.green(` ✓ 开始清理旧版本
311
321
  `);
312
322
  this.updateSpinner("正在清理旧版本...");
313
323
  try {
314
324
  await fs.access(paths.target);
315
- debugLog("[清理旧版本] 删除旧版本目录...");
325
+ debug.log("[清理旧版本] 删除旧版本目录...");
316
326
  await fs.rm(paths.target, { recursive: true, force: true });
317
327
  this.prefixText += chalk.green(` ✓ 旧版本清理成功
318
328
  `);
319
- debugLog("[清理旧版本] 旧版本清理成功");
329
+ debug.log("[清理旧版本] 旧版本清理成功");
320
330
  } catch {
331
+ debug.log("[清理旧版本] 无旧版本需要清理");
321
332
  this.prefixText += chalk.green(` ✓ 无旧版本需要清理
322
333
  `);
323
334
  }
@@ -325,27 +336,33 @@ class BoxInstaller {
325
336
  await fs.access(paths.temp);
326
337
  await fs.rm(paths.temp, { recursive: true, force: true });
327
338
  } catch {
339
+ debug.log("[清理旧版本] 无临时目录需要清理");
328
340
  }
329
341
  }
330
342
  async doDownloadFromNpm() {
331
343
  const paths = this.getPaths();
332
344
  this.spinner.prefixText = this.prefixText;
333
345
  this.spinner.text = chalk.cyan("正在准备安装目录...");
346
+ debug.log("[下载插件] 创建扩展目录...");
334
347
  await fs.mkdir(paths.extensions, { recursive: true });
335
- debugLog(`[下载插件] 扩展目录: ${paths.extensions}`);
348
+ debug.log(`[下载插件] 扩展目录: ${paths.extensions}`);
336
349
  const tempDir = path.join(paths.temp, `install-${Date.now()}`);
350
+ debug.log(`[下载插件] 创建临时目录: ${tempDir}`);
337
351
  await fs.mkdir(tempDir, { recursive: true });
338
352
  this.spinner.prefixText = this.prefixText;
339
353
  this.spinner.text = chalk.cyan("正在下载插件...");
354
+ debug.log("[下载插件] 执行 npm pack 下载源码包");
355
+ debug.log(`[下载插件] 工作目录: ${tempDir}`);
340
356
  const maxRetries = 3;
341
357
  let lastError = "";
342
358
  let tarballPath = "";
343
359
  for (let i = 1; i <= maxRetries; i++) {
344
360
  this.spinner.prefixText = this.prefixText;
345
361
  this.spinner.text = chalk.cyan(`正在下载 (${i}/${maxRetries})...`);
362
+ debug.log(`[下载插件] 第 ${i} 次尝试下载 tarball...`);
346
363
  try {
347
364
  const packageName = this.getPackageName();
348
- debugLog(`[下载插件] 下载包名: ${packageName}`);
365
+ debug.log(`[下载插件] 下载包名: ${packageName}`);
349
366
  this.spinner.text = chalk.cyan("正在从 npm 获取插件...");
350
367
  const output = await execAsync$1(
351
368
  `npm pack ${packageName} --registry=https://mirrors.tencent.com/npm/ --ignore-scripts --quiet`,
@@ -354,12 +371,14 @@ class BoxInstaller {
354
371
  const lines = output.trim().split("\n").filter((line) => line.trim());
355
372
  const filename = lines[lines.length - 1] || "";
356
373
  tarballPath = path.join(tempDir, filename);
357
- debugLog(`[下载插件] tarball 下载成功: ${tarballPath}`);
374
+ debug.log(`[下载插件] tarball 下载成功: ${tarballPath}`);
358
375
  break;
359
376
  } catch (error) {
360
377
  lastError = error.message || "未知错误";
378
+ debug.log(`[下载插件] 第 ${i} 次尝试失败: ${lastError}`);
361
379
  if (i < maxRetries) {
362
380
  this.spinner.text = chalk.cyan(`下载失败,3秒后重试...`);
381
+ debug.log("[下载插件] 等待 3 秒后重试...");
363
382
  await new Promise((resolve2) => setTimeout(resolve2, 3e3));
364
383
  }
365
384
  }
@@ -369,16 +388,16 @@ class BoxInstaller {
369
388
  }
370
389
  this.spinner.prefixText = this.prefixText;
371
390
  this.spinner.text = chalk.cyan("正在解压插件...");
372
- debugLog(`[下载插件] 创建插件目录: ${paths.target}`);
391
+ debug.log(`[下载插件] 创建插件目录: ${paths.target}`);
373
392
  await fs.mkdir(paths.target, { recursive: true });
374
- debugLog(`[下载插件] 解压 tarball 到: ${paths.target}`);
393
+ debug.log(`[下载插件] 解压 tarball 到: ${paths.target}`);
375
394
  try {
376
395
  await tar.extract({
377
396
  file: tarballPath,
378
397
  cwd: paths.target,
379
398
  strip: 1
380
399
  });
381
- debugLog("[下载插件] tarball 解压成功");
400
+ debug.log("[下载插件] tarball 解压成功");
382
401
  } catch (error) {
383
402
  throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, `tarball 解压失败: ${error.message}`);
384
403
  }
@@ -387,27 +406,35 @@ class BoxInstaller {
387
406
  if (!pluginExists) {
388
407
  throw new AppError2(ERROR_CODES.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
389
408
  }
409
+ debug.log("[下载插件] 插件解压成功");
390
410
  this.spinner.prefixText = this.prefixText;
391
411
  this.spinner.text = chalk.cyan("正在安装依赖...");
412
+ debug.log("[下载插件] 执行 npm install 安装生产环境依赖");
392
413
  try {
393
414
  await execAsync$1("npm install --omit=dev --ignore-scripts --quiet", {
394
415
  cwd: paths.target,
395
416
  timeout: 12e4
396
417
  });
397
- debugLog("[下载插件] npm install 执行成功");
418
+ debug.log("[下载插件] npm install 执行成功");
398
419
  } catch (error) {
399
420
  const errorMsg = error.message || "";
400
- if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) ;
421
+ if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) {
422
+ debug.log("[下载插件] npm install 有警告但可能成功,继续流程");
423
+ } else {
424
+ debug.log(`[下载插件] npm install 失败: ${errorMsg}`);
425
+ }
401
426
  }
402
427
  this.prefixText += chalk.green(` ✓ 插件安装完成
403
428
  `);
404
429
  try {
405
430
  await fs.rm(tempDir, { recursive: true, force: true });
406
- debugLog("[下载插件] 清理临时目录完成");
431
+ debug.log("[下载插件] 清理临时目录完成");
407
432
  } catch {
433
+ debug.log("[下载插件] 清理临时目录失败(忽略)");
408
434
  }
409
435
  }
410
436
  async doUpdateConfig(paths) {
437
+ debug.log("[更新配置] 开始更新配置...");
411
438
  this.prefixText += chalk.green(` ✓ 开始更新配置
412
439
  `);
413
440
  this.updateSpinner("正在生成配置...");
@@ -415,8 +442,9 @@ class BoxInstaller {
415
442
  try {
416
443
  const content = await fs.readFile(paths.config, "utf-8");
417
444
  originalConfig = JSON.parse(content);
418
- debugLog("[更新配置] 读取原有配置成功");
445
+ debug.log("[更新配置] 读取原有配置成功");
419
446
  } catch {
447
+ debug.log("[更新配置] 无原有配置");
420
448
  }
421
449
  const config = getConfig(this.config.env || "test", this.config.customIp);
422
450
  const newConfig = {
@@ -655,16 +683,19 @@ class BoxInstaller {
655
683
  };
656
684
  const finalConfig = deepMerge$1(originalConfig, newConfig);
657
685
  this.updateSpinner("正在写入配置...");
686
+ debug.log("[更新配置] 写入配置文件...");
658
687
  await fs.writeFile(paths.config, JSON.stringify(finalConfig, null, 2), "utf-8");
659
688
  this.prefixText += chalk.green(` ✓ 配置文件更新成功
660
689
  `);
661
- debugLog(`[更新配置] 配置文件写入成功: ${paths.config}`);
690
+ debug.log(`[更新配置] 配置文件写入成功: ${paths.config}`);
662
691
  }
663
692
  }
664
693
  async function createBoxCommand(options) {
665
694
  setDebug(!!options.debug);
666
- debugLog(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, customIp=${options.customIp}, debug=${options.debug}`);
695
+ debug.log("[盒子安装] 开始处理...");
696
+ debug.log(`[盒子安装] 参数: env=${options.env}, appKey=${options.appKey ? "***" : "未提供"}, customIp=${options.customIp}, debug=${options.debug}`);
667
697
  checkEnv();
698
+ debug.log("[盒子安装] 环境检查通过");
668
699
  try {
669
700
  let env = options.env;
670
701
  let appKey = options.appKey;
@@ -672,7 +703,7 @@ async function createBoxCommand(options) {
672
703
  let customIp = options.customIp;
673
704
  const questions = [];
674
705
  if (!env) {
675
- debugLog("[盒子安装] 需要选择环境");
706
+ debug.log("[盒子安装] 需要选择环境");
676
707
  questions.push({
677
708
  type: "list",
678
709
  name: "env",
@@ -685,10 +716,10 @@ async function createBoxCommand(options) {
685
716
  ]
686
717
  });
687
718
  } else {
688
- debugLog(`[盒子安装] 使用命令行参数: env=${env}`);
719
+ debug.log(`[盒子安装] 使用命令行参数: env=${env}`);
689
720
  }
690
721
  if (!appKey) {
691
- debugLog("[盒子安装] 需要输入 AppKey");
722
+ debug.log("[盒子安装] 需要输入 AppKey");
692
723
  questions.push({
693
724
  type: "input",
694
725
  name: "appKey",
@@ -702,10 +733,10 @@ async function createBoxCommand(options) {
702
733
  }
703
734
  });
704
735
  } else {
705
- debugLog("[盒子安装] 使用命令行参数: appKey");
736
+ debug.log("[盒子安装] 使用命令行参数: appKey");
706
737
  }
707
738
  if (!appSecret) {
708
- debugLog("[盒子安装] 需要输入 AppSecret");
739
+ debug.log("[盒子安装] 需要输入 AppSecret");
709
740
  questions.push({
710
741
  type: "input",
711
742
  name: "appSecret",
@@ -719,18 +750,18 @@ async function createBoxCommand(options) {
719
750
  }
720
751
  });
721
752
  } else {
722
- debugLog("[盒子安装] 使用命令行参数: appSecret");
753
+ debug.log("[盒子安装] 使用命令行参数: appSecret");
723
754
  }
724
755
  if (questions.length > 0) {
725
- debugLog(`[盒子安装] 开始交互式问答,共 ${questions.length} 个问题`);
756
+ debug.log(`[盒子安装] 开始交互式问答,共 ${questions.length} 个问题`);
726
757
  const answers = await inquirer.prompt(questions);
727
- debugLog("[盒子安装] 交互式问答完成");
758
+ debug.log("[盒子安装] 交互式问答完成");
728
759
  env = env || answers.env || "test";
729
760
  appKey = appKey || answers.appKey;
730
761
  appSecret = appSecret || answers.appSecret;
731
762
  }
732
763
  if (env === "custom" && !customIp) {
733
- debugLog("[盒子安装] 自定义环境需要输入后端 IP");
764
+ debug.log("[盒子安装] 自定义环境需要输入后端 IP");
734
765
  const answer = await inquirer.prompt([{
735
766
  type: "input",
736
767
  name: "customIp",
@@ -748,12 +779,12 @@ async function createBoxCommand(options) {
748
779
  }
749
780
  }]);
750
781
  customIp = answer.customIp;
751
- debugLog("[盒子安装] 获取自定义 customIp");
782
+ debug.log("[盒子安装] 获取自定义 customIp");
752
783
  } else if (env === "custom" && customIp) {
753
- debugLog(`[盒子安装] 使用命令行参数: customIp=${customIp}`);
784
+ debug.log(`[盒子安装] 使用命令行参数: customIp=${customIp}`);
754
785
  }
755
- debugLog(`[盒子安装] 最终参数: env=${env}, customIp=${customIp}, openclawPath=${options.openclawPath}`);
756
- debugLog("[盒子安装] 创建 BoxInstaller 实例...");
786
+ debug.log(`[盒子安装] 最终参数: env=${env}, customIp=${customIp}, openclawPath=${options.openclawPath}`);
787
+ debug.log("[盒子安装] 创建 BoxInstaller 实例...");
757
788
  const installer = new BoxInstaller({
758
789
  appKey,
759
790
  appSecret,
@@ -763,9 +794,9 @@ async function createBoxCommand(options) {
763
794
  pluginVersion: options.pluginVersion,
764
795
  openclawPath: options.openclawPath
765
796
  });
766
- debugLog("[盒子安装] 开始安装...");
797
+ debug.log("[盒子安装] 开始安装...");
767
798
  await installer.install();
768
- debugLog("[盒子安装] 安装完成");
799
+ debug.log("[盒子安装] 安装完成");
769
800
  console.log(installer.getPrefixText() + boxen(
770
801
  `${chalk.green("✦")} 插件初始化成功!`,
771
802
  {
@@ -779,7 +810,7 @@ async function createBoxCommand(options) {
779
810
  }
780
811
  ));
781
812
  } catch (error) {
782
- debugLog(`[盒子安装] 发生错误: ${error.message}`);
813
+ debug.log(`[盒子安装] 发生错误: ${error.message}`);
783
814
  console.error(boxen(
784
815
  `${chalk.yellow(error.message)}`,
785
816
  {
@@ -809,12 +840,13 @@ function createHttpClient(baseURL) {
809
840
  }
810
841
  async function httpPost(url, data, config) {
811
842
  const client = createHttpClient();
812
- debugLog(`[HTTP POST] 请求参数: ${JSON.stringify(data)}`);
813
- debugLog(`[HTTP POST] 请求头: ${JSON.stringify(config?.headers || {})}`);
843
+ debug.log(`[HTTP POST] 请求地址: ${url}`);
844
+ debug.log(`[HTTP POST] 请求参数: ${JSON.stringify(data)}`);
845
+ debug.log(`[HTTP POST] 请求头: ${JSON.stringify(config?.headers || {})}`);
814
846
  try {
815
847
  const response = await client.post(url, data, config);
816
- debugLog(`[HTTP POST] 响应状态: ${response.status}`);
817
- debugLog(`[HTTP POST] 响应内容: ${JSON.stringify(response.data)}`);
848
+ debug.log(`[HTTP POST] 响应状态: ${response.status}`);
849
+ debug.log(`[HTTP POST] 响应内容: ${JSON.stringify(response.data)}`);
818
850
  return {
819
851
  status: response.status,
820
852
  data: response.data
@@ -823,9 +855,9 @@ async function httpPost(url, data, config) {
823
855
  const axiosError = error;
824
856
  if (axiosError.response) {
825
857
  const responseData = axiosError.response.data;
826
- debugLog(`[HTTP POST] 响应状态: ${axiosError.response.status}`);
827
- debugLog(`[HTTP POST] 响应状态文本: ${axiosError.response.statusText}`);
828
- debugLog(`[HTTP POST] 响应数据: ${JSON.stringify(responseData)}`);
858
+ debug.log(`[HTTP POST] 响应状态: ${axiosError.response.status}`);
859
+ debug.log(`[HTTP POST] 响应状态文本: ${axiosError.response.statusText}`);
860
+ debug.log(`[HTTP POST] 响应数据: ${JSON.stringify(responseData)}`);
829
861
  if (typeof responseData === "string") {
830
862
  throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求失败 (${axiosError.response.status}): ${responseData}`);
831
863
  } else if (responseData && typeof responseData === "object" && "message" in responseData) {
@@ -834,40 +866,48 @@ async function httpPost(url, data, config) {
834
866
  throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求失败 (${axiosError.response.status}): ${axiosError.response.statusText}`);
835
867
  }
836
868
  } else if (axiosError.request) {
837
- debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
869
+ debug.log(`[HTTP POST] 未收到响应`);
870
+ debug.log(`[HTTP POST] 错误信息: ${axiosError.message}`);
838
871
  throw new AppError$1(ERROR_CODES$1.NETWORK_ERROR, `网络错误: ${axiosError.message}`);
839
872
  } else {
840
- debugLog(`[HTTP POST] 错误信息: ${axiosError.message}`);
873
+ debug.log(`[HTTP POST] 请求配置错误`);
874
+ debug.log(`[HTTP POST] 错误信息: ${axiosError.message}`);
841
875
  throw new AppError$1(ERROR_CODES$1.HTTP_ERROR, `请求配置错误: ${axiosError.message}`);
842
876
  }
843
877
  }
844
878
  }
845
879
  async function login(phone, password, config) {
846
880
  const url = `${config.API.TUZAI_BASE_URL}/user/login/pass`;
881
+ debug.log("[登录] 开始登录...");
882
+ debug.log(`[登录] 请求地址: ${url}`);
883
+ debug.log(`[登录] 请求参数: phone=${phone}, password=***`);
847
884
  try {
848
885
  const response = await httpPost(url, {
849
886
  phone,
850
887
  userPass: password
851
888
  });
852
889
  const data = response.data;
853
- debugLog(`[登录] 响应数据: ${JSON.stringify(data)}`);
890
+ debug.log(`[登录] 响应数据: ${JSON.stringify(data)}`);
854
891
  if (data.code === 200 && data.data?.token) {
855
- debugLog("[登录] 登录成功,获取到 token");
892
+ debug.log("[登录] 登录成功,获取到 token");
856
893
  return data.data.token;
857
894
  }
858
- debugLog("[登录] 登录失败");
895
+ debug.log("[登录] 登录失败");
859
896
  throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, data.message || "登录失败");
860
897
  } catch (error) {
861
898
  if (error instanceof AppError$1) {
862
899
  throw error;
863
900
  }
864
- debugLog(`[登录] 发生错误: ${error.message}`);
901
+ debug.log(`[登录] 发生错误: ${error.message}`);
865
902
  throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, error.message);
866
903
  }
867
904
  }
868
905
  async function fetchBoundConfig(token, phone, localCode, config) {
869
906
  const url = `${config.API.TUZAI_BASE_URL}/work-bot/local/bound/init`;
870
- debugLog(`[获取绑定配置] 请求头: Authorization=${token.substring(0, 20)}...`);
907
+ debug.log("[获取绑定配置] 开始获取绑定配置...");
908
+ debug.log(`[获取绑定配置] 请求地址: ${url}`);
909
+ debug.log(`[获取绑定配置] 请求参数: phone=${phone}, localCode=${localCode}`);
910
+ debug.log(`[获取绑定配置] 请求头: Authorization=${token.substring(0, 20)}...`);
871
911
  try {
872
912
  const response = await httpPost(url, {
873
913
  phone,
@@ -878,7 +918,7 @@ async function fetchBoundConfig(token, phone, localCode, config) {
878
918
  }
879
919
  });
880
920
  const data = response.data;
881
- debugLog(`[获取绑定配置] 响应数据: ${JSON.stringify(data)}`);
921
+ debug.log(`[获取绑定配置] 响应数据: ${JSON.stringify(data)}`);
882
922
  if (data.code === 200 && data.data) {
883
923
  const boundConfig = {
884
924
  appKey: data.data.app_key,
@@ -888,26 +928,26 @@ async function fetchBoundConfig(token, phone, localCode, config) {
888
928
  modelApiKey: data.data.model_api_key,
889
929
  modelApiBaseUrl: data.data.model_api_base_url
890
930
  };
891
- debugLog("[获取绑定配置] 获取绑定配置成功");
892
- debugLog(`[获取绑定配置] appKey: ${boundConfig.appKey}`);
893
- debugLog(`[获取绑定配置] appSecret: ${boundConfig.appSecret ? "***" : "undefined"}`);
894
- debugLog(`[获取绑定配置] userId: ${boundConfig.userId}`);
895
- debugLog(`[获取绑定配置] agentId: ${boundConfig.agentId}`);
896
- debugLog(`[获取绑定配置] modelApiKey: ${boundConfig.modelApiKey || "undefined"}`);
897
- debugLog(`[获取绑定配置] modelApiBaseUrl: ${boundConfig.modelApiBaseUrl || "undefined"}`);
931
+ debug.log("[获取绑定配置] 获取绑定配置成功");
932
+ debug.log(`[获取绑定配置] appKey: ${boundConfig.appKey}`);
933
+ debug.log(`[获取绑定配置] appSecret: ${boundConfig.appSecret ? "***" : "undefined"}`);
934
+ debug.log(`[获取绑定配置] userId: ${boundConfig.userId}`);
935
+ debug.log(`[获取绑定配置] agentId: ${boundConfig.agentId}`);
936
+ debug.log(`[获取绑定配置] modelApiKey: ${boundConfig.modelApiKey || "undefined"}`);
937
+ debug.log(`[获取绑定配置] modelApiBaseUrl: ${boundConfig.modelApiBaseUrl || "undefined"}`);
898
938
  if (!boundConfig.appKey || !boundConfig.appSecret || !boundConfig.agentId) {
899
- debugLog("[获取绑定配置] 缺少必要字段");
939
+ debug.log("[获取绑定配置] 缺少必要字段");
900
940
  throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, "获取绑定配置失败:缺少必要字段");
901
941
  }
902
942
  return boundConfig;
903
943
  }
904
- debugLog("[获取绑定配置] 获取绑定配置失败");
944
+ debug.log("[获取绑定配置] 获取绑定配置失败");
905
945
  throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, data.message || data.msg || "获取绑定配置失败");
906
946
  } catch (error) {
907
947
  if (error instanceof AppError$1) {
908
948
  throw error;
909
949
  }
910
- debugLog(`[获取绑定配置] 发生错误: ${error.message}`);
950
+ debug.log(`[获取绑定配置] 发生错误: ${error.message}`);
911
951
  throw new AppError$1(ERROR_CODES$1.GET_BOUND_CONFIG_FAILED, error.message);
912
952
  }
913
953
  }
@@ -4893,6 +4933,7 @@ class LocalInstaller {
4893
4933
  prefixText = "";
4894
4934
  config;
4895
4935
  envConfig;
4936
+ token = "";
4896
4937
  /**
4897
4938
  * 构造函数
4898
4939
  */
@@ -4906,25 +4947,27 @@ class LocalInstaller {
4906
4947
  * 验证安装配置
4907
4948
  */
4908
4949
  validateConfig() {
4950
+ debug.log("[验证配置] 检查配置...");
4909
4951
  const result = LocalInstallerConfigSchema.safeParse(this.config);
4910
4952
  if (!result.success) {
4911
- debugLog(`[验证配置] 验证失败: ${result.error.issues[0].message}`);
4953
+ debug.log(`[验证配置] 验证失败: ${result.error.issues[0].message}`);
4912
4954
  throw new AppError$1(ERROR_CODES$1.INVALID_ARGUMENT, result.error.issues[0].message);
4913
4955
  }
4956
+ debug.log("[验证配置] 配置验证通过");
4914
4957
  }
4915
4958
  /**
4916
4959
  * 执行安装流程
4917
4960
  */
4918
4961
  async install() {
4919
4962
  try {
4920
- debugLog("[安装开始]");
4963
+ debug.log("[安装开始]");
4921
4964
  this.validateConfig();
4922
4965
  let baseDir;
4923
4966
  if (this.config.openclawPath) {
4924
- debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
4967
+ debug.log(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
4925
4968
  try {
4926
4969
  validateOpenclawPath(this.config.openclawPath);
4927
- debugLog("[路径验证] 通过");
4970
+ debug.log("[路径验证] 通过");
4928
4971
  } catch (error) {
4929
4972
  throw new AppError$1(ERROR_CODES$1.INVALID_OPENCLAW_PATH, error.message);
4930
4973
  }
@@ -4941,25 +4984,26 @@ class LocalInstaller {
4941
4984
  workspace: path.join(baseDir, this.envConfig.DIRS.WORKSPACE),
4942
4985
  temp: path.join(baseDir, this.envConfig.DIRS.TEMP)
4943
4986
  };
4944
- debugLog(`[路径配置] home=${paths.home}`);
4945
- debugLog(`[路径配置] extensions=${paths.extensions}`);
4946
- debugLog(`[路径配置] target=${paths.target}`);
4947
- debugLog(`[路径配置] config=${paths.config}`);
4948
- debugLog(`[路径配置] workspace=${paths.workspace}`);
4987
+ debug.log(`[路径配置] home=${paths.home}`);
4988
+ debug.log(`[路径配置] extensions=${paths.extensions}`);
4989
+ debug.log(`[路径配置] target=${paths.target}`);
4990
+ debug.log(`[路径配置] config=${paths.config}`);
4991
+ debug.log(`[路径配置] workspace=${paths.workspace}`);
4949
4992
  const machineId = generateMachineId();
4950
4993
  const localCode = buildLocalCode(this.config.phone, machineId);
4951
- debugLog(`[机器码] machineId=${machineId}`);
4952
- debugLog(`[机器码] localCode=${localCode}`);
4994
+ debug.log(`[机器码] machineId=${machineId}`);
4995
+ debug.log(`[机器码] localCode=${localCode}`);
4953
4996
  const token = await this.doLogin();
4997
+ this.token = token;
4954
4998
  const boundConfig = await this.doFetchBoundConfig(token, localCode);
4955
4999
  await this.doCleanOldFiles(paths.target);
4956
5000
  await this.doDownloadFromNpm(paths);
4957
5001
  await this.doUpdateConfig(paths, boundConfig);
4958
5002
  try {
4959
5003
  await fs.rm(paths.temp, { recursive: true, force: true });
4960
- debugLog("[安装完成] 清理根临时目录完成");
5004
+ debug.log("[安装完成] 清理根临时目录完成");
4961
5005
  } catch {
4962
- debugLog("[安装完成] 清理根临时目录失败(忽略)");
5006
+ debug.log("[安装完成] 清理根临时目录失败(忽略)");
4963
5007
  }
4964
5008
  this.spinner.stop();
4965
5009
  } catch (error) {
@@ -4973,6 +5017,12 @@ class LocalInstaller {
4973
5017
  getPrefixText() {
4974
5018
  return this.prefixText;
4975
5019
  }
5020
+ /**
5021
+ * 获取登录 token
5022
+ */
5023
+ getToken() {
5024
+ return this.token;
5025
+ }
4976
5026
  /**
4977
5027
  * 获取完整的 npm 包名(包含版本号)
4978
5028
  */
@@ -4988,14 +5038,18 @@ class LocalInstaller {
4988
5038
  async doLogin() {
4989
5039
  this.spinner.prefixText = this.prefixText;
4990
5040
  this.spinner.text = chalk.cyan("正在验证账号...");
4991
- debugLog(`[用户登录] 手机号: ${this.config.phone}`);
5041
+ debug.log(`[用户登录] 手机号: ${this.config.phone}`);
5042
+ debug.log("[用户登录] RSA 加密密码...");
4992
5043
  const encryptedPassword = rsaEncrypt(this.config.userPass);
4993
5044
  if (!encryptedPassword) {
4994
5045
  throw new AppError$1(ERROR_CODES$1.LOGIN_FAILED, "密码加密失败");
4995
5046
  }
5047
+ debug.log("[用户登录] 密码加密成功");
5048
+ debug.log("[用户登录] 调用登录接口...");
4996
5049
  const token = await login(this.config.phone, encryptedPassword, this.envConfig);
4997
5050
  this.prefixText += chalk.green(` ✓ 账号验证成功
4998
5051
  `);
5052
+ debug.log("[用户登录] 登录成功");
4999
5053
  return token;
5000
5054
  }
5001
5055
  /**
@@ -5004,10 +5058,13 @@ class LocalInstaller {
5004
5058
  async doFetchBoundConfig(token, localCode) {
5005
5059
  this.spinner.prefixText = this.prefixText;
5006
5060
  this.spinner.text = chalk.cyan("正在获取绑定信息...");
5061
+ debug.log("[获取配置] 调用绑定配置接口...");
5062
+ debug.log(`[获取配置] localCode=${localCode}`);
5007
5063
  const boundConfig = await fetchBoundConfig(token, this.config.phone, localCode, this.envConfig);
5008
- debugLog(`[获取配置] agentId=${boundConfig.agentId}, appKey=${boundConfig.appKey?.slice(0, 8)}...`);
5064
+ debug.log(`[获取配置] agentId=${boundConfig.agentId}, appKey=${boundConfig.appKey?.slice(0, 8)}...`);
5009
5065
  this.prefixText += chalk.green(` ✓ 绑定信息获取成功
5010
5066
  `);
5067
+ debug.log("[获取配置] 获取成功");
5011
5068
  return boundConfig;
5012
5069
  }
5013
5070
  /**
@@ -5016,17 +5073,19 @@ class LocalInstaller {
5016
5073
  async doCleanOldFiles(targetPath) {
5017
5074
  this.spinner.prefixText = this.prefixText;
5018
5075
  this.spinner.text = chalk.cyan("正在检查已安装版本...");
5076
+ debug.log(`[清理旧版本] 检查目录: ${targetPath}`);
5019
5077
  try {
5020
5078
  await fs.access(targetPath);
5021
5079
  this.spinner.text = chalk.cyan("正在清理旧文件...");
5022
- debugLog("[清理旧版本] 发现旧版本,开始清理...");
5080
+ debug.log("[清理旧版本] 发现旧版本,开始清理...");
5023
5081
  await fs.rm(targetPath, { recursive: true, force: true });
5024
5082
  this.prefixText += chalk.green(` ✓ 旧版本清理完成
5025
5083
  `);
5026
- debugLog("[清理旧版本] 清理完成");
5084
+ debug.log("[清理旧版本] 清理完成");
5027
5085
  } catch {
5028
5086
  this.prefixText += chalk.green(` ✓ 无旧版本需要清理
5029
5087
  `);
5088
+ debug.log("[清理旧版本] 未发现旧版本");
5030
5089
  }
5031
5090
  }
5032
5091
  /**
@@ -5035,21 +5094,26 @@ class LocalInstaller {
5035
5094
  async doDownloadFromNpm(paths) {
5036
5095
  this.spinner.prefixText = this.prefixText;
5037
5096
  this.spinner.text = chalk.cyan("正在准备安装目录...");
5097
+ debug.log("[下载插件] 创建扩展目录...");
5038
5098
  await fs.mkdir(paths.extensions, { recursive: true });
5039
- debugLog(`[下载插件] 扩展目录: ${paths.extensions}`);
5099
+ debug.log(`[下载插件] 扩展目录: ${paths.extensions}`);
5040
5100
  const tempDir = path.join(paths.temp, `install-${Date.now()}`);
5101
+ debug.log(`[下载插件] 创建临时目录: ${tempDir}`);
5041
5102
  await fs.mkdir(tempDir, { recursive: true });
5042
5103
  this.spinner.prefixText = this.prefixText;
5043
5104
  this.spinner.text = chalk.cyan("正在下载插件...");
5105
+ debug.log("[下载插件] 执行 npm pack 下载源码包");
5106
+ debug.log(`[下载插件] 工作目录: ${tempDir}`);
5044
5107
  const maxRetries = 3;
5045
5108
  let lastError = "";
5046
5109
  let tarballPath = "";
5047
5110
  for (let i = 1; i <= maxRetries; i++) {
5048
5111
  this.spinner.prefixText = this.prefixText;
5049
5112
  this.spinner.text = chalk.cyan(`正在下载 (${i}/${maxRetries})...`);
5113
+ debug.log(`[下载插件] 第 ${i} 次尝试下载 tarball...`);
5050
5114
  try {
5051
5115
  const packageName = this.getPackageName();
5052
- debugLog(`[下载插件] 下载包名: ${packageName}`);
5116
+ debug.log(`[下载插件] 下载包名: ${packageName}`);
5053
5117
  this.spinner.text = chalk.cyan("正在从 npm 获取插件...");
5054
5118
  const output = await execAsync(
5055
5119
  `npm pack ${packageName} --registry=https://mirrors.tencent.com/npm/ --ignore-scripts --quiet`,
@@ -5058,12 +5122,14 @@ class LocalInstaller {
5058
5122
  const lines = output.trim().split("\n").filter((line) => line.trim());
5059
5123
  const filename = lines[lines.length - 1] || "";
5060
5124
  tarballPath = path.join(tempDir, filename);
5061
- debugLog(`[下载插件] tarball 下载成功: ${tarballPath}`);
5125
+ debug.log(`[下载插件] tarball 下载成功: ${tarballPath}`);
5062
5126
  break;
5063
5127
  } catch (error) {
5064
5128
  lastError = error.message || "未知错误";
5129
+ debug.log(`[下载插件] 第 ${i} 次尝试失败: ${lastError}`);
5065
5130
  if (i < maxRetries) {
5066
5131
  this.spinner.text = chalk.cyan(`下载失败,3秒后重试...`);
5132
+ debug.log("[下载插件] 等待 3 秒后重试...");
5067
5133
  await new Promise((resolve2) => setTimeout(resolve2, 3e3));
5068
5134
  }
5069
5135
  }
@@ -5073,16 +5139,16 @@ class LocalInstaller {
5073
5139
  }
5074
5140
  this.spinner.prefixText = this.prefixText;
5075
5141
  this.spinner.text = chalk.cyan("正在解压插件...");
5076
- debugLog(`[下载插件] 创建插件目录: ${paths.target}`);
5142
+ debug.log(`[下载插件] 创建插件目录: ${paths.target}`);
5077
5143
  await fs.mkdir(paths.target, { recursive: true });
5078
- debugLog(`[下载插件] 解压 tarball 到: ${paths.target}`);
5144
+ debug.log(`[下载插件] 解压 tarball 到: ${paths.target}`);
5079
5145
  try {
5080
5146
  await tar.extract({
5081
5147
  file: tarballPath,
5082
5148
  cwd: paths.target,
5083
5149
  strip: 1
5084
5150
  });
5085
- debugLog("[下载插件] tarball 解压成功");
5151
+ debug.log("[下载插件] tarball 解压成功");
5086
5152
  } catch (error) {
5087
5153
  throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, `tarball 解压失败: ${error.message}`);
5088
5154
  }
@@ -5091,18 +5157,22 @@ class LocalInstaller {
5091
5157
  if (!pluginExists) {
5092
5158
  throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, "插件解压后未找到 package.json");
5093
5159
  }
5160
+ debug.log("[下载插件] 插件解压成功");
5094
5161
  this.spinner.prefixText = this.prefixText;
5095
5162
  this.spinner.text = chalk.cyan("正在安装依赖...");
5163
+ debug.log("[下载插件] 执行 npm install 安装生产环境依赖");
5096
5164
  try {
5097
5165
  await execAsync("npm install --omit=dev --ignore-scripts --quiet", {
5098
5166
  cwd: paths.target,
5099
5167
  timeout: 12e4
5100
5168
  });
5101
- debugLog("[下载插件] npm install 执行成功");
5169
+ debug.log("[下载插件] npm install 执行成功");
5102
5170
  } catch (error) {
5103
5171
  const errorMsg = error instanceof Error ? error.message : String(error);
5104
- if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) ;
5105
- else {
5172
+ if (errorMsg.includes("npm warn") || errorMsg.includes("deprecated")) {
5173
+ debug.log("[下载插件] npm install 有警告但可能成功,继续流程");
5174
+ } else {
5175
+ debug.log(`[下载插件] npm install 失败: ${errorMsg}`);
5106
5176
  throw new AppError$1(ERROR_CODES$1.NPM_INSTALL_FAILED, `依赖安装失败: ${errorMsg}`);
5107
5177
  }
5108
5178
  }
@@ -5110,8 +5180,9 @@ class LocalInstaller {
5110
5180
  `);
5111
5181
  try {
5112
5182
  await fs.rm(tempDir, { recursive: true, force: true });
5113
- debugLog("[下载插件] 清理临时下载目录完成");
5183
+ debug.log("[下载插件] 清理临时下载目录完成");
5114
5184
  } catch {
5185
+ debug.log("[下载插件] 清理临时下载目录失败(忽略)");
5115
5186
  }
5116
5187
  }
5117
5188
  /**
@@ -5120,14 +5191,18 @@ class LocalInstaller {
5120
5191
  async doUpdateConfig(paths, boundConfig) {
5121
5192
  this.spinner.prefixText = this.prefixText;
5122
5193
  this.spinner.text = chalk.cyan("正在生成配置...");
5194
+ debug.log("[更新配置] 创建目录...");
5123
5195
  await fs.mkdir(paths.home, { recursive: true });
5124
5196
  await fs.mkdir(paths.workspace, { recursive: true });
5197
+ debug.log("[更新配置] 目录创建完成");
5198
+ debug.log("[更新配置] 读取原有配置...");
5125
5199
  let originalConfig = {};
5126
5200
  try {
5127
5201
  const content = await fs.readFile(paths.config, "utf-8");
5128
5202
  originalConfig = JSON.parse(content);
5129
- debugLog("[更新配置] 读取原有配置成功");
5203
+ debug.log("[更新配置] 读取原有配置成功");
5130
5204
  } catch {
5205
+ debug.log("[更新配置] 无原有配置");
5131
5206
  }
5132
5207
  const config = this.envConfig;
5133
5208
  const newConfig = {
@@ -5296,16 +5371,19 @@ class LocalInstaller {
5296
5371
  const finalConfig = deepMerge(originalConfig, newConfig);
5297
5372
  this.spinner.prefixText = this.prefixText;
5298
5373
  this.spinner.text = chalk.cyan("正在写入配置...");
5374
+ debug.log("[更新配置] 写入配置文件...");
5299
5375
  await fs.writeFile(paths.config, JSON.stringify(finalConfig, null, 2), "utf-8");
5300
5376
  this.prefixText += chalk.green(` ✓ 配置更新完成
5301
5377
  `);
5302
- debugLog(`[更新配置] 配置文件写入成功: ${paths.config}`);
5378
+ debug.log(`[更新配置] 配置文件写入成功: ${paths.config}`);
5303
5379
  }
5304
5380
  }
5305
5381
  async function createLocalCommand(options) {
5306
5382
  setDebug(!!options.debug);
5307
- debugLog(`[初始化] 参数: env=${options.env}, phone=${options.phone}, customIp=${options.customIp}, debug=${options.debug}`);
5383
+ debug.log("[初始化] 开始处理...");
5384
+ debug.log(`[初始化] 参数: env=${options.env}, phone=${options.phone}, customIp=${options.customIp}, debug=${options.debug}`);
5308
5385
  checkEnv();
5386
+ debug.log("[初始化] 环境检查通过");
5309
5387
  try {
5310
5388
  let env = options.env;
5311
5389
  let phone = options.phone;
@@ -5313,7 +5391,7 @@ async function createLocalCommand(options) {
5313
5391
  let customIp = options.customIp;
5314
5392
  const questions = [];
5315
5393
  if (!env) {
5316
- debugLog("[初始化] 需要选择环境");
5394
+ debug.log("[初始化] 需要选择环境");
5317
5395
  questions.push({
5318
5396
  type: "list",
5319
5397
  name: "env",
@@ -5326,10 +5404,10 @@ async function createLocalCommand(options) {
5326
5404
  ]
5327
5405
  });
5328
5406
  } else {
5329
- debugLog(`[初始化] 使用命令行参数: env=${env}`);
5407
+ debug.log(`[初始化] 使用命令行参数: env=${env}`);
5330
5408
  }
5331
5409
  if (!phone) {
5332
- debugLog("[初始化] 需要输入手机号码");
5410
+ debug.log("[初始化] 需要输入手机号码");
5333
5411
  questions.push({
5334
5412
  type: "input",
5335
5413
  name: "phone",
@@ -5346,10 +5424,10 @@ async function createLocalCommand(options) {
5346
5424
  }
5347
5425
  });
5348
5426
  } else {
5349
- debugLog("[初始化] 使用命令行参数: phone");
5427
+ debug.log("[初始化] 使用命令行参数: phone");
5350
5428
  }
5351
5429
  if (!userPass) {
5352
- debugLog("[初始化] 需要输入用户密码");
5430
+ debug.log("[初始化] 需要输入用户密码");
5353
5431
  questions.push({
5354
5432
  type: "input",
5355
5433
  name: "userPass",
@@ -5363,18 +5441,18 @@ async function createLocalCommand(options) {
5363
5441
  }
5364
5442
  });
5365
5443
  } else {
5366
- debugLog("[初始化] 使用命令行参数: userPass");
5444
+ debug.log("[初始化] 使用命令行参数: userPass");
5367
5445
  }
5368
5446
  if (questions.length > 0) {
5369
- debugLog(`[初始化] 开始交互式问答,共 ${questions.length} 个问题`);
5447
+ debug.log(`[初始化] 开始交互式问答,共 ${questions.length} 个问题`);
5370
5448
  const answers = await inquirer.prompt(questions);
5371
- debugLog("[初始化] 交互式问答完成");
5449
+ debug.log("[初始化] 交互式问答完成");
5372
5450
  env = env || answers.env || "test";
5373
5451
  phone = phone || answers.phone;
5374
5452
  userPass = userPass || answers.userPass;
5375
5453
  }
5376
5454
  if (env === "custom" && !customIp) {
5377
- debugLog("[初始化] 自定义环境需要输入后端 IP");
5455
+ debug.log("[初始化] 自定义环境需要输入后端 IP");
5378
5456
  const answer = await inquirer.prompt([{
5379
5457
  type: "input",
5380
5458
  name: "customIp",
@@ -5392,12 +5470,12 @@ async function createLocalCommand(options) {
5392
5470
  }
5393
5471
  }]);
5394
5472
  customIp = answer.customIp;
5395
- debugLog("[初始化] 获取自定义 customIp");
5473
+ debug.log("[初始化] 获取自定义 customIp");
5396
5474
  } else if (env === "custom" && customIp) {
5397
- debugLog(`[初始化] 使用命令行参数: customIp=${customIp}`);
5475
+ debug.log(`[初始化] 使用命令行参数: customIp=${customIp}`);
5398
5476
  }
5399
- debugLog(`[初始化] 最终参数: env=${env}, phone=${phone}, customIp=${customIp}, pluginVersion=${options.pluginVersion}, openclawPath=${options.openclawPath}`);
5400
- debugLog("[初始化] 创建 LocalInstaller 实例...");
5477
+ debug.log(`[初始化] 最终参数: env=${env}, phone=${phone}, customIp=${customIp}, pluginVersion=${options.pluginVersion}, openclawPath=${options.openclawPath}`);
5478
+ debug.log("[初始化] 创建 LocalInstaller 实例...");
5401
5479
  const installer = new LocalInstaller({
5402
5480
  phone,
5403
5481
  userPass,
@@ -5407,9 +5485,9 @@ async function createLocalCommand(options) {
5407
5485
  pluginVersion: options.pluginVersion,
5408
5486
  openclawPath: options.openclawPath
5409
5487
  });
5410
- debugLog("[初始化] 开始安装...");
5488
+ debug.log("[初始化] 开始安装...");
5411
5489
  await installer.install();
5412
- debugLog("[初始化] 安装完成");
5490
+ debug.log("[初始化] 安装完成");
5413
5491
  console.log(installer.getPrefixText() + boxen(
5414
5492
  `${chalk.green("✦")} 插件初始化成功!`,
5415
5493
  {
@@ -5422,8 +5500,12 @@ async function createLocalCommand(options) {
5422
5500
  textAlignment: "center"
5423
5501
  }
5424
5502
  ));
5503
+ if (options.printToken) {
5504
+ const token = installer.getToken();
5505
+ console.log("\n" + chalk.cyan("Token: ") + token);
5506
+ }
5425
5507
  } catch (error) {
5426
- debugLog(`[初始化] 发生错误: ${error.message}`);
5508
+ debug.log(`[初始化] 发生错误: ${error.message}`);
5427
5509
  console.error(boxen(
5428
5510
  `${chalk.yellow(error.message)}`,
5429
5511
  {
@@ -5440,7 +5522,7 @@ async function createLocalCommand(options) {
5440
5522
  }
5441
5523
  }
5442
5524
  function registerCommands(program2) {
5443
- program2.command("local").description("本地账户安装(需要登录)").option("-e, --env <env>", "环境 (test/prod/custom)").option("--phone <phone>", "手机号码").option("--user-pass <userPass>", "用户密码").option("--custom-ip <ip>", "自定义后端 IP(仅 custom 环境生效)").option("--ws-url <url>", "自定义 WebSocket URL(仅 custom 环境生效,默认自动生成)").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").action(createLocalCommand);
5525
+ program2.command("local").description("本地账户安装(需要登录)").option("-e, --env <env>", "环境 (test/prod/custom)").option("--phone <phone>", "手机号码").option("--user-pass <userPass>", "用户密码").option("--custom-ip <ip>", "自定义后端 IP(仅 custom 环境生效)").option("--ws-url <url>", "自定义 WebSocket URL(仅 custom 环境生效,默认自动生成)").option("--plugin-version <plugin-version>", "插件版本号(默认最新版)").option("--openclaw-path <path>", "OpenClaw 安装目录路径(默认 ~/.openclaw)").option("--debug", "开启调试日志").option("--print-token", "执行完成后输出 token").action(createLocalCommand);
5444
5526
  }
5445
5527
  const __filename$1 = fileURLToPath(import.meta.url);
5446
5528
  const __dirname$1 = dirname(__filename$1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-ZySzMX4-.js").then((cli) => {
2
+ import("./index-xy26TrIZ.js").then((cli) => {
3
3
  cli.default();
4
4
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAYvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAavD"}
@@ -8,6 +8,7 @@ export declare class LocalInstaller {
8
8
  private prefixText;
9
9
  private readonly config;
10
10
  private readonly envConfig;
11
+ private token;
11
12
  /**
12
13
  * 构造函数
13
14
  */
@@ -24,6 +25,10 @@ export declare class LocalInstaller {
24
25
  * 获取前缀文本(用于显示安装进度)
25
26
  */
26
27
  getPrefixText(): string;
28
+ /**
29
+ * 获取登录 token
30
+ */
31
+ getToken(): string;
27
32
  /**
28
33
  * 获取完整的 npm 包名(包含版本号)
29
34
  */
@@ -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;AAgF/E;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAE3C;;OAEG;gBACS,MAAM,EAAE,oBAAoB;IAOxC;;OAEG;IACH,cAAc,IAAI,IAAI;IAUtB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+D9B;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;YACW,OAAO;IAoBrB;;OAEG;YACW,kBAAkB;IAchC;;OAEG;YACW,eAAe;IAmB7B;;OAEG;YACW,iBAAiB;IAoH/B;;OAEG;YACW,cAAc;CAmN7B"}
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;AAgF/E;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,KAAK,CAAa;IAE1B;;OAEG;gBACS,MAAM,EAAE,oBAAoB;IAOxC;;OAEG;IACH,cAAc,IAAI,IAAI;IAUtB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgE9B;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;YACW,OAAO;IAoBrB;;OAEG;YACW,kBAAkB;IAchC;;OAEG;YACW,eAAe;IAmB7B;;OAEG;YACW,iBAAiB;IAoH/B;;OAEG;YACW,cAAc;CAmN7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/local/src/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAQ5C;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0J7E"}
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/local/src/local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAQ5C;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+J7E"}
@@ -8,6 +8,7 @@ export interface LocalOptions {
8
8
  pluginVersion?: string;
9
9
  openclawPath?: string;
10
10
  debug?: boolean;
11
+ printToken?: boolean;
11
12
  }
12
13
  /**
13
14
  * LocalInstaller 配置验证 schema
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBAmBtC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAE7E;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;iBAO5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBAmBtC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAA;AAE7E;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;iBAO5B,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE3D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -1,3 +1,5 @@
1
+ import { Debug } from '@mingto/debug';
2
+ declare const debug: Debug;
1
3
  /**
2
4
  * 设置调试模式
3
5
  */
@@ -6,8 +8,5 @@ export declare function setDebug(enabled: boolean): void;
6
8
  * 检查是否为调试模式
7
9
  */
8
10
  export declare function isDebugMode(): boolean;
9
- /**
10
- * 输出调试日志
11
- */
12
- export declare function debugLog(...args: unknown[]): void;
11
+ export { debug };
13
12
  //# sourceMappingURL=debug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/debug.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQ/C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CACjD"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAErC,QAAA,MAAM,KAAK,OAAc,CAAA;AAEzB;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAO/C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,OAAO,EAAE,KAAK,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- export { debugLog, isDebugMode, setDebug } from './debug';
1
+ export { debug, isDebugMode, setDebug } from './debug';
2
2
  export { checkEnv } from './env';
3
3
  export { createLogger, logger } from './logger';
4
4
  export type { Logger } from './logger';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC/C,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workclaw/cli",
3
3
  "type": "module",
4
- "version": "1.0.322",
4
+ "version": "1.0.323",
5
5
  "description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
6
6
  "license": "MIT",
7
7
  "keywords": [