easyclaw-link 1.6.0 → 1.7.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 +225 -104
- package/package.json +1 -1
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 path9 = require("path");
|
|
935
|
+
var fs12 = 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 = path9.resolve(baseDir, baseName);
|
|
1768
|
+
if (fs12.existsSync(localBin))
|
|
1769
1769
|
return localBin;
|
|
1770
|
-
if (sourceExt.includes(
|
|
1770
|
+
if (sourceExt.includes(path9.extname(baseName)))
|
|
1771
1771
|
return void 0;
|
|
1772
|
-
const foundExt = sourceExt.find((ext) =>
|
|
1772
|
+
const foundExt = sourceExt.find((ext) => fs12.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 = fs12.realpathSync(this._scriptPath);
|
|
1785
1785
|
} catch (err) {
|
|
1786
1786
|
resolvedScriptPath = this._scriptPath;
|
|
1787
1787
|
}
|
|
1788
|
-
executableDir =
|
|
1788
|
+
executableDir = path9.resolve(path9.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 = path9.basename(this._scriptPath, path9.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(path9.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 = path9.basename(filename, path9.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(path10) {
|
|
2617
|
+
if (path10 === void 0)
|
|
2618
2618
|
return this._executableDir;
|
|
2619
|
-
this._executableDir =
|
|
2619
|
+
this._executableDir = path10;
|
|
2620
2620
|
return this;
|
|
2621
2621
|
}
|
|
2622
2622
|
/**
|
|
@@ -2833,7 +2833,7 @@ 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
|
|
2836
|
+
var EXIT2 = {
|
|
2837
2837
|
OK: 0,
|
|
2838
2838
|
ERROR: 1,
|
|
2839
2839
|
AUTH: 2,
|
|
@@ -2848,26 +2848,26 @@ function httpError(status, serverMessage) {
|
|
|
2848
2848
|
case 401:
|
|
2849
2849
|
console.error(`\u274C \u8BA4\u8BC1\u5931\u8D25${msg}
|
|
2850
2850
|
\u2192 \u8BF7\u5148\u8FD0\u884C: ecl login`);
|
|
2851
|
-
process.exit(
|
|
2851
|
+
process.exit(EXIT2.AUTH);
|
|
2852
2852
|
case 403:
|
|
2853
2853
|
console.error(`\u274C \u6743\u9650\u4E0D\u8DB3${msg}
|
|
2854
2854
|
\u2192 \u5F53\u524D\u8D26\u53F7\u65E0\u6B64\u64CD\u4F5C\u6743\u9650\uFF0C\u68C0\u67E5\u8D26\u53F7\u89D2\u8272`);
|
|
2855
|
-
process.exit(
|
|
2855
|
+
process.exit(EXIT2.PERMISSION);
|
|
2856
2856
|
case 404:
|
|
2857
2857
|
console.error(`\u274C \u8D44\u6E90\u4E0D\u5B58\u5728${msg}
|
|
2858
2858
|
\u2192 \u68C0\u67E5 ID/slug \u662F\u5426\u6B63\u786E`);
|
|
2859
|
-
process.exit(
|
|
2859
|
+
process.exit(EXIT2.NOT_FOUND);
|
|
2860
2860
|
case 422:
|
|
2861
2861
|
console.error(`\u274C \u8BF7\u6C42\u6821\u9A8C\u5931\u8D25${msg}
|
|
2862
2862
|
\u2192 \u68C0\u67E5\u53C2\u6570\u683C\u5F0F`);
|
|
2863
|
-
process.exit(
|
|
2863
|
+
process.exit(EXIT2.VALIDATION);
|
|
2864
2864
|
case 429:
|
|
2865
2865
|
console.error(`\u274C \u89E6\u53D1\u9891\u7387\u9650\u5236${msg}
|
|
2866
2866
|
\u2192 \u8BF7\u7A0D\u540E\u91CD\u8BD5`);
|
|
2867
|
-
process.exit(
|
|
2867
|
+
process.exit(EXIT2.RATE_LIMIT);
|
|
2868
2868
|
default:
|
|
2869
2869
|
console.error(`\u274C \u8BF7\u6C42\u5931\u8D25 (HTTP ${status})${msg}`);
|
|
2870
|
-
process.exit(
|
|
2870
|
+
process.exit(EXIT2.ERROR);
|
|
2871
2871
|
}
|
|
2872
2872
|
}
|
|
2873
2873
|
async function assertOk(res) {
|
|
@@ -2901,7 +2901,7 @@ function requireApiKey() {
|
|
|
2901
2901
|
const cfg = readConfig();
|
|
2902
2902
|
if (!cfg.apiKey) {
|
|
2903
2903
|
console.error("\u274C \u672A\u767B\u5F55\uFF0C\u8BF7\u5148\u8FD0\u884C: ecl login");
|
|
2904
|
-
process.exit(
|
|
2904
|
+
process.exit(EXIT2.AUTH);
|
|
2905
2905
|
}
|
|
2906
2906
|
return cfg.apiKey;
|
|
2907
2907
|
}
|
|
@@ -2926,10 +2926,10 @@ async function fetchWithRetry(url, options, maxRetries = 3) {
|
|
|
2926
2926
|
// src/commands/login.ts
|
|
2927
2927
|
function prompt(question) {
|
|
2928
2928
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
2929
|
-
return new Promise((
|
|
2929
|
+
return new Promise((resolve5) => {
|
|
2930
2930
|
rl.question(question, (answer) => {
|
|
2931
2931
|
rl.close();
|
|
2932
|
-
|
|
2932
|
+
resolve5(answer.trim());
|
|
2933
2933
|
});
|
|
2934
2934
|
});
|
|
2935
2935
|
}
|
|
@@ -3234,10 +3234,10 @@ function prompt2(question) {
|
|
|
3234
3234
|
input: process.stdin,
|
|
3235
3235
|
output: process.stdout
|
|
3236
3236
|
});
|
|
3237
|
-
return new Promise((
|
|
3237
|
+
return new Promise((resolve5) => {
|
|
3238
3238
|
rl.question(question, (answer) => {
|
|
3239
3239
|
rl.close();
|
|
3240
|
-
|
|
3240
|
+
resolve5(answer.trim());
|
|
3241
3241
|
});
|
|
3242
3242
|
});
|
|
3243
3243
|
}
|
|
@@ -3417,13 +3417,15 @@ async function leaderboardAction(options) {
|
|
|
3417
3417
|
async function profileUpdateAction(options) {
|
|
3418
3418
|
const apiKey = requireApiKey();
|
|
3419
3419
|
const body = {};
|
|
3420
|
+
if (options.displayName !== void 0)
|
|
3421
|
+
body.display_name = options.displayName || null;
|
|
3420
3422
|
if (options.webhookUrl !== void 0)
|
|
3421
3423
|
body.webhook_url = options.webhookUrl || null;
|
|
3422
3424
|
if (options.ownerEmail !== void 0)
|
|
3423
3425
|
body.owner_email = options.ownerEmail || null;
|
|
3424
3426
|
if (!Object.keys(body).length) {
|
|
3425
|
-
console.error("\u274C \u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u4E2A\u5B57\u6BB5\uFF1A--webhook-url \u6216 --owner-email");
|
|
3426
|
-
process.exit(
|
|
3427
|
+
console.error("\u274C \u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u4E2A\u5B57\u6BB5\uFF1A--display-name\u3001--webhook-url \u6216 --owner-email");
|
|
3428
|
+
process.exit(EXIT.VALIDATION);
|
|
3427
3429
|
}
|
|
3428
3430
|
const res = await fetchWithRetry(`${BASE_URL}/api/auth/me`, {
|
|
3429
3431
|
method: "PATCH",
|
|
@@ -3437,6 +3439,8 @@ async function profileUpdateAction(options) {
|
|
|
3437
3439
|
return;
|
|
3438
3440
|
}
|
|
3439
3441
|
console.log("\u2705 \u4E2A\u4EBA\u8D44\u6599\u5DF2\u66F4\u65B0");
|
|
3442
|
+
if (body.display_name !== void 0)
|
|
3443
|
+
console.log(` \u663E\u793A\u540D\u79F0: ${body.display_name || "(\u5DF2\u6E05\u9664)"}`);
|
|
3440
3444
|
if (body.webhook_url !== void 0)
|
|
3441
3445
|
console.log(` Webhook URL: ${body.webhook_url || "(\u5DF2\u6E05\u9664)"}`);
|
|
3442
3446
|
if (body.owner_email !== void 0)
|
|
@@ -3446,73 +3450,189 @@ async function profileUpdateAction(options) {
|
|
|
3446
3450
|
// src/commands/validate.ts
|
|
3447
3451
|
var fs5 = __toESM(require("fs"));
|
|
3448
3452
|
var path5 = __toESM(require("path"));
|
|
3449
|
-
var
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
meta.name = nameMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
3456
|
-
if (descMatch)
|
|
3457
|
-
meta.description = descMatch[1].trim().replace(/^["']|["']$/g, "");
|
|
3458
|
-
return meta;
|
|
3459
|
-
}
|
|
3460
|
-
async function validateAction(dir) {
|
|
3461
|
-
const target = path5.resolve(dir || ".");
|
|
3453
|
+
var VALID_CATEGORIES = ["system", "office", "creative", "data", "coding", "ai_agent", "tools", "other"];
|
|
3454
|
+
var SKILL_MD_MAX = 5e4;
|
|
3455
|
+
var SKILL_MD_WARN_MIN = 200;
|
|
3456
|
+
var SKILL_MD_WARN_MAX = 2e4;
|
|
3457
|
+
var DESC_MAX = 1e3;
|
|
3458
|
+
function validateSkillDir2(dir) {
|
|
3462
3459
|
const errors = [];
|
|
3463
3460
|
const warnings = [];
|
|
3461
|
+
const skillMdPath = path5.join(dir, "SKILL.md");
|
|
3462
|
+
const pkgPath = path5.join(dir, "package.json");
|
|
3463
|
+
if (!fs5.existsSync(skillMdPath)) {
|
|
3464
|
+
errors.push("SKILL.md \u4E0D\u5B58\u5728");
|
|
3465
|
+
} else {
|
|
3466
|
+
const content = fs5.readFileSync(skillMdPath, "utf-8");
|
|
3467
|
+
const trimmed = content.trim();
|
|
3468
|
+
if (!trimmed) {
|
|
3469
|
+
errors.push("SKILL.md \u4E3A\u7A7A");
|
|
3470
|
+
} else {
|
|
3471
|
+
if (!/^#\s+\S/m.test(content)) {
|
|
3472
|
+
errors.push("SKILL.md \u7F3A\u5C11 # \u6807\u9898\u884C\uFF08\u81F3\u5C11\u4E00\u884C\u4EE5 # \u5F00\u5934\uFF09");
|
|
3473
|
+
}
|
|
3474
|
+
if (content.length > SKILL_MD_MAX) {
|
|
3475
|
+
errors.push(`SKILL.md \u8D85\u8FC7 ${SKILL_MD_MAX} \u5B57\u7B26\uFF08\u5F53\u524D ${content.length}\uFF09\uFF0C\u540E\u7AEF\u4F1A\u62D2\u7EDD`);
|
|
3476
|
+
}
|
|
3477
|
+
if (trimmed.length < SKILL_MD_WARN_MIN) {
|
|
3478
|
+
warnings.push(`SKILL.md \u5185\u5BB9\u8F83\u77ED\uFF08${trimmed.length} \u5B57\u7B26\uFF0C\u5EFA\u8BAE \u2265${SKILL_MD_WARN_MIN}\uFF09`);
|
|
3479
|
+
}
|
|
3480
|
+
if (!/##?\s*(使用方法|用法|usage|how to use)/i.test(content)) {
|
|
3481
|
+
warnings.push('SKILL.md \u7F3A\u5C11"\u4F7F\u7528\u65B9\u6CD5"\u7AE0\u8282\uFF08Agent \u9700\u8981\u77E5\u9053\u5982\u4F55\u8C03\u7528\uFF09');
|
|
3482
|
+
}
|
|
3483
|
+
if (content.length > SKILL_MD_WARN_MAX) {
|
|
3484
|
+
warnings.push(`SKILL.md \u8D85\u8FC7 ${SKILL_MD_WARN_MAX} \u5B57\u7B26\uFF0C\u8D85\u957F\u6587\u6863\u5F71\u54CD Agent \u4E0A\u4E0B\u6587\u52A0\u8F7D`);
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
if (!fs5.existsSync(pkgPath)) {
|
|
3489
|
+
warnings.push("package.json \u4E0D\u5B58\u5728\uFF0C\u6280\u80FD\u6807\u9898\u5C06\u964D\u7EA7\u4E3A\u76EE\u5F55\u540D");
|
|
3490
|
+
} else {
|
|
3491
|
+
let pkg;
|
|
3492
|
+
try {
|
|
3493
|
+
pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
|
|
3494
|
+
} catch {
|
|
3495
|
+
errors.push("package.json JSON \u8BED\u6CD5\u9519\u8BEF");
|
|
3496
|
+
return { errors, warnings };
|
|
3497
|
+
}
|
|
3498
|
+
if (!pkg.name || typeof pkg.name === "string" && !pkg.name.trim()) {
|
|
3499
|
+
errors.push("package.json \u7684 name \u5B57\u6BB5\u4E3A\u7A7A");
|
|
3500
|
+
}
|
|
3501
|
+
if (typeof pkg.description === "string" && pkg.description.length > DESC_MAX) {
|
|
3502
|
+
errors.push(`package.json description \u8D85\u8FC7 ${DESC_MAX} \u5B57\u7B26\uFF08\u5F53\u524D ${pkg.description.length}\uFF09`);
|
|
3503
|
+
}
|
|
3504
|
+
if (pkg.category && !VALID_CATEGORIES.includes(pkg.category)) {
|
|
3505
|
+
warnings.push(`package.json category "${pkg.category}" \u4E0D\u5728\u6709\u6548\u5217\u8868\u5185\uFF0C\u5C06\u964D\u7EA7\u4E3A "other"\uFF08\u6709\u6548\u503C: ${VALID_CATEGORIES.join(", ")}\uFF09`);
|
|
3506
|
+
}
|
|
3507
|
+
}
|
|
3508
|
+
return { errors, warnings };
|
|
3509
|
+
}
|
|
3510
|
+
async function validateAction(dir, options) {
|
|
3511
|
+
const target = path5.resolve(dir || ".");
|
|
3464
3512
|
if (!fs5.existsSync(target) || !fs5.statSync(target).isDirectory()) {
|
|
3465
3513
|
console.error(`\u274C \u76EE\u5F55\u4E0D\u5B58\u5728: ${target}`);
|
|
3466
|
-
process.exit(
|
|
3514
|
+
process.exit(EXIT2.NOT_FOUND);
|
|
3467
3515
|
}
|
|
3468
|
-
const
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
warnings.push("SKILL.md \u7F3A\u5C11 name \u5B57\u6BB5\uFF08\u5EFA\u8BAE\u5728 frontmatter \u4E2D\u6DFB\u52A0\uFF09");
|
|
3476
|
-
if (!meta.description)
|
|
3477
|
-
warnings.push("SKILL.md \u7F3A\u5C11 description \u5B57\u6BB5");
|
|
3478
|
-
if (content.length < 50)
|
|
3479
|
-
warnings.push("SKILL.md \u5185\u5BB9\u8FC7\u77ED\uFF08\u5C11\u4E8E 50 \u5B57\u7B26\uFF09\uFF0C\u5EFA\u8BAE\u8865\u5145\u8BF4\u660E");
|
|
3480
|
-
if (content.length > 5e4)
|
|
3481
|
-
warnings.push(`SKILL.md \u8FC7\u5927\uFF08${Math.round(content.length / 1024)}KB\uFF09\uFF0C\u5EFA\u8BAE\u7CBE\u7B80`);
|
|
3516
|
+
const { errors, warnings } = validateSkillDir2(target);
|
|
3517
|
+
const passed = errors.length === 0;
|
|
3518
|
+
if (options.json) {
|
|
3519
|
+
console.log(JSON.stringify({ path: target, passed, errors, warnings }, null, 2));
|
|
3520
|
+
if (!passed)
|
|
3521
|
+
process.exit(EXIT2.VALIDATION);
|
|
3522
|
+
return;
|
|
3482
3523
|
}
|
|
3483
|
-
|
|
3484
|
-
console.log(`\u274C \u9A8C\u8BC1\u5931\u8D25 (${errors.length} \u4E2A\u9519\u8BEF)
|
|
3524
|
+
console.log(`\u{1F50D} \u6821\u9A8C\u76EE\u5F55: ${target}
|
|
3485
3525
|
`);
|
|
3486
|
-
|
|
3526
|
+
if (errors.length) {
|
|
3527
|
+
console.log("\u274C \u9519\u8BEF\uFF08\u963B\u6B62\u53D1\u5E03\uFF09:");
|
|
3528
|
+
for (const e of errors)
|
|
3529
|
+
console.log(` \u2022 ${e}`);
|
|
3530
|
+
}
|
|
3531
|
+
if (warnings.length) {
|
|
3532
|
+
if (errors.length)
|
|
3533
|
+
console.log("");
|
|
3534
|
+
console.log("\u{1F7E1} \u8B66\u544A\uFF08\u5EFA\u8BAE\u4FEE\u590D\uFF09:");
|
|
3535
|
+
for (const w of warnings)
|
|
3536
|
+
console.log(` \u2022 ${w}`);
|
|
3537
|
+
}
|
|
3538
|
+
if (passed) {
|
|
3539
|
+
const warnSuffix = warnings.length ? `\uFF0C${warnings.length} \u4E2A\u8B66\u544A` : "";
|
|
3540
|
+
console.log(`
|
|
3541
|
+
\u2705 \u6821\u9A8C\u901A\u8FC7${warnSuffix}`);
|
|
3487
3542
|
} else {
|
|
3488
|
-
console.log(
|
|
3489
|
-
`);
|
|
3543
|
+
console.log(`
|
|
3544
|
+
\u274C \u6821\u9A8C\u5931\u8D25\uFF08${errors.length} \u4E2A\u9519\u8BEF\uFF09`);
|
|
3545
|
+
process.exit(EXIT2.VALIDATION);
|
|
3490
3546
|
}
|
|
3547
|
+
}
|
|
3548
|
+
|
|
3549
|
+
// src/commands/init.ts
|
|
3550
|
+
var fs6 = __toESM(require("fs"));
|
|
3551
|
+
var path6 = __toESM(require("path"));
|
|
3552
|
+
var SKILL_MD_TEMPLATE = (name) => `# ${name}
|
|
3553
|
+
|
|
3554
|
+
\u4E00\u53E5\u8BDD\u8BF4\u660E\u8FD9\u4E2A\u6280\u80FD\u7684\u7528\u9014\u548C\u9002\u7528\u573A\u666F\u3002
|
|
3555
|
+
|
|
3556
|
+
## \u529F\u80FD
|
|
3557
|
+
|
|
3558
|
+
- \u529F\u80FD\u70B9 1
|
|
3559
|
+
- \u529F\u80FD\u70B9 2
|
|
3560
|
+
- \u529F\u80FD\u70B9 3
|
|
3561
|
+
|
|
3562
|
+
## \u4F7F\u7528\u65B9\u6CD5
|
|
3563
|
+
|
|
3564
|
+
\u63CF\u8FF0 Agent \u5982\u4F55\u8C03\u7528\u8FD9\u4E2A\u6280\u80FD\uFF0C\u5305\u62EC\uFF1A
|
|
3565
|
+
- \u9700\u8981\u63D0\u4F9B\u54EA\u4E9B\u8F93\u5165
|
|
3566
|
+
- \u4F1A\u8FD4\u56DE\u4EC0\u4E48\u8F93\u51FA
|
|
3567
|
+
- \u6709\u54EA\u4E9B\u9650\u5236\u6216\u524D\u7F6E\u6761\u4EF6
|
|
3568
|
+
|
|
3569
|
+
## \u793A\u4F8B
|
|
3570
|
+
|
|
3571
|
+
**\u8F93\u5165\uFF1A**
|
|
3572
|
+
|
|
3573
|
+
\u793A\u4F8B\u8F93\u5165\u5185\u5BB9
|
|
3574
|
+
|
|
3575
|
+
**\u8F93\u51FA\uFF1A**
|
|
3576
|
+
|
|
3577
|
+
\u793A\u4F8B\u8F93\u51FA\u5185\u5BB9
|
|
3578
|
+
|
|
3579
|
+
## \u6CE8\u610F\u4E8B\u9879
|
|
3580
|
+
|
|
3581
|
+
- \u6CE8\u610F\u4E8B\u9879 1
|
|
3582
|
+
- \u6CE8\u610F\u4E8B\u9879 2
|
|
3583
|
+
`;
|
|
3584
|
+
var PKG_TEMPLATE = (name) => JSON.stringify({
|
|
3585
|
+
name,
|
|
3586
|
+
version: "1.0.0",
|
|
3587
|
+
description: "\u8BF7\u586B\u5199\u6280\u80FD\u63CF\u8FF0"
|
|
3588
|
+
}, null, 2) + "\n";
|
|
3589
|
+
async function skillInitAction(name, options) {
|
|
3590
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
3591
|
+
console.error("\u274C \u6280\u80FD\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u8FDE\u5B57\u7B26\uFF0C\u4F8B\u5982: my-skill");
|
|
3592
|
+
process.exit(EXIT2.VALIDATION);
|
|
3593
|
+
}
|
|
3594
|
+
const dir = path6.resolve(name);
|
|
3595
|
+
if (fs6.existsSync(dir)) {
|
|
3596
|
+
if (!options.force) {
|
|
3597
|
+
console.error(`\u274C \u76EE\u5F55\u5DF2\u5B58\u5728: ${dir}
|
|
3598
|
+
\u4F7F\u7528 --force \u8986\u76D6`);
|
|
3599
|
+
process.exit(EXIT2.VALIDATION);
|
|
3600
|
+
}
|
|
3601
|
+
} else {
|
|
3602
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
3603
|
+
}
|
|
3604
|
+
fs6.writeFileSync(path6.join(dir, "SKILL.md"), SKILL_MD_TEMPLATE(name), "utf-8");
|
|
3605
|
+
fs6.writeFileSync(path6.join(dir, "package.json"), PKG_TEMPLATE(name), "utf-8");
|
|
3606
|
+
console.log(`\u2705 \u6280\u80FD\u76EE\u5F55\u5DF2\u521B\u5EFA: ${dir}
|
|
3607
|
+
`);
|
|
3608
|
+
console.log(" \u{1F4C4} SKILL.md \u2014 \u586B\u5199\u6280\u80FD\u8BF4\u660E\u6587\u6863");
|
|
3609
|
+
console.log(" \u{1F4E6} package.json \u2014 \u586B\u5199 name / description\n");
|
|
3610
|
+
console.log("\u63A5\u4E0B\u6765\uFF1A");
|
|
3611
|
+
console.log(` 1. cd ${name}`);
|
|
3612
|
+
console.log(" 2. \u7F16\u8F91 SKILL.md \u548C package.json");
|
|
3613
|
+
console.log(" 3. ecl validate # \u53D1\u5E03\u524D\u6821\u9A8C");
|
|
3614
|
+
console.log(" 4. ecl publish # \u53D1\u5E03\u5230\u5E73\u53F0");
|
|
3615
|
+
console.log("\n\u521D\u59CB\u6821\u9A8C\uFF1A");
|
|
3616
|
+
const { errors, warnings } = validateSkillDir2(dir);
|
|
3491
3617
|
if (warnings.length) {
|
|
3492
|
-
|
|
3618
|
+
for (const w of warnings)
|
|
3619
|
+
console.log(` \u{1F7E1} ${w}`);
|
|
3493
3620
|
}
|
|
3494
3621
|
if (!errors.length) {
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
if (meta.name)
|
|
3498
|
-
console.log(`
|
|
3499
|
-
\u6280\u80FD\u540D\u79F0: ${meta.name}`);
|
|
3500
|
-
if (meta.description)
|
|
3501
|
-
console.log(`\u63CF\u8FF0: ${meta.description}`);
|
|
3502
|
-
}
|
|
3503
|
-
process.exit(errors.length ? 1 : 0);
|
|
3622
|
+
console.log(" \u2705 \u6A21\u677F\u7ED3\u6784\u5408\u6CD5\uFF0C\u586B\u597D\u5185\u5BB9\u5373\u53EF\u53D1\u5E03");
|
|
3623
|
+
}
|
|
3504
3624
|
}
|
|
3505
3625
|
|
|
3506
3626
|
// src/commands/skill.ts
|
|
3507
|
-
var
|
|
3508
|
-
var
|
|
3627
|
+
var fs7 = __toESM(require("fs"));
|
|
3628
|
+
var path7 = __toESM(require("path"));
|
|
3509
3629
|
var readline3 = __toESM(require("readline"));
|
|
3510
3630
|
function promptYN(question) {
|
|
3511
3631
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
3512
|
-
return new Promise((
|
|
3632
|
+
return new Promise((resolve5) => {
|
|
3513
3633
|
rl.question(question, (ans) => {
|
|
3514
3634
|
rl.close();
|
|
3515
|
-
|
|
3635
|
+
resolve5(ans.trim().toLowerCase() === "y" || ans.trim().toLowerCase() === "yes");
|
|
3516
3636
|
});
|
|
3517
3637
|
});
|
|
3518
3638
|
}
|
|
@@ -3571,12 +3691,12 @@ async function skillDownloadAction(id, options) {
|
|
|
3571
3691
|
await assertOk(res);
|
|
3572
3692
|
const buffer = Buffer.from(await res.arrayBuffer());
|
|
3573
3693
|
const outPath = options.out || `skill-${id}.zip`;
|
|
3574
|
-
const resolved =
|
|
3575
|
-
const dir =
|
|
3576
|
-
if (!
|
|
3577
|
-
|
|
3694
|
+
const resolved = path7.resolve(outPath);
|
|
3695
|
+
const dir = path7.dirname(resolved);
|
|
3696
|
+
if (!fs7.existsSync(dir)) {
|
|
3697
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
3578
3698
|
}
|
|
3579
|
-
|
|
3699
|
+
fs7.writeFileSync(resolved, buffer);
|
|
3580
3700
|
if (options.json) {
|
|
3581
3701
|
console.log(JSON.stringify({ success: true, path: resolved, size: buffer.length }));
|
|
3582
3702
|
return;
|
|
@@ -3615,7 +3735,7 @@ async function skillUseAction(id, options) {
|
|
|
3615
3735
|
async function skillSearchAction(keyword, options) {
|
|
3616
3736
|
if (!keyword?.trim()) {
|
|
3617
3737
|
console.error("\u274C \u8BF7\u63D0\u4F9B\u641C\u7D22\u5173\u952E\u8BCD");
|
|
3618
|
-
process.exit(
|
|
3738
|
+
process.exit(EXIT2.VALIDATION);
|
|
3619
3739
|
}
|
|
3620
3740
|
const apiKey = requireApiKey();
|
|
3621
3741
|
const parsed = parseInt(options.limit || "20", 10);
|
|
@@ -3653,7 +3773,7 @@ async function skillSearchAction(keyword, options) {
|
|
|
3653
3773
|
}
|
|
3654
3774
|
|
|
3655
3775
|
// src/commands/bounty.ts
|
|
3656
|
-
var
|
|
3776
|
+
var fs8 = __toESM(require("fs"));
|
|
3657
3777
|
async function bountyListAction(options) {
|
|
3658
3778
|
const apiKey = requireApiKey();
|
|
3659
3779
|
const status = options.status || "open";
|
|
@@ -3747,17 +3867,17 @@ async function bountySubmitAction(id, content, options) {
|
|
|
3747
3867
|
let body = content;
|
|
3748
3868
|
if (content.startsWith("@")) {
|
|
3749
3869
|
const filePath = content.slice(1);
|
|
3750
|
-
if (!
|
|
3870
|
+
if (!fs8.existsSync(filePath)) {
|
|
3751
3871
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
3752
3872
|
process.exit(1);
|
|
3753
3873
|
}
|
|
3754
|
-
const stat =
|
|
3874
|
+
const stat = fs8.statSync(filePath);
|
|
3755
3875
|
const MAX_SIZE = 512 * 1024;
|
|
3756
3876
|
if (stat.size > MAX_SIZE) {
|
|
3757
3877
|
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024)}KB\uFF09\uFF0C\u4E0A\u9650 512KB`);
|
|
3758
3878
|
process.exit(1);
|
|
3759
3879
|
}
|
|
3760
|
-
body =
|
|
3880
|
+
body = fs8.readFileSync(filePath, "utf-8");
|
|
3761
3881
|
}
|
|
3762
3882
|
if (!body.trim()) {
|
|
3763
3883
|
console.error("\u274C \u63D0\u4EA4\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A");
|
|
@@ -4273,7 +4393,7 @@ async function saasPolishAction(text, options) {
|
|
|
4273
4393
|
}
|
|
4274
4394
|
|
|
4275
4395
|
// src/commands/agent.ts
|
|
4276
|
-
var
|
|
4396
|
+
var fs9 = __toESM(require("fs"));
|
|
4277
4397
|
async function agentListAction(options) {
|
|
4278
4398
|
const apiKey = requireApiKey();
|
|
4279
4399
|
const parsed = parseInt(options.limit || "20", 10);
|
|
@@ -4310,17 +4430,17 @@ async function agentCallAction(username, intent, dataJson, options = {}) {
|
|
|
4310
4430
|
}
|
|
4311
4431
|
const body = { intent };
|
|
4312
4432
|
if (options.dataFile) {
|
|
4313
|
-
if (!
|
|
4433
|
+
if (!fs9.existsSync(options.dataFile)) {
|
|
4314
4434
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${options.dataFile}`);
|
|
4315
4435
|
process.exit(1);
|
|
4316
4436
|
}
|
|
4317
4437
|
const MAX_SIZE = 512 * 1024;
|
|
4318
|
-
const stat =
|
|
4438
|
+
const stat = fs9.statSync(options.dataFile);
|
|
4319
4439
|
if (stat.size > MAX_SIZE) {
|
|
4320
4440
|
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024)}KB\uFF09\uFF0C\u4E0A\u9650 512KB`);
|
|
4321
4441
|
process.exit(1);
|
|
4322
4442
|
}
|
|
4323
|
-
const raw =
|
|
4443
|
+
const raw = fs9.readFileSync(options.dataFile, "utf-8");
|
|
4324
4444
|
try {
|
|
4325
4445
|
body.data = JSON.parse(raw);
|
|
4326
4446
|
} catch {
|
|
@@ -4354,14 +4474,14 @@ async function agentCallAction(username, intent, dataJson, options = {}) {
|
|
|
4354
4474
|
}
|
|
4355
4475
|
|
|
4356
4476
|
// src/commands/forum.ts
|
|
4357
|
-
var
|
|
4477
|
+
var fs10 = __toESM(require("fs"));
|
|
4358
4478
|
var readline6 = __toESM(require("readline"));
|
|
4359
4479
|
function promptYN2(question) {
|
|
4360
4480
|
const rl = readline6.createInterface({ input: process.stdin, output: process.stdout });
|
|
4361
|
-
return new Promise((
|
|
4481
|
+
return new Promise((resolve5) => {
|
|
4362
4482
|
rl.question(question, (ans) => {
|
|
4363
4483
|
rl.close();
|
|
4364
|
-
|
|
4484
|
+
resolve5(ans.trim().toLowerCase() === "y" || ans.trim().toLowerCase() === "yes");
|
|
4365
4485
|
});
|
|
4366
4486
|
});
|
|
4367
4487
|
}
|
|
@@ -4420,11 +4540,11 @@ async function forumPostAction(title, filePath, options) {
|
|
|
4420
4540
|
if (options.content) {
|
|
4421
4541
|
content = options.content;
|
|
4422
4542
|
} else if (filePath) {
|
|
4423
|
-
if (!
|
|
4543
|
+
if (!fs10.existsSync(filePath)) {
|
|
4424
4544
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
4425
4545
|
process.exit(1);
|
|
4426
4546
|
}
|
|
4427
|
-
content =
|
|
4547
|
+
content = fs10.readFileSync(filePath, "utf-8");
|
|
4428
4548
|
} else {
|
|
4429
4549
|
console.error("\u274C \u8BF7\u63D0\u4F9B --content <text> \u6216 <file> \u53C2\u6570");
|
|
4430
4550
|
process.exit(1);
|
|
@@ -4498,8 +4618,8 @@ async function forumDeleteAction(slug, options) {
|
|
|
4498
4618
|
}
|
|
4499
4619
|
|
|
4500
4620
|
// src/commands/radio.ts
|
|
4501
|
-
var
|
|
4502
|
-
var
|
|
4621
|
+
var fs11 = __toESM(require("fs"));
|
|
4622
|
+
var path8 = __toESM(require("path"));
|
|
4503
4623
|
async function radioListAction(options) {
|
|
4504
4624
|
const apiKey = requireApiKey();
|
|
4505
4625
|
const res = await fetchWithRetry(`${BASE_URL}/api/radio/stations`, {
|
|
@@ -4592,20 +4712,20 @@ async function radioCreateAction(name, options) {
|
|
|
4592
4712
|
}
|
|
4593
4713
|
async function radioUploadAction(stationId, filePath, options) {
|
|
4594
4714
|
const apiKey = requireApiKey();
|
|
4595
|
-
if (!
|
|
4715
|
+
if (!fs11.existsSync(filePath)) {
|
|
4596
4716
|
console.error(`\u274C \u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
4597
4717
|
process.exit(1);
|
|
4598
4718
|
}
|
|
4599
4719
|
const MAX_SIZE = 5 * 1024 * 1024;
|
|
4600
|
-
const stat =
|
|
4720
|
+
const stat = fs11.statSync(filePath);
|
|
4601
4721
|
if (stat.size > MAX_SIZE) {
|
|
4602
4722
|
console.error(`\u274C \u6587\u4EF6\u8FC7\u5927\uFF08${Math.round(stat.size / 1024 / 1024 * 10) / 10}MB\uFF09\uFF0C\u4E0A\u9650 5MB`);
|
|
4603
4723
|
process.exit(1);
|
|
4604
4724
|
}
|
|
4605
|
-
const title = options.title ||
|
|
4725
|
+
const title = options.title || path8.basename(filePath, path8.extname(filePath));
|
|
4606
4726
|
const formData = new FormData();
|
|
4607
|
-
const blob = new Blob([
|
|
4608
|
-
formData.append("file", blob,
|
|
4727
|
+
const blob = new Blob([fs11.readFileSync(filePath)]);
|
|
4728
|
+
formData.append("file", blob, path8.basename(filePath));
|
|
4609
4729
|
formData.append("title", title);
|
|
4610
4730
|
if (options.artist)
|
|
4611
4731
|
formData.append("artist", options.artist);
|
|
@@ -4640,7 +4760,7 @@ async function radioUploadAction(stationId, filePath, options) {
|
|
|
4640
4760
|
|
|
4641
4761
|
// src/index.ts
|
|
4642
4762
|
var program2 = new Command();
|
|
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.
|
|
4763
|
+
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.7.1");
|
|
4644
4764
|
program2.command("login").description("\u767B\u5F55 EasyClaw Link\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").action(loginAction);
|
|
4645
4765
|
program2.command("logout").description("\u9000\u51FA\u767B\u5F55\uFF0C\u6E05\u9664\u672C\u5730 API Key").action(logoutAction);
|
|
4646
4766
|
program2.command("whoami").description("\u663E\u793A\u5F53\u524D\u767B\u5F55\u8D26\u53F7\u4FE1\u606F").option("--json", "JSON \u8F93\u51FA").action(() => whoamiAction());
|
|
@@ -4649,13 +4769,14 @@ program2.command("unread").description("\u67E5\u770B\u672A\u8BFB\u6D88\u606F/\u9
|
|
|
4649
4769
|
program2.command("stats").description("\u67E5\u770B\u5E73\u53F0\u7EDF\u8BA1\u6570\u636E").option("--json", "JSON \u8F93\u51FA").action((o) => statsAction(o));
|
|
4650
4770
|
program2.command("leaderboard").description("\u58F0\u671B\u6392\u884C\u699C").option("--json", "JSON \u8F93\u51FA").option("--limit <n>", "\u6761\u6570\u9650\u5236", "20").action((o) => leaderboardAction(o));
|
|
4651
4771
|
var profileCmd = program2.command("profile").description("\u4E2A\u4EBA\u8D44\u6599\u64CD\u4F5C");
|
|
4652
|
-
profileCmd.command("update").description("\u66F4\u65B0\u4E2A\u4EBA\u8D44\u6599").option("--webhook-url <url>", "Webhook \u5730\u5740\uFF08https://...\uFF0C\u7A7A\u5B57\u7B26\u4E32\u53EF\u6E05\u9664\uFF09").option("--owner-email <email>", "\u90AE\u7BB1\u5730\u5740\uFF08\u7A7A\u5B57\u7B26\u4E32\u53EF\u6E05\u9664\uFF09").option("--json", "JSON \u8F93\u51FA").action((o) => profileUpdateAction(o));
|
|
4772
|
+
profileCmd.command("update").description("\u66F4\u65B0\u4E2A\u4EBA\u8D44\u6599").option("--display-name <name>", "\u663E\u793A\u540D\u79F0\uFF08\u6700\u591A50\u5B57\uFF0C\u7A7A\u5B57\u7B26\u4E32\u53EF\u6E05\u9664\uFF09").option("--webhook-url <url>", "Webhook \u5730\u5740\uFF08https://...\uFF0C\u7A7A\u5B57\u7B26\u4E32\u53EF\u6E05\u9664\uFF09").option("--owner-email <email>", "\u90AE\u7BB1\u5730\u5740\uFF08\u7A7A\u5B57\u7B26\u4E32\u53EF\u6E05\u9664\uFF09").option("--json", "JSON \u8F93\u51FA").action((o) => profileUpdateAction(o));
|
|
4653
4773
|
var notifCmd = program2.command("notifications").description("\u67E5\u770B\u548C\u7BA1\u7406\u901A\u77E5");
|
|
4654
4774
|
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));
|
|
4655
4775
|
notifCmd.command("read").description("\u6807\u8BB0\u6240\u6709\u901A\u77E5\u4E3A\u5DF2\u8BFB").option("--json", "JSON \u8F93\u51FA").action((o) => notificationsReadAction(o));
|
|
4656
4776
|
program2.command("publish [dir]").description("\u53D1\u5E03\u6216\u66F4\u65B0\u6280\u80FD").option("--id <id>", "\u66F4\u65B0\u6307\u5B9A ID \u7684\u6280\u80FD").option("--slug <slug>", "\u901A\u8FC7 slug \u66F4\u65B0").action(publishAction);
|
|
4657
4777
|
program2.command("list").description("\u5217\u51FA\u4F60\u53D1\u5E03\u7684\u6240\u6709\u6280\u80FD").option("--json", "JSON \u8F93\u51FA").action(() => listAction());
|
|
4658
|
-
program2.command("validate [dir]").description("\u672C\u5730\u6821\u9A8C\u6280\u80FD\u76EE\u5F55\u683C\u5F0F").action((dir) => validateAction(dir));
|
|
4778
|
+
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));
|
|
4779
|
+
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));
|
|
4659
4780
|
var skillCmd = program2.command("skill").description("\u6280\u80FD\u8BE6\u7EC6\u64CD\u4F5C");
|
|
4660
4781
|
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));
|
|
4661
4782
|
skillCmd.command("view <id>").description("\u67E5\u770B\u6280\u80FD\u8BE6\u60C5").option("--json", "JSON \u8F93\u51FA").action((id, o) => skillViewAction(id, o));
|