easyclaw-link 1.2.0 → 1.3.1
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 +661 -34
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -931,8 +931,8 @@ var require_command = __commonJS({
|
|
|
931
931
|
"node_modules/commander/lib/command.js"(exports2) {
|
|
932
932
|
var EventEmitter = require("events").EventEmitter;
|
|
933
933
|
var childProcess = require("child_process");
|
|
934
|
-
var
|
|
935
|
-
var
|
|
934
|
+
var path6 = require("path");
|
|
935
|
+
var fs7 = require("fs");
|
|
936
936
|
var process2 = require("process");
|
|
937
937
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
938
938
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1764,12 +1764,12 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1764
1764
|
let launchWithNode = false;
|
|
1765
1765
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1766
1766
|
function findFile(baseDir, baseName) {
|
|
1767
|
-
const localBin =
|
|
1768
|
-
if (
|
|
1767
|
+
const localBin = path6.resolve(baseDir, baseName);
|
|
1768
|
+
if (fs7.existsSync(localBin))
|
|
1769
1769
|
return localBin;
|
|
1770
|
-
if (sourceExt.includes(
|
|
1770
|
+
if (sourceExt.includes(path6.extname(baseName)))
|
|
1771
1771
|
return void 0;
|
|
1772
|
-
const foundExt = sourceExt.find((ext) =>
|
|
1772
|
+
const foundExt = sourceExt.find((ext) => fs7.existsSync(`${localBin}${ext}`));
|
|
1773
1773
|
if (foundExt)
|
|
1774
1774
|
return `${localBin}${foundExt}`;
|
|
1775
1775
|
return void 0;
|
|
@@ -1781,23 +1781,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1781
1781
|
if (this._scriptPath) {
|
|
1782
1782
|
let resolvedScriptPath;
|
|
1783
1783
|
try {
|
|
1784
|
-
resolvedScriptPath =
|
|
1784
|
+
resolvedScriptPath = fs7.realpathSync(this._scriptPath);
|
|
1785
1785
|
} catch (err) {
|
|
1786
1786
|
resolvedScriptPath = this._scriptPath;
|
|
1787
1787
|
}
|
|
1788
|
-
executableDir =
|
|
1788
|
+
executableDir = path6.resolve(path6.dirname(resolvedScriptPath), executableDir);
|
|
1789
1789
|
}
|
|
1790
1790
|
if (executableDir) {
|
|
1791
1791
|
let localFile = findFile(executableDir, executableFile);
|
|
1792
1792
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1793
|
-
const legacyName =
|
|
1793
|
+
const legacyName = path6.basename(this._scriptPath, path6.extname(this._scriptPath));
|
|
1794
1794
|
if (legacyName !== this._name) {
|
|
1795
1795
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
1796
1796
|
}
|
|
1797
1797
|
}
|
|
1798
1798
|
executableFile = localFile || executableFile;
|
|
1799
1799
|
}
|
|
1800
|
-
launchWithNode = sourceExt.includes(
|
|
1800
|
+
launchWithNode = sourceExt.includes(path6.extname(executableFile));
|
|
1801
1801
|
let proc;
|
|
1802
1802
|
if (process2.platform !== "win32") {
|
|
1803
1803
|
if (launchWithNode) {
|
|
@@ -2599,7 +2599,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2599
2599
|
* @return {Command}
|
|
2600
2600
|
*/
|
|
2601
2601
|
nameFromFilename(filename) {
|
|
2602
|
-
this._name =
|
|
2602
|
+
this._name = path6.basename(filename, path6.extname(filename));
|
|
2603
2603
|
return this;
|
|
2604
2604
|
}
|
|
2605
2605
|
/**
|
|
@@ -2613,10 +2613,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2613
2613
|
* @param {string} [path]
|
|
2614
2614
|
* @return {string|null|Command}
|
|
2615
2615
|
*/
|
|
2616
|
-
executableDir(
|
|
2617
|
-
if (
|
|
2616
|
+
executableDir(path7) {
|
|
2617
|
+
if (path7 === void 0)
|
|
2618
2618
|
return this._executableDir;
|
|
2619
|
-
this._executableDir =
|
|
2619
|
+
this._executableDir = path7;
|
|
2620
2620
|
return this;
|
|
2621
2621
|
}
|
|
2622
2622
|
/**
|
|
@@ -2878,10 +2878,10 @@ async function fetchWithRetry(url, options, maxRetries = 3) {
|
|
|
2878
2878
|
// src/commands/login.ts
|
|
2879
2879
|
function prompt(question) {
|
|
2880
2880
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
2881
|
-
return new Promise((
|
|
2881
|
+
return new Promise((resolve3) => {
|
|
2882
2882
|
rl.question(question, (answer) => {
|
|
2883
2883
|
rl.close();
|
|
2884
|
-
|
|
2884
|
+
resolve3(answer.trim());
|
|
2885
2885
|
});
|
|
2886
2886
|
});
|
|
2887
2887
|
}
|
|
@@ -2916,20 +2916,34 @@ async function loginAction() {
|
|
|
2916
2916
|
console.log(" npx easyclaw-link list # \u67E5\u770B\u6280\u80FD\u5217\u8868");
|
|
2917
2917
|
}
|
|
2918
2918
|
|
|
2919
|
+
// src/commands/logout.ts
|
|
2920
|
+
var fs2 = __toESM(require("fs"));
|
|
2921
|
+
var path2 = __toESM(require("path"));
|
|
2922
|
+
var os2 = __toESM(require("os"));
|
|
2923
|
+
var CONFIG_FILE2 = path2.join(os2.homedir(), ".easyclaw-link", "config.json");
|
|
2924
|
+
async function logoutAction() {
|
|
2925
|
+
if (!fs2.existsSync(CONFIG_FILE2)) {
|
|
2926
|
+
console.log("\u2139\uFE0F \u5F53\u524D\u672A\u767B\u5F55");
|
|
2927
|
+
return;
|
|
2928
|
+
}
|
|
2929
|
+
fs2.rmSync(CONFIG_FILE2);
|
|
2930
|
+
console.log("\u2705 \u5DF2\u9000\u51FA\u767B\u5F55\uFF0C\u672C\u5730 API Key \u5DF2\u6E05\u9664");
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2919
2933
|
// src/commands/publish.ts
|
|
2920
|
-
var
|
|
2921
|
-
var
|
|
2934
|
+
var fs4 = __toESM(require("fs"));
|
|
2935
|
+
var path4 = __toESM(require("path"));
|
|
2922
2936
|
|
|
2923
2937
|
// src/validate.ts
|
|
2924
|
-
var
|
|
2925
|
-
var
|
|
2938
|
+
var fs3 = __toESM(require("fs"));
|
|
2939
|
+
var path3 = __toESM(require("path"));
|
|
2926
2940
|
function validateSkillDir(dir) {
|
|
2927
2941
|
const errors = [];
|
|
2928
|
-
const skillPath =
|
|
2929
|
-
if (!
|
|
2942
|
+
const skillPath = path3.join(dir, "SKILL.md");
|
|
2943
|
+
if (!fs3.existsSync(skillPath)) {
|
|
2930
2944
|
errors.push("\u7F3A\u5C11 SKILL.md \u6587\u4EF6");
|
|
2931
2945
|
} else {
|
|
2932
|
-
const content =
|
|
2946
|
+
const content = fs3.readFileSync(skillPath, "utf-8");
|
|
2933
2947
|
const trimmed = content.trim();
|
|
2934
2948
|
if (!trimmed) {
|
|
2935
2949
|
errors.push("SKILL.md \u6587\u4EF6\u4E3A\u7A7A");
|
|
@@ -2975,28 +2989,28 @@ async function resolveId(apiKey, slug) {
|
|
|
2975
2989
|
}
|
|
2976
2990
|
async function publishAction(dir, options) {
|
|
2977
2991
|
const apiKey = requireApiKey();
|
|
2978
|
-
const targetDir =
|
|
2992
|
+
const targetDir = path4.resolve(dir || ".");
|
|
2979
2993
|
const { valid, errors } = validateSkillDir(targetDir);
|
|
2980
2994
|
if (!valid) {
|
|
2981
2995
|
console.error("\u274C \u6821\u9A8C\u5931\u8D25\uFF1A");
|
|
2982
2996
|
errors.forEach((e) => console.error(` \u2022 ${e}`));
|
|
2983
2997
|
process.exit(1);
|
|
2984
2998
|
}
|
|
2985
|
-
const content =
|
|
2999
|
+
const content = fs4.readFileSync(path4.join(targetDir, "SKILL.md"), "utf-8");
|
|
2986
3000
|
let pkgName;
|
|
2987
3001
|
let pkgVersion;
|
|
2988
3002
|
let pkgDescription;
|
|
2989
|
-
const pkgJsonPath =
|
|
2990
|
-
if (
|
|
3003
|
+
const pkgJsonPath = path4.join(targetDir, "package.json");
|
|
3004
|
+
if (fs4.existsSync(pkgJsonPath)) {
|
|
2991
3005
|
try {
|
|
2992
|
-
const pkg = JSON.parse(
|
|
3006
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
2993
3007
|
pkgName = pkg.name;
|
|
2994
3008
|
pkgVersion = pkg.version;
|
|
2995
3009
|
pkgDescription = pkg.description;
|
|
2996
3010
|
} catch {
|
|
2997
3011
|
}
|
|
2998
3012
|
}
|
|
2999
|
-
const title = pkgName ||
|
|
3013
|
+
const title = pkgName || path4.basename(targetDir);
|
|
3000
3014
|
const description = pkgDescription || title;
|
|
3001
3015
|
let resolvedId = options.id;
|
|
3002
3016
|
if (!resolvedId && options.slug) {
|
|
@@ -3137,12 +3151,625 @@ async function creditsAction() {
|
|
|
3137
3151
|
\u5171 ${data.transactions.length} \u6761\u8BB0\u5F55\uFF0C\u663E\u793A\u6700\u8FD1 ${recentTxs.length} \u6761`);
|
|
3138
3152
|
}
|
|
3139
3153
|
|
|
3154
|
+
// src/commands/tasks.ts
|
|
3155
|
+
async function tasksAction() {
|
|
3156
|
+
const apiKey = requireApiKey();
|
|
3157
|
+
const res = await fetch(`${BASE_URL}/api/bounties?status=open&sort=date_desc`, {
|
|
3158
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3159
|
+
});
|
|
3160
|
+
if (!res.ok) {
|
|
3161
|
+
const body = await res.text();
|
|
3162
|
+
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (${res.status}): ${body}`);
|
|
3163
|
+
process.exit(1);
|
|
3164
|
+
}
|
|
3165
|
+
const data = await res.json();
|
|
3166
|
+
const bounties = data.bounties ?? [];
|
|
3167
|
+
if (bounties.length === 0) {
|
|
3168
|
+
console.log("\u{1F4ED} \u5F53\u524D\u6CA1\u6709\u53EF\u63A5\u7684\u4EFB\u52A1");
|
|
3169
|
+
return;
|
|
3170
|
+
}
|
|
3171
|
+
console.log(`\u{1F3AF} \u53EF\u63A5\u4EFB\u52A1\u5217\u8868 (\u5171 ${data.total} \u4E2A)
|
|
3172
|
+
`);
|
|
3173
|
+
const idW = 6;
|
|
3174
|
+
const titleW = 36;
|
|
3175
|
+
const rewardW = 8;
|
|
3176
|
+
const expiresW = 12;
|
|
3177
|
+
const submissionsW = 5;
|
|
3178
|
+
const header = [
|
|
3179
|
+
"ID".padEnd(idW),
|
|
3180
|
+
"\u6807\u9898".padEnd(titleW),
|
|
3181
|
+
"\u5956\u52B1\u{1F99E}".padEnd(rewardW),
|
|
3182
|
+
"\u622A\u6B62\u65E5\u671F".padEnd(expiresW),
|
|
3183
|
+
"\u6295\u9012".padEnd(submissionsW)
|
|
3184
|
+
].join(" | ");
|
|
3185
|
+
const separator = [
|
|
3186
|
+
"-".repeat(idW),
|
|
3187
|
+
"-".repeat(titleW),
|
|
3188
|
+
"-".repeat(rewardW),
|
|
3189
|
+
"-".repeat(expiresW),
|
|
3190
|
+
"-".repeat(submissionsW)
|
|
3191
|
+
].join("-+-");
|
|
3192
|
+
console.log(header);
|
|
3193
|
+
console.log(separator);
|
|
3194
|
+
for (const b of bounties) {
|
|
3195
|
+
const expiresStr = b.expires_at ? new Date(b.expires_at).toLocaleDateString("zh-CN") : "\u65E0\u671F\u9650";
|
|
3196
|
+
const row = [
|
|
3197
|
+
String(b.id).padEnd(idW),
|
|
3198
|
+
(b.title || "").slice(0, titleW).padEnd(titleW),
|
|
3199
|
+
String(b.reward).padEnd(rewardW),
|
|
3200
|
+
expiresStr.padEnd(expiresW),
|
|
3201
|
+
String(b.submission_count ?? 0).padEnd(submissionsW)
|
|
3202
|
+
].join(" | ");
|
|
3203
|
+
console.log(row);
|
|
3204
|
+
}
|
|
3205
|
+
console.log(`
|
|
3206
|
+
\u4F7F\u7528 npx easyclaw-link bid <\u4EFB\u52A1ID> \u63A5\u53D6\u4EFB\u52A1`);
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3209
|
+
// src/commands/bid.ts
|
|
3210
|
+
var readline2 = __toESM(require("readline"));
|
|
3211
|
+
function prompt2(question) {
|
|
3212
|
+
const rl = readline2.createInterface({
|
|
3213
|
+
input: process.stdin,
|
|
3214
|
+
output: process.stdout
|
|
3215
|
+
});
|
|
3216
|
+
return new Promise((resolve3) => {
|
|
3217
|
+
rl.question(question, (answer) => {
|
|
3218
|
+
rl.close();
|
|
3219
|
+
resolve3(answer.trim());
|
|
3220
|
+
});
|
|
3221
|
+
});
|
|
3222
|
+
}
|
|
3223
|
+
async function bidAction(taskId) {
|
|
3224
|
+
const apiKey = requireApiKey();
|
|
3225
|
+
const id = parseInt(taskId, 10);
|
|
3226
|
+
if (isNaN(id) || id <= 0) {
|
|
3227
|
+
console.error("\u274C \u65E0\u6548\u7684\u4EFB\u52A1 ID\uFF0C\u8BF7\u4F20\u5165\u6570\u5B57 ID\uFF08\u4F8B\u5982\uFF1Anpx easyclaw-link bid 42\uFF09");
|
|
3228
|
+
process.exit(1);
|
|
3229
|
+
}
|
|
3230
|
+
const infoRes = await fetch(`${BASE_URL}/api/bounties/${id}`, {
|
|
3231
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3232
|
+
});
|
|
3233
|
+
if (!infoRes.ok) {
|
|
3234
|
+
if (infoRes.status === 404) {
|
|
3235
|
+
console.error(`\u274C \u4EFB\u52A1 #${id} \u4E0D\u5B58\u5728`);
|
|
3236
|
+
} else {
|
|
3237
|
+
console.error(`\u274C \u83B7\u53D6\u4EFB\u52A1\u4FE1\u606F\u5931\u8D25 (${infoRes.status})`);
|
|
3238
|
+
}
|
|
3239
|
+
process.exit(1);
|
|
3240
|
+
}
|
|
3241
|
+
const { bounty } = await infoRes.json();
|
|
3242
|
+
if (bounty.status !== "open") {
|
|
3243
|
+
console.error(`\u274C \u4EFB\u52A1 #${id} \u5DF2\u5173\u95ED\uFF08\u5F53\u524D\u72B6\u6001\uFF1A${bounty.status}\uFF09`);
|
|
3244
|
+
process.exit(1);
|
|
3245
|
+
}
|
|
3246
|
+
console.log(`\u{1F4CB} \u4EFB\u52A1\u8BE6\u60C5`);
|
|
3247
|
+
console.log(`ID: ${bounty.id}`);
|
|
3248
|
+
console.log(`\u6807\u9898: ${bounty.title}`);
|
|
3249
|
+
console.log(`\u5956\u52B1: ${bounty.reward} \u{1F99E}`);
|
|
3250
|
+
if (bounty.expires_at) {
|
|
3251
|
+
console.log(`\u622A\u6B62: ${new Date(bounty.expires_at).toLocaleString("zh-CN")}`);
|
|
3252
|
+
}
|
|
3253
|
+
console.log(`
|
|
3254
|
+
${bounty.description}
|
|
3255
|
+
`);
|
|
3256
|
+
const content = await prompt2("\u{1F4DD} \u8BF7\u8F93\u5165\u4F60\u7684\u7533\u8BF7\u5185\u5BB9\uFF08\u63CF\u8FF0\u4F60\u7684\u65B9\u6848/\u80FD\u529B\uFF09: ");
|
|
3257
|
+
if (!content) {
|
|
3258
|
+
console.error("\u274C \u7533\u8BF7\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
3259
|
+
process.exit(1);
|
|
3260
|
+
}
|
|
3261
|
+
console.log("\n\u23F3 \u6B63\u5728\u63D0\u4EA4\u7533\u8BF7...");
|
|
3262
|
+
const res = await fetch(`${BASE_URL}/api/bounties/${id}/submit`, {
|
|
3263
|
+
method: "POST",
|
|
3264
|
+
headers: {
|
|
3265
|
+
Authorization: `Bearer ${apiKey}`,
|
|
3266
|
+
"Content-Type": "application/json"
|
|
3267
|
+
},
|
|
3268
|
+
body: JSON.stringify({ content })
|
|
3269
|
+
});
|
|
3270
|
+
if (!res.ok) {
|
|
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
|
+
}
|
|
3276
|
+
const { submission } = await res.json();
|
|
3277
|
+
console.log(`\u2705 \u7533\u8BF7\u63D0\u4EA4\u6210\u529F\uFF01\u63D0\u4EA4 ID: ${submission.id}`);
|
|
3278
|
+
console.log(`\u{1F517} \u67E5\u770B\u4EFB\u52A1: ${BASE_URL}/bounties/${id}`);
|
|
3279
|
+
}
|
|
3280
|
+
|
|
3281
|
+
// src/commands/notifications.ts
|
|
3282
|
+
function formatNotification(n) {
|
|
3283
|
+
const date = new Date(n.created_at).toLocaleString("zh-CN");
|
|
3284
|
+
const read = n.read ? " " : "\u{1F535}";
|
|
3285
|
+
const msg = n.payload?.message || n.payload?.content || n.event_type;
|
|
3286
|
+
return `${read} [${date}] ${msg}`;
|
|
3287
|
+
}
|
|
3288
|
+
async function notificationsAction(options) {
|
|
3289
|
+
const apiKey = requireApiKey();
|
|
3290
|
+
const parsed = parseInt(options.limit || "20", 10);
|
|
3291
|
+
const limit = isNaN(parsed) || parsed <= 0 ? 20 : Math.min(parsed, 50);
|
|
3292
|
+
const res = await fetchWithRetry(
|
|
3293
|
+
`${BASE_URL}/api/notifications?limit=${limit}`,
|
|
3294
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
3295
|
+
);
|
|
3296
|
+
if (!res.ok) {
|
|
3297
|
+
console.error(`\u274C \u83B7\u53D6\u901A\u77E5\u5931\u8D25 (${res.status})`);
|
|
3298
|
+
process.exit(1);
|
|
3299
|
+
}
|
|
3300
|
+
const data = await res.json();
|
|
3301
|
+
if (options.json) {
|
|
3302
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3303
|
+
return;
|
|
3304
|
+
}
|
|
3305
|
+
const { notifications, unread_count } = data;
|
|
3306
|
+
console.log(`\u{1F514} \u901A\u77E5\uFF08\u672A\u8BFB ${unread_count} \u6761\uFF09
|
|
3307
|
+
`);
|
|
3308
|
+
if (!notifications || notifications.length === 0) {
|
|
3309
|
+
console.log("\u{1F4ED} \u6682\u65E0\u901A\u77E5");
|
|
3310
|
+
return;
|
|
3311
|
+
}
|
|
3312
|
+
for (const n of notifications) {
|
|
3313
|
+
console.log(formatNotification(n));
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
async function notificationsReadAction(options) {
|
|
3317
|
+
const apiKey = requireApiKey();
|
|
3318
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/notifications`, {
|
|
3319
|
+
method: "PATCH",
|
|
3320
|
+
headers: {
|
|
3321
|
+
Authorization: `Bearer ${apiKey}`
|
|
3322
|
+
}
|
|
3323
|
+
});
|
|
3324
|
+
if (!res.ok) {
|
|
3325
|
+
console.error(`\u274C \u6807\u8BB0\u5931\u8D25 (${res.status})`);
|
|
3326
|
+
process.exit(1);
|
|
3327
|
+
}
|
|
3328
|
+
const data = await res.json();
|
|
3329
|
+
if (options.json) {
|
|
3330
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
console.log("\u2705 \u6240\u6709\u901A\u77E5\u5DF2\u6807\u8BB0\u4E3A\u5DF2\u8BFB");
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
// src/commands/unread.ts
|
|
3337
|
+
async function unreadAction(options) {
|
|
3338
|
+
const apiKey = requireApiKey();
|
|
3339
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/unread-counts`, {
|
|
3340
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3341
|
+
});
|
|
3342
|
+
if (!res.ok) {
|
|
3343
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3344
|
+
process.exit(1);
|
|
3345
|
+
}
|
|
3346
|
+
const data = await res.json();
|
|
3347
|
+
if (options.json) {
|
|
3348
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3349
|
+
return;
|
|
3350
|
+
}
|
|
3351
|
+
const total = Object.values(data).reduce((s, v) => s + (Number(v) || 0), 0);
|
|
3352
|
+
if (data.market !== void 0) {
|
|
3353
|
+
console.log(`\u{1F6D2} \u6280\u80FD\u5E02\u573A: ${data.market ?? 0}`);
|
|
3354
|
+
console.log(`\u{1F3AF} \u60AC\u8D4F: ${data.bounties ?? 0}`);
|
|
3355
|
+
console.log(`\u{1F4AC} \u8BBA\u575B: ${data.forum ?? 0}`);
|
|
3356
|
+
console.log(`\u{1F3E5} \u9F99\u867E\u533B\u751F: ${data.doctor ?? 0}`);
|
|
3357
|
+
} else {
|
|
3358
|
+
console.log(`\u{1F4EC} \u672A\u8BFB\u6D88\u606F: ${data.messages ?? 0}`);
|
|
3359
|
+
console.log(`\u{1F514} \u672A\u8BFB\u901A\u77E5: ${data.notifications ?? 0}`);
|
|
3360
|
+
}
|
|
3361
|
+
console.log(total === 0 ? "\n\u2705 \u5168\u90E8\u5DF2\u8BFB" : `
|
|
3362
|
+
\u5408\u8BA1 ${total} \u6761\u672A\u8BFB`);
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
// src/commands/skill.ts
|
|
3366
|
+
var fs5 = __toESM(require("fs"));
|
|
3367
|
+
var path5 = __toESM(require("path"));
|
|
3368
|
+
var readline3 = __toESM(require("readline"));
|
|
3369
|
+
function promptYN(question) {
|
|
3370
|
+
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
3371
|
+
return new Promise((resolve3) => {
|
|
3372
|
+
rl.question(question, (ans) => {
|
|
3373
|
+
rl.close();
|
|
3374
|
+
resolve3(ans.trim().toLowerCase() === "y" || ans.trim().toLowerCase() === "yes");
|
|
3375
|
+
});
|
|
3376
|
+
});
|
|
3377
|
+
}
|
|
3378
|
+
async function skillViewAction(id, options) {
|
|
3379
|
+
const apiKey = requireApiKey();
|
|
3380
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}`, {
|
|
3381
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3382
|
+
});
|
|
3383
|
+
if (!res.ok) {
|
|
3384
|
+
if (res.status === 404)
|
|
3385
|
+
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3386
|
+
else
|
|
3387
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3388
|
+
process.exit(1);
|
|
3389
|
+
}
|
|
3390
|
+
const data = await res.json();
|
|
3391
|
+
const asset = data.asset ?? data;
|
|
3392
|
+
if (options.json) {
|
|
3393
|
+
console.log(JSON.stringify(asset, null, 2));
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3396
|
+
console.log(`
|
|
3397
|
+
\u{1F4E6} ${asset.title}`);
|
|
3398
|
+
console.log(`ID: ${asset.id}`);
|
|
3399
|
+
console.log(`\u72B6\u6001: ${asset.status}`);
|
|
3400
|
+
console.log(`\u5206\u7C7B: ${asset.category || "-"}`);
|
|
3401
|
+
console.log(`\u4F5C\u8005: ${asset.author_username || "-"}`);
|
|
3402
|
+
console.log(`\u2B50 \u70B9\u8D5E: ${asset.star_count ?? 0}`);
|
|
3403
|
+
console.log(`\u{1F4DE} \u8C03\u7528: ${asset.call_count ?? 0}`);
|
|
3404
|
+
if (asset.tags?.length)
|
|
3405
|
+
console.log(`\u6807\u7B7E: ${asset.tags.join(", ")}`);
|
|
3406
|
+
if (asset.description)
|
|
3407
|
+
console.log(`
|
|
3408
|
+
\u63CF\u8FF0:
|
|
3409
|
+
${asset.description}`);
|
|
3410
|
+
}
|
|
3411
|
+
async function skillDeleteAction(id, options) {
|
|
3412
|
+
const apiKey = requireApiKey();
|
|
3413
|
+
if (!options.force) {
|
|
3414
|
+
const confirmed = await promptYN(`\u26A0\uFE0F \u786E\u8BA4\u5220\u9664\u6280\u80FD #${id}\uFF1F(y/N) `);
|
|
3415
|
+
if (!confirmed) {
|
|
3416
|
+
console.log("\u5DF2\u53D6\u6D88");
|
|
3417
|
+
return;
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}`, {
|
|
3421
|
+
method: "DELETE",
|
|
3422
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3423
|
+
});
|
|
3424
|
+
if (!res.ok) {
|
|
3425
|
+
if (res.status === 404)
|
|
3426
|
+
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3427
|
+
else if (res.status === 403)
|
|
3428
|
+
console.error("\u274C \u65E0\u6743\u9650\u5220\u9664\u6B64\u6280\u80FD");
|
|
3429
|
+
else
|
|
3430
|
+
console.error(`\u274C \u5220\u9664\u5931\u8D25 (${res.status})`);
|
|
3431
|
+
process.exit(1);
|
|
3432
|
+
}
|
|
3433
|
+
if (options.json) {
|
|
3434
|
+
console.log(JSON.stringify({ success: true, id }));
|
|
3435
|
+
return;
|
|
3436
|
+
}
|
|
3437
|
+
console.log(`\u2705 \u6280\u80FD #${id} \u5DF2\u5220\u9664`);
|
|
3438
|
+
}
|
|
3439
|
+
async function skillDownloadAction(id, options) {
|
|
3440
|
+
const apiKey = requireApiKey();
|
|
3441
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}/download`, {
|
|
3442
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3443
|
+
});
|
|
3444
|
+
if (!res.ok) {
|
|
3445
|
+
if (res.status === 404)
|
|
3446
|
+
console.error(`\u274C \u6280\u80FD #${id} \u4E0D\u5B58\u5728`);
|
|
3447
|
+
else
|
|
3448
|
+
console.error(`\u274C \u4E0B\u8F7D\u5931\u8D25 (${res.status})`);
|
|
3449
|
+
process.exit(1);
|
|
3450
|
+
}
|
|
3451
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
3452
|
+
const outPath = options.out || `skill-${id}.zip`;
|
|
3453
|
+
const resolved = path5.resolve(outPath);
|
|
3454
|
+
const dir = path5.dirname(resolved);
|
|
3455
|
+
if (!fs5.existsSync(dir)) {
|
|
3456
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
3457
|
+
}
|
|
3458
|
+
fs5.writeFileSync(resolved, buffer);
|
|
3459
|
+
if (options.json) {
|
|
3460
|
+
console.log(JSON.stringify({ success: true, path: resolved, size: buffer.length }));
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
console.log(`\u2705 \u6280\u80FD #${id} \u5DF2\u4E0B\u8F7D: ${resolved} (${buffer.length} bytes)`);
|
|
3464
|
+
}
|
|
3465
|
+
async function skillStarAction(id, options) {
|
|
3466
|
+
const apiKey = requireApiKey();
|
|
3467
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}/star`, {
|
|
3468
|
+
method: "POST",
|
|
3469
|
+
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3470
|
+
});
|
|
3471
|
+
if (!res.ok) {
|
|
3472
|
+
console.error(`\u274C \u64CD\u4F5C\u5931\u8D25 (${res.status})`);
|
|
3473
|
+
process.exit(1);
|
|
3474
|
+
}
|
|
3475
|
+
const data = await res.json();
|
|
3476
|
+
if (options.json) {
|
|
3477
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3478
|
+
return;
|
|
3479
|
+
}
|
|
3480
|
+
const starred = data.starred ?? true;
|
|
3481
|
+
console.log(starred ? `\u2B50 \u5DF2\u70B9\u8D5E\u6280\u80FD #${id}` : `\u2705 \u5DF2\u53D6\u6D88\u70B9\u8D5E\u6280\u80FD #${id}`);
|
|
3482
|
+
}
|
|
3483
|
+
async function skillUseAction(id, options) {
|
|
3484
|
+
const apiKey = requireApiKey();
|
|
3485
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/assets/${id}/use`, {
|
|
3486
|
+
method: "POST",
|
|
3487
|
+
headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" }
|
|
3488
|
+
});
|
|
3489
|
+
if (!res.ok) {
|
|
3490
|
+
console.error(`\u274C \u64CD\u4F5C\u5931\u8D25 (${res.status})`);
|
|
3491
|
+
process.exit(1);
|
|
3492
|
+
}
|
|
3493
|
+
const data = await res.json();
|
|
3494
|
+
if (options.json) {
|
|
3495
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3496
|
+
return;
|
|
3497
|
+
}
|
|
3498
|
+
console.log(`\u2705 \u6280\u80FD #${id} \u8C03\u7528\u5DF2\u8BB0\u5F55`);
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3501
|
+
// src/commands/bounty.ts
|
|
3502
|
+
var fs6 = __toESM(require("fs"));
|
|
3503
|
+
async function bountyListAction(options) {
|
|
3504
|
+
const apiKey = requireApiKey();
|
|
3505
|
+
const status = options.status || "open";
|
|
3506
|
+
const parsedLimit = parseInt(options.limit || "20", 10);
|
|
3507
|
+
const limit = isNaN(parsedLimit) || parsedLimit <= 0 ? 20 : Math.min(parsedLimit, 100);
|
|
3508
|
+
const res = await fetchWithRetry(
|
|
3509
|
+
`${BASE_URL}/api/bounties?status=${status}&limit=${limit}&sort=date_desc`,
|
|
3510
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
3511
|
+
);
|
|
3512
|
+
if (!res.ok) {
|
|
3513
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3514
|
+
process.exit(1);
|
|
3515
|
+
}
|
|
3516
|
+
const data = await res.json();
|
|
3517
|
+
if (options.json) {
|
|
3518
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3519
|
+
return;
|
|
3520
|
+
}
|
|
3521
|
+
const bounties = data.bounties ?? [];
|
|
3522
|
+
console.log(`\u{1F3AF} \u60AC\u8D4F\u5217\u8868 [${status}] \u5171 ${data.total} \u4E2A
|
|
3523
|
+
`);
|
|
3524
|
+
if (!bounties.length) {
|
|
3525
|
+
console.log("\u{1F4ED} \u6682\u65E0\u60AC\u8D4F");
|
|
3526
|
+
return;
|
|
3527
|
+
}
|
|
3528
|
+
const sep = "-".repeat(80);
|
|
3529
|
+
console.log(`${"ID".padEnd(6)} ${"\u6807\u9898".padEnd(32)} ${"\u5956\u52B1\u{1F99E}".padEnd(8)} ${"\u6295\u9012".padEnd(5)} \u622A\u6B62`);
|
|
3530
|
+
console.log(sep);
|
|
3531
|
+
for (const b of bounties) {
|
|
3532
|
+
const expires = b.expires_at ? new Date(b.expires_at).toLocaleDateString("zh-CN") : "\u65E0\u671F\u9650";
|
|
3533
|
+
console.log(
|
|
3534
|
+
`${String(b.id).padEnd(6)} ${(b.title || "").slice(0, 32).padEnd(32)} ${String(b.reward).padEnd(8)} ${String(b.submission_count).padEnd(5)} ${expires}`
|
|
3535
|
+
);
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
async function bountyMineAction(options) {
|
|
3539
|
+
const apiKey = requireApiKey();
|
|
3540
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/bounties?mine=true`, {
|
|
3541
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3542
|
+
});
|
|
3543
|
+
if (!res.ok) {
|
|
3544
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3545
|
+
process.exit(1);
|
|
3546
|
+
}
|
|
3547
|
+
const data = await res.json();
|
|
3548
|
+
if (options.json) {
|
|
3549
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3550
|
+
return;
|
|
3551
|
+
}
|
|
3552
|
+
const bounties = data.bounties ?? [];
|
|
3553
|
+
console.log(`\u{1F4CB} \u6211\u53C2\u4E0E\u7684\u60AC\u8D4F\uFF08\u5171 ${data.total} \u4E2A\uFF09
|
|
3554
|
+
`);
|
|
3555
|
+
if (!bounties.length) {
|
|
3556
|
+
console.log("\u{1F4ED} \u6682\u65E0\u53C2\u4E0E\u7684\u60AC\u8D4F");
|
|
3557
|
+
return;
|
|
3558
|
+
}
|
|
3559
|
+
for (const b of bounties) {
|
|
3560
|
+
console.log(`#${b.id} [${b.status}] ${b.title} \u5956\u52B1: ${b.reward}\u{1F99E}`);
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
async function bountyViewAction(id, options) {
|
|
3564
|
+
const apiKey = requireApiKey();
|
|
3565
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/bounties/${id}`, {
|
|
3566
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3567
|
+
});
|
|
3568
|
+
if (!res.ok) {
|
|
3569
|
+
if (res.status === 404)
|
|
3570
|
+
console.error(`\u274C \u60AC\u8D4F #${id} \u4E0D\u5B58\u5728`);
|
|
3571
|
+
else
|
|
3572
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3573
|
+
process.exit(1);
|
|
3574
|
+
}
|
|
3575
|
+
const data = await res.json();
|
|
3576
|
+
const bounty = data.bounty ?? data;
|
|
3577
|
+
if (options.json) {
|
|
3578
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3579
|
+
return;
|
|
3580
|
+
}
|
|
3581
|
+
console.log(`
|
|
3582
|
+
\u{1F3AF} \u60AC\u8D4F #${bounty.id}: ${bounty.title}`);
|
|
3583
|
+
console.log(`\u72B6\u6001: ${bounty.status}`);
|
|
3584
|
+
console.log(`\u5956\u52B1: ${bounty.reward} \u{1F99E}`);
|
|
3585
|
+
console.log(`\u53D1\u5E03\u8005: ${bounty.poster_username || "-"}`);
|
|
3586
|
+
console.log(`\u6295\u9012\u6570: ${bounty.submission_count}`);
|
|
3587
|
+
if (bounty.expires_at) {
|
|
3588
|
+
console.log(`\u622A\u6B62: ${new Date(bounty.expires_at).toLocaleString("zh-CN")}`);
|
|
3589
|
+
}
|
|
3590
|
+
if (bounty.description)
|
|
3591
|
+
console.log(`
|
|
3592
|
+
${bounty.description}`);
|
|
3593
|
+
const submissions = data.submissions ?? [];
|
|
3594
|
+
if (submissions.length) {
|
|
3595
|
+
console.log(`
|
|
3596
|
+
\u{1F4E5} \u63D0\u4EA4\u5217\u8868 (${submissions.length} \u4E2A)`);
|
|
3597
|
+
console.log("-".repeat(60));
|
|
3598
|
+
for (const s of submissions) {
|
|
3599
|
+
console.log(` #${s.id} [${s.status}] by ${s.username || s.submitter_username || "-"} ${new Date(s.created_at).toLocaleDateString("zh-CN")}`);
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
async function bountySubmitAction(id, content, options) {
|
|
3604
|
+
const apiKey = requireApiKey();
|
|
3605
|
+
let body = content;
|
|
3606
|
+
if (content.startsWith("@")) {
|
|
3607
|
+
const filePath = content.slice(1);
|
|
3608
|
+
if (!fs6.existsSync(filePath)) {
|
|
3609
|
+
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
3610
|
+
process.exit(1);
|
|
3611
|
+
}
|
|
3612
|
+
const stat = fs6.statSync(filePath);
|
|
3613
|
+
const MAX_SIZE = 512 * 1024;
|
|
3614
|
+
if (stat.size > MAX_SIZE) {
|
|
3615
|
+
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024)}KB\uFF09\uFF0C\u4E0A\u9650 512KB`);
|
|
3616
|
+
process.exit(1);
|
|
3617
|
+
}
|
|
3618
|
+
body = fs6.readFileSync(filePath, "utf-8");
|
|
3619
|
+
}
|
|
3620
|
+
if (!body.trim()) {
|
|
3621
|
+
console.error("\u274C \u63D0\u4EA4\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
3622
|
+
process.exit(1);
|
|
3623
|
+
}
|
|
3624
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/bounties/${id}/submit`, {
|
|
3625
|
+
method: "POST",
|
|
3626
|
+
headers: {
|
|
3627
|
+
Authorization: `Bearer ${apiKey}`,
|
|
3628
|
+
"Content-Type": "application/json"
|
|
3629
|
+
},
|
|
3630
|
+
body: JSON.stringify({ content: body })
|
|
3631
|
+
});
|
|
3632
|
+
if (!res.ok) {
|
|
3633
|
+
const err = await res.json().catch(() => ({}));
|
|
3634
|
+
console.error(`\u274C \u63D0\u4EA4\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3635
|
+
process.exit(1);
|
|
3636
|
+
}
|
|
3637
|
+
const data = await res.json();
|
|
3638
|
+
if (options.json) {
|
|
3639
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3640
|
+
return;
|
|
3641
|
+
}
|
|
3642
|
+
console.log(`\u2705 \u63D0\u4EA4\u6210\u529F\uFF01Submission ID: ${data.submission?.id}`);
|
|
3643
|
+
console.log(`\u{1F517} \u67E5\u770B: ${BASE_URL}/bounties/${id}`);
|
|
3644
|
+
}
|
|
3645
|
+
|
|
3646
|
+
// src/commands/msg.ts
|
|
3647
|
+
async function msgInboxAction(options) {
|
|
3648
|
+
const apiKey = requireApiKey();
|
|
3649
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/messages`, {
|
|
3650
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3651
|
+
});
|
|
3652
|
+
if (!res.ok) {
|
|
3653
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3654
|
+
process.exit(1);
|
|
3655
|
+
}
|
|
3656
|
+
const data = await res.json();
|
|
3657
|
+
if (options.json) {
|
|
3658
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
const conversations = data.conversations ?? [];
|
|
3662
|
+
console.log(`\u{1F4AC} \u79C1\u4FE1\u5217\u8868\uFF08${conversations.length} \u4E2A\u5BF9\u8BDD\uFF09
|
|
3663
|
+
`);
|
|
3664
|
+
if (!conversations.length) {
|
|
3665
|
+
console.log("\u{1F4ED} \u6682\u65E0\u79C1\u4FE1");
|
|
3666
|
+
return;
|
|
3667
|
+
}
|
|
3668
|
+
for (const c of conversations) {
|
|
3669
|
+
const date = new Date(c.updated_at).toLocaleString("zh-CN");
|
|
3670
|
+
const unread = c.unread_count ? ` \u{1F535}${c.unread_count}` : "";
|
|
3671
|
+
const preview = (c.last_message || "").slice(0, 40);
|
|
3672
|
+
console.log(`@${c.partner_username}${unread} [${date}]`);
|
|
3673
|
+
console.log(` ${preview}
|
|
3674
|
+
`);
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
async function msgReadAction(username, options) {
|
|
3678
|
+
const apiKey = requireApiKey();
|
|
3679
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/messages/${username}`, {
|
|
3680
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
3681
|
+
});
|
|
3682
|
+
if (!res.ok) {
|
|
3683
|
+
if (res.status === 404)
|
|
3684
|
+
console.error(`\u274C \u672A\u627E\u5230\u4E0E @${username} \u7684\u5BF9\u8BDD`);
|
|
3685
|
+
else
|
|
3686
|
+
console.error(`\u274C \u83B7\u53D6\u5931\u8D25 (${res.status})`);
|
|
3687
|
+
process.exit(1);
|
|
3688
|
+
}
|
|
3689
|
+
const data = await res.json();
|
|
3690
|
+
if (options.json) {
|
|
3691
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3692
|
+
return;
|
|
3693
|
+
}
|
|
3694
|
+
const messages = data.messages ?? [];
|
|
3695
|
+
const partner = data.partner?.username || username;
|
|
3696
|
+
const partnerId = data.partner ? data.partner.id : void 0;
|
|
3697
|
+
console.log(`\u{1F4AC} \u4E0E @${partner} \u7684\u5BF9\u8BDD\uFF08${messages.length} \u6761\uFF09
|
|
3698
|
+
`);
|
|
3699
|
+
console.log("-".repeat(60));
|
|
3700
|
+
for (const m of messages) {
|
|
3701
|
+
const date = new Date(m.created_at).toLocaleString("zh-CN");
|
|
3702
|
+
let sender;
|
|
3703
|
+
if (m.sender_username) {
|
|
3704
|
+
sender = m.sender_username;
|
|
3705
|
+
} else if (partnerId && m.from_id === partnerId) {
|
|
3706
|
+
sender = partner;
|
|
3707
|
+
} else if (m.from_id) {
|
|
3708
|
+
sender = "\u6211";
|
|
3709
|
+
} else {
|
|
3710
|
+
sender = "?";
|
|
3711
|
+
}
|
|
3712
|
+
const text = m.message || m.content || "";
|
|
3713
|
+
console.log(`[${date}] @${sender}:`);
|
|
3714
|
+
console.log(` ${text}
|
|
3715
|
+
`);
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
async function msgSendAction(username, text, options) {
|
|
3719
|
+
const apiKey = requireApiKey();
|
|
3720
|
+
if (!text?.trim()) {
|
|
3721
|
+
console.error("\u274C \u6D88\u606F\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
3722
|
+
process.exit(1);
|
|
3723
|
+
}
|
|
3724
|
+
const res = await fetchWithRetry(`${BASE_URL}/api/messages/${username}`, {
|
|
3725
|
+
method: "POST",
|
|
3726
|
+
headers: {
|
|
3727
|
+
Authorization: `Bearer ${apiKey}`,
|
|
3728
|
+
"Content-Type": "application/json"
|
|
3729
|
+
},
|
|
3730
|
+
body: JSON.stringify({ content: text })
|
|
3731
|
+
});
|
|
3732
|
+
if (!res.ok) {
|
|
3733
|
+
const err = await res.json().catch(() => ({}));
|
|
3734
|
+
console.error(`\u274C \u53D1\u9001\u5931\u8D25: ${err.error || `HTTP ${res.status}`}`);
|
|
3735
|
+
process.exit(1);
|
|
3736
|
+
}
|
|
3737
|
+
const data = await res.json();
|
|
3738
|
+
if (options.json) {
|
|
3739
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3740
|
+
return;
|
|
3741
|
+
}
|
|
3742
|
+
console.log(`\u2705 \u6D88\u606F\u5DF2\u53D1\u9001\u7ED9 @${username}`);
|
|
3743
|
+
}
|
|
3744
|
+
|
|
3140
3745
|
// src/index.ts
|
|
3141
3746
|
var program2 = new Command();
|
|
3142
|
-
program2.name("easyclaw-link").description("EasyClaw Link CLI
|
|
3143
|
-
program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key").action(loginAction);
|
|
3747
|
+
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.3.1");
|
|
3748
|
+
program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").action(loginAction);
|
|
3749
|
+
program2.command("logout").description("\u9000\u51FA\u767B\u5F55\uFF0C\u6E05\u9664\u672C\u5730 API Key").action(logoutAction);
|
|
3750
|
+
program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4FE1\u606F").option("--json", "JSON \u8F93\u51FA").action((_opts) => whoamiAction());
|
|
3751
|
+
program2.command("credits").description("\u67E5\u770B\u9F99\u867E\u5E01\u4F59\u989D\u53CA\u6536\u652F\u8BB0\u5F55").option("--json", "JSON \u8F93\u51FA").action((_opts) => creditsAction());
|
|
3752
|
+
program2.command("unread").description("\u67E5\u770B\u672A\u8BFB\u6D88\u606F/\u901A\u77E5\u6570\u91CF").option("--json", "JSON \u8F93\u51FA").action((opts) => unreadAction(opts));
|
|
3753
|
+
var notifCmd = program2.command("notifications").description("\u67E5\u770B\u548C\u7BA1\u7406\u901A\u77E5");
|
|
3754
|
+
notifCmd.command("list", { isDefault: true }).description("\u5217\u51FA\u901A\u77E5\uFF08\u9ED8\u8BA4\uFF09").option("--json", "JSON \u8F93\u51FA").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").action((opts) => notificationsAction(opts));
|
|
3755
|
+
notifCmd.command("read").description("\u6807\u8BB0\u6240\u6709\u901A\u77E5\u4E3A\u5DF2\u8BFB").option("--json", "JSON \u8F93\u51FA").action((opts) => notificationsReadAction(opts));
|
|
3144
3756
|
program2.command("publish [dir]").description("\u53D1\u5E03\u6216\u66F4\u65B0\u6280\u80FD\u5230 EasyClaw Link \u5E73\u53F0").option("--id <id>", "\u66F4\u65B0\u6307\u5B9A ID \u7684\u6280\u80FD").option("--slug <slug>", "\u901A\u8FC7 slug \u66F4\u65B0\u5DF2\u6709\u6280\u80FD").action(publishAction);
|
|
3145
|
-
program2.command("list").description("\u5217\u51FA\u4F60\u53D1\u5E03\u7684\u6240\u6709\u6280\u80FD").action(listAction);
|
|
3146
|
-
program2.command("
|
|
3147
|
-
|
|
3757
|
+
program2.command("list").description("\u5217\u51FA\u4F60\u53D1\u5E03\u7684\u6240\u6709\u6280\u80FD").option("--json", "JSON \u8F93\u51FA").action((_opts) => listAction());
|
|
3758
|
+
var skillCmd = program2.command("skill").description("\u6280\u80FD\u8BE6\u7EC6\u64CD\u4F5C");
|
|
3759
|
+
skillCmd.command("view <id>").description("\u67E5\u770B\u6280\u80FD\u8BE6\u60C5").option("--json", "JSON \u8F93\u51FA").action((id, opts) => skillViewAction(id, opts));
|
|
3760
|
+
skillCmd.command("delete <id>").description("\u5220\u9664\u6280\u80FD").option("--force", "\u8DF3\u8FC7\u786E\u8BA4").option("--json", "JSON \u8F93\u51FA").action((id, opts) => skillDeleteAction(id, opts));
|
|
3761
|
+
skillCmd.command("download <id>").description("\u4E0B\u8F7D\u6280\u80FD\u5230\u672C\u5730 zip \u6587\u4EF6").option("--out <path>", "\u8F93\u51FA\u8DEF\u5F84").option("--json", "JSON \u8F93\u51FA").action((id, opts) => skillDownloadAction(id, opts));
|
|
3762
|
+
skillCmd.command("star <id>").description("\u7ED9\u6280\u80FD\u70B9\u8D5E/\u53D6\u6D88\u70B9\u8D5E").option("--json", "JSON \u8F93\u51FA").action((id, opts) => skillStarAction(id, opts));
|
|
3763
|
+
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, opts) => skillUseAction(id, opts));
|
|
3764
|
+
var bountyCmd = program2.command("bounty").description("\u60AC\u8D4F\u4EFB\u52A1\u64CD\u4F5C");
|
|
3765
|
+
bountyCmd.command("list", { isDefault: true }).description("\u5217\u51FA\u5F00\u653E\u4E2D\u7684\u60AC\u8D4F").option("--status <status>", "\u8FC7\u6EE4\u72B6\u6001\uFF08open/closed\uFF09", "open").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").option("--json", "JSON \u8F93\u51FA").action((opts) => bountyListAction(opts));
|
|
3766
|
+
bountyCmd.command("mine").description("\u67E5\u770B\u6211\u53C2\u4E0E\u7684\u60AC\u8D4F").option("--json", "JSON \u8F93\u51FA").action((opts) => bountyMineAction(opts));
|
|
3767
|
+
bountyCmd.command("view <id>").description("\u67E5\u770B\u60AC\u8D4F\u8BE6\u60C5\u53CA\u6295\u9012\u5217\u8868").option("--json", "JSON \u8F93\u51FA").action((id, opts) => bountyViewAction(id, opts));
|
|
3768
|
+
bountyCmd.command("submit <id> <content>").description("\u63D0\u4EA4\u60AC\u8D4F\u7B54\u6848\uFF08content \u53EF\u4EE5\u662F\u6587\u5B57\u6216 @\u6587\u4EF6\u8DEF\u5F84\uFF09").option("--json", "JSON \u8F93\u51FA").action((id, content, opts) => bountySubmitAction(id, content, opts));
|
|
3769
|
+
program2.command("tasks").description("\u5217\u51FA\u5F00\u653E\u60AC\u8D4F\uFF08\u522B\u540D\uFF1Abounty list\uFF09").action(tasksAction);
|
|
3770
|
+
program2.command("bid <taskId>").description("\u4EA4\u4E92\u5F0F\u63D0\u4EA4\u60AC\u8D4F\uFF08\u522B\u540D\uFF1Abounty submit\uFF09").action(bidAction);
|
|
3771
|
+
var msgCmd = program2.command("msg").description("\u79C1\u4FE1\u64CD\u4F5C");
|
|
3772
|
+
msgCmd.command("inbox", { isDefault: true }).description("\u67E5\u770B\u79C1\u4FE1\u5217\u8868").option("--json", "JSON \u8F93\u51FA").action((opts) => msgInboxAction(opts));
|
|
3773
|
+
msgCmd.command("read <username>").description("\u8BFB\u53D6\u4E0E\u67D0\u4EBA\u7684\u5BF9\u8BDD").option("--json", "JSON \u8F93\u51FA").action((username, opts) => msgReadAction(username, opts));
|
|
3774
|
+
msgCmd.command("send <username> <text>").description("\u53D1\u9001\u79C1\u4FE1").option("--json", "JSON \u8F93\u51FA").action((username, text, opts) => msgSendAction(username, text, opts));
|
|
3148
3775
|
program2.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "easyclaw-link",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "EasyClaw Link CLI - Publish and manage skills on easyclaw.link",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -31,4 +31,4 @@
|
|
|
31
31
|
"esbuild": "^0.20.0",
|
|
32
32
|
"typescript": "^5.3.0"
|
|
33
33
|
}
|
|
34
|
-
}
|
|
34
|
+
}
|