easyclaw-link 1.4.2 → 1.6.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.
- package/dist/index.js +178 -279
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -932,7 +932,7 @@ var require_command = __commonJS({
|
|
|
932
932
|
var EventEmitter = require("events").EventEmitter;
|
|
933
933
|
var childProcess = require("child_process");
|
|
934
934
|
var path8 = require("path");
|
|
935
|
-
var
|
|
935
|
+
var fs11 = require("fs");
|
|
936
936
|
var process2 = require("process");
|
|
937
937
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
938
938
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1765,11 +1765,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1765
1765
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1766
1766
|
function findFile(baseDir, baseName) {
|
|
1767
1767
|
const localBin = path8.resolve(baseDir, baseName);
|
|
1768
|
-
if (
|
|
1768
|
+
if (fs11.existsSync(localBin))
|
|
1769
1769
|
return localBin;
|
|
1770
1770
|
if (sourceExt.includes(path8.extname(baseName)))
|
|
1771
1771
|
return void 0;
|
|
1772
|
-
const foundExt = sourceExt.find((ext) =>
|
|
1772
|
+
const foundExt = sourceExt.find((ext) => fs11.existsSync(`${localBin}${ext}`));
|
|
1773
1773
|
if (foundExt)
|
|
1774
1774
|
return `${localBin}${foundExt}`;
|
|
1775
1775
|
return void 0;
|
|
@@ -1781,7 +1781,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1781
1781
|
if (this._scriptPath) {
|
|
1782
1782
|
let resolvedScriptPath;
|
|
1783
1783
|
try {
|
|
1784
|
-
resolvedScriptPath =
|
|
1784
|
+
resolvedScriptPath = fs11.realpathSync(this._scriptPath);
|
|
1785
1785
|
} catch (err) {
|
|
1786
1786
|
resolvedScriptPath = this._scriptPath;
|
|
1787
1787
|
}
|
|
@@ -2833,6 +2833,54 @@ var os = __toESM(require("os"));
|
|
|
2833
2833
|
var CONFIG_DIR = path.join(os.homedir(), ".easyclaw-link");
|
|
2834
2834
|
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
2835
2835
|
var BASE_URL = process.env.EASYCLAW_LINK_API || "https://easyclaw.link";
|
|
2836
|
+
var EXIT = {
|
|
2837
|
+
OK: 0,
|
|
2838
|
+
ERROR: 1,
|
|
2839
|
+
AUTH: 2,
|
|
2840
|
+
PERMISSION: 3,
|
|
2841
|
+
NOT_FOUND: 4,
|
|
2842
|
+
VALIDATION: 5,
|
|
2843
|
+
RATE_LIMIT: 6
|
|
2844
|
+
};
|
|
2845
|
+
function httpError(status, serverMessage) {
|
|
2846
|
+
const msg = serverMessage ? `: ${serverMessage}` : "";
|
|
2847
|
+
switch (status) {
|
|
2848
|
+
case 401:
|
|
2849
|
+
console.error(`\u274C \u8BA4\u8BC1\u5931\u8D25${msg}
|
|
2850
|
+
\u2192 \u8BF7\u5148\u8FD0\u884C: ecl login`);
|
|
2851
|
+
process.exit(EXIT.AUTH);
|
|
2852
|
+
case 403:
|
|
2853
|
+
console.error(`\u274C \u6743\u9650\u4E0D\u8DB3${msg}
|
|
2854
|
+
\u2192 \u5F53\u524D\u8D26\u53F7\u65E0\u6B64\u64CD\u4F5C\u6743\u9650\uFF0C\u68C0\u67E5\u8D26\u53F7\u89D2\u8272`);
|
|
2855
|
+
process.exit(EXIT.PERMISSION);
|
|
2856
|
+
case 404:
|
|
2857
|
+
console.error(`\u274C \u8D44\u6E90\u4E0D\u5B58\u5728${msg}
|
|
2858
|
+
\u2192 \u68C0\u67E5 ID/slug \u662F\u5426\u6B63\u786E`);
|
|
2859
|
+
process.exit(EXIT.NOT_FOUND);
|
|
2860
|
+
case 422:
|
|
2861
|
+
console.error(`\u274C \u8BF7\u6C42\u6821\u9A8C\u5931\u8D25${msg}
|
|
2862
|
+
\u2192 \u68C0\u67E5\u53C2\u6570\u683C\u5F0F`);
|
|
2863
|
+
process.exit(EXIT.VALIDATION);
|
|
2864
|
+
case 429:
|
|
2865
|
+
console.error(`\u274C \u89E6\u53D1\u9891\u7387\u9650\u5236${msg}
|
|
2866
|
+
\u2192 \u8BF7\u7A0D\u540E\u91CD\u8BD5`);
|
|
2867
|
+
process.exit(EXIT.RATE_LIMIT);
|
|
2868
|
+
default:
|
|
2869
|
+
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (HTTP ${status})${msg}`);
|
|
2870
|
+
process.exit(EXIT.ERROR);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
async function assertOk(res) {
|
|
2874
|
+
if (res.ok)
|
|
2875
|
+
return;
|
|
2876
|
+
let serverMsg;
|
|
2877
|
+
try {
|
|
2878
|
+
const body = await res.clone().json();
|
|
2879
|
+
serverMsg = body.error || body.message;
|
|
2880
|
+
} catch {
|
|
2881
|
+
}
|
|
2882
|
+
httpError(res.status, serverMsg);
|
|
2883
|
+
}
|
|
2836
2884
|
function readConfig() {
|
|
2837
2885
|
try {
|
|
2838
2886
|
if (!fs.existsSync(CONFIG_FILE))
|
|
@@ -2852,8 +2900,8 @@ function writeConfig(config) {
|
|
|
2852
2900
|
function requireApiKey() {
|
|
2853
2901
|
const cfg = readConfig();
|
|
2854
2902
|
if (!cfg.apiKey) {
|
|
2855
|
-
console.error("\u274C \u672A\u767B\u5F55\uFF0C\u8BF7\u5148\u8FD0\u884C:
|
|
2856
|
-
process.exit(
|
|
2903
|
+
console.error("\u274C \u672A\u767B\u5F55\uFF0C\u8BF7\u5148\u8FD0\u884C: ecl login");
|
|
2904
|
+
process.exit(EXIT.AUTH);
|
|
2857
2905
|
}
|
|
2858
2906
|
return cfg.apiKey;
|
|
2859
2907
|
}
|
|
@@ -2970,10 +3018,7 @@ async function resolveId(apiKey, slug) {
|
|
|
2970
3018
|
`${BASE_URL}/api/assets?author=me&limit=${PAGE_SIZE}&offset=${offset}`,
|
|
2971
3019
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
2972
3020
|
);
|
|
2973
|
-
|
|
2974
|
-
console.error(`\u274C \u67E5\u8BE2\u6280\u80FD\u5217\u8868\u5931\u8D25 (${res.status})`);
|
|
2975
|
-
process.exit(1);
|
|
2976
|
-
}
|
|
3021
|
+
await assertOk(res);
|
|
2977
3022
|
const { assets } = await res.json();
|
|
2978
3023
|
if (!assets || assets.length === 0)
|
|
2979
3024
|
break;
|
|
@@ -3027,11 +3072,7 @@ async function publishAction(dir, options) {
|
|
|
3027
3072
|
body: JSON.stringify({ content })
|
|
3028
3073
|
}
|
|
3029
3074
|
);
|
|
3030
|
-
|
|
3031
|
-
const body = await res.text();
|
|
3032
|
-
console.error(`\u274C \u66F4\u65B0\u5931\u8D25 (${res.status}): ${body}`);
|
|
3033
|
-
process.exit(1);
|
|
3034
|
-
}
|
|
3075
|
+
await assertOk(res);
|
|
3035
3076
|
const { asset } = await res.json();
|
|
3036
3077
|
console.log(`\u2705 \u6280\u80FD\u5DF2\u66F4\u65B0`);
|
|
3037
3078
|
console.log(`\u{1F517} ${BASE_URL}/market/${asset?.id ?? resolvedId}`);
|
|
@@ -3045,11 +3086,7 @@ async function publishAction(dir, options) {
|
|
|
3045
3086
|
body: JSON.stringify({ title, content, description, category: "other" })
|
|
3046
3087
|
}
|
|
3047
3088
|
);
|
|
3048
|
-
|
|
3049
|
-
const body = await res.text();
|
|
3050
|
-
console.error(`\u274C \u53D1\u5E03\u5931\u8D25 (${res.status}): ${body}`);
|
|
3051
|
-
process.exit(1);
|
|
3052
|
-
}
|
|
3089
|
+
await assertOk(res);
|
|
3053
3090
|
const { asset } = await res.json();
|
|
3054
3091
|
console.log(`\u2705 \u6280\u80FD\u53D1\u5E03\u6210\u529F\uFF01`);
|
|
3055
3092
|
console.log(`\u{1F517} ${BASE_URL}/market/${asset?.id}`);
|
|
@@ -3066,11 +3103,7 @@ async function listAction() {
|
|
|
3066
3103
|
`${BASE_URL}/api/assets?author=me`,
|
|
3067
3104
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
3068
3105
|
);
|
|
3069
|
-
|
|
3070
|
-
const body = await res.text();
|
|
3071
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status}): ${body}`);
|
|
3072
|
-
process.exit(1);
|
|
3073
|
-
}
|
|
3106
|
+
await assertOk(res);
|
|
3074
3107
|
const { assets } = await res.json();
|
|
3075
3108
|
if (!assets || assets.length === 0) {
|
|
3076
3109
|
console.log("\u{1F4ED} \u6682\u65E0\u6280\u80FD\uFF0C\u4F7F\u7528 npx easyclaw-link publish . \u53D1\u5E03\u4F60\u7684\u7B2C\u4E00\u4E2A\u6280\u80FD");
|
|
@@ -3099,11 +3132,7 @@ async function whoamiAction() {
|
|
|
3099
3132
|
const res = await fetch(`${BASE_URL}/api/auth/me`, {
|
|
3100
3133
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3101
3134
|
});
|
|
3102
|
-
|
|
3103
|
-
const body = await res.text();
|
|
3104
|
-
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (${res.status}): ${body}`);
|
|
3105
|
-
process.exit(1);
|
|
3106
|
-
}
|
|
3135
|
+
await assertOk(res);
|
|
3107
3136
|
const { user } = await res.json();
|
|
3108
3137
|
if (!user) {
|
|
3109
3138
|
console.error("\u274C \u672A\u767B\u5F55\u6216 API Key \u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C npx easyclaw-link login");
|
|
@@ -3124,11 +3153,7 @@ async function creditsAction() {
|
|
|
3124
3153
|
const res = await fetch(`${BASE_URL}/api/credits`, {
|
|
3125
3154
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3126
3155
|
});
|
|
3127
|
-
|
|
3128
|
-
const body = await res.text();
|
|
3129
|
-
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (${res.status}): ${body}`);
|
|
3130
|
-
process.exit(1);
|
|
3131
|
-
}
|
|
3156
|
+
await assertOk(res);
|
|
3132
3157
|
const data = await res.json();
|
|
3133
3158
|
console.log(`\u{1F4B0} \u9F99\u867E\u5E01\u4F59\u989D: ${data.credits} \u{1F99E}`);
|
|
3134
3159
|
console.log(`\u2B50 \u58F0\u671B: ${data.reputation} ${data.level.badge} ${data.level.name}
|
|
@@ -3157,11 +3182,7 @@ async function tasksAction() {
|
|
|
3157
3182
|
const res = await fetch(`${BASE_URL}/api/bounties?status=open&sort=date_desc`, {
|
|
3158
3183
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3159
3184
|
});
|
|
3160
|
-
|
|
3161
|
-
const body = await res.text();
|
|
3162
|
-
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (${res.status}): ${body}`);
|
|
3163
|
-
process.exit(1);
|
|
3164
|
-
}
|
|
3185
|
+
await assertOk(res);
|
|
3165
3186
|
const data = await res.json();
|
|
3166
3187
|
const bounties = data.bounties ?? [];
|
|
3167
3188
|
if (bounties.length === 0) {
|
|
@@ -3267,12 +3288,7 @@ ${bounty.description}
|
|
|
3267
3288
|
},
|
|
3268
3289
|
body: JSON.stringify({ content })
|
|
3269
3290
|
});
|
|
3270
|
-
|
|
3271
|
-
const body = await res.json().catch(() => ({}));
|
|
3272
|
-
const msg = typeof body.error === "string" ? body.error : `HTTP ${res.status}`;
|
|
3273
|
-
console.error(`\u274C \u63D0\u4EA4\u5931\u8D25: ${msg}`);
|
|
3274
|
-
process.exit(1);
|
|
3275
|
-
}
|
|
3291
|
+
await assertOk(res);
|
|
3276
3292
|
const { submission } = await res.json();
|
|
3277
3293
|
console.log(`\u2705 \u7533\u8BF7\u63D0\u4EA4\u6210\u529F\uFF01\u63D0\u4EA4 ID: ${submission.id}`);
|
|
3278
3294
|
console.log(`\u{1F517} \u67E5\u770B\u4EFB\u52A1: ${BASE_URL}/bounties/${id}`);
|
|
@@ -3293,10 +3309,7 @@ async function notificationsAction(options) {
|
|
|
3293
3309
|
`${BASE_URL}/api/notifications?limit=${limit}`,
|
|
3294
3310
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
3295
3311
|
);
|
|
3296
|
-
|
|
3297
|
-
console.error(`\u274C \u83B7\u53D6\u901A\u77E5\u5931\u8D25 (${res.status})`);
|
|
3298
|
-
process.exit(1);
|
|
3299
|
-
}
|
|
3312
|
+
await assertOk(res);
|
|
3300
3313
|
const data = await res.json();
|
|
3301
3314
|
if (options.json) {
|
|
3302
3315
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3321,10 +3334,7 @@ async function notificationsReadAction(options) {
|
|
|
3321
3334
|
Authorization: `Bearer ${apiKey}`
|
|
3322
3335
|
}
|
|
3323
3336
|
});
|
|
3324
|
-
|
|
3325
|
-
console.error(`\u274C \u6807\u8BB0\u5931\u8D25 (${res.status})`);
|
|
3326
|
-
process.exit(1);
|
|
3327
|
-
}
|
|
3337
|
+
await assertOk(res);
|
|
3328
3338
|
const data = await res.json();
|
|
3329
3339
|
if (options.json) {
|
|
3330
3340
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3339,10 +3349,7 @@ async function unreadAction(options) {
|
|
|
3339
3349
|
const res = await fetchWithRetry(`${BASE_URL}/api/unread-counts`, {
|
|
3340
3350
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3341
3351
|
});
|
|
3342
|
-
|
|
3343
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3344
|
-
process.exit(1);
|
|
3345
|
-
}
|
|
3352
|
+
await assertOk(res);
|
|
3346
3353
|
const data = await res.json();
|
|
3347
3354
|
if (options.json) {
|
|
3348
3355
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3368,10 +3375,7 @@ async function statsAction(options) {
|
|
|
3368
3375
|
const res = await fetchWithRetry(`${BASE_URL}/api/stats`, {
|
|
3369
3376
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3370
3377
|
});
|
|
3371
|
-
|
|
3372
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3373
|
-
process.exit(1);
|
|
3374
|
-
}
|
|
3378
|
+
await assertOk(res);
|
|
3375
3379
|
const data = await res.json();
|
|
3376
3380
|
if (options.json) {
|
|
3377
3381
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3392,10 +3396,7 @@ async function leaderboardAction(options) {
|
|
|
3392
3396
|
const res = await fetchWithRetry(`${BASE_URL}/api/leaderboard?limit=${limit}`, {
|
|
3393
3397
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3394
3398
|
});
|
|
3395
|
-
|
|
3396
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3397
|
-
process.exit(1);
|
|
3398
|
-
}
|
|
3399
|
+
await assertOk(res);
|
|
3399
3400
|
const data = await res.json();
|
|
3400
3401
|
if (options.json) {
|
|
3401
3402
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3429,11 +3430,7 @@ async function profileUpdateAction(options) {
|
|
|
3429
3430
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
3430
3431
|
body: JSON.stringify(body)
|
|
3431
3432
|
});
|
|
3432
|
-
|
|
3433
|
-
const err = await res.json().catch(() => ({}));
|
|
3434
|
-
console.error(`\u274C \u66F4\u65B0\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3435
|
-
process.exit(1);
|
|
3436
|
-
}
|
|
3433
|
+
await assertOk(res);
|
|
3437
3434
|
const data = await res.json();
|
|
3438
3435
|
if (options.json) {
|
|
3439
3436
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3524,13 +3521,7 @@ async function skillViewAction(id, options) {
|
|
|
3524
3521
|
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}`, {
|
|
3525
3522
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3526
3523
|
});
|
|
3527
|
-
|
|
3528
|
-
if (res.status === 404)
|
|
3529
|
-
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3530
|
-
else
|
|
3531
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3532
|
-
process.exit(1);
|
|
3533
|
-
}
|
|
3524
|
+
await assertOk(res);
|
|
3534
3525
|
const data = await res.json();
|
|
3535
3526
|
const asset = data.asset ?? data;
|
|
3536
3527
|
if (options.json) {
|
|
@@ -3565,15 +3556,7 @@ async function skillDeleteAction(id, options) {
|
|
|
3565
3556
|
method: "DELETE",
|
|
3566
3557
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3567
3558
|
});
|
|
3568
|
-
|
|
3569
|
-
if (res.status === 404)
|
|
3570
|
-
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3571
|
-
else if (res.status === 403)
|
|
3572
|
-
console.error("\u274C \u65E0\u6743\u9650\u5220\u9664\u6B64\u6280\u80FD");
|
|
3573
|
-
else
|
|
3574
|
-
console.error(`\u274C \u5220\u9664\u5931\u8D25 (${res.status})`);
|
|
3575
|
-
process.exit(1);
|
|
3576
|
-
}
|
|
3559
|
+
await assertOk(res);
|
|
3577
3560
|
if (options.json) {
|
|
3578
3561
|
console.log(JSON.stringify({ success: true, id }));
|
|
3579
3562
|
return;
|
|
@@ -3585,13 +3568,7 @@ async function skillDownloadAction(id, options) {
|
|
|
3585
3568
|
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}/download`, {
|
|
3586
3569
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3587
3570
|
});
|
|
3588
|
-
|
|
3589
|
-
if (res.status === 404)
|
|
3590
|
-
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3591
|
-
else
|
|
3592
|
-
console.error(`\u274C \u4E0B\u8F7D\u5931\u8D25 (${res.status})`);
|
|
3593
|
-
process.exit(1);
|
|
3594
|
-
}
|
|
3571
|
+
await assertOk(res);
|
|
3595
3572
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
3596
3573
|
const outPath = options.out || `skill-${id}.zip`;
|
|
3597
3574
|
const resolved = path6.resolve(outPath);
|
|
@@ -3612,10 +3589,7 @@ async function skillStarAction(id, options) {
|
|
|
3612
3589
|
method: "POST",
|
|
3613
3590
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3614
3591
|
});
|
|
3615
|
-
|
|
3616
|
-
console.error(`\u274C \u64CD\u4F5C\u5931\u8D25 (${res.status})`);
|
|
3617
|
-
process.exit(1);
|
|
3618
|
-
}
|
|
3592
|
+
await assertOk(res);
|
|
3619
3593
|
const data = await res.json();
|
|
3620
3594
|
if (options.json) {
|
|
3621
3595
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3630,10 +3604,7 @@ async function skillUseAction(id, options) {
|
|
|
3630
3604
|
method: "POST",
|
|
3631
3605
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3632
3606
|
});
|
|
3633
|
-
|
|
3634
|
-
console.error(`\u274C \u64CD\u4F5C\u5931\u8D25 (${res.status})`);
|
|
3635
|
-
process.exit(1);
|
|
3636
|
-
}
|
|
3607
|
+
await assertOk(res);
|
|
3637
3608
|
const data = await res.json();
|
|
3638
3609
|
if (options.json) {
|
|
3639
3610
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3641,6 +3612,45 @@ async function skillUseAction(id, options) {
|
|
|
3641
3612
|
}
|
|
3642
3613
|
console.log(`\u2705 \u6280\u80FD #${id} \u8C03\u7528\u5DF2\u8BB0\u5F55`);
|
|
3643
3614
|
}
|
|
3615
|
+
async function skillSearchAction(keyword, options) {
|
|
3616
|
+
if (!keyword?.trim()) {
|
|
3617
|
+
console.error("\u274C \u8BF7\u63D0\u4F9B\u641C\u7D22\u5173\u952E\u8BCD");
|
|
3618
|
+
process.exit(EXIT.VALIDATION);
|
|
3619
|
+
}
|
|
3620
|
+
const apiKey = requireApiKey();
|
|
3621
|
+
const parsed = parseInt(options.limit || "20", 10);
|
|
3622
|
+
const limit = isNaN(parsed) || parsed <= 0 ? 20 : Math.min(parsed, 50);
|
|
3623
|
+
const qs = new URLSearchParams({ q: keyword, limit: String(limit) });
|
|
3624
|
+
if (options.category)
|
|
3625
|
+
qs.set("category", options.category);
|
|
3626
|
+
if (options.grade)
|
|
3627
|
+
qs.set("grade", options.grade.toUpperCase());
|
|
3628
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets?${qs}`, {
|
|
3629
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3630
|
+
});
|
|
3631
|
+
await assertOk(res);
|
|
3632
|
+
const data = await res.json();
|
|
3633
|
+
if (options.json) {
|
|
3634
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3635
|
+
return;
|
|
3636
|
+
}
|
|
3637
|
+
const assets = data.assets ?? [];
|
|
3638
|
+
console.log(`\u{1F50D} \u641C\u7D22\u7ED3\u679C\uFF1A"${keyword}" (${data.total ?? assets.length} \u4E2A)
|
|
3639
|
+
`);
|
|
3640
|
+
if (!assets.length) {
|
|
3641
|
+
console.log("\u65E0\u5339\u914D\u6280\u80FD");
|
|
3642
|
+
return;
|
|
3643
|
+
}
|
|
3644
|
+
const sep = "-".repeat(72);
|
|
3645
|
+
console.log(`${"#ID".padEnd(6)} ${"\u7B49\u7EA7".padEnd(4)} ${"\u6807\u9898".padEnd(28)} ${"\u4F5C\u8005".padEnd(18)} \u2B50 \u{1F4DE}`);
|
|
3646
|
+
console.log(sep);
|
|
3647
|
+
for (const a of assets) {
|
|
3648
|
+
const title = (a.title || "").slice(0, 28).padEnd(28);
|
|
3649
|
+
const author = (a.author_username || "-").slice(0, 18).padEnd(18);
|
|
3650
|
+
const grade = (a.grade || "-").padEnd(4);
|
|
3651
|
+
console.log(`#${String(a.id).padEnd(5)} ${grade} ${title} ${author} ${a.stars ?? 0} ${a.calls ?? 0}`);
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3644
3654
|
|
|
3645
3655
|
// src/commands/bounty.ts
|
|
3646
3656
|
var fs7 = __toESM(require("fs"));
|
|
@@ -3653,10 +3663,7 @@ async function bountyListAction(options) {
|
|
|
3653
3663
|
`${BASE_URL}/api/bounties?status=${status}&limit=${limit}&sort=date_desc`,
|
|
3654
3664
|
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
3655
3665
|
);
|
|
3656
|
-
|
|
3657
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3658
|
-
process.exit(1);
|
|
3659
|
-
}
|
|
3666
|
+
await assertOk(res);
|
|
3660
3667
|
const data = await res.json();
|
|
3661
3668
|
if (options.json) {
|
|
3662
3669
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3684,10 +3691,7 @@ async function bountyMineAction(options) {
|
|
|
3684
3691
|
const res = await fetchWithRetry(`${BASE_URL}/api/bounties?mine=true`, {
|
|
3685
3692
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3686
3693
|
});
|
|
3687
|
-
|
|
3688
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3689
|
-
process.exit(1);
|
|
3690
|
-
}
|
|
3694
|
+
await assertOk(res);
|
|
3691
3695
|
const data = await res.json();
|
|
3692
3696
|
if (options.json) {
|
|
3693
3697
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3709,13 +3713,7 @@ async function bountyViewAction(id, options) {
|
|
|
3709
3713
|
const res = await fetchWithRetry(`${BASE_URL}/api/bounties/${id}`, {
|
|
3710
3714
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3711
3715
|
});
|
|
3712
|
-
|
|
3713
|
-
if (res.status === 404)
|
|
3714
|
-
console.error(`\u274C \u60AC\u8D4F #${id} \u4E0D\u5B58\u5728`);
|
|
3715
|
-
else
|
|
3716
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3717
|
-
process.exit(1);
|
|
3718
|
-
}
|
|
3716
|
+
await assertOk(res);
|
|
3719
3717
|
const data = await res.json();
|
|
3720
3718
|
const bounty = data.bounty ?? data;
|
|
3721
3719
|
if (options.json) {
|
|
@@ -3773,11 +3771,7 @@ async function bountySubmitAction(id, content, options) {
|
|
|
3773
3771
|
},
|
|
3774
3772
|
body: JSON.stringify({ content: body })
|
|
3775
3773
|
});
|
|
3776
|
-
|
|
3777
|
-
const err = await res.json().catch(() => ({}));
|
|
3778
|
-
console.error(`\u274C \u63D0\u4EA4\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3779
|
-
process.exit(1);
|
|
3780
|
-
}
|
|
3774
|
+
await assertOk(res);
|
|
3781
3775
|
const data = await res.json();
|
|
3782
3776
|
if (options.json) {
|
|
3783
3777
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3828,11 +3822,7 @@ async function bountyCreateAction(options) {
|
|
|
3828
3822
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
3829
3823
|
body: JSON.stringify(body)
|
|
3830
3824
|
});
|
|
3831
|
-
|
|
3832
|
-
const err = await res.json().catch(() => ({}));
|
|
3833
|
-
console.error(`\u274C \u521B\u5EFA\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3834
|
-
process.exit(1);
|
|
3835
|
-
}
|
|
3825
|
+
await assertOk(res);
|
|
3836
3826
|
const data = await res.json();
|
|
3837
3827
|
if (options.json) {
|
|
3838
3828
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3847,11 +3837,7 @@ async function bountyAcceptAction(bountyId, submissionId, options) {
|
|
|
3847
3837
|
method: "POST",
|
|
3848
3838
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3849
3839
|
});
|
|
3850
|
-
|
|
3851
|
-
const err = await res.json().catch(() => ({}));
|
|
3852
|
-
console.error(`\u274C \u91C7\u7EB3\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3853
|
-
process.exit(1);
|
|
3854
|
-
}
|
|
3840
|
+
await assertOk(res);
|
|
3855
3841
|
const data = await res.json();
|
|
3856
3842
|
if (options.json) {
|
|
3857
3843
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3865,11 +3851,7 @@ async function bountyCancelAction(bountyId, options) {
|
|
|
3865
3851
|
method: "POST",
|
|
3866
3852
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3867
3853
|
});
|
|
3868
|
-
|
|
3869
|
-
const err = await res.json().catch(() => ({}));
|
|
3870
|
-
console.error(`\u274C \u53D6\u6D88\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3871
|
-
process.exit(1);
|
|
3872
|
-
}
|
|
3854
|
+
await assertOk(res);
|
|
3873
3855
|
const data = await res.json();
|
|
3874
3856
|
if (options.json) {
|
|
3875
3857
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3884,11 +3866,7 @@ async function bountyVoteAction(bountyId, submissionId, options) {
|
|
|
3884
3866
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
3885
3867
|
body: JSON.stringify({ submission_id: parseInt(submissionId, 10) })
|
|
3886
3868
|
});
|
|
3887
|
-
|
|
3888
|
-
const err = await res.json().catch(() => ({}));
|
|
3889
|
-
console.error(`\u274C \u6295\u7968\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3890
|
-
process.exit(1);
|
|
3891
|
-
}
|
|
3869
|
+
await assertOk(res);
|
|
3892
3870
|
const data = await res.json();
|
|
3893
3871
|
if (options.json) {
|
|
3894
3872
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3903,10 +3881,7 @@ async function msgInboxAction(options) {
|
|
|
3903
3881
|
const res = await fetchWithRetry(`${BASE_URL}/api/messages`, {
|
|
3904
3882
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3905
3883
|
});
|
|
3906
|
-
|
|
3907
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3908
|
-
process.exit(1);
|
|
3909
|
-
}
|
|
3884
|
+
await assertOk(res);
|
|
3910
3885
|
const data = await res.json();
|
|
3911
3886
|
if (options.json) {
|
|
3912
3887
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3933,13 +3908,7 @@ async function msgReadAction(username, options) {
|
|
|
3933
3908
|
const res = await fetchWithRetry(`${BASE_URL}/api/messages/${username}`, {
|
|
3934
3909
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3935
3910
|
});
|
|
3936
|
-
|
|
3937
|
-
if (res.status === 404)
|
|
3938
|
-
console.error(`\u274C \u672A\u627E\u5230\u4E0E @${username} \u7684\u5BF9\u8BDD`);
|
|
3939
|
-
else
|
|
3940
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3941
|
-
process.exit(1);
|
|
3942
|
-
}
|
|
3911
|
+
await assertOk(res);
|
|
3943
3912
|
const data = await res.json();
|
|
3944
3913
|
if (options.json) {
|
|
3945
3914
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -3983,11 +3952,7 @@ async function msgSendAction(username, text, options) {
|
|
|
3983
3952
|
},
|
|
3984
3953
|
body: JSON.stringify({ content: text })
|
|
3985
3954
|
});
|
|
3986
|
-
|
|
3987
|
-
const err = await res.json().catch(() => ({}));
|
|
3988
|
-
console.error(`\u274C \u53D1\u9001\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3989
|
-
process.exit(1);
|
|
3990
|
-
}
|
|
3955
|
+
await assertOk(res);
|
|
3991
3956
|
const data = await res.json();
|
|
3992
3957
|
if (options.json) {
|
|
3993
3958
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4017,10 +3982,7 @@ async function doctorListAction(options) {
|
|
|
4017
3982
|
const res = await fetchWithRetry(`${BASE_URL}/api/doctor/cases?${qs}`, {
|
|
4018
3983
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4019
3984
|
});
|
|
4020
|
-
|
|
4021
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4022
|
-
process.exit(1);
|
|
4023
|
-
}
|
|
3985
|
+
await assertOk(res);
|
|
4024
3986
|
const data = await res.json();
|
|
4025
3987
|
if (options.json) {
|
|
4026
3988
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4054,11 +4016,7 @@ async function doctorCreateAction(options) {
|
|
|
4054
4016
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4055
4017
|
body: JSON.stringify({ title, category, description })
|
|
4056
4018
|
});
|
|
4057
|
-
|
|
4058
|
-
const err = await res.json().catch(() => ({}));
|
|
4059
|
-
console.error(`\u274C \u521B\u5EFA\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4060
|
-
process.exit(1);
|
|
4061
|
-
}
|
|
4019
|
+
await assertOk(res);
|
|
4062
4020
|
const data = await res.json();
|
|
4063
4021
|
if (options.json) {
|
|
4064
4022
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4071,13 +4029,7 @@ async function doctorViewAction(id, options) {
|
|
|
4071
4029
|
const res = await fetchWithRetry(`${BASE_URL}/api/doctor/cases/${id}`, {
|
|
4072
4030
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4073
4031
|
});
|
|
4074
|
-
|
|
4075
|
-
if (res.status === 404)
|
|
4076
|
-
console.error(`\u274C \u75C5\u4F8B #${id} \u4E0D\u5B58\u5728`);
|
|
4077
|
-
else
|
|
4078
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4079
|
-
process.exit(1);
|
|
4080
|
-
}
|
|
4032
|
+
await assertOk(res);
|
|
4081
4033
|
const data = await res.json();
|
|
4082
4034
|
if (options.json) {
|
|
4083
4035
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4109,11 +4061,7 @@ async function patchCaseAction(id, action, options) {
|
|
|
4109
4061
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4110
4062
|
body: JSON.stringify({ action })
|
|
4111
4063
|
});
|
|
4112
|
-
|
|
4113
|
-
const err = await res.json().catch(() => ({}));
|
|
4114
|
-
console.error(`\u274C \u64CD\u4F5C\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4115
|
-
process.exit(1);
|
|
4116
|
-
}
|
|
4064
|
+
await assertOk(res);
|
|
4117
4065
|
const data = await res.json();
|
|
4118
4066
|
if (options.json) {
|
|
4119
4067
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4135,11 +4083,7 @@ async function doctorMsgAction(id, text, options) {
|
|
|
4135
4083
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4136
4084
|
body: JSON.stringify({ message: text })
|
|
4137
4085
|
});
|
|
4138
|
-
|
|
4139
|
-
const err = await res.json().catch(() => ({}));
|
|
4140
|
-
console.error(`\u274C \u53D1\u9001\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4141
|
-
process.exit(1);
|
|
4142
|
-
}
|
|
4086
|
+
await assertOk(res);
|
|
4143
4087
|
const data = await res.json();
|
|
4144
4088
|
if (options.json) {
|
|
4145
4089
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4154,10 +4098,7 @@ async function saasServicesAction(options) {
|
|
|
4154
4098
|
const res = await fetchWithRetry(`${BASE_URL}/api/saas/services`, {
|
|
4155
4099
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4156
4100
|
});
|
|
4157
|
-
|
|
4158
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4159
|
-
process.exit(1);
|
|
4160
|
-
}
|
|
4101
|
+
await assertOk(res);
|
|
4161
4102
|
const data = await res.json();
|
|
4162
4103
|
if (options.json) {
|
|
4163
4104
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4191,11 +4132,7 @@ async function saasRunAction(serviceId, inputJson, options = {}) {
|
|
|
4191
4132
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4192
4133
|
body: JSON.stringify(body)
|
|
4193
4134
|
});
|
|
4194
|
-
|
|
4195
|
-
const err = await res.json().catch(() => ({}));
|
|
4196
|
-
console.error(`\u274C \u63D0\u4EA4\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4197
|
-
process.exit(1);
|
|
4198
|
-
}
|
|
4135
|
+
await assertOk(res);
|
|
4199
4136
|
const data = await res.json();
|
|
4200
4137
|
const taskId = data.task?.id;
|
|
4201
4138
|
if (!taskId) {
|
|
@@ -4269,10 +4206,7 @@ async function saasTasksAction(options) {
|
|
|
4269
4206
|
const res = await fetchWithRetry(`${BASE_URL}/api/saas/tasks?limit=${limit}`, {
|
|
4270
4207
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4271
4208
|
});
|
|
4272
|
-
|
|
4273
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4274
|
-
process.exit(1);
|
|
4275
|
-
}
|
|
4209
|
+
await assertOk(res);
|
|
4276
4210
|
const data = await res.json();
|
|
4277
4211
|
if (options.json) {
|
|
4278
4212
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4295,13 +4229,7 @@ async function saasTaskViewAction(taskId, options) {
|
|
|
4295
4229
|
const res = await fetchWithRetry(`${BASE_URL}/api/saas/tasks/${taskId}`, {
|
|
4296
4230
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4297
4231
|
});
|
|
4298
|
-
|
|
4299
|
-
if (res.status === 404)
|
|
4300
|
-
console.error(`\u274C \u4EFB\u52A1 ${taskId} \u4E0D\u5B58\u5728`);
|
|
4301
|
-
else
|
|
4302
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4303
|
-
process.exit(1);
|
|
4304
|
-
}
|
|
4232
|
+
await assertOk(res);
|
|
4305
4233
|
const data = await res.json();
|
|
4306
4234
|
if (options.json) {
|
|
4307
4235
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4334,11 +4262,7 @@ async function saasPolishAction(text, options) {
|
|
|
4334
4262
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4335
4263
|
body: JSON.stringify({ text })
|
|
4336
4264
|
});
|
|
4337
|
-
|
|
4338
|
-
const err = await res.json().catch(() => ({}));
|
|
4339
|
-
console.error(`\u274C \u6DA6\u8272\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4340
|
-
process.exit(1);
|
|
4341
|
-
}
|
|
4265
|
+
await assertOk(res);
|
|
4342
4266
|
const data = await res.json();
|
|
4343
4267
|
if (options.json) {
|
|
4344
4268
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4349,6 +4273,7 @@ async function saasPolishAction(text, options) {
|
|
|
4349
4273
|
}
|
|
4350
4274
|
|
|
4351
4275
|
// src/commands/agent.ts
|
|
4276
|
+
var fs8 = __toESM(require("fs"));
|
|
4352
4277
|
async function agentListAction(options) {
|
|
4353
4278
|
const apiKey = requireApiKey();
|
|
4354
4279
|
const parsed = parseInt(options.limit || "20", 10);
|
|
@@ -4356,10 +4281,7 @@ async function agentListAction(options) {
|
|
|
4356
4281
|
const res = await fetchWithRetry(`${BASE_URL}/api/a2a/agents?limit=${limit}`, {
|
|
4357
4282
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4358
4283
|
});
|
|
4359
|
-
|
|
4360
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4361
|
-
process.exit(1);
|
|
4362
|
-
}
|
|
4284
|
+
await assertOk(res);
|
|
4363
4285
|
const data = await res.json();
|
|
4364
4286
|
if (options.json) {
|
|
4365
4287
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4382,8 +4304,29 @@ async function agentListAction(options) {
|
|
|
4382
4304
|
}
|
|
4383
4305
|
async function agentCallAction(username, intent, dataJson, options = {}) {
|
|
4384
4306
|
const apiKey = requireApiKey();
|
|
4307
|
+
if (dataJson && options.dataFile) {
|
|
4308
|
+
console.error("\u274C `dataJson` \u548C `--data-file` \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528\uFF0C\u8BF7\u9009\u5176\u4E00");
|
|
4309
|
+
process.exit(1);
|
|
4310
|
+
}
|
|
4385
4311
|
const body = { intent };
|
|
4386
|
-
if (
|
|
4312
|
+
if (options.dataFile) {
|
|
4313
|
+
if (!fs8.existsSync(options.dataFile)) {
|
|
4314
|
+
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${options.dataFile}`);
|
|
4315
|
+
process.exit(1);
|
|
4316
|
+
}
|
|
4317
|
+
const MAX_SIZE = 512 * 1024;
|
|
4318
|
+
const stat = fs8.statSync(options.dataFile);
|
|
4319
|
+
if (stat.size > MAX_SIZE) {
|
|
4320
|
+
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024)}KB\uFF09\uFF0C\u4E0A\u9650 512KB`);
|
|
4321
|
+
process.exit(1);
|
|
4322
|
+
}
|
|
4323
|
+
const raw = fs8.readFileSync(options.dataFile, "utf-8");
|
|
4324
|
+
try {
|
|
4325
|
+
body.data = JSON.parse(raw);
|
|
4326
|
+
} catch {
|
|
4327
|
+
body.data = { text: raw };
|
|
4328
|
+
}
|
|
4329
|
+
} else if (dataJson) {
|
|
4387
4330
|
try {
|
|
4388
4331
|
body.data = JSON.parse(dataJson);
|
|
4389
4332
|
} catch {
|
|
@@ -4400,11 +4343,7 @@ async function agentCallAction(username, intent, dataJson, options = {}) {
|
|
|
4400
4343
|
},
|
|
4401
4344
|
body: JSON.stringify(body)
|
|
4402
4345
|
});
|
|
4403
|
-
|
|
4404
|
-
const err = await res.json().catch(() => ({}));
|
|
4405
|
-
console.error(`\u274C \u8C03\u7528\u5931\u8D25 (${res.status}): ${err.error || ""}`);
|
|
4406
|
-
process.exit(1);
|
|
4407
|
-
}
|
|
4346
|
+
await assertOk(res);
|
|
4408
4347
|
const data = await res.json();
|
|
4409
4348
|
if (options.json) {
|
|
4410
4349
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4415,7 +4354,7 @@ async function agentCallAction(username, intent, dataJson, options = {}) {
|
|
|
4415
4354
|
}
|
|
4416
4355
|
|
|
4417
4356
|
// src/commands/forum.ts
|
|
4418
|
-
var
|
|
4357
|
+
var fs9 = __toESM(require("fs"));
|
|
4419
4358
|
var readline6 = __toESM(require("readline"));
|
|
4420
4359
|
function promptYN2(question) {
|
|
4421
4360
|
const rl = readline6.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -4436,10 +4375,7 @@ async function forumListAction(options) {
|
|
|
4436
4375
|
const res = await fetchWithRetry(`${BASE_URL}/api/forum?${qs}`, {
|
|
4437
4376
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4438
4377
|
});
|
|
4439
|
-
|
|
4440
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4441
|
-
process.exit(1);
|
|
4442
|
-
}
|
|
4378
|
+
await assertOk(res);
|
|
4443
4379
|
const data = await res.json();
|
|
4444
4380
|
if (options.json) {
|
|
4445
4381
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4463,13 +4399,7 @@ async function forumViewAction(slug, options) {
|
|
|
4463
4399
|
const res = await fetchWithRetry(`${BASE_URL}/api/forum/${slug}`, {
|
|
4464
4400
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4465
4401
|
});
|
|
4466
|
-
|
|
4467
|
-
if (res.status === 404)
|
|
4468
|
-
console.error(`\u274C \u5E16\u5B50 "${slug}" \u4E0D\u5B58\u5728`);
|
|
4469
|
-
else
|
|
4470
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4471
|
-
process.exit(1);
|
|
4472
|
-
}
|
|
4402
|
+
await assertOk(res);
|
|
4473
4403
|
const data = await res.json();
|
|
4474
4404
|
if (options.json) {
|
|
4475
4405
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4490,11 +4420,11 @@ async function forumPostAction(title, filePath, options) {
|
|
|
4490
4420
|
if (options.content) {
|
|
4491
4421
|
content = options.content;
|
|
4492
4422
|
} else if (filePath) {
|
|
4493
|
-
if (!
|
|
4423
|
+
if (!fs9.existsSync(filePath)) {
|
|
4494
4424
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
4495
4425
|
process.exit(1);
|
|
4496
4426
|
}
|
|
4497
|
-
content =
|
|
4427
|
+
content = fs9.readFileSync(filePath, "utf-8");
|
|
4498
4428
|
} else {
|
|
4499
4429
|
console.error("\u274C \u8BF7\u63D0\u4F9B --content <text> \u6216 <file> \u53C2\u6570");
|
|
4500
4430
|
process.exit(1);
|
|
@@ -4516,11 +4446,7 @@ async function forumPostAction(title, filePath, options) {
|
|
|
4516
4446
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4517
4447
|
body: JSON.stringify(body)
|
|
4518
4448
|
});
|
|
4519
|
-
|
|
4520
|
-
const err = await res.json().catch(() => ({}));
|
|
4521
|
-
console.error(`\u274C \u53D1\u5E16\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4522
|
-
process.exit(1);
|
|
4523
|
-
}
|
|
4449
|
+
await assertOk(res);
|
|
4524
4450
|
const data = await res.json();
|
|
4525
4451
|
if (options.json) {
|
|
4526
4452
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4541,11 +4467,7 @@ async function forumCommentAction(slug, text, options) {
|
|
|
4541
4467
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4542
4468
|
body: JSON.stringify({ content: text })
|
|
4543
4469
|
});
|
|
4544
|
-
|
|
4545
|
-
const err = await res.json().catch(() => ({}));
|
|
4546
|
-
console.error(`\u274C \u8BC4\u8BBA\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4547
|
-
process.exit(1);
|
|
4548
|
-
}
|
|
4470
|
+
await assertOk(res);
|
|
4549
4471
|
const data = await res.json();
|
|
4550
4472
|
if (options.json) {
|
|
4551
4473
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4566,11 +4488,7 @@ async function forumDeleteAction(slug, options) {
|
|
|
4566
4488
|
method: "DELETE",
|
|
4567
4489
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4568
4490
|
});
|
|
4569
|
-
|
|
4570
|
-
const err = await res.json().catch(() => ({}));
|
|
4571
|
-
console.error(`\u274C \u5220\u9664\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4572
|
-
process.exit(1);
|
|
4573
|
-
}
|
|
4491
|
+
await assertOk(res);
|
|
4574
4492
|
const data = await res.json();
|
|
4575
4493
|
if (options.json) {
|
|
4576
4494
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4580,17 +4498,14 @@ async function forumDeleteAction(slug, options) {
|
|
|
4580
4498
|
}
|
|
4581
4499
|
|
|
4582
4500
|
// src/commands/radio.ts
|
|
4583
|
-
var
|
|
4501
|
+
var fs10 = __toESM(require("fs"));
|
|
4584
4502
|
var path7 = __toESM(require("path"));
|
|
4585
4503
|
async function radioListAction(options) {
|
|
4586
4504
|
const apiKey = requireApiKey();
|
|
4587
4505
|
const res = await fetchWithRetry(`${BASE_URL}/api/radio/stations`, {
|
|
4588
4506
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4589
4507
|
});
|
|
4590
|
-
|
|
4591
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4592
|
-
process.exit(1);
|
|
4593
|
-
}
|
|
4508
|
+
await assertOk(res);
|
|
4594
4509
|
const data = await res.json();
|
|
4595
4510
|
if (options.json) {
|
|
4596
4511
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4613,13 +4528,7 @@ async function radioViewAction(id, options) {
|
|
|
4613
4528
|
const res = await fetchWithRetry(`${BASE_URL}/api/radio/stations/${id}`, {
|
|
4614
4529
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4615
4530
|
});
|
|
4616
|
-
|
|
4617
|
-
if (res.status === 404)
|
|
4618
|
-
console.error(`\u274C \u7535\u53F0 #${id} \u4E0D\u5B58\u5728`);
|
|
4619
|
-
else
|
|
4620
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4621
|
-
process.exit(1);
|
|
4622
|
-
}
|
|
4531
|
+
await assertOk(res);
|
|
4623
4532
|
const data = await res.json();
|
|
4624
4533
|
if (options.json) {
|
|
4625
4534
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4640,10 +4549,7 @@ async function radioTracksAction(id, options) {
|
|
|
4640
4549
|
const res = await fetchWithRetry(`${BASE_URL}/api/radio/stations/${id}/tracks`, {
|
|
4641
4550
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
4642
4551
|
});
|
|
4643
|
-
|
|
4644
|
-
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
4645
|
-
process.exit(1);
|
|
4646
|
-
}
|
|
4552
|
+
await assertOk(res);
|
|
4647
4553
|
const data = await res.json();
|
|
4648
4554
|
if (options.json) {
|
|
4649
4555
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4675,11 +4581,7 @@ async function radioCreateAction(name, options) {
|
|
|
4675
4581
|
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
|
|
4676
4582
|
body: JSON.stringify(body)
|
|
4677
4583
|
});
|
|
4678
|
-
|
|
4679
|
-
const err = await res.json().catch(() => ({}));
|
|
4680
|
-
console.error(`\u274C \u521B\u5EFA\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4681
|
-
process.exit(1);
|
|
4682
|
-
}
|
|
4584
|
+
await assertOk(res);
|
|
4683
4585
|
const data = await res.json();
|
|
4684
4586
|
if (options.json) {
|
|
4685
4587
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4690,19 +4592,19 @@ async function radioCreateAction(name, options) {
|
|
|
4690
4592
|
}
|
|
4691
4593
|
async function radioUploadAction(stationId, filePath, options) {
|
|
4692
4594
|
const apiKey = requireApiKey();
|
|
4693
|
-
if (!
|
|
4595
|
+
if (!fs10.existsSync(filePath)) {
|
|
4694
4596
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
4695
4597
|
process.exit(1);
|
|
4696
4598
|
}
|
|
4697
4599
|
const MAX_SIZE = 5 * 1024 * 1024;
|
|
4698
|
-
const stat =
|
|
4600
|
+
const stat = fs10.statSync(filePath);
|
|
4699
4601
|
if (stat.size > MAX_SIZE) {
|
|
4700
4602
|
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024 / 1024 * 10) / 10}MB\uFF09\uFF0C\u4E0A\u9650 5MB`);
|
|
4701
4603
|
process.exit(1);
|
|
4702
4604
|
}
|
|
4703
4605
|
const title = options.title || path7.basename(filePath, path7.extname(filePath));
|
|
4704
4606
|
const formData = new FormData();
|
|
4705
|
-
const blob = new Blob([
|
|
4607
|
+
const blob = new Blob([fs10.readFileSync(filePath)]);
|
|
4706
4608
|
formData.append("file", blob, path7.basename(filePath));
|
|
4707
4609
|
formData.append("title", title);
|
|
4708
4610
|
if (options.artist)
|
|
@@ -4716,11 +4618,7 @@ async function radioUploadAction(stationId, filePath, options) {
|
|
|
4716
4618
|
headers: { Authorization: `Bearer ${apiKey}` },
|
|
4717
4619
|
body: formData
|
|
4718
4620
|
});
|
|
4719
|
-
|
|
4720
|
-
const err = await res.json().catch(() => ({}));
|
|
4721
|
-
console.error(`\u274C \u4E0A\u4F20\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
4722
|
-
process.exit(1);
|
|
4723
|
-
}
|
|
4621
|
+
await assertOk(res);
|
|
4724
4622
|
const data = await res.json();
|
|
4725
4623
|
if (options.json) {
|
|
4726
4624
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -4742,7 +4640,7 @@ async function radioUploadAction(stationId, filePath, options) {
|
|
|
4742
4640
|
|
|
4743
4641
|
// src/index.ts
|
|
4744
4642
|
var program2 = new Command();
|
|
4745
|
-
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.
|
|
4643
|
+
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.6.0");
|
|
4746
4644
|
program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").action(loginAction);
|
|
4747
4645
|
program2.command("logout").description("\u9000\u51FA\u767B\u5F55\uFF0C\u6E05\u9664\u672C\u5730 API Key").action(logoutAction);
|
|
4748
4646
|
program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4FE1\u606F").option("--json", "JSON \u8F93\u51FA").action(() => whoamiAction());
|
|
@@ -4759,6 +4657,7 @@ program2.command("publish [dir]").description("\u53D1\u5E03\u6216\u66F4\u65B0\u6
|
|
|
4759
4657
|
program2.command("list").description("\u5217\u51FA\u4F60\u53D1\u5E03\u7684\u6240\u6709\u6280\u80FD").option("--json", "JSON \u8F93\u51FA").action(() => listAction());
|
|
4760
4658
|
program2.command("validate [dir]").description("\u672C\u5730\u6821\u9A8C\u6280\u80FD\u76EE\u5F55\u683C\u5F0F").action((dir) => validateAction(dir));
|
|
4761
4659
|
var skillCmd = program2.command("skill").description("\u6280\u80FD\u8BE6\u7EC6\u64CD\u4F5C");
|
|
4660
|
+
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));
|
|
4762
4661
|
skillCmd.command("view <id>").description("\u67E5\u770B\u6280\u80FD\u8BE6\u60C5").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillViewAction(id, o));
|
|
4763
4662
|
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));
|
|
4764
4663
|
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));
|
|
@@ -4793,7 +4692,7 @@ program2.command("task <taskId>").description("\u67E5\u770B SaaS \u4EFB\u52A1\u7
|
|
|
4793
4692
|
program2.command("polish <text>").description("AI \u6DA6\u8272\u6587\u672C").option("--json", "JSON \u8F93\u51FA").action((t, o) => saasPolishAction(t, o));
|
|
4794
4693
|
var agentCmd = program2.command("agent").description("Agent \u4E92\u8054\uFF08A2A\uFF09");
|
|
4795
4694
|
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));
|
|
4796
|
-
agentCmd.command("call <username> <intent> [data]").description("\u8C03\u7528\u53E6\u4E00\u4E2A Agent\uFF08A2A\uFF09").option("--json", "JSON \u8F93\u51FA").action((u, intent, data, o) => agentCallAction(u, intent, data, o));
|
|
4695
|
+
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));
|
|
4797
4696
|
var forumCmd = program2.command("forum").description("\u8BBA\u575B\u64CD\u4F5C");
|
|
4798
4697
|
forumCmd.command("list", { isDefault: true }).description("\u6D4F\u89C8\u5E16\u5B50\u5217\u8868").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--category <cat>", "\u6309\u5206\u7C7B\u8FC7\u6EE4").option("--json", "JSON \u8F93\u51FA").action((o) => forumListAction(o));
|
|
4799
4698
|
forumCmd.command("view <slug>").description("\u67E5\u770B\u5E16\u5B50\u8BE6\u60C5").option("--json", "JSON \u8F93\u51FA").action((slug, o) => forumViewAction(slug, o));
|