bfi-cli 0.1.0 → 0.1.1
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/_chunks/agents.mjs +1 -1
- package/dist/cli.mjs +107 -107
- package/package.json +1 -1
- package/skills/bfi-skill/SKILL.md +176 -0
- package/skills/gbfi-skill/SKILL.md +0 -176
package/dist/_chunks/agents.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { agents, loadGlobalConfig } from "../cli.mjs";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import os from "node:os";
|
|
5
|
-
const CACHE_FILE = path.join(os.homedir(), ".
|
|
5
|
+
const CACHE_FILE = path.join(os.homedir(), ".bfi", "agents-cache.json");
|
|
6
6
|
const CACHE_TTL_MS = 1440 * 60 * 1e3;
|
|
7
7
|
function loadCache() {
|
|
8
8
|
try {
|
package/dist/cli.mjs
CHANGED
|
@@ -192,8 +192,8 @@ function parseSource(input) {
|
|
|
192
192
|
...fragmentRef ? { ref: fragmentRef } : {}
|
|
193
193
|
};
|
|
194
194
|
}
|
|
195
|
-
const
|
|
196
|
-
if (
|
|
195
|
+
const bfiPrefixMatch = input.match(/^bfi:(.+)$/);
|
|
196
|
+
if (bfiPrefixMatch) return parseSource(appendFragmentRef(`@${bfiPrefixMatch[1]}`, fragmentRef, fragmentSkillFilter));
|
|
197
197
|
const skillhubAtMatch = input.match(/^@([^/]+)\/(.+)$/);
|
|
198
198
|
if (skillhubAtMatch) return {
|
|
199
199
|
type: "skillhub",
|
|
@@ -773,10 +773,10 @@ var config_exports = /* @__PURE__ */ __exportAll({
|
|
|
773
773
|
saveProjectConfig: () => saveProjectConfig,
|
|
774
774
|
setConfigValue: () => setConfigValue
|
|
775
775
|
});
|
|
776
|
-
const GLOBAL_CONFIG_DIR = path$1.join(os$1.homedir(), ".
|
|
776
|
+
const GLOBAL_CONFIG_DIR = path$1.join(os$1.homedir(), ".bfi");
|
|
777
777
|
const GLOBAL_CONFIG_FILE = path$1.join(GLOBAL_CONFIG_DIR, "config.json");
|
|
778
|
-
const PROJECT_CONFIG_FILE = ".
|
|
779
|
-
const LOCK_FILE = path$1.join(".
|
|
778
|
+
const PROJECT_CONFIG_FILE = ".bfirc";
|
|
779
|
+
const LOCK_FILE = path$1.join(".bfi", "lock.json");
|
|
780
780
|
function resolveConfig(globalOpts = {}) {
|
|
781
781
|
return {
|
|
782
782
|
registry: getConfigValue("registry", globalOpts) || "https://bfi.yyuap.com:811",
|
|
@@ -4446,7 +4446,7 @@ async function installFromSkillHub(parsed, options, spinner) {
|
|
|
4446
4446
|
}
|
|
4447
4447
|
const meta = metadata;
|
|
4448
4448
|
spinner.stop(`Skill: ${import_picocolors.default.cyan(`@${namespace}/${slug}`)}${meta.description ? ` — ${import_picocolors.default.dim(meta.description)}` : ""}`);
|
|
4449
|
-
const tempDir = join(tmpdir(), `.
|
|
4449
|
+
const tempDir = join(tmpdir(), `.bfi-skillhub-${canonicalSlug.replace(/[/:@]/g, "-")}-${Date.now()}`);
|
|
4450
4450
|
mkdirSync(tempDir, { recursive: true });
|
|
4451
4451
|
const zipPath = join(tempDir, "skill.zip");
|
|
4452
4452
|
spinner.start("Downloading skill...");
|
|
@@ -6724,7 +6724,7 @@ async function runLogin(args, globalOpts) {
|
|
|
6724
6724
|
const token = getOptionValue$3(args, "--token");
|
|
6725
6725
|
const { registry } = resolveConfig(globalOpts);
|
|
6726
6726
|
if (!token) {
|
|
6727
|
-
console.error("Usage:
|
|
6727
|
+
console.error("Usage: bfi auth login --token <token>");
|
|
6728
6728
|
process.exit(1);
|
|
6729
6729
|
}
|
|
6730
6730
|
const api = new SkillHubAPI(registry, token);
|
|
@@ -6759,7 +6759,7 @@ async function runLogout() {
|
|
|
6759
6759
|
async function runWhoami(globalOpts) {
|
|
6760
6760
|
const { registry, token } = resolveConfig(globalOpts);
|
|
6761
6761
|
if (!token) {
|
|
6762
|
-
console.error("Not authenticated. Run:
|
|
6762
|
+
console.error("Not authenticated. Run: bfi auth login --token <token>");
|
|
6763
6763
|
process.exit(1);
|
|
6764
6764
|
}
|
|
6765
6765
|
const response = await new SkillHubAPI(registry, token).whoami();
|
|
@@ -6784,7 +6784,7 @@ async function runSearch(args, globalOpts) {
|
|
|
6784
6784
|
const query = parseSearchQuery(args);
|
|
6785
6785
|
const namespace = args.includes("--namespace") ? getOptionValue$2(args, "--namespace") : void 0;
|
|
6786
6786
|
if (!query) {
|
|
6787
|
-
console.log("Usage:
|
|
6787
|
+
console.log("Usage: bfi search <query> [--namespace <ns>] [--marketplace]");
|
|
6788
6788
|
console.log();
|
|
6789
6789
|
console.log("Options:");
|
|
6790
6790
|
console.log(" --namespace <ns> Filter by SkillHub namespace");
|
|
@@ -6899,8 +6899,8 @@ const GREEN$4 = "\x1B[32m";
|
|
|
6899
6899
|
async function runInfo(args, globalOpts) {
|
|
6900
6900
|
const slug = args[0];
|
|
6901
6901
|
if (!slug) {
|
|
6902
|
-
console.log("Usage:
|
|
6903
|
-
console.log("Example:
|
|
6902
|
+
console.log("Usage: bfi info <skill-slug>");
|
|
6903
|
+
console.log("Example: bfi info global/my-skill");
|
|
6904
6904
|
process.exit(1);
|
|
6905
6905
|
}
|
|
6906
6906
|
const { registry, token } = resolveConfig(globalOpts);
|
|
@@ -6994,8 +6994,8 @@ async function runConfig(args, globalOpts) {
|
|
|
6994
6994
|
}
|
|
6995
6995
|
function printConfigHelp() {
|
|
6996
6996
|
console.log("Config Commands:");
|
|
6997
|
-
console.log("
|
|
6998
|
-
console.log("
|
|
6997
|
+
console.log(" bfi config get [key] Get configuration value");
|
|
6998
|
+
console.log(" bfi config set <key> <value> Set configuration value");
|
|
6999
6999
|
console.log();
|
|
7000
7000
|
console.log("Available keys (global):");
|
|
7001
7001
|
console.log(" registry API registry URL");
|
|
@@ -7033,17 +7033,17 @@ async function handleGet(args, globalOpts) {
|
|
|
7033
7033
|
const projectValue = projectConfig[projectConfigKey];
|
|
7034
7034
|
console.log(`\nConfiguration: ${key}`);
|
|
7035
7035
|
console.log("-".repeat(40));
|
|
7036
|
-
if (projectValue !== void 0) console.log(`Project (.
|
|
7037
|
-
else console.log(`Project (.
|
|
7038
|
-
if (globalValue !== void 0) console.log(`Global (~/.
|
|
7039
|
-
else console.log(`Global (~/.
|
|
7036
|
+
if (projectValue !== void 0) console.log(`Project (.bfirc): ${projectValue}`);
|
|
7037
|
+
else console.log(`Project (.bfirc): (not set)`);
|
|
7038
|
+
if (globalValue !== void 0) console.log(`Global (~/.bfi/config.json): ${key === "token" ? "********" : globalValue}`);
|
|
7039
|
+
else console.log(`Global (~/.bfi/config.json): (not set)`);
|
|
7040
7040
|
console.log();
|
|
7041
7041
|
} else {
|
|
7042
|
-
console.log("\nProject Configuration (.
|
|
7042
|
+
console.log("\nProject Configuration (.bfirc):");
|
|
7043
7043
|
console.log("-".repeat(40));
|
|
7044
7044
|
if (Object.keys(projectConfig).length === 0) console.log(" (no project config)");
|
|
7045
7045
|
else for (const [k, v] of Object.entries(projectConfig)) console.log(` ${k}: ${v}`);
|
|
7046
|
-
console.log("\nGlobal Configuration (~/.
|
|
7046
|
+
console.log("\nGlobal Configuration (~/.bfi/config.json):");
|
|
7047
7047
|
console.log("-".repeat(40));
|
|
7048
7048
|
if (Object.keys(globalConfig).length === 0) console.log(" (no global config)");
|
|
7049
7049
|
else for (const [k, v] of Object.entries(globalConfig)) console.log(` ${k}: ${k === "token" ? "********" : v}`);
|
|
@@ -7054,11 +7054,11 @@ async function handleSet(args, _globalOpts) {
|
|
|
7054
7054
|
const key = args[1];
|
|
7055
7055
|
const value = args[2];
|
|
7056
7056
|
if (!key || value === void 0) {
|
|
7057
|
-
console.error("Usage:
|
|
7057
|
+
console.error("Usage: bfi config set <key> <value>");
|
|
7058
7058
|
console.log();
|
|
7059
7059
|
console.log("Use --global flag to set globally:");
|
|
7060
|
-
console.log("
|
|
7061
|
-
console.log("
|
|
7060
|
+
console.log(" bfi config set registry https://skillhub.example.com --global");
|
|
7061
|
+
console.log(" bfi config set namespace myteam --global");
|
|
7062
7062
|
process.exit(1);
|
|
7063
7063
|
}
|
|
7064
7064
|
const validKeys = [
|
|
@@ -7097,19 +7097,19 @@ async function runDocs(args, globalOpts) {
|
|
|
7097
7097
|
}
|
|
7098
7098
|
function printDocsHelp() {
|
|
7099
7099
|
console.log("Document Commands:");
|
|
7100
|
-
console.log("
|
|
7101
|
-
console.log("
|
|
7102
|
-
console.log("
|
|
7100
|
+
console.log(" bfi docs upload <file> Upload a document for processing");
|
|
7101
|
+
console.log(" bfi docs list List uploaded documents");
|
|
7102
|
+
console.log(" bfi docs info <id> Show document processing status");
|
|
7103
7103
|
console.log();
|
|
7104
7104
|
console.log("Examples:");
|
|
7105
|
-
console.log(` ${DIM$5}$ ${RESET$5}
|
|
7106
|
-
console.log(` ${DIM$5}$ ${RESET$5}
|
|
7107
|
-
console.log(` ${DIM$5}$ ${RESET$5}
|
|
7105
|
+
console.log(` ${DIM$5}$ ${RESET$5}bfi docs upload resume.pdf`);
|
|
7106
|
+
console.log(` ${DIM$5}$ ${RESET$5}bfi docs list`);
|
|
7107
|
+
console.log(` ${DIM$5}$ ${RESET$5}bfi docs info 42`);
|
|
7108
7108
|
}
|
|
7109
7109
|
async function handleUpload(args, globalOpts) {
|
|
7110
7110
|
const filePath = args[0];
|
|
7111
7111
|
if (!filePath) {
|
|
7112
|
-
console.error("Usage:
|
|
7112
|
+
console.error("Usage: bfi docs upload <file>");
|
|
7113
7113
|
console.log("Upload a document file for processing.");
|
|
7114
7114
|
process.exit(1);
|
|
7115
7115
|
}
|
|
@@ -7138,7 +7138,7 @@ async function handleUpload(args, globalOpts) {
|
|
|
7138
7138
|
if (result.status) console.log(` ${BOLD$3}Status:${RESET$5} ${TEXT$5}${result.status}${RESET$5}`);
|
|
7139
7139
|
if (result.fileName) console.log(` ${BOLD$3}File:${RESET$5} ${TEXT$5}${result.fileName}${RESET$5}`);
|
|
7140
7140
|
console.log();
|
|
7141
|
-
if (result.id) console.log(`${DIM$5}Check status:
|
|
7141
|
+
if (result.id) console.log(`${DIM$5}Check status: bfi docs info ${result.id}${RESET$5}`);
|
|
7142
7142
|
} catch (error) {
|
|
7143
7143
|
console.error(`Upload failed: ${error.message}`);
|
|
7144
7144
|
process.exit(1);
|
|
@@ -7170,7 +7170,7 @@ async function handleList$1(args, globalOpts) {
|
|
|
7170
7170
|
console.log();
|
|
7171
7171
|
}
|
|
7172
7172
|
const total = result.total || result.totalElements;
|
|
7173
|
-
if (total && Number(total) > (page + 1) * size) console.log(`${DIM$5}Next page:
|
|
7173
|
+
if (total && Number(total) > (page + 1) * size) console.log(`${DIM$5}Next page: bfi docs list ${page + 1}${RESET$5}`);
|
|
7174
7174
|
console.log();
|
|
7175
7175
|
} catch (error) {
|
|
7176
7176
|
console.error(`Failed to list documents: ${error.message}`);
|
|
@@ -7180,7 +7180,7 @@ async function handleList$1(args, globalOpts) {
|
|
|
7180
7180
|
async function handleInfo$1(args, globalOpts) {
|
|
7181
7181
|
const docId = args[0];
|
|
7182
7182
|
if (!docId) {
|
|
7183
|
-
console.error("Usage:
|
|
7183
|
+
console.error("Usage: bfi docs info <id>");
|
|
7184
7184
|
process.exit(1);
|
|
7185
7185
|
}
|
|
7186
7186
|
const id = parseInt(docId, 10);
|
|
@@ -7270,14 +7270,14 @@ async function runPublish(args, globalOpts) {
|
|
|
7270
7270
|
default:
|
|
7271
7271
|
console.error(`Unknown publish mode: ${mode}`);
|
|
7272
7272
|
console.log("Valid modes: dir, zip, git");
|
|
7273
|
-
console.log("Usage:
|
|
7273
|
+
console.log("Usage: bfi publish [source] --from dir|zip|git [options]");
|
|
7274
7274
|
process.exit(1);
|
|
7275
7275
|
}
|
|
7276
7276
|
}
|
|
7277
7277
|
async function publishFromDir(positionalArgs, api, namespace, visibility) {
|
|
7278
7278
|
const dirPath = positionalArgs[0];
|
|
7279
7279
|
if (!dirPath) {
|
|
7280
|
-
console.error("Usage:
|
|
7280
|
+
console.error("Usage: bfi publish <directory> --from dir");
|
|
7281
7281
|
console.log("Publish a skill from a local directory containing SKILL.md.");
|
|
7282
7282
|
process.exit(1);
|
|
7283
7283
|
}
|
|
@@ -7322,7 +7322,7 @@ async function publishFromDir(positionalArgs, api, namespace, visibility) {
|
|
|
7322
7322
|
async function publishFromZip(positionalArgs, api, namespace, visibility) {
|
|
7323
7323
|
const zipPath = positionalArgs[0];
|
|
7324
7324
|
if (!zipPath) {
|
|
7325
|
-
console.error("Usage:
|
|
7325
|
+
console.error("Usage: bfi publish <file.zip> --from zip");
|
|
7326
7326
|
console.log("Publish a skill from a zip file containing SKILL.md.");
|
|
7327
7327
|
process.exit(1);
|
|
7328
7328
|
}
|
|
@@ -7332,7 +7332,7 @@ async function publishFromZip(positionalArgs, api, namespace, visibility) {
|
|
|
7332
7332
|
process.exit(1);
|
|
7333
7333
|
}
|
|
7334
7334
|
console.log(`${DIM$4}Extracting zip...${RESET$4}`);
|
|
7335
|
-
const tmpDir = path$1.join(os$1.tmpdir(), `.
|
|
7335
|
+
const tmpDir = path$1.join(os$1.tmpdir(), `.bfi-publish-${Date.now()}`);
|
|
7336
7336
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
7337
7337
|
try {
|
|
7338
7338
|
await extractZip(resolvedZip, tmpDir);
|
|
@@ -7373,12 +7373,12 @@ async function publishFromZip(positionalArgs, api, namespace, visibility) {
|
|
|
7373
7373
|
async function publishFromGit(positionalArgs, api, namespace, visibility, yes, branch, directory, skillFilter) {
|
|
7374
7374
|
const repoArg = positionalArgs[0];
|
|
7375
7375
|
if (!repoArg) {
|
|
7376
|
-
console.error("Usage:
|
|
7376
|
+
console.error("Usage: bfi publish <repo-url> --from git [options]");
|
|
7377
7377
|
console.log("Publish skills from a Git repository using server-side discovery.");
|
|
7378
7378
|
console.log();
|
|
7379
7379
|
console.log("Examples:");
|
|
7380
|
-
console.log(` ${DIM$4}$ ${RESET$4}
|
|
7381
|
-
console.log(` ${DIM$4}$ ${RESET$4}
|
|
7380
|
+
console.log(` ${DIM$4}$ ${RESET$4}bfi publish https://github.com/user/repo --from git`);
|
|
7381
|
+
console.log(` ${DIM$4}$ ${RESET$4}bfi publish user/repo --from git --branch main`);
|
|
7382
7382
|
process.exit(1);
|
|
7383
7383
|
}
|
|
7384
7384
|
let repoUrl;
|
|
@@ -7581,11 +7581,11 @@ async function runPackage(args, globalOpts) {
|
|
|
7581
7581
|
function printPackageHelp() {
|
|
7582
7582
|
console.log();
|
|
7583
7583
|
console.log(`${BOLD$1}Package Commands:${RESET$3}`);
|
|
7584
|
-
console.log(` ${DIM$3}
|
|
7585
|
-
console.log(` ${DIM$3}
|
|
7586
|
-
console.log(` ${DIM$3}
|
|
7587
|
-
console.log(` ${DIM$3}
|
|
7588
|
-
console.log(` ${DIM$3}
|
|
7584
|
+
console.log(` ${DIM$3}bfi package list${RESET$3} List packages`);
|
|
7585
|
+
console.log(` ${DIM$3}bfi package info <ref>${RESET$3} Show package details`);
|
|
7586
|
+
console.log(` ${DIM$3}bfi package create <slug>${RESET$3} Create new package`);
|
|
7587
|
+
console.log(` ${DIM$3}bfi package add <pkg> <skills>${RESET$3} Add skills to package`);
|
|
7588
|
+
console.log(` ${DIM$3}bfi package remove <pkg> <skills>${RESET$3} Remove skills from package`);
|
|
7589
7589
|
console.log();
|
|
7590
7590
|
console.log(`${BOLD$1}Options:${RESET$3}`);
|
|
7591
7591
|
console.log(` --namespace <ns> Target namespace`);
|
|
@@ -7595,11 +7595,11 @@ function printPackageHelp() {
|
|
|
7595
7595
|
console.log(` --json Output as JSON`);
|
|
7596
7596
|
console.log();
|
|
7597
7597
|
console.log(`${BOLD$1}Examples:${RESET$3}`);
|
|
7598
|
-
console.log(` ${DIM$3}$ ${RESET$3}
|
|
7599
|
-
console.log(` ${DIM$3}$ ${RESET$3}
|
|
7600
|
-
console.log(` ${DIM$3}$ ${RESET$3}
|
|
7601
|
-
console.log(` ${DIM$3}$ ${RESET$3}
|
|
7602
|
-
console.log(` ${DIM$3}$ ${RESET$3}
|
|
7598
|
+
console.log(` ${DIM$3}$ ${RESET$3}bfi package list --namespace myteam`);
|
|
7599
|
+
console.log(` ${DIM$3}$ ${RESET$3}bfi package info @myteam/my-package`);
|
|
7600
|
+
console.log(` ${DIM$3}$ ${RESET$3}bfi package create my-utils --namespace myteam`);
|
|
7601
|
+
console.log(` ${DIM$3}$ ${RESET$3}bfi package add @myteam/my-package @myteam/skill-a @myteam/skill-b`);
|
|
7602
|
+
console.log(` ${DIM$3}$ ${RESET$3}bfi package remove @myteam/my-package @myteam/skill-a`);
|
|
7603
7603
|
console.log();
|
|
7604
7604
|
}
|
|
7605
7605
|
async function handleList(args, api, globalOpts) {
|
|
@@ -7637,11 +7637,11 @@ async function handleList(args, api, globalOpts) {
|
|
|
7637
7637
|
async function handleInfo(args, api, globalOpts) {
|
|
7638
7638
|
const pkgRef = args[0];
|
|
7639
7639
|
if (!pkgRef) {
|
|
7640
|
-
console.error("Usage:
|
|
7640
|
+
console.error("Usage: bfi package info <package-ref>");
|
|
7641
7641
|
console.log();
|
|
7642
7642
|
console.log("Examples:");
|
|
7643
|
-
console.log("
|
|
7644
|
-
console.log("
|
|
7643
|
+
console.log(" bfi package info @myteam/my-package");
|
|
7644
|
+
console.log(" bfi package info myteam--my-package");
|
|
7645
7645
|
process.exit(1);
|
|
7646
7646
|
}
|
|
7647
7647
|
const json = args.includes("--json");
|
|
@@ -7675,7 +7675,7 @@ async function handleInfo(args, api, globalOpts) {
|
|
|
7675
7675
|
async function handleCreate(args, api, globalOpts) {
|
|
7676
7676
|
const slug = args[0];
|
|
7677
7677
|
if (!slug) {
|
|
7678
|
-
console.error("Usage:
|
|
7678
|
+
console.error("Usage: bfi package create <slug> [options]");
|
|
7679
7679
|
process.exit(1);
|
|
7680
7680
|
}
|
|
7681
7681
|
const namespace = getOptionValue(args, "--namespace") || globalOpts.namespace || "global";
|
|
@@ -7704,7 +7704,7 @@ async function handleAdd(args, api, globalOpts) {
|
|
|
7704
7704
|
const pkgRef = args[0];
|
|
7705
7705
|
const skillRefs = args.slice(1);
|
|
7706
7706
|
if (!pkgRef || skillRefs.length === 0) {
|
|
7707
|
-
console.error("Usage:
|
|
7707
|
+
console.error("Usage: bfi package add <package-ref> <skill-ref...>");
|
|
7708
7708
|
process.exit(1);
|
|
7709
7709
|
}
|
|
7710
7710
|
const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
|
|
@@ -7728,7 +7728,7 @@ async function handleRemove(args, api, globalOpts) {
|
|
|
7728
7728
|
const pkgRef = args[0];
|
|
7729
7729
|
const skillRefs = args.slice(1);
|
|
7730
7730
|
if (!pkgRef || skillRefs.length === 0) {
|
|
7731
|
-
console.error("Usage:
|
|
7731
|
+
console.error("Usage: bfi package remove <package-ref> <skill-ref...>");
|
|
7732
7732
|
process.exit(1);
|
|
7733
7733
|
}
|
|
7734
7734
|
const { namespace, slug } = parseSkillRef(pkgRef, globalOpts.namespace);
|
|
@@ -7760,13 +7760,13 @@ const RED = "\x1B[31m";
|
|
|
7760
7760
|
async function runLog(args, globalOpts) {
|
|
7761
7761
|
const skillRef = args[0];
|
|
7762
7762
|
if (!skillRef) {
|
|
7763
|
-
console.log("Usage:
|
|
7763
|
+
console.log("Usage: bfi log <skill-ref> [summary]");
|
|
7764
7764
|
console.log();
|
|
7765
7765
|
console.log("Log skill usage to SkillHub for tracking and analytics.");
|
|
7766
7766
|
console.log();
|
|
7767
7767
|
console.log("Examples:");
|
|
7768
|
-
console.log(` ${DIM$2}$ ${RESET$2}
|
|
7769
|
-
console.log(` ${DIM$2}$ ${RESET$2}
|
|
7768
|
+
console.log(` ${DIM$2}$ ${RESET$2}bfi log @myteam/my-skill`);
|
|
7769
|
+
console.log(` ${DIM$2}$ ${RESET$2}bfi log my-skill "Used for code review"`);
|
|
7770
7770
|
process.exit(1);
|
|
7771
7771
|
}
|
|
7772
7772
|
const summary = args.slice(1).join(" ") || "";
|
|
@@ -7792,8 +7792,8 @@ async function runInstall(args, globalOpts) {
|
|
|
7792
7792
|
const skillEntries = Object.entries(lock.skills);
|
|
7793
7793
|
const packageEntries = Object.entries(lock.packages);
|
|
7794
7794
|
if (skillEntries.length === 0 && packageEntries.length === 0) {
|
|
7795
|
-
console.log(`${DIM$1}No skills or packages found in lockfile (.
|
|
7796
|
-
console.log(`${DIM$1}Run '
|
|
7795
|
+
console.log(`${DIM$1}No skills or packages found in lockfile (.bfi/lock.json).${RESET$1}`);
|
|
7796
|
+
console.log(`${DIM$1}Run 'bfi skills add <source>' to install skills first.${RESET$1}`);
|
|
7797
7797
|
return;
|
|
7798
7798
|
}
|
|
7799
7799
|
console.log();
|
|
@@ -7860,12 +7860,12 @@ const BOLD = "\x1B[1m";
|
|
|
7860
7860
|
const DIM = "\x1B[38;5;102m";
|
|
7861
7861
|
const TEXT = "\x1B[38;5;145m";
|
|
7862
7862
|
const LOGO_LINES = [
|
|
7863
|
-
"
|
|
7864
|
-
"
|
|
7865
|
-
"
|
|
7866
|
-
"
|
|
7867
|
-
"
|
|
7868
|
-
"
|
|
7863
|
+
"██████╗ ███████╗██╗",
|
|
7864
|
+
"██╔══██╗██╔════╝██║",
|
|
7865
|
+
"██████╔╝█████╗ ██║",
|
|
7866
|
+
"██╔══██╗██╔══╝ ██║",
|
|
7867
|
+
"██████╔╝██║ ██║",
|
|
7868
|
+
"╚═════╝ ╚═╝ ╚═╝"
|
|
7869
7869
|
];
|
|
7870
7870
|
const GRAYS = [
|
|
7871
7871
|
"\x1B[38;5;250m",
|
|
@@ -7886,12 +7886,12 @@ function showBanner() {
|
|
|
7886
7886
|
console.log();
|
|
7887
7887
|
console.log(`${DIM}SkillHub CLI${RESET}`);
|
|
7888
7888
|
console.log();
|
|
7889
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7890
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7891
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7892
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7893
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7894
|
-
console.log(` ${DIM}$${RESET} ${TEXT}npx
|
|
7889
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills add ${DIM}<source>${RESET}`);
|
|
7890
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills use ${DIM}<source>${RESET}`);
|
|
7891
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills remove${RESET}`);
|
|
7892
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills list${RESET}`);
|
|
7893
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills search ${DIM}[query]${RESET}`);
|
|
7894
|
+
console.log(` ${DIM}$${RESET} ${TEXT}npx bfi skills update${RESET}`);
|
|
7895
7895
|
console.log();
|
|
7896
7896
|
console.log(`Discover more skills at ${TEXT}https://skills.sh/${RESET}`);
|
|
7897
7897
|
console.log(`and at ${TEXT}https://skillhub.skillhub.woa.com/${RESET}`);
|
|
@@ -7899,7 +7899,7 @@ function showBanner() {
|
|
|
7899
7899
|
}
|
|
7900
7900
|
function showHelp() {
|
|
7901
7901
|
console.log(`
|
|
7902
|
-
${BOLD}Usage:${RESET}
|
|
7902
|
+
${BOLD}Usage:${RESET} bfi <command> [options]
|
|
7903
7903
|
|
|
7904
7904
|
${BOLD}Manage Skills:${RESET}
|
|
7905
7905
|
skills add <source> Add a skill package
|
|
@@ -7958,26 +7958,26 @@ ${BOLD}Options:${RESET}
|
|
|
7958
7958
|
--version, -v Show version number
|
|
7959
7959
|
|
|
7960
7960
|
${BOLD}Examples:${RESET}
|
|
7961
|
-
${DIM}$${RESET}
|
|
7962
|
-
${DIM}$${RESET}
|
|
7963
|
-
${DIM}$${RESET}
|
|
7964
|
-
${DIM}$${RESET}
|
|
7965
|
-
${DIM}$${RESET}
|
|
7966
|
-
${DIM}$${RESET}
|
|
7967
|
-
${DIM}$${RESET}
|
|
7968
|
-
${DIM}$${RESET}
|
|
7969
|
-
${DIM}$${RESET}
|
|
7970
|
-
${DIM}$${RESET}
|
|
7971
|
-
${DIM}$${RESET}
|
|
7972
|
-
${DIM}$${RESET}
|
|
7973
|
-
${DIM}$${RESET}
|
|
7974
|
-
${DIM}$${RESET}
|
|
7975
|
-
${DIM}$${RESET}
|
|
7976
|
-
${DIM}$${RESET}
|
|
7977
|
-
${DIM}$${RESET}
|
|
7978
|
-
${DIM}$${RESET}
|
|
7979
|
-
${DIM}$${RESET}
|
|
7980
|
-
${DIM}$${RESET}
|
|
7961
|
+
${DIM}$${RESET} bfi skills add vercel-labs/agent-skills
|
|
7962
|
+
${DIM}$${RESET} bfi skills use vercel-labs/agent-skills@vercel-optimize | claude
|
|
7963
|
+
${DIM}$${RESET} bfi skills use vercel-labs/agent-skills --skill vercel-optimize --agent claude-code
|
|
7964
|
+
${DIM}$${RESET} bfi skills add vercel-labs/agent-skills -g
|
|
7965
|
+
${DIM}$${RESET} bfi skills add vercel-labs/agent-skills --agent claude-code cursor
|
|
7966
|
+
${DIM}$${RESET} bfi skills add vercel-labs/agent-skills --skill pr-review commit
|
|
7967
|
+
${DIM}$${RESET} bfi skills remove ${DIM}# interactive remove${RESET}
|
|
7968
|
+
${DIM}$${RESET} bfi skills remove web-design ${DIM}# remove by name${RESET}
|
|
7969
|
+
${DIM}$${RESET} bfi skills rm --global frontend-design
|
|
7970
|
+
${DIM}$${RESET} bfi skills list ${DIM}# list project skills${RESET}
|
|
7971
|
+
${DIM}$${RESET} bfi skills ls -g ${DIM}# list global skills${RESET}
|
|
7972
|
+
${DIM}$${RESET} bfi skills ls -a claude-code ${DIM}# filter by agent${RESET}
|
|
7973
|
+
${DIM}$${RESET} bfi skills ls --json ${DIM}# JSON output${RESET}
|
|
7974
|
+
${DIM}$${RESET} bfi skills search ${DIM}# interactive search${RESET}
|
|
7975
|
+
${DIM}$${RESET} bfi skills search typescript ${DIM}# search by keyword${RESET}
|
|
7976
|
+
${DIM}$${RESET} bfi skills search react --owner vercel ${DIM}# search within an owner${RESET}
|
|
7977
|
+
${DIM}$${RESET} bfi skills update
|
|
7978
|
+
${DIM}$${RESET} bfi skills update my-skill ${DIM}# update a single skill${RESET}
|
|
7979
|
+
${DIM}$${RESET} bfi skills update -g ${DIM}# update global skills only${RESET}
|
|
7980
|
+
${DIM}$${RESET} bfi init my-skill
|
|
7981
7981
|
|
|
7982
7982
|
Discover more skills at ${TEXT}https://skills.sh/${RESET}
|
|
7983
7983
|
and at ${TEXT}https://skillhub.skillhub.woa.com/${RESET}
|
|
@@ -7985,7 +7985,7 @@ and at ${TEXT}https://skillhub.skillhub.woa.com/${RESET}
|
|
|
7985
7985
|
}
|
|
7986
7986
|
function showRemoveHelp() {
|
|
7987
7987
|
console.log(`
|
|
7988
|
-
${BOLD}Usage:${RESET}
|
|
7988
|
+
${BOLD}Usage:${RESET} bfi skills remove [skills...] [options]
|
|
7989
7989
|
|
|
7990
7990
|
${BOLD}Description:${RESET}
|
|
7991
7991
|
Remove installed skills from agents. If no skill names are provided,
|
|
@@ -8002,13 +8002,13 @@ ${BOLD}Options:${RESET}
|
|
|
8002
8002
|
--all Shorthand for --skill '*' --agent '*' -y
|
|
8003
8003
|
|
|
8004
8004
|
${BOLD}Examples:${RESET}
|
|
8005
|
-
${DIM}$${RESET}
|
|
8006
|
-
${DIM}$${RESET}
|
|
8007
|
-
${DIM}$${RESET}
|
|
8008
|
-
${DIM}$${RESET}
|
|
8009
|
-
${DIM}$${RESET}
|
|
8010
|
-
${DIM}$${RESET}
|
|
8011
|
-
${DIM}$${RESET}
|
|
8005
|
+
${DIM}$${RESET} bfi skills remove ${DIM}# interactive selection${RESET}
|
|
8006
|
+
${DIM}$${RESET} bfi skills remove my-skill ${DIM}# remove specific skill${RESET}
|
|
8007
|
+
${DIM}$${RESET} bfi skills remove skill1 skill2 -y ${DIM}# remove multiple skills${RESET}
|
|
8008
|
+
${DIM}$${RESET} bfi skills remove --global my-skill ${DIM}# remove from global scope${RESET}
|
|
8009
|
+
${DIM}$${RESET} bfi skills rm --agent claude-code my-skill ${DIM}# remove from specific agent${RESET}
|
|
8010
|
+
${DIM}$${RESET} bfi skills remove --all ${DIM}# remove all skills${RESET}
|
|
8011
|
+
${DIM}$${RESET} bfi skills remove --skill '*' -a cursor ${DIM}# remove all skills from cursor${RESET}
|
|
8012
8012
|
|
|
8013
8013
|
Discover more skills at ${TEXT}https://skills.sh/${RESET}
|
|
8014
8014
|
and at ${TEXT}https://skillhub.skillhub.woa.com/${RESET}
|
|
@@ -8055,8 +8055,8 @@ Describe when this skill should be used.
|
|
|
8055
8055
|
console.log(` 2. Update the ${TEXT}name${RESET} and ${TEXT}description${RESET} in the frontmatter`);
|
|
8056
8056
|
console.log();
|
|
8057
8057
|
console.log(`${DIM}Publishing:${RESET}`);
|
|
8058
|
-
console.log(` ${DIM}GitHub:${RESET} Push to a repo, then ${TEXT}npx
|
|
8059
|
-
console.log(` ${DIM}URL:${RESET} Host the file, then ${TEXT}npx
|
|
8058
|
+
console.log(` ${DIM}GitHub:${RESET} Push to a repo, then ${TEXT}npx bfi skills add <owner>/<repo>${RESET}`);
|
|
8059
|
+
console.log(` ${DIM}URL:${RESET} Host the file, then ${TEXT}npx bfi skills add https://example.com/${displayPath}${RESET}`);
|
|
8060
8060
|
console.log();
|
|
8061
8061
|
console.log(`Browse existing skills for inspiration at ${TEXT}https://skills.sh/${RESET}`);
|
|
8062
8062
|
console.log();
|
|
@@ -8157,7 +8157,7 @@ async function dispatchSkillSubcommand(args, globalOpts) {
|
|
|
8157
8157
|
break;
|
|
8158
8158
|
default: if (!sub || sub.startsWith("-")) {
|
|
8159
8159
|
console.log();
|
|
8160
|
-
console.log(`${BOLD}Usage:${RESET}
|
|
8160
|
+
console.log(`${BOLD}Usage:${RESET} bfi skills <command> [options]`);
|
|
8161
8161
|
console.log();
|
|
8162
8162
|
console.log(`${BOLD}Commands:${RESET}`);
|
|
8163
8163
|
console.log(` add <source> Add a skill package`);
|
|
@@ -8182,10 +8182,10 @@ async function dispatchSkillSubcommand(args, globalOpts) {
|
|
|
8182
8182
|
console.log(`${BOLD}Docs:${RESET}`);
|
|
8183
8183
|
console.log(` docs <cmd> Document management`);
|
|
8184
8184
|
console.log();
|
|
8185
|
-
console.log(`Run ${BOLD}
|
|
8185
|
+
console.log(`Run ${BOLD}bfi --help${RESET} for more details.`);
|
|
8186
8186
|
} else {
|
|
8187
8187
|
console.log(`Unknown skills command: ${sub}`);
|
|
8188
|
-
console.log(`Run ${BOLD}
|
|
8188
|
+
console.log(`Run ${BOLD}bfi skills --help${RESET} for usage.`);
|
|
8189
8189
|
}
|
|
8190
8190
|
}
|
|
8191
8191
|
}
|
|
@@ -8313,7 +8313,7 @@ async function main() {
|
|
|
8313
8313
|
break;
|
|
8314
8314
|
default:
|
|
8315
8315
|
console.log(`Unknown command: ${command}`);
|
|
8316
|
-
console.log(`Run ${BOLD}
|
|
8316
|
+
console.log(`Run ${BOLD}bfi --help${RESET} for usage.`);
|
|
8317
8317
|
}
|
|
8318
8318
|
}
|
|
8319
8319
|
main().finally(() => process.exit(process.exitCode ?? 0));
|
package/package.json
CHANGED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bfi-skill
|
|
3
|
+
description: 使用 bfi CLI 在 SkillHub 上搜索、安装、发布和管理技能。当用户需要查找技能、从任意来源安装技能、发布技能到 SkillHub 或管理技能包时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# bfi-skill — SkillHub 命令行工具
|
|
7
|
+
|
|
8
|
+
bfi 是 SkillHub 生态的统一命令行工具。融合了开源 agent skills 生态能力(70+ AI agent 支持、GitHub/GitLab/URL 多源安装)和 SkillHub 专有功能(发布、包管理、认证)。
|
|
9
|
+
|
|
10
|
+
## 何时使用
|
|
11
|
+
|
|
12
|
+
当用户有以下需求时使用 bfi:
|
|
13
|
+
- 搜索技能("帮我找个 React 技能"、"搜索数据库相关的技能")
|
|
14
|
+
- 安装技能("安装这个技能"、"把 db-explore 装上")
|
|
15
|
+
- 发布技能("发布我的技能"、"把这个技能上传到 SkillHub")
|
|
16
|
+
- 管理技能包("创建一个技能包"、"把几个技能打包")
|
|
17
|
+
- 认证操作("登录 skillhub"、"查看当前用户")
|
|
18
|
+
- 查看/卸载已安装技能("我装了哪些技能"、"卸载某某技能")
|
|
19
|
+
|
|
20
|
+
## 全局选项
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
--token <token> API Token(也可通过 BFI_TOKEN 环境变量设置)
|
|
24
|
+
--registry <url> API 地址(默认: https://bfi.yyuap.com:811)
|
|
25
|
+
--namespace <ns> 默认命名空间(默认: global)
|
|
26
|
+
--help, -h 显示帮助
|
|
27
|
+
--version, -v 显示版本
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Token 解析优先级:CLI `--token` → 环境变量 `BFI_TOKEN` → 项目配置 `.bfirc` → 全局配置 `~/.bfirc`
|
|
31
|
+
|
|
32
|
+
## 命令参考
|
|
33
|
+
|
|
34
|
+
### 认证
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bfi auth login --token <token> # 保存 API Token 到本地
|
|
38
|
+
bfi auth logout # 清除已保存的 Token
|
|
39
|
+
bfi auth whoami # 查看当前登录用户信息
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 搜索
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bfi skills search <关键词> # 搜索 SkillHub 市场(默认)
|
|
46
|
+
bfi skills search <关键词> --namespace <ns> # 在指定命名空间搜索
|
|
47
|
+
bfi skills search <关键词> --marketplace # 搜索 skills.sh 公开市场
|
|
48
|
+
bfi skills search <关键词> --all # 同时搜索 SkillHub + skills.sh
|
|
49
|
+
bfi skills search <关键词> --json # JSON 格式输出
|
|
50
|
+
bfi skills search <关键词> --limit 50 # 最大返回数(默认 20)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 安装
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# 从 SkillHub 安装
|
|
57
|
+
bfi skills add @命名空间/技能名 # 从 SkillHub 安装指定技能
|
|
58
|
+
bfi skills add 命名空间--技能名 # 兼容格式
|
|
59
|
+
bfi skills add 技能名 # 跨命名空间搜索并安装
|
|
60
|
+
|
|
61
|
+
# 从 GitHub/GitLab 安装
|
|
62
|
+
bfi skills add owner/repo # GitHub 简写
|
|
63
|
+
bfi skills add owner/repo/路径/到/技能 # 指定子目录
|
|
64
|
+
bfi skills add owner/repo@技能名 # 指定仓库中的某个技能
|
|
65
|
+
bfi skills add https://github.com/owner/repo # 完整 URL
|
|
66
|
+
bfi skills add gitlab:owner/repo # GitLab 简写
|
|
67
|
+
|
|
68
|
+
# 安装选项
|
|
69
|
+
bfi skills add <来源> --skill <名称> # 安装指定技能
|
|
70
|
+
bfi skills add <来源> --agent <agent> # 安装到指定 agent
|
|
71
|
+
bfi skills add <来源> -g # 全局安装
|
|
72
|
+
bfi skills add <来源> --all # 安装全部技能到全部 agent
|
|
73
|
+
bfi skills add <来源> --list # 仅列出可用技能,不安装
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 查看
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
bfi skills list # 列出项目已安装技能
|
|
80
|
+
bfi skills ls -g # 列出全局已安装技能
|
|
81
|
+
bfi skills ls --json # JSON 格式输出
|
|
82
|
+
bfi skills ls -a claude-code # 按 agent 过滤
|
|
83
|
+
|
|
84
|
+
bfi skills info @命名空间/技能名 # 查看 SkillHub 技能详情
|
|
85
|
+
bfi skills info 命名空间--技能名 # 兼容格式
|
|
86
|
+
bfi skills info <引用> --json # JSON 格式输出
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 卸载
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
bfi skills remove # 交互式选择卸载
|
|
93
|
+
bfi skills remove 技能名 # 卸载指定技能
|
|
94
|
+
bfi skills rm -g 技能名 # 从全局卸载
|
|
95
|
+
bfi skills remove --all # 卸载全部技能
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 更新
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
bfi skills update # 更新全部已安装技能
|
|
102
|
+
bfi skills update 技能名 # 更新指定技能
|
|
103
|
+
bfi skills update -g # 更新全局技能
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 发布
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
bfi skills publish # 发布当前目录的技能
|
|
110
|
+
bfi skills publish <路径> # 从指定目录发布
|
|
111
|
+
bfi skills publish <路径> --from zip # 从 .zip 压缩包发布
|
|
112
|
+
bfi skills publish <url> --from git # 走服务端 Git API(parse → publish)
|
|
113
|
+
bfi skills publish <路径> --namespace <ns> # 指定目标命名空间
|
|
114
|
+
bfi skills publish <路径> --visibility public # 公开发布
|
|
115
|
+
bfi skills publish <路径> --yes # 跳过确认提示
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 技能包管理
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
bfi skills package list [--namespace <ns>] # 列出技能包
|
|
122
|
+
bfi skills package info @ns/包名 # 查看包详情
|
|
123
|
+
bfi skills package create <slug> [--name] [--desc] # 创建技能包
|
|
124
|
+
bfi skills package add <包名> <技能...> # 添加技能到包
|
|
125
|
+
bfi skills package remove <包名> <技能...> # 从包移除技能
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 初始化
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
bfi skills init # 在当前目录创建 SKILL.md
|
|
132
|
+
bfi skills init 技能名 # 在子目录中创建 SKILL.md
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 技能引用格式
|
|
136
|
+
|
|
137
|
+
SkillHub 技能使用带命名空间的引用格式:
|
|
138
|
+
|
|
139
|
+
| 格式 | 示例 | 说明 |
|
|
140
|
+
|------|------|------|
|
|
141
|
+
| `@ns/slug` | `@myteam/db-explore` | 命名空间 myteam,技能 db-explore |
|
|
142
|
+
| `ns--slug` | `myteam--db-explore` | 同上(兼容旧格式) |
|
|
143
|
+
| `slug` | `db-explore` | 仅 slug,安装时自动搜索全部命名空间 |
|
|
144
|
+
|
|
145
|
+
## 配置管理
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
bfi config get # 查看全部配置
|
|
149
|
+
bfi config get registry # 查看指定配置项
|
|
150
|
+
bfi config set registry <url> # 设置项目配置
|
|
151
|
+
bfi config set registry <url> --global # 设置全局配置
|
|
152
|
+
bfi config set namespace <ns> # 设置默认命名空间
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 典型用法示例
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# 完整流程:搜索 → 安装 → 查看
|
|
159
|
+
bfi skills search react
|
|
160
|
+
bfi skills add @myteam/react-best-practices
|
|
161
|
+
bfi skills list
|
|
162
|
+
|
|
163
|
+
# 发布技能
|
|
164
|
+
bfi skills init my-skill
|
|
165
|
+
# ... 编辑 my-skill/SKILL.md ...
|
|
166
|
+
bfi auth login --token sk-xxx
|
|
167
|
+
bfi skills publish my-skill --namespace myteam --visibility public
|
|
168
|
+
|
|
169
|
+
# 技能包管理
|
|
170
|
+
bfi skills package create frontend-kit --namespace myteam
|
|
171
|
+
bfi skills package add @myteam/frontend-kit @myteam/react-best-practices @myteam/css-guide
|
|
172
|
+
bfi skills package info @myteam/frontend-kit
|
|
173
|
+
|
|
174
|
+
# 从 GitHub 安装
|
|
175
|
+
bfi skills add vercel-labs/agent-skills --skill pr-review --agent claude-code
|
|
176
|
+
```
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gbfi-skill
|
|
3
|
-
description: 使用 gbfi CLI 在 SkillHub 上搜索、安装、发布和管理技能。当用户需要查找技能、从任意来源安装技能、发布技能到 SkillHub 或管理技能包时使用。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# gbfi-skill — SkillHub 命令行工具
|
|
7
|
-
|
|
8
|
-
gbfi 是 SkillHub 生态的统一命令行工具。融合了开源 agent skills 生态能力(70+ AI agent 支持、GitHub/GitLab/URL 多源安装)和 SkillHub 专有功能(发布、包管理、认证)。
|
|
9
|
-
|
|
10
|
-
## 何时使用
|
|
11
|
-
|
|
12
|
-
当用户有以下需求时使用 gbfi:
|
|
13
|
-
- 搜索技能("帮我找个 React 技能"、"搜索数据库相关的技能")
|
|
14
|
-
- 安装技能("安装这个技能"、"把 db-explore 装上")
|
|
15
|
-
- 发布技能("发布我的技能"、"把这个技能上传到 SkillHub")
|
|
16
|
-
- 管理技能包("创建一个技能包"、"把几个技能打包")
|
|
17
|
-
- 认证操作("登录 skillhub"、"查看当前用户")
|
|
18
|
-
- 查看/卸载已安装技能("我装了哪些技能"、"卸载某某技能")
|
|
19
|
-
|
|
20
|
-
## 全局选项
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
--token <token> API Token(也可通过 GBFI_TOKEN 环境变量设置)
|
|
24
|
-
--registry <url> API 地址(默认: https://bfi.yyuap.com:811)
|
|
25
|
-
--namespace <ns> 默认命名空间(默认: global)
|
|
26
|
-
--help, -h 显示帮助
|
|
27
|
-
--version, -v 显示版本
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Token 解析优先级:CLI `--token` → 环境变量 `GBFI_TOKEN` → 项目配置 `.gbfirc` → 全局配置 `~/.gbfirc`
|
|
31
|
-
|
|
32
|
-
## 命令参考
|
|
33
|
-
|
|
34
|
-
### 认证
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
gbfi auth login --token <token> # 保存 API Token 到本地
|
|
38
|
-
gbfi auth logout # 清除已保存的 Token
|
|
39
|
-
gbfi auth whoami # 查看当前登录用户信息
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 搜索
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
gbfi skills search <关键词> # 搜索 SkillHub 市场(默认)
|
|
46
|
-
gbfi skills search <关键词> --namespace <ns> # 在指定命名空间搜索
|
|
47
|
-
gbfi skills search <关键词> --marketplace # 搜索 skills.sh 公开市场
|
|
48
|
-
gbfi skills search <关键词> --all # 同时搜索 SkillHub + skills.sh
|
|
49
|
-
gbfi skills search <关键词> --json # JSON 格式输出
|
|
50
|
-
gbfi skills search <关键词> --limit 50 # 最大返回数(默认 20)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### 安装
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# 从 SkillHub 安装
|
|
57
|
-
gbfi skills add @命名空间/技能名 # 从 SkillHub 安装指定技能
|
|
58
|
-
gbfi skills add 命名空间--技能名 # 兼容格式
|
|
59
|
-
gbfi skills add 技能名 # 跨命名空间搜索并安装
|
|
60
|
-
|
|
61
|
-
# 从 GitHub/GitLab 安装
|
|
62
|
-
gbfi skills add owner/repo # GitHub 简写
|
|
63
|
-
gbfi skills add owner/repo/路径/到/技能 # 指定子目录
|
|
64
|
-
gbfi skills add owner/repo@技能名 # 指定仓库中的某个技能
|
|
65
|
-
gbfi skills add https://github.com/owner/repo # 完整 URL
|
|
66
|
-
gbfi skills add gitlab:owner/repo # GitLab 简写
|
|
67
|
-
|
|
68
|
-
# 安装选项
|
|
69
|
-
gbfi skills add <来源> --skill <名称> # 安装指定技能
|
|
70
|
-
gbfi skills add <来源> --agent <agent> # 安装到指定 agent
|
|
71
|
-
gbfi skills add <来源> -g # 全局安装
|
|
72
|
-
gbfi skills add <来源> --all # 安装全部技能到全部 agent
|
|
73
|
-
gbfi skills add <来源> --list # 仅列出可用技能,不安装
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### 查看
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
gbfi skills list # 列出项目已安装技能
|
|
80
|
-
gbfi skills ls -g # 列出全局已安装技能
|
|
81
|
-
gbfi skills ls --json # JSON 格式输出
|
|
82
|
-
gbfi skills ls -a claude-code # 按 agent 过滤
|
|
83
|
-
|
|
84
|
-
gbfi skills info @命名空间/技能名 # 查看 SkillHub 技能详情
|
|
85
|
-
gbfi skills info 命名空间--技能名 # 兼容格式
|
|
86
|
-
gbfi skills info <引用> --json # JSON 格式输出
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### 卸载
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
gbfi skills remove # 交互式选择卸载
|
|
93
|
-
gbfi skills remove 技能名 # 卸载指定技能
|
|
94
|
-
gbfi skills rm -g 技能名 # 从全局卸载
|
|
95
|
-
gbfi skills remove --all # 卸载全部技能
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 更新
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
gbfi skills update # 更新全部已安装技能
|
|
102
|
-
gbfi skills update 技能名 # 更新指定技能
|
|
103
|
-
gbfi skills update -g # 更新全局技能
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### 发布
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
gbfi skills publish # 发布当前目录的技能
|
|
110
|
-
gbfi skills publish <路径> # 从指定目录发布
|
|
111
|
-
gbfi skills publish <路径> --from zip # 从 .zip 压缩包发布
|
|
112
|
-
gbfi skills publish <url> --from git # 走服务端 Git API(parse → publish)
|
|
113
|
-
gbfi skills publish <路径> --namespace <ns> # 指定目标命名空间
|
|
114
|
-
gbfi skills publish <路径> --visibility public # 公开发布
|
|
115
|
-
gbfi skills publish <路径> --yes # 跳过确认提示
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### 技能包管理
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
gbfi skills package list [--namespace <ns>] # 列出技能包
|
|
122
|
-
gbfi skills package info @ns/包名 # 查看包详情
|
|
123
|
-
gbfi skills package create <slug> [--name] [--desc] # 创建技能包
|
|
124
|
-
gbfi skills package add <包名> <技能...> # 添加技能到包
|
|
125
|
-
gbfi skills package remove <包名> <技能...> # 从包移除技能
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### 初始化
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
gbfi skills init # 在当前目录创建 SKILL.md
|
|
132
|
-
gbfi skills init 技能名 # 在子目录中创建 SKILL.md
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## 技能引用格式
|
|
136
|
-
|
|
137
|
-
SkillHub 技能使用带命名空间的引用格式:
|
|
138
|
-
|
|
139
|
-
| 格式 | 示例 | 说明 |
|
|
140
|
-
|------|------|------|
|
|
141
|
-
| `@ns/slug` | `@myteam/db-explore` | 命名空间 myteam,技能 db-explore |
|
|
142
|
-
| `ns--slug` | `myteam--db-explore` | 同上(兼容旧格式) |
|
|
143
|
-
| `slug` | `db-explore` | 仅 slug,安装时自动搜索全部命名空间 |
|
|
144
|
-
|
|
145
|
-
## 配置管理
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
gbfi config get # 查看全部配置
|
|
149
|
-
gbfi config get registry # 查看指定配置项
|
|
150
|
-
gbfi config set registry <url> # 设置项目配置
|
|
151
|
-
gbfi config set registry <url> --global # 设置全局配置
|
|
152
|
-
gbfi config set namespace <ns> # 设置默认命名空间
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## 典型用法示例
|
|
156
|
-
|
|
157
|
-
```bash
|
|
158
|
-
# 完整流程:搜索 → 安装 → 查看
|
|
159
|
-
gbfi skills search react
|
|
160
|
-
gbfi skills add @myteam/react-best-practices
|
|
161
|
-
gbfi skills list
|
|
162
|
-
|
|
163
|
-
# 发布技能
|
|
164
|
-
gbfi skills init my-skill
|
|
165
|
-
# ... 编辑 my-skill/SKILL.md ...
|
|
166
|
-
gbfi auth login --token sk-xxx
|
|
167
|
-
gbfi skills publish my-skill --namespace myteam --visibility public
|
|
168
|
-
|
|
169
|
-
# 技能包管理
|
|
170
|
-
gbfi skills package create frontend-kit --namespace myteam
|
|
171
|
-
gbfi skills package add @myteam/frontend-kit @myteam/react-best-practices @myteam/css-guide
|
|
172
|
-
gbfi skills package info @myteam/frontend-kit
|
|
173
|
-
|
|
174
|
-
# 从 GitHub 安装
|
|
175
|
-
gbfi skills add vercel-labs/agent-skills --skill pr-review --agent claude-code
|
|
176
|
-
```
|