bfi-cli 0.1.20 → 0.1.24

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 -20
  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) {
@@ -4401,6 +4435,18 @@ async function handleWellKnownSkills(source, url, options, spinner) {
4401
4435
  outro(import_picocolors.default.green("完成!") + import_picocolors.default.dim(" 使用前请审阅技能;技能以 Agent 的全部权限运行。"));
4402
4436
  await promptForFindSkills(options, targetAgents);
4403
4437
  }
4438
+ async function cloneWithGitHubFallback(url, ref, spinner) {
4439
+ try {
4440
+ spinner.start("正在克隆仓库...");
4441
+ return await cloneRepo(url, ref);
4442
+ } catch (error) {
4443
+ if (error instanceof GitCloneError && !url.includes("github.com")) {
4444
+ spinner.message(`GitLab 未找到,降级到 GitHub: ${url.replace(/https:\/\/[^/]+\//, "https://github.com/")}`);
4445
+ return await cloneRepo(url.replace(/https:\/\/[^/]+\//, "https://github.com/"), ref);
4446
+ }
4447
+ throw error;
4448
+ }
4449
+ }
4404
4450
  async function installFromSkillHub(parsed, options, spinner) {
4405
4451
  const config = resolveConfig();
4406
4452
  const api = new SkillHubAPI(config.registry, config.token);
@@ -4625,8 +4671,7 @@ async function runAdd(args, options = {}) {
4625
4671
  skills = blobResult.skills;
4626
4672
  spinner$2.stop(`Found ${import_picocolors.default.green(skills.length)} skill${skills.length > 1 ? "s" : ""}`);
4627
4673
  } else {
4628
- spinner$2.start("正在克隆仓库...");
4629
- tempDir = await cloneRepo(parsed.url, parsed.ref);
4674
+ tempDir = await cloneWithGitHubFallback(parsed.url, parsed.ref, spinner$2);
4630
4675
  spinner$2.stop("仓库克隆完成");
4631
4676
  spinner$2.start("正在发现技能...");
4632
4677
  skills = await discoverSkills(tempDir, parsed.subpath, {
@@ -4635,8 +4680,7 @@ async function runAdd(args, options = {}) {
4635
4680
  });
4636
4681
  }
4637
4682
  } else {
4638
- spinner$2.start("正在克隆仓库...");
4639
- tempDir = await cloneRepo(parsed.url, parsed.ref);
4683
+ tempDir = await cloneWithGitHubFallback(parsed.url, parsed.ref, spinner$2);
4640
4684
  spinner$2.stop("仓库克隆完成");
4641
4685
  spinner$2.start("正在发现技能...");
4642
4686
  skills = await discoverSkills(tempDir, parsed.subpath, {
@@ -6923,9 +6967,10 @@ async function searchMarketplace(query) {
6923
6967
  for (const skill of skills.slice(0, 12)) {
6924
6968
  const installs = formatInstalls(skill.installs);
6925
6969
  console.log(` ${BOLD$5}${skill.name}${RESET$8}`);
6926
- if (skill.source) console.log(` ${DIM$8}source: ${skill.source}${RESET$8}`);
6970
+ if (skill.source) console.log(` ${DIM$8}来源:${skill.source}${RESET$8}`);
6927
6971
  if (installs) console.log(` ${CYAN}${installs}${RESET$8}`);
6928
6972
  console.log(` ${TEXT$7}https://skills.sh/${skill.id}${RESET$8}`);
6973
+ if (skill.source) console.log(` ${DIM$8}安装:${TEXT$7}BFI_GIT_HOST=github.com bfi skills add ${skill.source}${RESET$8}`);
6929
6974
  console.log();
6930
6975
  }
6931
6976
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfi-cli",
3
- "version": "0.1.20",
3
+ "version": "0.1.24",
4
4
  "description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
5
5
  "type": "module",
6
6
  "bin": {