bfi-cli 0.1.96 → 0.1.98
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/THIRD-PARTY-LICENSES.md +293 -0
- package/dist/_chunks/libs/@clack/core.mjs +58 -63
- package/dist/_chunks/libs/@clack/prompts.mjs +45 -46
- package/dist/_chunks/libs/@kwsites/file-exists.mjs +9 -10
- package/dist/_chunks/libs/simple-git.mjs +2 -4
- package/dist/_chunks/rolldown-runtime.mjs +1 -1
- package/dist/_chunks/skills.mjs +3 -6
- package/dist/cli.d.mts +1 -1
- package/dist/cli.mjs +100 -136
- package/dist/mcp-codesearch/main.d.mts +1 -1
- package/dist/mcp-codesearch/main.mjs +2 -0
- package/dist/mcp-db/main.d.mts +1 -1
- package/dist/mcp-db/main.mjs +12 -2
- package/dist/mcp-weknora/main.d.mts +1 -1
- package/dist/mcp-weknora/main.mjs +41 -158
- package/package.json +4 -2
- package/dist/THIRD-PARTY-LICENSES.md.gz +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -451,10 +451,8 @@ async function searchMultiselect(options) {
|
|
|
451
451
|
}
|
|
452
452
|
if (key.name === "space") {
|
|
453
453
|
const item = filtered[cursor];
|
|
454
|
-
if (item)
|
|
455
|
-
|
|
456
|
-
else selected.add(item.value);
|
|
457
|
-
}
|
|
454
|
+
if (item) if (selected.has(item.value)) selected.delete(item.value);
|
|
455
|
+
else selected.add(item.value);
|
|
458
456
|
render();
|
|
459
457
|
return;
|
|
460
458
|
}
|
|
@@ -514,14 +512,12 @@ var SkillHubAPI = class {
|
|
|
514
512
|
if (url.protocol === "https:") requestOptions.rejectUnauthorized = this.rejectUnauthorized;
|
|
515
513
|
let bodyStr;
|
|
516
514
|
let bodyBuf;
|
|
517
|
-
if (options.body !== void 0)
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
bodyStr = JSON.stringify(options.body);
|
|
524
|
-
}
|
|
515
|
+
if (options.body !== void 0) if (options.body instanceof Buffer) bodyBuf = options.body;
|
|
516
|
+
else if (typeof options.body === "string") bodyStr = options.body;
|
|
517
|
+
else if (typeof FormData !== "undefined" && options.body instanceof FormData) return this.fetchRequest(url, requestOptions, options.body);
|
|
518
|
+
else {
|
|
519
|
+
requestOptions.headers["Content-Type"] = "application/json";
|
|
520
|
+
bodyStr = JSON.stringify(options.body);
|
|
525
521
|
}
|
|
526
522
|
return new Promise((resolve, reject) => {
|
|
527
523
|
const req = (url.protocol === "https:" ? https : http).request(url, requestOptions, (res) => {
|
|
@@ -1300,12 +1296,10 @@ async function isDirEntryOrSymlinkToDir(entry, entryPath) {
|
|
|
1300
1296
|
}
|
|
1301
1297
|
}
|
|
1302
1298
|
function getCanonicalSkillsDir(global, cwd) {
|
|
1303
|
-
|
|
1304
|
-
return join(baseDir, AGENTS_DIR, SKILLS_SUBDIR);
|
|
1299
|
+
return join(global ? homedir() : cwd || process.cwd(), AGENTS_DIR, SKILLS_SUBDIR);
|
|
1305
1300
|
}
|
|
1306
1301
|
function getEveSubagentSkillsDir(subagent, cwd) {
|
|
1307
|
-
|
|
1308
|
-
return join(baseDir, EVE_SUBAGENTS_DIR, sanitizeName(subagent), "skills");
|
|
1302
|
+
return join(cwd || process.cwd(), EVE_SUBAGENTS_DIR, sanitizeName(subagent), "skills");
|
|
1309
1303
|
}
|
|
1310
1304
|
function getAgentBaseDir(agentType, global, cwd, eveSubagent) {
|
|
1311
1305
|
if (isUniversalAgent(agentType)) return getCanonicalSkillsDir(global, cwd);
|
|
@@ -1383,8 +1377,7 @@ async function resolveParentSymlinks(path) {
|
|
|
1383
1377
|
const dir = dirname(resolved);
|
|
1384
1378
|
const base = basename(resolved);
|
|
1385
1379
|
try {
|
|
1386
|
-
|
|
1387
|
-
return join(realDir, base);
|
|
1380
|
+
return join(await realpath(dir), base);
|
|
1388
1381
|
} catch {
|
|
1389
1382
|
return resolved;
|
|
1390
1383
|
}
|
|
@@ -1408,8 +1401,7 @@ async function createSymlink(target, linkPath) {
|
|
|
1408
1401
|
}
|
|
1409
1402
|
const linkDir = dirname(linkPath);
|
|
1410
1403
|
await mkdir(linkDir, { recursive: true });
|
|
1411
|
-
const
|
|
1412
|
-
const relativePath = relative(realLinkDir, target);
|
|
1404
|
+
const relativePath = relative(await resolveParentSymlinks(linkDir), target);
|
|
1413
1405
|
const symlinkType = platform() === "win32" ? "junction" : void 0;
|
|
1414
1406
|
await symlink(symlinkType === "junction" ? resolvedTarget : relativePath, linkPath, symlinkType);
|
|
1415
1407
|
return true;
|
|
@@ -1478,8 +1470,7 @@ async function installSkillForAgent(skill, agentType, options = {}) {
|
|
|
1478
1470
|
mode: "symlink"
|
|
1479
1471
|
};
|
|
1480
1472
|
if (!isGlobal && !isUniversalAgent(agentType)) {
|
|
1481
|
-
|
|
1482
|
-
if (!existsSync(agentRootDir) && agentType !== "claude-code") return {
|
|
1473
|
+
if (!existsSync(join(cwd, agents[agentType].skillsDir.split("/")[0])) && agentType !== "claude-code") return {
|
|
1483
1474
|
success: true,
|
|
1484
1475
|
path: canonicalDir,
|
|
1485
1476
|
canonicalPath: canonicalDir,
|
|
@@ -1553,8 +1544,7 @@ async function copyDirectory(src, dest, agentType) {
|
|
|
1553
1544
|
dereference: true,
|
|
1554
1545
|
recursive: true
|
|
1555
1546
|
});
|
|
1556
|
-
|
|
1557
|
-
await chmod(destPath, sourceStats.mode & 511);
|
|
1547
|
+
await chmod(destPath, (await stat(srcPath)).mode & 511);
|
|
1558
1548
|
} catch (err) {
|
|
1559
1549
|
if (err instanceof Error && "code" in err && err.code === "ENOENT" && entry.isSymbolicLink()) console.warn(`Skipping broken symlink: ${srcPath}`);
|
|
1560
1550
|
else throw err;
|
|
@@ -1771,8 +1761,7 @@ async function installBlobSkillForAgent(skill, agentType, options = {}) {
|
|
|
1771
1761
|
mode: "symlink"
|
|
1772
1762
|
};
|
|
1773
1763
|
if (!isGlobal && !isUniversalAgent(agentType)) {
|
|
1774
|
-
|
|
1775
|
-
if (!existsSync(agentRootDir)) return {
|
|
1764
|
+
if (!existsSync(join(cwd, agents[agentType].skillsDir.split("/")[0]))) return {
|
|
1776
1765
|
success: true,
|
|
1777
1766
|
path: canonicalDir,
|
|
1778
1767
|
canonicalPath: canonicalDir,
|
|
@@ -2000,7 +1989,7 @@ var ProviderRegistryImpl = class {
|
|
|
2000
1989
|
};
|
|
2001
1990
|
new ProviderRegistryImpl();
|
|
2002
1991
|
const DISCOVERY_SCHEMA_V2 = "https://schemas.agentskills.io/discovery/0.2.0/schema.json";
|
|
2003
|
-
const MAX_ARCHIVE_UNPACKED_BYTES =
|
|
1992
|
+
const MAX_ARCHIVE_UNPACKED_BYTES = 50 * 1024 * 1024;
|
|
2004
1993
|
const MAX_ARCHIVE_FILES = 1e3;
|
|
2005
1994
|
var WellKnownProvider = class {
|
|
2006
1995
|
id = "well-known";
|
|
@@ -3153,23 +3142,22 @@ async function handleWellKnownSkills(source, url, options, spinner) {
|
|
|
3153
3142
|
const installedAgents = await detectInstalledAgents();
|
|
3154
3143
|
const totalAgents = Object.keys(agents).length;
|
|
3155
3144
|
spinner.stop(`${totalAgents} agents`);
|
|
3156
|
-
if (installedAgents.length === 0) {
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
process.exit(0);
|
|
3169
|
-
}
|
|
3170
|
-
targetAgents = selected;
|
|
3145
|
+
if (installedAgents.length === 0) if (options.yes) {
|
|
3146
|
+
targetAgents = validAgents;
|
|
3147
|
+
log.info("正在安装到全部 Agent");
|
|
3148
|
+
} else {
|
|
3149
|
+
log.info("请选择要安装技能的 Agent");
|
|
3150
|
+
const selected = await promptForAgents("请选择要安装到的 Agent:", Object.entries(agents).map(([key, config]) => ({
|
|
3151
|
+
value: key,
|
|
3152
|
+
label: config.displayName
|
|
3153
|
+
})));
|
|
3154
|
+
if (isCancel(selected)) {
|
|
3155
|
+
cancel("安装已取消");
|
|
3156
|
+
process.exit(0);
|
|
3171
3157
|
}
|
|
3172
|
-
|
|
3158
|
+
targetAgents = selected;
|
|
3159
|
+
}
|
|
3160
|
+
else if (installedAgents.length === 1 || options.yes) {
|
|
3173
3161
|
targetAgents = ensureUniversalAgents(installedAgents);
|
|
3174
3162
|
if (installedAgents.length === 1) {
|
|
3175
3163
|
const firstAgent = installedAgents[0];
|
|
@@ -3404,14 +3392,13 @@ async function installFromSkillHub(parsed, options, spinner) {
|
|
|
3404
3392
|
slug = hit.slug;
|
|
3405
3393
|
log.info(`自动选择:${import_picocolors.default.cyan(`@${namespace}/${slug}`)} — ${hit.description || hit.name}`);
|
|
3406
3394
|
} else {
|
|
3407
|
-
const choices = hits.map((h, idx) => ({
|
|
3408
|
-
value: idx,
|
|
3409
|
-
label: `@${h.namespace}/${h.slug}`,
|
|
3410
|
-
hint: h.description || h.name
|
|
3411
|
-
}));
|
|
3412
3395
|
const idx = await select({
|
|
3413
3396
|
message: "匹配到多个技能 — 请选择一个",
|
|
3414
|
-
options:
|
|
3397
|
+
options: hits.map((h, idx) => ({
|
|
3398
|
+
value: idx,
|
|
3399
|
+
label: `@${h.namespace}/${h.slug}`,
|
|
3400
|
+
hint: h.description || h.name
|
|
3401
|
+
}))
|
|
3415
3402
|
});
|
|
3416
3403
|
if (isCancel(idx)) {
|
|
3417
3404
|
cancel("安装已取消");
|
|
@@ -3438,8 +3425,7 @@ async function installFromSkillHub(parsed, options, spinner) {
|
|
|
3438
3425
|
}
|
|
3439
3426
|
const meta = metadata;
|
|
3440
3427
|
spinner.stop(`Skill: ${import_picocolors.default.cyan(`@${namespace}/${slug}`)}${meta.description ? ` — ${import_picocolors.default.dim(meta.description)}` : ""}`);
|
|
3441
|
-
|
|
3442
|
-
tempDir = join(tmpRoot, `.skillhub-skillshub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
|
|
3428
|
+
tempDir = join(tmpdir(), `.skillhub-skillshub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
|
|
3443
3429
|
mkdirSync(tempDir, { recursive: true });
|
|
3444
3430
|
const zipPath = join(tempDir, "skill.zip");
|
|
3445
3431
|
spinner.start("正在下载技能...");
|
|
@@ -3775,24 +3761,23 @@ async function runAdd(args, options = {}) {
|
|
|
3775
3761
|
}
|
|
3776
3762
|
targetAgents = selected;
|
|
3777
3763
|
}
|
|
3778
|
-
} else if (installedAgents.length === 0) {
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
process.exit(0);
|
|
3792
|
-
}
|
|
3793
|
-
targetAgents = selected;
|
|
3764
|
+
} else if (installedAgents.length === 0) if (options.yes) {
|
|
3765
|
+
targetAgents = validAgents;
|
|
3766
|
+
log.info("正在安装到全部 Agent");
|
|
3767
|
+
} else {
|
|
3768
|
+
log.info("请选择要安装技能的 Agent");
|
|
3769
|
+
const selected = await promptForAgents("请选择要安装到的 Agent:", Object.entries(agents).filter(([key]) => key !== "eve").map(([key, config]) => ({
|
|
3770
|
+
value: key,
|
|
3771
|
+
label: config.displayName
|
|
3772
|
+
})));
|
|
3773
|
+
if (isCancel(selected)) {
|
|
3774
|
+
cancel("安装已取消");
|
|
3775
|
+
await cleanup(tempDir);
|
|
3776
|
+
process.exit(0);
|
|
3794
3777
|
}
|
|
3795
|
-
|
|
3778
|
+
targetAgents = selected;
|
|
3779
|
+
}
|
|
3780
|
+
else if (installedAgents.length === 1 || options.yes) {
|
|
3796
3781
|
targetAgents = ensureUniversalAgents(installedAgents);
|
|
3797
3782
|
if (installedAgents.length === 1) {
|
|
3798
3783
|
const firstAgent = installedAgents[0];
|
|
@@ -3814,18 +3799,17 @@ async function runAdd(args, options = {}) {
|
|
|
3814
3799
|
const availableSubagents = getEveSubagents(process.cwd());
|
|
3815
3800
|
if (options.subagent && options.subagent.length > 0) eveSubagentTargets = options.subagent.map((s) => s === "root" || s === "." ? void 0 : s);
|
|
3816
3801
|
else if (availableSubagents.length > 0 && !options.yes) {
|
|
3817
|
-
const subagentChoices = [{
|
|
3818
|
-
value: "",
|
|
3819
|
-
label: "根 Agent",
|
|
3820
|
-
hint: "agent/skills"
|
|
3821
|
-
}, ...availableSubagents.map((name) => ({
|
|
3822
|
-
value: name,
|
|
3823
|
-
label: name,
|
|
3824
|
-
hint: `agent/subagents/${name}/skills`
|
|
3825
|
-
}))];
|
|
3826
3802
|
const selectedSubagents = await multiselect$1({
|
|
3827
3803
|
message: "Eve 技能安装位置?",
|
|
3828
|
-
options:
|
|
3804
|
+
options: [{
|
|
3805
|
+
value: "",
|
|
3806
|
+
label: "根 Agent",
|
|
3807
|
+
hint: "agent/skills"
|
|
3808
|
+
}, ...availableSubagents.map((name) => ({
|
|
3809
|
+
value: name,
|
|
3810
|
+
label: name,
|
|
3811
|
+
hint: `agent/subagents/${name}/skills`
|
|
3812
|
+
}))],
|
|
3829
3813
|
initialValues: [""],
|
|
3830
3814
|
required: true
|
|
3831
3815
|
});
|
|
@@ -4003,11 +3987,9 @@ async function runAdd(args, options = {}) {
|
|
|
4003
3987
|
const normalizedSource = getOwnerRepo(parsed);
|
|
4004
3988
|
const lockSource = getLockSource(parsed.url, normalizedSource);
|
|
4005
3989
|
const projectLockSourceUrl = getProjectLockSourceUrl(parsed.type, parsed.url);
|
|
4006
|
-
if (normalizedSource) {
|
|
4007
|
-
if (
|
|
4008
|
-
|
|
4009
|
-
} else selectedSkills.map((s) => s.name).join(","), targetAgents.join(","), { ...installGlobally && { global: "1" } }, JSON.stringify(skillFiles), options.metadata;
|
|
4010
|
-
}
|
|
3990
|
+
if (normalizedSource) if (parseOwnerRepo(normalizedSource)) {
|
|
3991
|
+
if (await repoPrivacyPromise === false) selectedSkills.map((s) => s.name).join(","), targetAgents.join(","), { ...installGlobally && { global: "1" } }, JSON.stringify(skillFiles), options.metadata;
|
|
3992
|
+
} else selectedSkills.map((s) => s.name).join(","), targetAgents.join(","), { ...installGlobally && { global: "1" } }, JSON.stringify(skillFiles), options.metadata;
|
|
4011
3993
|
if (successful.length > 0 && installGlobally && (normalizedSource || parsed.type === "skillhub")) {
|
|
4012
3994
|
const successfulSkillNames = new Set(successful.map((r) => r.skill));
|
|
4013
3995
|
let cachedTree;
|
|
@@ -4024,8 +4006,7 @@ async function runAdd(args, options = {}) {
|
|
|
4024
4006
|
const hash = getSkillFolderHashFromTree(cachedTree, skillPathValue);
|
|
4025
4007
|
if (hash) skillFolderHash = hash;
|
|
4026
4008
|
} else if (skillPathValue && tempDir) {
|
|
4027
|
-
const
|
|
4028
|
-
const hash = await computeSkillFolderHash(skillDir);
|
|
4009
|
+
const hash = await computeSkillFolderHash(join(tempDir, dirname(skillPathValue)));
|
|
4029
4010
|
if (hash) skillFolderHash = hash;
|
|
4030
4011
|
}
|
|
4031
4012
|
await addSkillToLock(skill.name, {
|
|
@@ -4069,13 +4050,11 @@ async function runAdd(args, options = {}) {
|
|
|
4069
4050
|
const skillResults = bySkill.get(r.skill) || [];
|
|
4070
4051
|
skillResults.push(r);
|
|
4071
4052
|
bySkill.set(r.skill, skillResults);
|
|
4072
|
-
if (skillResults.length === 1) {
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
} else ungroupedResults.push(r);
|
|
4078
|
-
}
|
|
4053
|
+
if (skillResults.length === 1) if (r.pluginName) {
|
|
4054
|
+
const group = r.pluginName;
|
|
4055
|
+
if (!groupedResults[group]) groupedResults[group] = [];
|
|
4056
|
+
groupedResults[group].push(r);
|
|
4057
|
+
} else ungroupedResults.push(r);
|
|
4079
4058
|
}
|
|
4080
4059
|
const skillCount = bySkill.size;
|
|
4081
4060
|
const symlinkFailures = successful.filter((r) => r.mode === "symlink" && r.symlinkFailed);
|
|
@@ -4771,15 +4750,12 @@ async function removeCommand(skillNames, options) {
|
|
|
4771
4750
|
}
|
|
4772
4751
|
const remainingAgents = (await detectInstalledAgents()).filter((a) => !targetAgents.includes(a));
|
|
4773
4752
|
let isStillUsed = false;
|
|
4774
|
-
for (const agentKey of remainingAgents) {
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
isStillUsed = true;
|
|
4781
|
-
break;
|
|
4782
|
-
}
|
|
4753
|
+
for (const agentKey of remainingAgents) if (await lstat(getInstallPath(skillName, agentKey, {
|
|
4754
|
+
global: isGlobal,
|
|
4755
|
+
cwd
|
|
4756
|
+
})).catch(() => null)) {
|
|
4757
|
+
isStillUsed = true;
|
|
4758
|
+
break;
|
|
4783
4759
|
}
|
|
4784
4760
|
if (!isStillUsed) await rm(canonicalPath, {
|
|
4785
4761
|
recursive: true,
|
|
@@ -4919,14 +4895,12 @@ function parseUpdateOptions(args) {
|
|
|
4919
4895
|
}
|
|
4920
4896
|
function hasProjectSkills(cwd) {
|
|
4921
4897
|
const dir = cwd || process.cwd();
|
|
4922
|
-
|
|
4923
|
-
if (existsSync(lockPath)) return true;
|
|
4898
|
+
if (existsSync(join(dir, "skills-lock.json"))) return true;
|
|
4924
4899
|
const skillsDir = join(dir, ".agents", "skills");
|
|
4925
4900
|
try {
|
|
4926
4901
|
const entries = readdirSync(skillsDir, { withFileTypes: true });
|
|
4927
4902
|
for (const entry of entries) if (entry.isDirectory()) {
|
|
4928
|
-
|
|
4929
|
-
if (existsSync(skillMd)) return true;
|
|
4903
|
+
if (existsSync(join(skillsDir, entry.name, "SKILL.md"))) return true;
|
|
4930
4904
|
}
|
|
4931
4905
|
} catch {}
|
|
4932
4906
|
return false;
|
|
@@ -5350,8 +5324,7 @@ async function updateProjectSkills(options = {}) {
|
|
|
5350
5324
|
try {
|
|
5351
5325
|
tempDir = await cloneRepo(sourceUrl, ref);
|
|
5352
5326
|
const discoveredPaths = (await discoverSkills(tempDir)).map((s) => {
|
|
5353
|
-
|
|
5354
|
-
return join(relPath, "SKILL.md").split(sep).join("/");
|
|
5327
|
+
return join(relative(tempDir, s.path), "SKILL.md").split(sep).join("/");
|
|
5355
5328
|
});
|
|
5356
5329
|
deletedSkills = await checkAndPromptForDeletions(source, allLockedForSource, localLock.skills, false, options, discoveredPaths);
|
|
5357
5330
|
} catch (error) {
|
|
@@ -6285,8 +6258,8 @@ const DIM$5 = "\x1B[38;5;102m";
|
|
|
6285
6258
|
const TEXT$4 = "\x1B[38;5;145m";
|
|
6286
6259
|
function formatFileSize(bytes) {
|
|
6287
6260
|
if (bytes < 1024) return `${bytes} B`;
|
|
6288
|
-
if (bytes <
|
|
6289
|
-
return `${(bytes /
|
|
6261
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
6262
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
6290
6263
|
}
|
|
6291
6264
|
async function runDocs(args, globalOpts) {
|
|
6292
6265
|
switch (args[0]) {
|
|
@@ -6550,8 +6523,7 @@ async function publishFromDir(positionalArgs, api, namespace, visibility) {
|
|
|
6550
6523
|
console.log("需要包含 frontmatter(name, description)的 SKILL.md 文件。");
|
|
6551
6524
|
process.exit(1);
|
|
6552
6525
|
}
|
|
6553
|
-
const
|
|
6554
|
-
const { data: frontmatter } = parseFrontmatter(skillMdContent);
|
|
6526
|
+
const { data: frontmatter } = parseFrontmatter(fs.readFileSync(skillMdPath, "utf-8"));
|
|
6555
6527
|
const skillName = frontmatter.name || path$1.basename(resolvedDir);
|
|
6556
6528
|
console.log(`${DIM$4}正在从目录发布技能...${RESET$4}`);
|
|
6557
6529
|
console.log(` ${BOLD$2}名称:${RESET$4} ${TEXT$3}${skillName}${RESET$4}`);
|
|
@@ -6598,8 +6570,7 @@ async function publishFromZip(positionalArgs, api, namespace, visibility) {
|
|
|
6598
6570
|
}
|
|
6599
6571
|
const skillDir = path$1.dirname(skillMdPath);
|
|
6600
6572
|
console.log(` ${GREEN$3}在 ${path$1.relative(tmpDir, skillDir) || "."} 中找到 SKILL.md${RESET$4}`);
|
|
6601
|
-
const
|
|
6602
|
-
const { data: frontmatter } = parseFrontmatter(skillMdContent);
|
|
6573
|
+
const { data: frontmatter } = parseFrontmatter(fs.readFileSync(skillMdPath, "utf-8"));
|
|
6603
6574
|
const skillName = frontmatter.name || path$1.basename(skillDir);
|
|
6604
6575
|
console.log(` ${BOLD$2}名称:${RESET$4} ${TEXT$3}${skillName}${RESET$4}`);
|
|
6605
6576
|
console.log(` ${BOLD$2}命名空间:${RESET$4} ${TEXT$3}${namespace}${RESET$4}`);
|
|
@@ -6769,8 +6740,8 @@ function findSkillMd(dir) {
|
|
|
6769
6740
|
}
|
|
6770
6741
|
function formatSize(bytes) {
|
|
6771
6742
|
if (bytes < 1024) return `${bytes} B`;
|
|
6772
|
-
if (bytes <
|
|
6773
|
-
return `${(bytes /
|
|
6743
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
6744
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
6774
6745
|
}
|
|
6775
6746
|
function truncate(text, maxLen) {
|
|
6776
6747
|
if (text.length <= maxLen) return text;
|
|
@@ -7055,8 +7026,7 @@ function printPackageHelp() {
|
|
|
7055
7026
|
console.log();
|
|
7056
7027
|
}
|
|
7057
7028
|
async function handleLocalList(args, globalOpts) {
|
|
7058
|
-
const
|
|
7059
|
-
const lock = loadLockfile(cwd);
|
|
7029
|
+
const lock = loadLockfile(getWorkdir(globalOpts, args));
|
|
7060
7030
|
args.includes("-g") || args.includes("--global");
|
|
7061
7031
|
const pkgs = lock.packages || {};
|
|
7062
7032
|
const entries = Object.entries(pkgs);
|
|
@@ -7162,7 +7132,6 @@ async function handleInstall(args, api, globalOpts) {
|
|
|
7162
7132
|
console.error(`${RED$1}获取包信息失败:${error.message}${RESET$3}`);
|
|
7163
7133
|
process.exit(1);
|
|
7164
7134
|
}
|
|
7165
|
-
if (pkgInfo.kind === "PLUGIN") throw new Error("这是完整插件,不是技能组合;请使用 --as plugin --agent <目标Agent> 安装,插件可能包含 MCP 和 Hooks。");
|
|
7166
7135
|
const skills = pkgInfo.skills || [];
|
|
7167
7136
|
if (skills.length === 0) {
|
|
7168
7137
|
console.log(`${YELLOW$1}包中没有可独立安装的技能。${RESET$3}`);
|
|
@@ -7254,18 +7223,17 @@ async function handleInstall(args, api, globalOpts) {
|
|
|
7254
7223
|
if (targetAgents.includes("eve")) {
|
|
7255
7224
|
const availableSubagents = getEveSubagents(process.cwd());
|
|
7256
7225
|
if (availableSubagents.length > 0) {
|
|
7257
|
-
const subagentChoices = [{
|
|
7258
|
-
value: "",
|
|
7259
|
-
label: "根 Agent",
|
|
7260
|
-
hint: "agent/skills"
|
|
7261
|
-
}, ...availableSubagents.map((name) => ({
|
|
7262
|
-
value: name,
|
|
7263
|
-
label: name,
|
|
7264
|
-
hint: `agent/subagents/${name}/skills`
|
|
7265
|
-
}))];
|
|
7266
7226
|
const selectedSubagents = await multiselect$1({
|
|
7267
7227
|
message: "Eve 技能安装位置?",
|
|
7268
|
-
options:
|
|
7228
|
+
options: [{
|
|
7229
|
+
value: "",
|
|
7230
|
+
label: "根 Agent",
|
|
7231
|
+
hint: "agent/skills"
|
|
7232
|
+
}, ...availableSubagents.map((name) => ({
|
|
7233
|
+
value: name,
|
|
7234
|
+
label: name,
|
|
7235
|
+
hint: `agent/subagents/${name}/skills`
|
|
7236
|
+
}))],
|
|
7269
7237
|
initialValues: [""],
|
|
7270
7238
|
required: true
|
|
7271
7239
|
});
|
|
@@ -7460,8 +7428,7 @@ async function handleUninstall(args, globalOpts) {
|
|
|
7460
7428
|
}
|
|
7461
7429
|
async function handleUpdate(args, api, globalOpts) {
|
|
7462
7430
|
const pkgRef = args[0];
|
|
7463
|
-
const
|
|
7464
|
-
const lock = loadLockfile(cwd);
|
|
7431
|
+
const lock = loadLockfile(getWorkdir(globalOpts, args));
|
|
7465
7432
|
let packagesToUpdate = [];
|
|
7466
7433
|
const pkgs = lock.packages || {};
|
|
7467
7434
|
if (pkgRef) {
|
|
@@ -7485,9 +7452,7 @@ async function handleUpdate(args, api, globalOpts) {
|
|
|
7485
7452
|
console.log(`${DIM$3}正在更新 ${packagesToUpdate.length} 个包...${RESET$3}`);
|
|
7486
7453
|
for (const pkg of packagesToUpdate) try {
|
|
7487
7454
|
const pkgInfo = await api.getPackage(pkg.namespace, pkg.slug);
|
|
7488
|
-
const
|
|
7489
|
-
if (info.kind === "PLUGIN") throw new Error("这是完整插件,请使用 --as plugin --agent <目标Agent> 更新;不会按技能组合安装。");
|
|
7490
|
-
const skills = info.skills || [];
|
|
7455
|
+
const skills = (pkgInfo.data || pkgInfo).skills || [];
|
|
7491
7456
|
console.log(` ${DIM$3}更新 @${pkg.namespace}/${pkg.slug}(${skills.length} 个技能)...${RESET$3}`);
|
|
7492
7457
|
for (const skill of skills) {
|
|
7493
7458
|
const skillRef = skill.namespace ? `@${skill.namespace}/${skill.slug}` : skill.slug;
|
|
@@ -9883,7 +9848,7 @@ function runInit(args) {
|
|
|
9883
9848
|
return;
|
|
9884
9849
|
}
|
|
9885
9850
|
if (hasName) mkdirSync(skillDir, { recursive: true });
|
|
9886
|
-
|
|
9851
|
+
writeFileSync(skillFile, `---
|
|
9887
9852
|
name: ${skillName}
|
|
9888
9853
|
description: A brief description of what this skill does
|
|
9889
9854
|
---
|
|
@@ -9901,8 +9866,7 @@ Describe when this skill should be used.
|
|
|
9901
9866
|
1. First step
|
|
9902
9867
|
2. Second step
|
|
9903
9868
|
3. Additional steps as needed
|
|
9904
|
-
|
|
9905
|
-
writeFileSync(skillFile, skillContent);
|
|
9869
|
+
`);
|
|
9906
9870
|
console.log(`${TEXT}已初始化技能:${DIM}${skillName}${RESET}`);
|
|
9907
9871
|
console.log();
|
|
9908
9872
|
console.log(`${DIM}已创建:${RESET}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {}
|
|
1
|
+
export { };
|
|
@@ -3,6 +3,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
|
3
3
|
import { CallToolRequestSchema, CallToolResultSchema, ListToolsRequestSchema, ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
4
4
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
5
5
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
6
|
+
import JSONbig from "json-bigint";
|
|
6
7
|
import fs from "node:fs";
|
|
7
8
|
import path from "node:path";
|
|
8
9
|
import os from "node:os";
|
|
@@ -90,6 +91,7 @@ function loadGlobalConfig() {
|
|
|
90
91
|
}
|
|
91
92
|
return null;
|
|
92
93
|
}
|
|
94
|
+
JSONbig({ storeAsString: true });
|
|
93
95
|
function resolveApiBase() {
|
|
94
96
|
return process.env.BFI_API_BASE || "https://bfi.yyuap.com/bfi-api";
|
|
95
97
|
}
|
package/dist/mcp-db/main.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {}
|
|
1
|
+
export { };
|
package/dist/mcp-db/main.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import mysql from "mysql2/promise";
|
|
5
|
+
import JSONbig from "json-bigint";
|
|
5
6
|
import fs from "node:fs";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
import os from "node:os";
|
|
@@ -98,7 +99,9 @@ async function directExecute(dsn, sql, maxRows = DEFAULT_MAX_ROWS) {
|
|
|
98
99
|
try {
|
|
99
100
|
conn = await mysql.createConnection({
|
|
100
101
|
uri: dsn,
|
|
101
|
-
connectTimeout: 8e3
|
|
102
|
+
connectTimeout: 8e3,
|
|
103
|
+
supportBigNumbers: true,
|
|
104
|
+
bigNumberStrings: true
|
|
102
105
|
});
|
|
103
106
|
} catch (e) {
|
|
104
107
|
return {
|
|
@@ -150,6 +153,7 @@ function loadGlobalConfig() {
|
|
|
150
153
|
}
|
|
151
154
|
return null;
|
|
152
155
|
}
|
|
156
|
+
const JSONBigString = JSONbig({ storeAsString: true });
|
|
153
157
|
function resolveApiBase() {
|
|
154
158
|
return process.env.BFI_API_BASE || "https://bfi.yyuap.com/bfi-api";
|
|
155
159
|
}
|
|
@@ -185,7 +189,13 @@ async function post(path, payload, fetchImpl = fetch) {
|
|
|
185
189
|
throw new RestError("upstream_unreachable", `bfi-api(${resolveApiBase()})不可达:${e instanceof Error ? e.message : String(e)}`);
|
|
186
190
|
}
|
|
187
191
|
if (resp.status === 401) throw new RestError("unauthorized", "v2 token 无效或过期:请重新 `bfi auth login --token <token>`");
|
|
188
|
-
const
|
|
192
|
+
const rawText = await resp.text().catch(() => "");
|
|
193
|
+
let body = {};
|
|
194
|
+
try {
|
|
195
|
+
body = JSONBigString.parse(rawText);
|
|
196
|
+
} catch {
|
|
197
|
+
body = {};
|
|
198
|
+
}
|
|
189
199
|
if (body.code === 0) return body.data;
|
|
190
200
|
throw new RestError(body.data?.error_kind || "upstream_error", body.msg || "bfi-api 返回错误");
|
|
191
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {}
|
|
1
|
+
export { };
|