bfi-cli 0.1.26 → 0.1.29

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 +145 -42
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -4471,6 +4471,7 @@ async function cloneWithGitHubFallback(url, ref, spinner) {
4471
4471
  }
4472
4472
  }
4473
4473
  async function installFromSkillHub(parsed, options, spinner) {
4474
+ let tempDir = null;
4474
4475
  const config = resolveConfig();
4475
4476
  const api = new SkillHubAPI(config.registry, config.token);
4476
4477
  const rawRef = parsed.url.startsWith("skillhub:") ? parsed.url.slice(9) : parsed.url;
@@ -4492,6 +4493,15 @@ async function installFromSkillHub(parsed, options, spinner) {
4492
4493
  return (b.score || 0) - (a.score || 0);
4493
4494
  }).slice(0, 20);
4494
4495
  if (hits.length === 0) {
4496
+ spinner.stop("SkillHub 未找到,尝试作为 Git 仓库...");
4497
+ const gitSource = parseSource(rawRef);
4498
+ if (gitSource.type === "git" || gitSource.type === "github" || gitSource.type === "gitlab") {
4499
+ tempDir = await cloneWithGitHubFallback(gitSource.url, gitSource.ref, spinner);
4500
+ return {
4501
+ skills: await discoverSkills(tempDir, gitSource.subpath, { includeInternal: true }),
4502
+ tempDir
4503
+ };
4504
+ }
4495
4505
  spinner.stop(import_picocolors.default.red("无结果"));
4496
4506
  outro(import_picocolors.default.red(`No skills found on SkillHub for "${rawRef}".`));
4497
4507
  process.exit(1);
@@ -4536,7 +4546,7 @@ async function installFromSkillHub(parsed, options, spinner) {
4536
4546
  }
4537
4547
  const meta = metadata;
4538
4548
  spinner.stop(`Skill: ${import_picocolors.default.cyan(`@${namespace}/${slug}`)}${meta.description ? ` — ${import_picocolors.default.dim(meta.description)}` : ""}`);
4539
- const tempDir = join(tmpdir(), `.bfi-skillhub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
4549
+ tempDir = join(tmpdir(), `.bfi-skillhub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
4540
4550
  mkdirSync(tempDir, { recursive: true });
4541
4551
  const zipPath = join(tempDir, "skill.zip");
4542
4552
  spinner.start("正在下载技能...");
@@ -6242,7 +6252,7 @@ async function updateGlobalSkills(options = {}) {
6242
6252
  console.log(` ${DIM$9}✗ Cannot update ${safeName}: lock file is missing sourceUrl for this generic Git source${RESET$9}`);
6243
6253
  continue;
6244
6254
  }
6245
- const cliEntry = join(__dirname$1, "..", "bin", "cli.mjs");
6255
+ const cliEntry = join(__dirname$1, "..", "bin", "bfi.mjs");
6246
6256
  if (!existsSync(cliEntry)) {
6247
6257
  failCount++;
6248
6258
  console.log(` ${DIM$9}✗ Failed to update ${safeName}: CLI entrypoint not found at ${cliEntry}${RESET$9}`);
@@ -6326,7 +6336,7 @@ async function updateProjectSkills(options = {}) {
6326
6336
  bySource.set(source, existing);
6327
6337
  }
6328
6338
  const localLock = await readLocalLock();
6329
- const cliEntry = join(__dirname$1, "..", "bin", "cli.mjs");
6339
+ const cliEntry = join(__dirname$1, "..", "bin", "bfi.mjs");
6330
6340
  if (!existsSync(cliEntry)) {
6331
6341
  console.log(`${DIM$9}✗ CLI 入口未找到 ${cliEntry}${RESET$9}`);
6332
6342
  return {
@@ -6901,29 +6911,31 @@ const MARKETPLACE_API = process.env.SKILLS_API_URL || "https://skills.sh";
6901
6911
  async function runSearch(args, globalOpts) {
6902
6912
  const query = parseSearchQuery(args);
6903
6913
  const namespace = args.includes("--namespace") ? getOptionValue$2(args, "--namespace") : void 0;
6914
+ const json = args.includes("--json");
6904
6915
  if (!query) {
6905
- console.log("用法:bfi search <query> [--namespace <ns>] [--marketplace]");
6916
+ console.log("用法:bfi search <query> [--namespace <ns>] [--marketplace] [--json]");
6906
6917
  console.log();
6907
6918
  console.log("选项:");
6908
6919
  console.log(" --namespace <ns> 按 SkillHub 命名空间筛选");
6909
6920
  console.log(" --marketplace 仅搜索 skills.sh 市场");
6910
6921
  console.log(" --all 同时搜索 SkillHub 和市场");
6922
+ console.log(" --json 以 JSON 格式输出结果");
6911
6923
  return;
6912
6924
  }
6913
6925
  const useMarketplace = args.includes("--marketplace");
6914
6926
  const searchAll = args.includes("--all");
6915
6927
  if (useMarketplace) {
6916
- await searchMarketplace(query);
6928
+ await searchMarketplace(query, json);
6917
6929
  return;
6918
6930
  }
6919
6931
  if (searchAll) {
6920
6932
  console.log(`${BOLD$5}=== SkillHub 注册表 ===${RESET$8}\n`);
6921
- await searchSkillHub(query, namespace, globalOpts);
6933
+ await searchSkillHub(query, namespace, globalOpts, json);
6922
6934
  console.log(`\n${BOLD$5}=== skills.sh 市场 ===${RESET$8}\n`);
6923
- await searchMarketplace(query);
6935
+ await searchMarketplace(query, json);
6924
6936
  return;
6925
6937
  }
6926
- await searchSkillHub(query, namespace, globalOpts);
6938
+ await searchSkillHub(query, namespace, globalOpts, json);
6927
6939
  }
6928
6940
  function parseSearchQuery(args) {
6929
6941
  const parts = [];
@@ -6938,7 +6950,7 @@ function parseSearchQuery(args) {
6938
6950
  }
6939
6951
  return parts.join(" ");
6940
6952
  }
6941
- async function searchSkillHub(query, namespace, globalOpts) {
6953
+ async function searchSkillHub(query, namespace, globalOpts, json = false) {
6942
6954
  const { registry, token } = resolveConfig(globalOpts);
6943
6955
  const api = new SkillHubAPI(registry, token);
6944
6956
  try {
@@ -6949,7 +6961,30 @@ async function searchSkillHub(query, namespace, globalOpts) {
6949
6961
  });
6950
6962
  const skills = result.results || result.data || [];
6951
6963
  if (skills.length === 0) {
6952
- console.log(`${DIM$8}SkillHub 上未找到 "${query}" 的技能${RESET$8}`);
6964
+ if (json) console.log(JSON.stringify({
6965
+ source: "skillhub",
6966
+ count: 0,
6967
+ results: []
6968
+ }, null, 2));
6969
+ else console.log(`${DIM$8}SkillHub 上未找到 "${query}" 的技能${RESET$8}`);
6970
+ return;
6971
+ }
6972
+ if (json) {
6973
+ const results = skills.map((skill) => {
6974
+ const canonicalSlug = skill.slug || "";
6975
+ const displaySlug = canonicalSlug.indexOf("--") > 0 ? canonicalSlug : `global--${canonicalSlug}`;
6976
+ return {
6977
+ name: skill.displayName || skill.name || skill.slug,
6978
+ slug: displaySlug,
6979
+ description: skill.summary || skill.description || "",
6980
+ version: skill.version || null
6981
+ };
6982
+ });
6983
+ console.log(JSON.stringify({
6984
+ source: "skillhub",
6985
+ count: results.length,
6986
+ results
6987
+ }, null, 2));
6953
6988
  return;
6954
6989
  }
6955
6990
  console.log(`SkillHub 上找到 ${skills.length} 个技能:\n`);
@@ -6969,7 +7004,7 @@ async function searchSkillHub(query, namespace, globalOpts) {
6969
7004
  console.error(`${DIM$8}SkillHub 搜索失败:${error.message}${RESET$8}`);
6970
7005
  }
6971
7006
  }
6972
- async function searchMarketplace(query) {
7007
+ async function searchMarketplace(query, json = false) {
6973
7008
  try {
6974
7009
  const params = new URLSearchParams({
6975
7010
  q: query,
@@ -6978,12 +7013,37 @@ async function searchMarketplace(query) {
6978
7013
  const url = `${MARKETPLACE_API}/api/search?${params.toString()}`;
6979
7014
  const res = await fetch(url);
6980
7015
  if (!res.ok) {
6981
- console.log(`${DIM$8}skills.sh 市场无结果${RESET$8}`);
7016
+ if (json) console.log(JSON.stringify({
7017
+ source: "marketplace",
7018
+ count: 0,
7019
+ results: []
7020
+ }, null, 2));
7021
+ else console.log(`${DIM$8}skills.sh 市场无结果${RESET$8}`);
6982
7022
  return;
6983
7023
  }
6984
7024
  const skills = (await res.json()).skills || [];
6985
7025
  if (skills.length === 0) {
6986
- console.log(`${DIM$8}skills.sh 上未找到 "${query}" 的技能${RESET$8}`);
7026
+ if (json) console.log(JSON.stringify({
7027
+ source: "marketplace",
7028
+ count: 0,
7029
+ results: []
7030
+ }, null, 2));
7031
+ else console.log(`${DIM$8}skills.sh 上未找到 "${query}" 的技能${RESET$8}`);
7032
+ return;
7033
+ }
7034
+ if (json) {
7035
+ const results = skills.slice(0, 12).map((skill) => ({
7036
+ name: skill.name,
7037
+ source: skill.source || null,
7038
+ installs: skill.installs || 0,
7039
+ url: `https://skills.sh/${skill.id}`,
7040
+ installCommand: skill.source ? `bfi skills add github:${skill.source}` : null
7041
+ }));
7042
+ console.log(JSON.stringify({
7043
+ source: "marketplace",
7044
+ count: results.length,
7045
+ results
7046
+ }, null, 2));
6987
7047
  return;
6988
7048
  }
6989
7049
  console.log(`skills.sh 上找到 ${skills.length} 个技能:\n`);
@@ -7022,19 +7082,21 @@ const YELLOW$2 = "\x1B[33m";
7022
7082
  const RED$2 = "\x1B[31m";
7023
7083
  const GREEN$4 = "\x1B[32m";
7024
7084
  async function runInfo(args, globalOpts) {
7025
- const slug = args[0];
7026
- if (!slug) {
7027
- console.log("用法:bfi info <skill-slug>");
7028
- console.log("示例:bfi info global/my-skill");
7085
+ const ref = args[0];
7086
+ if (!ref) {
7087
+ console.log("用法:bfi info <skill-ref>");
7088
+ console.log("示例:bfi info @global/my-skill");
7029
7089
  process.exit(1);
7030
7090
  }
7031
7091
  const { registry, token } = resolveConfig(globalOpts);
7032
7092
  const api = new SkillHubAPI(registry, token);
7093
+ const { namespace, slug } = parseSkillRef(ref, "global");
7094
+ const canonical = toCanonicalSlug(namespace, slug);
7033
7095
  try {
7034
- const result = await api.getSkill(slug);
7096
+ const result = await api.getSkill(canonical);
7035
7097
  const skill = result.data || result.skill || result;
7036
7098
  if (!skill || !skill.slug) {
7037
- console.log(`${DIM$7}未找到技能:${slug}${RESET$7}`);
7099
+ console.log(`${DIM$7}未找到技能:${ref}${RESET$7}`);
7038
7100
  process.exit(1);
7039
7101
  }
7040
7102
  console.log();
@@ -7095,7 +7157,7 @@ async function runInfo(args, globalOpts) {
7095
7157
  }
7096
7158
  console.log();
7097
7159
  } catch (error) {
7098
- if (error.status === 404) console.error(`未找到技能:${slug}`);
7160
+ if (error.status === 404) console.error(`未找到技能:${ref}`);
7099
7161
  else console.error(`获取技能信息失败:${error.message}`);
7100
7162
  process.exit(1);
7101
7163
  }
@@ -7706,11 +7768,11 @@ async function runPackage(args, globalOpts) {
7706
7768
  function printPackageHelp() {
7707
7769
  console.log();
7708
7770
  console.log(`${BOLD$1}包命令:${RESET$3}`);
7709
- console.log(` ${DIM$3}bfi package list${RESET$3} 列出包`);
7710
- console.log(` ${DIM$3}bfi package info <ref>${RESET$3} 查看包详情`);
7711
- console.log(` ${DIM$3}bfi package create <slug>${RESET$3} 创建新包`);
7712
- console.log(` ${DIM$3}bfi package add <pkg> <skills>${RESET$3} 添加技能到包`);
7713
- console.log(` ${DIM$3}bfi package remove <pkg> <skills>${RESET$3} 从包移除技能`);
7771
+ console.log(` ${DIM$3}bfi skills package list${RESET$3} 列出包`);
7772
+ console.log(` ${DIM$3}bfi skills package info <ref>${RESET$3} 查看包详情`);
7773
+ console.log(` ${DIM$3}bfi skills package create <slug>${RESET$3} 创建新包`);
7774
+ console.log(` ${DIM$3}bfi skills package add <pkg> [skills]${RESET$3} 添加技能到包(默认全部)`);
7775
+ console.log(` ${DIM$3}bfi skills package remove <pkg> [skills]${RESET$3} 从包移除技能(默认全部)`);
7714
7776
  console.log();
7715
7777
  console.log(`${BOLD$1}选项:${RESET$3}`);
7716
7778
  console.log(` --namespace <ns> 目标命名空间`);
@@ -7720,11 +7782,11 @@ function printPackageHelp() {
7720
7782
  console.log(` --json 以 JSON 输出`);
7721
7783
  console.log();
7722
7784
  console.log(`${BOLD$1}示例:${RESET$3}`);
7723
- console.log(` ${DIM$3}$ ${RESET$3}bfi package list --namespace myteam`);
7724
- console.log(` ${DIM$3}$ ${RESET$3}bfi package info @myteam/my-package`);
7725
- console.log(` ${DIM$3}$ ${RESET$3}bfi package create my-utils --namespace myteam`);
7726
- console.log(` ${DIM$3}$ ${RESET$3}bfi package add @myteam/my-package @myteam/skill-a @myteam/skill-b`);
7727
- console.log(` ${DIM$3}$ ${RESET$3}bfi package remove @myteam/my-package @myteam/skill-a`);
7785
+ console.log(` ${DIM$3}$ ${RESET$3}bfi skills package list --namespace myteam`);
7786
+ console.log(` ${DIM$3}$ ${RESET$3}bfi skills package info @myteam/my-package`);
7787
+ console.log(` ${DIM$3}$ ${RESET$3}bfi skills package create my-utils --namespace myteam`);
7788
+ console.log(` ${DIM$3}$ ${RESET$3}bfi skills package add @myteam/my-package @myteam/skill-a @myteam/skill-b`);
7789
+ console.log(` ${DIM$3}$ ${RESET$3}bfi skills package remove @myteam/my-package @myteam/skill-a`);
7728
7790
  console.log();
7729
7791
  }
7730
7792
  async function handleList(args, api, globalOpts) {
@@ -7734,11 +7796,15 @@ async function handleList(args, api, globalOpts) {
7734
7796
  const result = await api.listPackages(namespace);
7735
7797
  const packages = result.packages || result.data || [];
7736
7798
  if (json) {
7737
- console.log(JSON.stringify({ packages }, null, 2));
7799
+ console.log(JSON.stringify({
7800
+ namespace,
7801
+ packages
7802
+ }, null, 2));
7738
7803
  return;
7739
7804
  }
7740
7805
  if (packages.length === 0) {
7741
- console.log(`No packages found in namespace "${namespace}".`);
7806
+ console.log(`命名空间 "${namespace}" 中没有包。`);
7807
+ console.log(`使用 --namespace <ns> 查看其他命名空间,或 bfi whoami 查看你的命名空间列表。`);
7742
7808
  return;
7743
7809
  }
7744
7810
  console.log();
@@ -7762,11 +7828,11 @@ async function handleList(args, api, globalOpts) {
7762
7828
  async function handleInfo(args, api, globalOpts) {
7763
7829
  const pkgRef = args[0];
7764
7830
  if (!pkgRef) {
7765
- console.error("Usage: bfi package info <package-ref>");
7831
+ console.error("Usage: bfi skills package info <package-ref>");
7766
7832
  console.log();
7767
7833
  console.log("Examples:");
7768
- console.log(" bfi package info @myteam/my-package");
7769
- console.log(" bfi package info myteam--my-package");
7834
+ console.log(" bfi skills package info @myteam/my-package");
7835
+ console.log(" bfi skills package info myteam--my-package");
7770
7836
  process.exit(1);
7771
7837
  }
7772
7838
  const json = args.includes("--json");
@@ -7800,7 +7866,7 @@ async function handleInfo(args, api, globalOpts) {
7800
7866
  async function handleCreate(args, api, globalOpts) {
7801
7867
  const slug = args[0];
7802
7868
  if (!slug) {
7803
- console.error("用法:bfi package create <slug> [options]");
7869
+ console.error("用法:bfi skills package create <slug> [options]");
7804
7870
  process.exit(1);
7805
7871
  }
7806
7872
  const namespace = getOptionValue(args, "--namespace") || globalOpts.namespace || "global";
@@ -7828,12 +7894,33 @@ async function handleCreate(args, api, globalOpts) {
7828
7894
  async function handleAdd(args, api, globalOpts) {
7829
7895
  const pkgRef = args[0];
7830
7896
  const skillRefs = args.slice(1);
7831
- if (!pkgRef || skillRefs.length === 0) {
7832
- console.error("用法:bfi package add <package-ref> <skill-ref...>");
7897
+ if (!pkgRef) {
7898
+ console.error("用法:bfi skills package add <package-ref> [skill-ref...]");
7899
+ console.error(" 不指定技能时,添加当前命名空间的所有技能到包");
7833
7900
  process.exit(1);
7834
7901
  }
7835
7902
  const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
7836
- const skills = skillRefs.map((ref) => {
7903
+ let skills;
7904
+ if (skillRefs.length === 0) try {
7905
+ skills = ((await api.searchSkills("", {
7906
+ namespace,
7907
+ limit: 1e3
7908
+ })).results || []).map((r) => {
7909
+ const { namespace: ns, slug: s } = parseSkillRef(r.slug, namespace);
7910
+ return {
7911
+ namespace: ns,
7912
+ slug: s
7913
+ };
7914
+ });
7915
+ if (skills.length === 0) {
7916
+ console.error(`命名空间 "${namespace}" 中没有技能。`);
7917
+ process.exit(1);
7918
+ }
7919
+ } catch (error) {
7920
+ console.error(`获取技能列表失败:${error.message}`);
7921
+ process.exit(1);
7922
+ }
7923
+ else skills = skillRefs.map((ref) => {
7837
7924
  const { namespace: skillNs, slug: skillSlug } = parseSkillRef(ref, namespace);
7838
7925
  return {
7839
7926
  namespace: skillNs,
@@ -7852,12 +7939,28 @@ async function handleAdd(args, api, globalOpts) {
7852
7939
  async function handleRemove(args, api, globalOpts) {
7853
7940
  const pkgRef = args[0];
7854
7941
  const skillRefs = args.slice(1);
7855
- if (!pkgRef || skillRefs.length === 0) {
7856
- console.error("用法:bfi package remove <package-ref> <skill-ref...>");
7942
+ if (!pkgRef) {
7943
+ console.error("用法:bfi skills package remove <package-ref> [skill-ref...]");
7944
+ console.error(" 不指定技能时,移除包中所有技能");
7857
7945
  process.exit(1);
7858
7946
  }
7859
7947
  const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
7860
- const skills = skillRefs.map((ref) => {
7948
+ let skills;
7949
+ if (skillRefs.length === 0) try {
7950
+ const existingSkills = (await api.getPackage(namespace, slug)).skills || [];
7951
+ if (existingSkills.length === 0) {
7952
+ console.log("包中没有技能。");
7953
+ return;
7954
+ }
7955
+ skills = existingSkills.map((s) => ({
7956
+ namespace: s.namespace || namespace,
7957
+ slug: s.slug
7958
+ }));
7959
+ } catch (error) {
7960
+ console.error(`获取包信息失败:${error.message}`);
7961
+ process.exit(1);
7962
+ }
7963
+ else skills = skillRefs.map((ref) => {
7861
7964
  const { namespace: skillNs, slug: skillSlug } = parseSkillRef(ref, namespace);
7862
7965
  return {
7863
7966
  namespace: skillNs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfi-cli",
3
- "version": "0.1.26",
3
+ "version": "0.1.29",
4
4
  "description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
5
5
  "type": "module",
6
6
  "bin": {