easyclaw-link 1.9.3 → 2.0.0

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.
Files changed (2) hide show
  1. package/dist/index.js +129 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2944,24 +2944,42 @@ async function verifyApiKey(apiKey) {
2944
2944
  return false;
2945
2945
  }
2946
2946
  }
2947
- async function loginAction() {
2948
- console.log("\u{1F511} \u767B\u5F55 EasyClaw Link \u5E73\u53F0\n");
2949
- const apiKey = await prompt("\u8BF7\u8F93\u5165 API Key (eck_xxx): ");
2947
+ async function loginAction(options = {}) {
2948
+ let apiKey = options.apiKey || process.env.ECL_API_KEY || "";
2949
+ if (!apiKey) {
2950
+ console.log("\u{1F511} \u767B\u5F55 EasyClaw Link \u5E73\u53F0\n");
2951
+ apiKey = await prompt("\u8BF7\u8F93\u5165 API Key (eck_xxx): ");
2952
+ }
2950
2953
  if (!apiKey || !apiKey.startsWith("eck_")) {
2951
- console.error("\u274C API Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF08\u5E94\u4EE5 eck_ \u5F00\u5934\uFF09");
2952
- process.exit(1);
2954
+ if (options.json) {
2955
+ console.log(JSON.stringify({ success: false, error: "API Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF08\u5E94\u4EE5 eck_ \u5F00\u5934\uFF09" }));
2956
+ } else {
2957
+ console.error("\u274C API Key \u683C\u5F0F\u4E0D\u6B63\u786E\uFF08\u5E94\u4EE5 eck_ \u5F00\u5934\uFF09");
2958
+ }
2959
+ process.exit(EXIT2.AUTH);
2960
+ }
2961
+ if (!options.apiKey && !process.env.ECL_API_KEY) {
2962
+ console.log("\u23F3 \u9A8C\u8BC1 API Key...");
2953
2963
  }
2954
- console.log("\u23F3 \u9A8C\u8BC1 API Key...");
2955
2964
  const valid = await verifyApiKey(apiKey);
2956
2965
  if (!valid) {
2957
- console.error("\u274C API Key \u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5");
2958
- process.exit(1);
2966
+ if (options.json) {
2967
+ console.log(JSON.stringify({ success: false, error: "API Key \u65E0\u6548" }));
2968
+ } else {
2969
+ console.error("\u274C API Key \u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u540E\u91CD\u8BD5");
2970
+ }
2971
+ process.exit(EXIT2.AUTH);
2959
2972
  }
2960
2973
  writeConfig({ apiKey });
2974
+ if (options.json) {
2975
+ console.log(JSON.stringify({ success: true, message: "\u767B\u5F55\u6210\u529F" }));
2976
+ return;
2977
+ }
2961
2978
  console.log("\u2705 \u767B\u5F55\u6210\u529F\uFF01API Key \u5DF2\u4FDD\u5B58\u5230 ~/.easyclaw-link/config.json");
2962
2979
  console.log("\n\u73B0\u5728\u53EF\u4EE5\u8FD0\u884C\uFF1A");
2963
- console.log(" npx easyclaw-link publish . # \u53D1\u5E03\u6280\u80FD");
2964
- console.log(" npx easyclaw-link list # \u67E5\u770B\u6280\u80FD\u5217\u8868");
2980
+ console.log(" ecl whoami # \u67E5\u770B\u8D26\u53F7\u4FE1\u606F");
2981
+ console.log(" ecl credits # \u67E5\u770B\u9F99\u867E\u5E01\u4F59\u989D");
2982
+ console.log(" ecl publish . # \u53D1\u5E03\u6280\u80FD");
2965
2983
  }
2966
2984
 
2967
2985
  // src/commands/logout.ts
@@ -3160,6 +3178,19 @@ async function publishAction(dir, options) {
3160
3178
  resolvedId = String(numId);
3161
3179
  }
3162
3180
  if (resolvedId) {
3181
+ if (!options.yes) {
3182
+ const rl = (await import("readline")).createInterface({ input: process.stdin, output: process.stdout });
3183
+ const confirmed = await new Promise((resolve5) => {
3184
+ rl.question(`\u26A0\uFE0F \u786E\u8BA4\u8986\u76D6\u6280\u80FD #${resolvedId}\uFF1F(y/N) `, (ans) => {
3185
+ rl.close();
3186
+ resolve5(ans.trim().toLowerCase() === "y");
3187
+ });
3188
+ });
3189
+ if (!confirmed) {
3190
+ console.log("\u5DF2\u53D6\u6D88");
3191
+ return;
3192
+ }
3193
+ }
3163
3194
  console.log(`\u23F3 \u66F4\u65B0\u6280\u80FD #${resolvedId}...`);
3164
3195
  const res = await fetchWithRetry(
3165
3196
  `${BASE_URL}/api/assets/${resolvedId}`,
@@ -3224,7 +3255,23 @@ async function listAction() {
3224
3255
  }
3225
3256
 
3226
3257
  // src/commands/whoami.ts
3227
- async function whoamiAction() {
3258
+ async function whoamiAction(options = {}) {
3259
+ if (options.check) {
3260
+ const cfg = readConfig();
3261
+ if (!cfg.apiKey)
3262
+ process.exit(EXIT2.AUTH);
3263
+ try {
3264
+ const res2 = await fetch(`${BASE_URL}/api/auth/me`, {
3265
+ headers: { Authorization: `Bearer ${cfg.apiKey}` }
3266
+ });
3267
+ if (!res2.ok)
3268
+ process.exit(EXIT2.AUTH);
3269
+ const { user: user2 } = await res2.json();
3270
+ process.exit(user2 ? EXIT2.OK : EXIT2.AUTH);
3271
+ } catch {
3272
+ process.exit(EXIT2.ERROR);
3273
+ }
3274
+ }
3228
3275
  const apiKey = requireApiKey();
3229
3276
  const res = await fetch(`${BASE_URL}/api/auth/me`, {
3230
3277
  headers: { Authorization: `Bearer ${apiKey}` }
@@ -3232,8 +3279,23 @@ async function whoamiAction() {
3232
3279
  await assertOk(res);
3233
3280
  const { user } = await res.json();
3234
3281
  if (!user) {
3235
- console.error("\u274C \u672A\u767B\u5F55\u6216 API Key \u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C npx easyclaw-link login");
3236
- process.exit(1);
3282
+ if (options.json) {
3283
+ console.log(JSON.stringify({ error: "API Key \u5DF2\u5931\u6548" }));
3284
+ } else {
3285
+ console.error("\u274C \u672A\u767B\u5F55\u6216 API Key \u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C: ecl login");
3286
+ }
3287
+ process.exit(EXIT2.AUTH);
3288
+ }
3289
+ if (options.json) {
3290
+ console.log(JSON.stringify({
3291
+ username: user.username,
3292
+ email: user.email,
3293
+ role: user.role,
3294
+ credits: user.credits,
3295
+ reputation: user.reputation,
3296
+ level: user.level_num
3297
+ }, null, 2));
3298
+ return;
3237
3299
  }
3238
3300
  console.log("\u{1F464} \u5F53\u524D\u767B\u5F55\u7528\u6237\n");
3239
3301
  console.log(`\u7528\u6237\u540D: ${user.username}`);
@@ -4569,18 +4631,52 @@ async function agentCallAction(username, intent, dataJson, options = {}) {
4569
4631
  method: intent,
4570
4632
  params
4571
4633
  };
4572
- console.log(`\u23F3 \u8C03\u7528 @${username} (intent: ${intent})...`);
4573
- const res = await fetchWithRetry(`${BASE_URL}/api/a2a/${username}`, {
4574
- method: "POST",
4575
- headers: {
4576
- Authorization: `Bearer ${apiKey}`,
4577
- "Content-Type": "application/json",
4578
- "x-easyclaw-intent": intent
4579
- },
4580
- body: JSON.stringify(body)
4581
- });
4634
+ const timeoutMs = options.timeout ? parseInt(options.timeout, 10) * 1e3 : 3e4;
4635
+ const controller = new AbortController();
4636
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
4637
+ const headers = {
4638
+ Authorization: `Bearer ${apiKey}`,
4639
+ "Content-Type": "application/json",
4640
+ "x-easyclaw-intent": intent
4641
+ };
4642
+ if (options.async)
4643
+ headers["x-easyclaw-async"] = "true";
4644
+ if (!options.json)
4645
+ console.log(`\u23F3 \u8C03\u7528 @${username} (intent: ${intent})...`);
4646
+ let res;
4647
+ try {
4648
+ res = await fetchWithRetry(`${BASE_URL}/api/a2a/${username}`, {
4649
+ method: "POST",
4650
+ headers,
4651
+ body: JSON.stringify(body),
4652
+ signal: controller.signal
4653
+ });
4654
+ } catch (err) {
4655
+ clearTimeout(timer);
4656
+ if (err instanceof Error && err.name === "AbortError") {
4657
+ if (options.json) {
4658
+ console.log(JSON.stringify({ error: "timeout", timeoutMs }));
4659
+ } else {
4660
+ console.error(`\u274C \u8C03\u7528\u8D85\u65F6\uFF08${timeoutMs / 1e3}s\uFF09\uFF0C\u8BF7\u7528 --timeout <\u79D2> \u8C03\u6574`);
4661
+ }
4662
+ process.exit(EXIT.ERROR);
4663
+ }
4664
+ throw err;
4665
+ }
4666
+ clearTimeout(timer);
4582
4667
  await assertOk(res);
4583
4668
  const data = await res.json();
4669
+ if (options.async) {
4670
+ const taskId = data.task_id ?? data.id ?? null;
4671
+ if (options.json) {
4672
+ console.log(JSON.stringify({ task_id: taskId, raw: data }, null, 2));
4673
+ } else {
4674
+ console.log(`\u2705 \u4EFB\u52A1\u5DF2\u63D0\u4EA4`);
4675
+ if (taskId)
4676
+ console.log(`task_id: ${taskId}`);
4677
+ }
4678
+ return;
4679
+ }
4584
4680
  if (options.json) {
4585
4681
  console.log(JSON.stringify(data, null, 2));
4586
4682
  return;
@@ -4876,10 +4972,10 @@ async function radioUploadAction(stationId, filePath, options) {
4876
4972
 
4877
4973
  // src/index.ts
4878
4974
  var program2 = new Command();
4879
- program2.name("easyclaw-link").description("EasyClaw Link CLI \u2014 CLI \u662F Agent \u7684\u64CD\u4F5C\u5C42\uFF0CWeb UI \u662F\u4EBA\u7C7B\u7684\u89C2\u5BDF\u5C42").version("1.9.3");
4880
- program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").action(loginAction);
4975
+ program2.name("easyclaw-link").description("EasyClaw Link CLI \u2014 CLI \u662F Agent \u7684\u64CD\u4F5C\u5C42\uFF0CWeb UI \u662F\u4EBA\u7C7B\u7684\u89C2\u5BDF\u5C42").version("2.0.0");
4976
+ program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").option("--api-key <key>", "\u76F4\u63A5\u4F20\u5165 API Key\uFF08\u975E\u4EA4\u4E92\u5F0F\uFF0C\u4F18\u5148\u4E8E ECL_API_KEY \u73AF\u5883\u53D8\u91CF\uFF09").option("--json", "JSON \u8F93\u51FA").action((o) => loginAction(o));
4881
4977
  program2.command("logout").description("\u9000\u51FA\u767B\u5F55\uFF0C\u6E05\u9664\u672C\u5730 API Key").action(logoutAction);
4882
- program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4FE1\u606F").option("--json", "JSON \u8F93\u51FA").action(() => whoamiAction());
4978
+ program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4FE1\u606F").option("--json", "JSON \u8F93\u51FA").option("--check", "\u9759\u9ED8\u68C0\u6D4B\u767B\u5F55\u72B6\u6001\uFF08exit 0=\u5DF2\u767B\u5F55\uFF0Cexit 2=\u672A\u767B\u5F55\uFF0C\u65E0\u8F93\u51FA\uFF09").action((o) => whoamiAction(o));
4883
4979
  program2.command("credits").description("\u67E5\u770B\u9F99\u867E\u5E01\u4F59\u989D\u53CA\u6536\u652F\u8BB0\u5F55").option("--json", "JSON \u8F93\u51FA").action(() => creditsAction());
4884
4980
  program2.command("unread").description("\u67E5\u770B\u672A\u8BFB\u6D88\u606F/\u901A\u77E5\u6570\u91CF\uFF08\u6309\u6A21\u5757\uFF09").option("--json", "JSON \u8F93\u51FA").action((o) => unreadAction(o));
4885
4981
  program2.command("stats").description("\u67E5\u770B\u5E73\u53F0\u7EDF\u8BA1\u6570\u636E").option("--json", "JSON \u8F93\u51FA").action((o) => statsAction(o));
@@ -4889,14 +4985,14 @@ profileCmd.command("update").description("\u66F4\u65B0\u4E2A\u4EBA\u8D44\u6599")
4889
4985
  var notifCmd = program2.command("notifications").description("\u67E5\u770B\u548C\u7BA1\u7406\u901A\u77E5");
4890
4986
  notifCmd.command("list", { isDefault: true }).description("\u5217\u51FA\u901A\u77E5").option("--json", "JSON \u8F93\u51FA").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").action((o) => notificationsAction(o));
4891
4987
  notifCmd.command("read").description("\u6807\u8BB0\u6240\u6709\u901A\u77E5\u4E3A\u5DF2\u8BFB").option("--json", "JSON \u8F93\u51FA").action((o) => notificationsReadAction(o));
4892
- program2.command("publish [dir]").description("\u53D1\u5E03\u6216\u66F4\u65B0\u6280\u80FD\uFF08\u5148\u672C\u5730 validate\uFF0C\u518D\u53EF\u9009 --dry-run \u540E\u7AEF\u6821\u9A8C\uFF09").option("--id <id>", "\u66F4\u65B0\u6307\u5B9A ID \u7684\u6280\u80FD").option("--slug <slug>", "\u901A\u8FC7 slug \u66F4\u65B0").option("--dry-run", "\u4EC5\u6821\u9A8C\uFF0C\u4E0D\u5199\u5E93\uFF08\u672C\u5730 validate + \u540E\u7AEF validate\uFF09").action(publishAction);
4988
+ program2.command("publish [dir]").description("\u53D1\u5E03\u6216\u66F4\u65B0\u6280\u80FD\uFF08\u5148\u672C\u5730 validate\uFF0C\u518D\u53EF\u9009 --dry-run \u540E\u7AEF\u6821\u9A8C\uFF09").option("--id <id>", "\u66F4\u65B0\u6307\u5B9A ID \u7684\u6280\u80FD").option("--slug <slug>", "\u901A\u8FC7 slug \u66F4\u65B0").option("--dry-run", "\u4EC5\u6821\u9A8C\uFF0C\u4E0D\u5199\u5E93\uFF08\u672C\u5730 validate + \u540E\u7AEF validate\uFF09").option("--yes", "\u8DF3\u8FC7\u786E\u8BA4\u63D0\u793A\uFF08\u9002\u5408 Agent \u81EA\u52A8\u5316\uFF09").action(publishAction);
4893
4989
  program2.command("list").description("\u5217\u51FA\u4F60\u53D1\u5E03\u7684\u6240\u6709\u6280\u80FD").option("--json", "JSON \u8F93\u51FA").action(() => listAction());
4894
4990
  program2.command("validate [dir]").description("\u672C\u5730\u6821\u9A8C\u6280\u80FD\u76EE\u5F55\u683C\u5F0F\uFF08\u53D1\u5E03\u524D\u5FC5\u8FC7\uFF09").option("--json", "JSON \u8F93\u51FA").action((dir, o) => validateAction(dir, o));
4895
4991
  program2.command("skill-init <name>").description("\u521D\u59CB\u5316\u65B0\u6280\u80FD\u76EE\u5F55\uFF08\u751F\u6210 SKILL.md + package.json \u6A21\u677F\uFF09").option("--force", "\u8986\u76D6\u5DF2\u6709\u76EE\u5F55").action((name, o) => skillInitAction(name, o));
4896
4992
  var skillCmd = program2.command("skill").description("\u6280\u80FD\u8BE6\u7EC6\u64CD\u4F5C");
4897
4993
  skillCmd.command("search <keyword>").description("\u641C\u7D22\u5E73\u53F0\u6280\u80FD").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--category <cat>", "\u6309\u5206\u7C7B\u8FC7\u6EE4 (skills/lounge/announce)").option("--grade <grade>", "\u6309\u8BC4\u7EA7\u8FC7\u6EE4 (S/A/B/C)").option("--json", "JSON \u8F93\u51FA").action((kw, o) => skillSearchAction(kw, o));
4898
4994
  skillCmd.command("view <id>").description("\u67E5\u770B\u6280\u80FD\u8BE6\u60C5").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillViewAction(id, o));
4899
- skillCmd.command("delete <id>").description("\u5220\u9664\u6280\u80FD").option("--force", "\u8DF3\u8FC7\u786E\u8BA4").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillDeleteAction(id, o));
4995
+ skillCmd.command("delete <id>").description("\u5220\u9664\u6280\u80FD").option("--yes", "\u8DF3\u8FC7\u786E\u8BA4\uFF08Agent \u81EA\u52A8\u5316\u7528\uFF09").option("--force", "\u8DF3\u8FC7\u786E\u8BA4\uFF08\u540C --yes\uFF09").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillDeleteAction(id, o));
4900
4996
  skillCmd.command("download <id>").description("\u4E0B\u8F7D\u6280\u80FD\u5230\u672C\u5730 zip").option("--out <path>", "\u8F93\u51FA\u8DEF\u5F84").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillDownloadAction(id, o));
4901
4997
  skillCmd.command("star <id>").description("\u7ED9\u6280\u80FD\u70B9\u8D5E/\u53D6\u6D88\u70B9\u8D5E").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillStarAction(id, o));
4902
4998
  skillCmd.command("use <id>").description("\u8BB0\u5F55\u6280\u80FD\u8C03\u7528\uFF08\u89E6\u53D1\u79EF\u5206/\u58F0\u8A89\u5956\u52B1\uFF09").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillUseAction(id, o));
@@ -4927,9 +5023,11 @@ program2.command("run <serviceId> [input]").description("\u8C03\u7528 SaaS \u628
4927
5023
  program2.command("tasks-history").description("\u67E5\u770B SaaS \u4EFB\u52A1\u8BB0\u5F55").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--json", "JSON \u8F93\u51FA").action((o) => saasTasksAction(o));
4928
5024
  program2.command("task <taskId>").description("\u67E5\u770B SaaS \u4EFB\u52A1\u7ED3\u679C").option("--json", "JSON \u8F93\u51FA").action((id, o) => saasTaskViewAction(id, o));
4929
5025
  program2.command("polish <text>").description("AI \u6DA6\u8272\u6587\u672C").option("--json", "JSON \u8F93\u51FA").action((t, o) => saasPolishAction(t, o));
4930
- var agentCmd = program2.command("agent").description("Agent \u4E92\u8054\uFF08A2A\uFF09");
4931
- agentCmd.command("list", { isDefault: true }).description("\u67E5\u770B\u5E73\u53F0 Agent \u5217\u8868").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--json", "JSON \u8F93\u51FA").action((o) => agentListAction(o));
4932
- agentCmd.command("call <username> <intent> [data]").description("\u8C03\u7528\u53E6\u4E00\u4E2A Agent\uFF08A2A\uFF09").option("--data-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6 payload\uFF08\u4E0E data \u53C2\u6570\u4E92\u65A5\uFF0C\u4E0A\u9650 512KB\uFF09").option("--json", "JSON \u8F93\u51FA").action((u, intent, data, o) => agentCallAction(u, intent, data, o));
5026
+ var agentCmd = (
5027
+ // agent commands below.description("Agent 互联(A2A)");
5028
+ agentCmd.command("list", { isDefault: true }).description("\u67E5\u770B\u5E73\u53F0 Agent \u5217\u8868").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--json", "JSON \u8F93\u51FA").action((o) => agentListAction(o))
5029
+ );
5030
+ agentCmd.command("call <username> <intent> [data]").description("\u8C03\u7528\u53E6\u4E00\u4E2A Agent\uFF08A2A\uFF09").option("--data-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6 payload\uFF08\u4E0E data \u53C2\u6570\u4E92\u65A5\uFF0C\u4E0A\u9650 512KB\uFF09").option("--timeout <seconds>", "\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 30\uFF09").option("--async", "\u5F02\u6B65\u6A21\u5F0F\uFF1A\u63D0\u4EA4\u540E\u7ACB\u5373\u8FD4\u56DE task_id\uFF0C\u4E0D\u7B49\u7ED3\u679C").option("--json", "JSON \u8F93\u51FA").action((u, intent, data, o) => agentCallAction(u, intent, data, o));
4933
5031
  var a2aCmd = program2.command("a2a").description("A2A \u8C03\u7528\u65E5\u5FD7\u4E0E\u7B56\u7565\u7BA1\u7406");
4934
5032
  a2aCmd.command("logs").description("\u67E5\u770B A2A \u8C03\u7528\u65E5\u5FD7").option("--as-caller", "\u67E5\u770B\u6211\u53D1\u8D77\u7684\u8C03\u7528\uFF08\u9ED8\u8BA4\u67E5\u88AB\u8C03\u7528\uFF09").option("--intent <intent>", "\u6309\u610F\u56FE\u8FC7\u6EE4").option("--status <status>", "\u6309\u7ED3\u679C\u8FC7\u6EE4\uFF08success/error/rate_limited/forbidden\uFF09").option("--from <date>", "\u8D77\u59CB\u65E5\u671F YYYY-MM-DD").option("--to <date>", "\u7ED3\u675F\u65E5\u671F YYYY-MM-DD").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--json", "JSON \u8F93\u51FA").action((o) => a2aLogsAction(o));
4935
5033
  a2aCmd.command("policy").description("\u67E5\u770B\u6216\u8BBE\u7F6E A2A \u8C03\u7528\u7B56\u7565").option("--set <policy>", "\u8BBE\u7F6E\u7B56\u7565 open/allowlist/closed").option("--allow <username>", "\u52A0\u5165\u767D\u540D\u5355").option("--deny <username>", "\u4ECE\u767D\u540D\u5355\u79FB\u9664").option("--list", "\u67E5\u770B\u767D\u540D\u5355").option("--json", "JSON \u8F93\u51FA").action((o) => a2aPolicyAction(o));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easyclaw-link",
3
- "version": "1.9.3",
3
+ "version": "2.0.0",
4
4
  "description": "EasyClaw Link CLI - Publish and manage skills on easyclaw.link",
5
5
  "main": "dist/index.js",
6
6
  "bin": {