bfi-cli 0.1.19 → 0.1.22
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/cli.mjs +65 -18
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -28,6 +28,7 @@ import { determineAgent } from "@vercel/detect-agent";
|
|
|
28
28
|
var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
|
|
29
29
|
const GIT_HOST = process.env.BFI_GIT_HOST || "git.yyrd.com";
|
|
30
30
|
const GIT_URL = `https://${GIT_HOST}`;
|
|
31
|
+
const GIT_SOURCE_TYPE = GIT_HOST === "github.com" ? "github" : "gitlab";
|
|
31
32
|
function getOwnerRepo(parsed) {
|
|
32
33
|
if (parsed.type === "local") return null;
|
|
33
34
|
const sshMatch = parsed.url.match(/^git@[^:]+:(.+)$/);
|
|
@@ -212,7 +213,7 @@ function parseSource(input) {
|
|
|
212
213
|
if (atSkillMatch && !input.includes(":") && !input.startsWith(".") && !input.startsWith("/")) {
|
|
213
214
|
const [, owner, repo, skillFilter] = atSkillMatch;
|
|
214
215
|
return {
|
|
215
|
-
type:
|
|
216
|
+
type: GIT_SOURCE_TYPE,
|
|
216
217
|
url: `${GIT_URL}/${owner}/${repo}.git`,
|
|
217
218
|
...fragmentRef ? { ref: fragmentRef } : {},
|
|
218
219
|
skillFilter: fragmentSkillFilter || skillFilter
|
|
@@ -222,7 +223,7 @@ function parseSource(input) {
|
|
|
222
223
|
if (shorthandMatch && !input.includes(":") && !input.startsWith(".") && !input.startsWith("/")) {
|
|
223
224
|
const [, owner, repo, subpath] = shorthandMatch;
|
|
224
225
|
return {
|
|
225
|
-
type:
|
|
226
|
+
type: GIT_SOURCE_TYPE,
|
|
226
227
|
url: `${GIT_URL}/${owner}/${repo}.git`,
|
|
227
228
|
...fragmentRef ? { ref: fragmentRef } : {},
|
|
228
229
|
subpath: subpath ? sanitizeSubpath(subpath) : subpath,
|
|
@@ -4003,15 +4004,20 @@ function splitAgentsByType(agentTypes) {
|
|
|
4003
4004
|
symlinked
|
|
4004
4005
|
};
|
|
4005
4006
|
}
|
|
4006
|
-
function buildAgentSummaryLines(targetAgents, installMode) {
|
|
4007
|
+
function buildAgentSummaryLines(targetAgents, installMode, selectedAgents) {
|
|
4007
4008
|
const lines = [];
|
|
4008
4009
|
const { universal, symlinked } = splitAgentsByType(targetAgents);
|
|
4010
|
+
const selectedSet = new Set(selectedAgents || targetAgents);
|
|
4009
4011
|
if (installMode === "symlink") {
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
+
const selectedUniversal = universal.filter((a) => selectedSet.has(a));
|
|
4013
|
+
const selectedSymlink = symlinked.filter((a) => selectedSet.has(a));
|
|
4014
|
+
if (selectedUniversal.length > 0) lines.push(` ${import_picocolors.default.green("共享目录:")} ${formatList$1(selectedUniversal)}`);
|
|
4015
|
+
if (selectedSymlink.length > 0) lines.push(` ${import_picocolors.default.dim("符号链接 →")} ${formatList$1(selectedSymlink)}`);
|
|
4016
|
+
const otherUniversal = universal.filter((a) => !selectedSet.has(a));
|
|
4017
|
+
if (otherUniversal.length > 0) lines.push(` ${import_picocolors.default.dim(`(另外 ${otherUniversal.length} 个使用共享目录的 Agent 也会自动获得此技能)`)}`);
|
|
4012
4018
|
} else {
|
|
4013
|
-
const allNames = targetAgents.map((a) => agents[a].displayName);
|
|
4014
|
-
lines.push(` ${import_picocolors.default.dim("
|
|
4019
|
+
const allNames = targetAgents.filter((a) => selectedSet.has(a)).map((a) => agents[a].displayName);
|
|
4020
|
+
lines.push(` ${import_picocolors.default.dim("复制 →")} ${formatList$1(allNames)}`);
|
|
4015
4021
|
}
|
|
4016
4022
|
return lines;
|
|
4017
4023
|
}
|
|
@@ -4037,7 +4043,7 @@ function buildTargetSummaryLines(targets, installMode) {
|
|
|
4037
4043
|
const subagentNames = targets.filter((t) => t.subagent).map(targetDisplayName);
|
|
4038
4044
|
const { universal, symlinked } = splitAgentsByType(rootAgents);
|
|
4039
4045
|
if (installMode === "symlink") {
|
|
4040
|
-
if (universal.length > 0) lines.push(` ${import_picocolors.default.green("共享目录:")} ${formatList$1(universal)}`);
|
|
4046
|
+
if (universal.length > 0) lines.push(` ${import_picocolors.default.green("共享目录:")} ${formatList$1(universal, 3)}`);
|
|
4041
4047
|
if (symlinked.length > 0) lines.push(` ${import_picocolors.default.dim("符号链接 →")} ${formatList$1(symlinked)}`);
|
|
4042
4048
|
if (subagentNames.length > 0) lines.push(` ${import_picocolors.default.dim("copy →")} ${formatList$1(subagentNames)}`);
|
|
4043
4049
|
} else {
|
|
@@ -4096,22 +4102,36 @@ async function promptForAgents(message, choices) {
|
|
|
4096
4102
|
}
|
|
4097
4103
|
async function selectAgentsInteractive(options) {
|
|
4098
4104
|
const supportsGlobalFilter = (a) => !options.global || agents[a].globalSkillsDir;
|
|
4105
|
+
let installedAgents = [];
|
|
4106
|
+
try {
|
|
4107
|
+
installedAgents = await detectInstalledAgents();
|
|
4108
|
+
} catch {}
|
|
4109
|
+
const hasDetected = installedAgents.length > 0;
|
|
4110
|
+
const installedSet = new Set(installedAgents);
|
|
4099
4111
|
const universalAgents = getUniversalAgents().filter(supportsGlobalFilter);
|
|
4100
4112
|
const visibleUniversalAgents = getVisibleUniversalAgents().filter(supportsGlobalFilter);
|
|
4101
4113
|
const otherAgents = getNonUniversalAgents().filter((agent) => agent !== "eve" && supportsGlobalFilter(agent));
|
|
4114
|
+
const showAll = hasDetected ? false : true;
|
|
4115
|
+
const filteredUniversal = showAll ? visibleUniversalAgents : visibleUniversalAgents.filter((a) => installedSet.has(a));
|
|
4102
4116
|
const universalSection = {
|
|
4103
|
-
title:
|
|
4104
|
-
items:
|
|
4117
|
+
title: `共享目录 (.agents/skills) — ${showAll ? "全部" : `已检测到 ${filteredUniversal.length} 个`}`,
|
|
4118
|
+
items: filteredUniversal.map((a) => ({
|
|
4105
4119
|
value: a,
|
|
4106
4120
|
label: agents[a].displayName
|
|
4107
4121
|
})),
|
|
4108
|
-
hiddenCount: universalAgents.length - visibleUniversalAgents.length
|
|
4122
|
+
hiddenCount: showAll ? universalAgents.length - visibleUniversalAgents.length : 0
|
|
4109
4123
|
};
|
|
4110
|
-
const
|
|
4124
|
+
const filteredOther = showAll ? otherAgents : otherAgents.filter((a) => installedSet.has(a));
|
|
4125
|
+
const otherChoices = filteredOther.map((a) => ({
|
|
4111
4126
|
value: a,
|
|
4112
4127
|
label: agents[a].displayName,
|
|
4113
4128
|
hint: options.global ? agents[a].globalSkillsDir : agents[a].skillsDir
|
|
4114
4129
|
}));
|
|
4130
|
+
if (!showAll && otherAgents.length > filteredOther.length) otherChoices.push({
|
|
4131
|
+
value: "__show_all__",
|
|
4132
|
+
label: `显示全部 ${otherAgents.length + universalAgents.length} 个 Agent...`,
|
|
4133
|
+
hint: "包括未检测到的"
|
|
4134
|
+
});
|
|
4115
4135
|
let lastSelected;
|
|
4116
4136
|
try {
|
|
4117
4137
|
lastSelected = await getLastSelectedAgents();
|
|
@@ -4122,9 +4142,23 @@ async function selectAgentsInteractive(options) {
|
|
|
4122
4142
|
initialSelected: lastSelected ? lastSelected.filter((a) => otherAgents.includes(a) && !universalAgents.includes(a)) : [],
|
|
4123
4143
|
lockedSection: universalSection
|
|
4124
4144
|
});
|
|
4125
|
-
if (!isCancelled(selected))
|
|
4126
|
-
|
|
4127
|
-
|
|
4145
|
+
if (!isCancelled(selected)) {
|
|
4146
|
+
const selection = selected;
|
|
4147
|
+
if (selection.includes("__show_all__")) {
|
|
4148
|
+
const allSelected = [
|
|
4149
|
+
...selection.filter((s) => s !== "__show_all__"),
|
|
4150
|
+
...otherAgents.filter((a) => !installedSet.has(a)),
|
|
4151
|
+
...universalAgents.filter((a) => !installedSet.has(a))
|
|
4152
|
+
];
|
|
4153
|
+
try {
|
|
4154
|
+
await saveSelectedAgents(allSelected);
|
|
4155
|
+
} catch {}
|
|
4156
|
+
return [...new Set(allSelected)];
|
|
4157
|
+
}
|
|
4158
|
+
try {
|
|
4159
|
+
await saveSelectedAgents(selection);
|
|
4160
|
+
} catch {}
|
|
4161
|
+
}
|
|
4128
4162
|
return selected;
|
|
4129
4163
|
}
|
|
4130
4164
|
async function handleWellKnownSkills(source, url, options, spinner) {
|
|
@@ -4410,7 +4444,18 @@ async function installFromSkillHub(parsed, options, spinner) {
|
|
|
4410
4444
|
let slug;
|
|
4411
4445
|
if (restParts.length === 0) {
|
|
4412
4446
|
spinner.start(`正在 SkillHub 搜索 "${rawRef}"...`);
|
|
4413
|
-
const hits = ((await api.searchSkills(rawRef)).results || []).
|
|
4447
|
+
const hits = ((await api.searchSkills(rawRef)).results || []).map((h) => {
|
|
4448
|
+
const { namespace: ns, slug: s } = parseSkillRef(h.slug, "global");
|
|
4449
|
+
return {
|
|
4450
|
+
...h,
|
|
4451
|
+
namespace: ns,
|
|
4452
|
+
slug: s
|
|
4453
|
+
};
|
|
4454
|
+
}).sort((a, b) => {
|
|
4455
|
+
const aExact = a.slug === rawRef || a.name === rawRef;
|
|
4456
|
+
if (aExact !== (b.slug === rawRef || b.name === rawRef)) return aExact ? -1 : 1;
|
|
4457
|
+
return (b.score || 0) - (a.score || 0);
|
|
4458
|
+
}).slice(0, 20);
|
|
4414
4459
|
if (hits.length === 0) {
|
|
4415
4460
|
spinner.stop(import_picocolors.default.red("无结果"));
|
|
4416
4461
|
outro(import_picocolors.default.red(`No skills found on SkillHub for "${rawRef}".`));
|
|
@@ -6878,11 +6923,13 @@ async function searchSkillHub(query, namespace, globalOpts) {
|
|
|
6878
6923
|
for (const skill of skills) {
|
|
6879
6924
|
const name = skill.displayName || skill.name || skill.slug;
|
|
6880
6925
|
const desc = skill.summary || skill.description || "";
|
|
6926
|
+
const canonicalSlug = skill.slug || "";
|
|
6927
|
+
const displaySlug = canonicalSlug.indexOf("--") > 0 ? canonicalSlug : `global--${canonicalSlug}`;
|
|
6881
6928
|
console.log(` ${BOLD$5}${name}${RESET$8}`);
|
|
6882
6929
|
if (desc) console.log(` ${DIM$8}${truncate$2(desc, 100)}${RESET$8}`);
|
|
6883
|
-
console.log(` ${TEXT$7}slug: ${
|
|
6930
|
+
console.log(` ${TEXT$7}slug: ${displaySlug}${RESET$8}`);
|
|
6884
6931
|
if (skill.version) console.log(` ${DIM$8}version: ${skill.version}${RESET$8}`);
|
|
6885
|
-
console.log(` ${DIM$8}安装:${TEXT$7}bfi skills add ${
|
|
6932
|
+
console.log(` ${DIM$8}安装:${TEXT$7}bfi skills add ${displaySlug}${RESET$8}`);
|
|
6886
6933
|
console.log();
|
|
6887
6934
|
}
|
|
6888
6935
|
} catch (error) {
|