@workclaw/cli 1.0.319 → 1.0.320

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
@@ -100,27 +100,27 @@ npx @workclaw/cli --help
100
100
 
101
101
  ### local 命令参数
102
102
 
103
- | 参数 | 说明 |
104
- | ---------------- | ----------------------------------- |
105
- | --phone | 手机号码(登录账号),未填写时会交互式提示输入 |
106
- | --user-pass | 用户密码,未填写时会交互式提示输入 |
103
+ | 参数 | 说明 |
104
+ | ---------------- | ------------------------------------------ |
105
+ | --phone | 手机号码(登录账号),未填写时会交互式提示输入 |
106
+ | --user-pass | 用户密码,未填写时会交互式提示输入 |
107
107
  | --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
108
- | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
109
- | --plugin-version | 插件版本号(默认安装最新版) |
110
- | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
111
- | --debug | 开启调试日志 |
108
+ | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
109
+ | --plugin-version | 插件版本号(默认安装最新版) |
110
+ | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
111
+ | --debug | 开启调试日志 |
112
112
 
113
113
  ### box 命令参数
114
114
 
115
- | 参数 | 说明 |
116
- | ---------------- | ----------------------------------- |
117
- | --app-key | App Key,未填写时会交互式提示输入 |
118
- | --app-secret | App Secret,未填写时会交互式提示输入 |
115
+ | 参数 | 说明 |
116
+ | ---------------- | ------------------------------------------ |
117
+ | --app-key | App Key,未填写时会交互式提示输入 |
118
+ | --app-secret | App Secret,未填写时会交互式提示输入 |
119
119
  | --env | 环境 (test/prod/custom),默认 test,未填写时会交互式提示选择 |
120
- | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
121
- | --plugin-version | 插件版本号(默认安装最新版) |
122
- | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
123
- | --debug | 开启调试日志 |
120
+ | --customIp | 自定义环境后端 IP,仅当 env 为 custom 时使用 |
121
+ | --plugin-version | 插件版本号(默认安装最新版) |
122
+ | --openclaw-path | OpenClaw 安装目录(默认 \~/.openclaw) |
123
+ | --debug | 开启调试日志 |
124
124
 
125
125
  ## 💡 使用示例
126
126
 
