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.
Files changed (2) hide show
  1. package/dist/cli.mjs +65 -18
  2. 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: "github",
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: "github",
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
- if (universal.length > 0) lines.push(` ${import_picocolors.default.green("共享目录:")} ${formatList$1(universal)}`);
4011
- if (symlinked.length > 0) lines.push(` ${import_picocolors.default.dim("符号链接 →")} ${formatList$1(symlinked)}`);
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("copy →")} ${formatList$1(allNames)}`);
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: "共享目录 (.agents/skills)",
4104
- items: visibleUniversalAgents.map((a) => ({
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 otherChoices = otherAgents.map((a) => ({
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)) try {
4126
- await saveSelectedAgents(selected);
4127
- } catch {}
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 || []).slice(0, 20);
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: ${skill.slug}${RESET$8}`);
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 ${skill.slug}${RESET$8}`);
6932
+ console.log(` ${DIM$8}安装:${TEXT$7}bfi skills add ${displaySlug}${RESET$8}`);
6886
6933
  console.log();
6887
6934
  }
6888
6935
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfi-cli",
3
- "version": "0.1.19",
3
+ "version": "0.1.22",
4
4
  "description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
5
5
  "type": "module",
6
6
  "bin": {