@@ -1 +1 @@
1
- {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/box/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAsDhE,qBAAa,YAAY;IAIX,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,kBAAkB;IAI9C,cAAc,IAAI,IAAI;IAyBtB,OAAO,CAAC,QAAQ;IAmChB,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"}
1
+ {"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../../src/box/installer/installer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAsDhE,qBAAa,YAAY;IAIX,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAAa;gBAEX,MAAM,EAAE,kBAAkB;IAI9C,cAAc,IAAI,IAAI;IAyBtB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,aAAa;IAMrB,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;IAOhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA0BhB,eAAe;YA0Bf,iBAAiB;YAoHjB,cAAc;CAmR7B"}
@@ -28,10 +28,10 @@ function validateOpenclawPath(openclawPath) {
28
28
  debugLog(`[路径验证] 失败: 路径不是绝对路径`);
29
29
  throw new Error(`路径必须是绝对路径,当前输入: ${openclawPath}`);
30
30
  }
31
- const invalidChars = /[<>:"|?*]/.test(openclawPath);
31
+ const invalidChars = /[<>"|?*]/.test(openclawPath);
32
32
  if (invalidChars) {
33
33
  debugLog(`[路径验证] 失败: 路径包含特殊字符`);
34
- throw new Error('路径不能包含特殊字符: < > : " | ? *');
34
+ throw new Error('路径不能包含特殊字符: < > " | ? *');
35
35
  }
36
36
  debugLog(`[路径验证] 通过: ${openclawPath}`);
37
37
  }
@@ -510,7 +510,7 @@ class BoxInstaller {
510
510
  // 应用密钥
511
511
  appSecret: this.config.appSecret,
512
512
  // API 基础 URL
513
- baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
513
+ baseUrl: this.config.customIp ? `http://${this.config.customIp}` : config.DEFAULT_BASE_URL,
514
514
  // WebSocket URL
515
515
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
516
516
  // 允许不安全的 TLS 连接
@@ -833,8 +833,7 @@ async function httpPost(url, data, config) {
833
833
  }
834
834
  }
835
835
  }
836
- async function login(phone, password, env) {
837
- const config = getConfig(env);
836
+ async function login(phone, password, config) {
838
837
  const url = `${config.API.TUZAI_BASE_URL}/user/login/pass`;
839
838
  debugLog("[登录] 开始登录...");
840
839
  debugLog(`[登录] 请求地址: ${url}`);
@@ -860,8 +859,7 @@ async function login(phone, password, env) {
860
859
  throw new AppError2(ERROR_CODES.LOGIN_FAILED, error.message);
861
860
  }
862
861
  }
863
- async function fetchBoundConfig(token, phone, env) {
864
- const config = getConfig(env);
862
+ async function fetchBoundConfig(token, phone, config) {
865
863
  const url = `${config.API.TUZAI_BASE_URL}/work-bot/local/bound/init`;
866
864
  debugLog("[获取绑定配置] 开始获取绑定配置...");
867
865
  debugLog(`[获取绑定配置] 请求地址: ${url}`);
@@ -4829,12 +4827,16 @@ function deepMerge(target, source) {
4829
4827
  return result;
4830
4828
  }
4831
4829
  class LocalInstaller {
4830
+ spinner;
4831
+ prefixText = "";
4832
+ config;
4833
+ envConfig;
4832
4834
  constructor(config) {
4833
4835
  this.config = config;
4836
+ const env = this.config.env || "test";
4837
+ this.envConfig = getConfig(env, this.config.customIp);
4834
4838
  this.spinner = ora({ color: "cyan" }).start();
4835
4839
  }
4836
- spinner;
4837
- prefixText = "";
4838
4840
  validateConfig() {
4839
4841
  debugLog("[验证配置] 检查手机号码和密码...");
4840
4842
  if (!this.config.phone) {
@@ -4846,7 +4848,7 @@ class LocalInstaller {
4846
4848
  if (this.config.env === "custom") {
4847
4849
  debugLog("[验证配置] 检查自定义环境 IP...");
4848
4850
  if (!this.config.customIp) {
4849
- throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, "自定义环境必须提供 --customIp 参数");
4851
+ throw new AppError2(ERROR_CODES.INVALID_ARGUMENT, "自定义环境必须提供 --custom-ip 参数");
4850
4852
  }
4851
4853
  const result = ipv4Schema.safeParse(this.config.customIp);
4852
4854
  if (!result.success) {
@@ -4861,8 +4863,6 @@ class LocalInstaller {
4861
4863
  debugLog("[安装开始]");
4862
4864
  this.validateConfig();
4863
4865
  const env = this.config.env || "test";
4864
- debugLog(`[getConfig] env=${env}, customIp=${this.config.customIp}`);
4865
- const config = getConfig(env, this.config.customIp);
4866
4866
  let baseDir;
4867
4867
  if (this.config.openclawPath) {
4868
4868
  debugLog(`[路径验证] 验证自定义路径: ${this.config.openclawPath}`);
@@ -4875,15 +4875,15 @@ class LocalInstaller {
4875
4875
  baseDir = this.config.openclawPath;
4876
4876
  } else {
4877
4877
  const homeDir = getHomeDir();
4878
- baseDir = path.join(homeDir, config.DIRS.OPENCLAW);
4878
+ baseDir = path.join(homeDir, this.envConfig.DIRS.OPENCLAW);
4879
4879
  }
4880
4880
  const paths = {
4881
4881
  home: baseDir,
4882
- extensions: path.join(baseDir, config.DIRS.EXTENSIONS),
4883
- target: path.join(baseDir, config.DIRS.EXTENSIONS, config.PLUGIN_NAME),
4884
- config: path.join(baseDir, config.DIRS.CONFIG_FILE),
4885
- workspace: path.join(baseDir, config.DIRS.WORKSPACE),
4886
- temp: path.join(baseDir, config.DIRS.TEMP)
4882
+ extensions: path.join(baseDir, this.envConfig.DIRS.EXTENSIONS),
4883
+ target: path.join(baseDir, this.envConfig.DIRS.EXTENSIONS, this.envConfig.PLUGIN_NAME),
4884
+ config: path.join(baseDir, this.envConfig.DIRS.CONFIG_FILE),
4885
+ workspace: path.join(baseDir, this.envConfig.DIRS.WORKSPACE),
4886
+ temp: path.join(baseDir, this.envConfig.DIRS.TEMP)
4887
4887
  };
4888
4888
  debugLog(`[路径配置] home=${paths.home}`);
4889
4889
  debugLog(`[路径配置] extensions=${paths.extensions}`);
@@ -4894,7 +4894,13 @@ class LocalInstaller {
4894
4894
  const boundConfig = await this.doFetchBoundConfig(token);
4895
4895
  await this.doCleanOldFiles(paths.target);
4896
4896
  await this.doDownloadFromNpm(paths);
4897
- await this.doUpdateConfig(paths, boundConfig, env);
4897
+ await this.doUpdateConfig(paths, boundConfig);
4898
+ try {
4899
+ await fs.rm(paths.temp, { recursive: true, force: true });
4900
+ debugLog("[安装完成] 清理根临时目录完成");
4901
+ } catch {
4902
+ debugLog("[安装完成] 清理根临时目录失败(忽略)");
4903
+ }
4898
4904
  this.spinner.stop();
4899
4905
  } catch (error) {
4900
4906
  this.spinner.stop();
@@ -4911,7 +4917,6 @@ class LocalInstaller {
4911
4917
  return PLUGIN_PACKAGE_NAME;
4912
4918
  }
4913
4919
  async doLogin() {
4914
- const env = this.config.env || "test";
4915
4920
  this.spinner.prefixText = this.prefixText;
4916
4921
  this.spinner.text = chalk.cyan("正在验证账号...");
4917
4922
  debugLog(`[用户登录] 手机号: ${this.config.phone}`);
@@ -4922,18 +4927,17 @@ class LocalInstaller {
4922
4927
  }
4923
4928
  debugLog("[用户登录] 密码加密成功");
4924
4929
  debugLog("[用户登录] 调用登录接口...");
4925
- const token = await login(this.config.phone, encryptedPassword, env);
4930
+ const token = await login(this.config.phone, encryptedPassword, this.envConfig);
4926
4931
  this.prefixText += chalk.green(` ✓ 账号验证成功
4927
4932
  `);
4928
4933
  debugLog("[用户登录] 登录成功");
4929
4934
  return token;
4930
4935
  }
4931
4936
  async doFetchBoundConfig(token) {
4932
- const env = this.config.env || "test";
4933
4937
  this.spinner.prefixText = this.prefixText;
4934
4938
  this.spinner.text = chalk.cyan("正在获取绑定信息...");
4935
4939
  debugLog("[获取配置] 调用绑定配置接口...");
4936
- const boundConfig = await fetchBoundConfig(token, this.config.phone, env);
4940
+ const boundConfig = await fetchBoundConfig(token, this.config.phone, this.envConfig);
4937
4941
  debugLog(`[获取配置] agentId=${boundConfig.agentId}, appKey=${boundConfig.appKey?.slice(0, 8)}...`);
4938
4942
  this.prefixText += chalk.green(` ✓ 绑定信息获取成功
4939
4943
  `);
@@ -5046,12 +5050,12 @@ class LocalInstaller {
5046
5050
  `);
5047
5051
  try {
5048
5052
  await fs.rm(tempDir, { recursive: true, force: true });
5049
- debugLog("[下载插件] 清理临时目录完成");
5053
+ debugLog("[下载插件] 清理临时下载目录完成");
5050
5054
  } catch {
5051
- debugLog("[下载插件] 清理临时目录失败(忽略)");
5055
+ debugLog("[下载插件] 清理临时下载目录失败(忽略)");
5052
5056
  }
5053
5057
  }
5054
- async doUpdateConfig(paths, boundConfig, env) {
5058
+ async doUpdateConfig(paths, boundConfig) {
5055
5059
  this.spinner.prefixText = this.prefixText;
5056
5060
  this.spinner.text = chalk.cyan("正在生成配置...");
5057
5061
  debugLog("[更新配置] 创建目录...");
@@ -5067,7 +5071,7 @@ class LocalInstaller {
5067
5071
  } catch {
5068
5072
  debugLog("[更新配置] 无原有配置");
5069
5073
  }
5070
- const config = getConfig(env, this.config.customIp);
5074
+ const config = this.envConfig;
5071
5075
  const newConfig = {
5072
5076
  // diagnostics: 诊断配置
5073
5077
  diagnostics: {
@@ -5163,7 +5167,7 @@ class LocalInstaller {
5163
5167
  connectionMode: "websocket",
5164
5168
  appKey: boundConfig.appKey,
5165
5169
  appSecret: boundConfig.appSecret,
5166
- baseUrl: this.config.customIp || config.DEFAULT_BASE_URL,
5170
+ baseUrl: this.config.customIp ? `http://${this.config.customIp}` : config.DEFAULT_BASE_URL,
5167
5171
  websocketUrl: this.config.wsUrl || config.DEFAULT_WS_URL,
5168
5172
  allowInsecureTls: true,
5169
5173
  allowRawJsonPayload: true,
@@ -5394,7 +5398,7 @@ async function createLocalCommand(options) {
5394
5398
  }
5395
5399
  }
5396
5400
  function registerCommands(program2) {
5397
- program2.command("local").description("本地账户安装(需要登录)").option("-e, --env <env>", "环境 (test/prod/custom)").option("--phone <phone>", "手机号码").option("--user-pass <userPass>", "用户密码").option("--customIp <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);
5401
+ 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);
5398
5402
  }
5399
5403
  const __filename$1 = fileURLToPath(import.meta.url);
5400
5404
  const __dirname$1 = dirname(__filename$1);
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import("./index-DU1f2pnd.js").then((cli) => {
2
+ import("./index-CzXh8eTR.js").then((cli) => {
3
3
  cli.default();
4
4
  });
@@ -1,11 +1,11 @@
1
1
  import { AxiosRequestConfig } from 'axios';
2
2
  import { BoundConfig } from '../types';
3
- import { Environment } from '../../shared/config';
3
+ import { ConfigInterface } from '../../shared/config';
4
4
  export interface HttpResponse<T = any> {
5
5
  status: number;
6
6
  data: T;
7
7
  }
8
8
  export declare function httpPost<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<HttpResponse<T>>;
9
- export declare function login(phone: string, password: string, env: Environment): Promise<string>;
10
- export declare function fetchBoundConfig(token: string, phone: string, env: Environment): Promise<BoundConfig>;
9
+ export declare function login(phone: string, password: string, config: ConfigInterface): Promise<string>;
10
+ export declare function fetchBoundConfig(token: string, phone: string, config: ConfigInterface): Promise<BoundConfig>;
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/apis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,kBAAkB,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAMlD,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,GAAG;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,CAAC,CAAA;CACR;AAWD,wBAAsB,QAAQ,CAAC,CAAC,GAAG,GAAG,EACpC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA+C1B;AAED,wBAAsB,KAAK,CACzB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,WAAW,CAAC,CA0DtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/local/apis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,kBAAkB,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAKtD,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,GAAG;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,CAAC,CAAA;CACR;AAWD,wBAAsB,QAAQ,CAAC,CAAC,GAAG,GAAG,EACpC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA+C1B;AAED,wBAAsB,KAAK,CACzB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,WAAW,CAAC,CAyDtB"}
@@ -1,8 +1,9 @@
1
1
  import { LocalInstallerConfig } from '../types';
2
2
  export declare class LocalInstaller {
3
- private config;
4
3
  private spinner;
5
4
  private prefixText;
5
+ private readonly config;
6
+ private readonly envConfig;
6
7
  constructor(config: LocalInstallerConfig);
7
8
  validateConfig(): void;
8
9
  install(): Promise<void>;
@@ -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;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;IAyBhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD9B,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;YAOR,OAAO;YAqBP,kBAAkB;YAclB,eAAe;YAmBf,iBAAiB;YAmHjB,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;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;gBAE/B,MAAM,EAAE,oBAAoB;IAOxC,cAAc,IAAI,IAAI;IAyBhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD9B,aAAa,IAAI,MAAM;IAIvB,OAAO,CAAC,cAAc;YAOR,OAAO;YAoBP,kBAAkB;YAalB,eAAe;YAmBf,iBAAiB;YAmHjB,cAAc;CAiN7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/path.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAiB/D"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../../src/shared/utils/path.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAkB/D"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workclaw/cli",
3
3
  "type": "module",
4
- "version": "1.0.319",
4
+ "version": "1.0.320",
5
5
  "description": "WorkClaw CLI 工具 - 用于初始化和配置 WorkClaw 插件",
6
6
  "license": "MIT",
7
7
  "keywords": [