@bgicli/bgicli 2.2.13 → 2.2.14

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/bgi.js +180 -6
  2. package/package.json +1 -1
package/dist/bgi.js CHANGED
@@ -15410,7 +15410,85 @@ function clearCheckpoints(sessionId) {
15410
15410
 
15411
15411
  // src/index.ts
15412
15412
  var import_fs6 = require("fs");
15413
- var VERSION2 = "2.2.13";
15413
+ var VERSION2 = "2.2.14";
15414
+ var SKILLHUB_HUBS = {
15415
+ bgi: { label: "BGI\u5185\u7F51", apiBase: "https://clawhub.ai", backend: "clawhub" },
15416
+ clawhub: { label: "clawhub.ai", apiBase: "https://clawhub.ai", backend: "clawhub" },
15417
+ tencent: { label: "Tencent", apiBase: "https://lightmake.site", backend: "tencent" }
15418
+ };
15419
+ function httpGetJson(url) {
15420
+ const mod = url.startsWith("https") ? import_https2.get : require("http").get;
15421
+ return new Promise((resolve3, reject) => {
15422
+ const req = mod(url, { headers: { "User-Agent": `bgicli/${VERSION2}`, Accept: "application/json" } }, (res) => {
15423
+ const chunks = [];
15424
+ res.on("data", (c2) => chunks.push(c2));
15425
+ res.on("end", () => {
15426
+ try {
15427
+ resolve3(JSON.parse(Buffer.concat(chunks).toString()));
15428
+ } catch (e2) {
15429
+ reject(new Error(`JSON parse error from ${url}`));
15430
+ }
15431
+ });
15432
+ });
15433
+ req.setTimeout(1e4, () => {
15434
+ req.destroy();
15435
+ reject(new Error("timeout"));
15436
+ });
15437
+ req.on("error", reject);
15438
+ });
15439
+ }
15440
+ async function searchSkillHub(query, hub, limit2 = 10) {
15441
+ const cfg = SKILLHUB_HUBS[hub];
15442
+ if (cfg.backend === "tencent") {
15443
+ const data = await httpGetJson(
15444
+ `${cfg.apiBase}/api/skills?page=1&pageSize=${limit2}&keyword=${encodeURIComponent(query)}`
15445
+ );
15446
+ if (data.code !== 0 || !data.data?.skills) return [];
15447
+ return data.data.skills.map((s2) => ({
15448
+ slug: s2.slug,
15449
+ name: s2.name,
15450
+ summary: s2.description ?? "",
15451
+ version: s2.version,
15452
+ owner: s2.ownerName ?? (s2.homepage ? s2.homepage.replace(/.*clawhub\.ai\/([^/]+)\/.*/, "$1") : void 0)
15453
+ }));
15454
+ } else {
15455
+ const data = await httpGetJson(
15456
+ `${cfg.apiBase}/api/v1/search?q=${encodeURIComponent(query)}&limit=${limit2}&nonSuspiciousOnly=true`
15457
+ );
15458
+ if (!data.results) return [];
15459
+ return data.results.map((s2) => ({
15460
+ slug: s2.slug,
15461
+ name: s2.displayName ?? s2.slug,
15462
+ summary: s2.summary ?? "",
15463
+ version: s2.version ?? void 0
15464
+ }));
15465
+ }
15466
+ }
15467
+ async function downloadSkillMd(slug) {
15468
+ const data = await new Promise((resolve3, reject) => {
15469
+ const req = (0, import_https2.get)(
15470
+ `https://clawhub.ai/api/v1/skills/${encodeURIComponent(slug)}/file?path=SKILL.md`,
15471
+ { headers: { "User-Agent": `bgicli/${VERSION2}` } },
15472
+ (res) => {
15473
+ if (res.statusCode === 404) {
15474
+ req.destroy();
15475
+ reject(new Error("not_found"));
15476
+ return;
15477
+ }
15478
+ const chunks = [];
15479
+ res.on("data", (c2) => chunks.push(c2));
15480
+ res.on("end", () => resolve3(Buffer.concat(chunks).toString()));
15481
+ }
15482
+ );
15483
+ req.setTimeout(15e3, () => {
15484
+ req.destroy();
15485
+ reject(new Error("timeout"));
15486
+ });
15487
+ req.on("error", reject);
15488
+ });
15489
+ return data;
15490
+ }
15491
+ var _lastSearchResults = [];
15414
15492
  function isNewer(latest, current) {
15415
15493
  const [lM, lm, lp] = latest.split(".").map(Number);
15416
15494
  const [cM, cm, cp] = current.split(".").map(Number);
@@ -15555,7 +15633,8 @@ function printHelp() {
15555
15633
  console.log(source_default.bold.cyan("\u2500\u2500\u2500 \u5DE5\u4F5C\u6D41\u5411\u5BFC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
15556
15634
  console.log(` ${source_default.cyan("/run")} <skill-id> \u4EA4\u4E92\u5F0F\u53C2\u6570\u5411\u5BFC\uFF0C\u81EA\u52A8\u751F\u6210\u5E76\u6267\u884C\u5206\u6790\u811A\u672C`);
15557
15635
  console.log(` ${source_default.cyan("/check-env")} [id] \u68C0\u6D4B Skill \u6240\u9700 R/Python \u5305\u662F\u5426\u5DF2\u5B89\u88C5`);
15558
- console.log(` ${source_default.cyan("/install")} <url> \u4ECE GitHub \u5B89\u88C5\u7B2C\u4E09\u65B9 Skill`);
15636
+ console.log(` ${source_default.cyan("/search")} <\u5173\u952E\u8BCD> \u5728 SkillHub \u641C\u7D22\u5E76\u4E0B\u8F7D\u6280\u80FD ${source_default.dim("[--hub=bgi|clawhub|tencent]")}`);
15637
+ console.log(` ${source_default.cyan("/install")} <url|slug> \u4ECE GitHub \u6216 SkillHub \u5B89\u88C5 Skill`);
15559
15638
  console.log(` ${source_default.cyan("/uninstall")} <id> \u5378\u8F7D\u5DF2\u5B89\u88C5\u7684\u7B2C\u4E09\u65B9 Skill`);
15560
15639
  console.log();
15561
15640
  console.log(source_default.bold.cyan("\u2500\u2500\u2500 \u6587\u4EF6 & \u76EE\u5F55 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
@@ -16417,15 +16496,110 @@ ${paramSummary}
16417
16496
  }
16418
16497
  break;
16419
16498
  }
16420
- // ── /install from GitHub ─────────────────────────────────────────────────
16499
+ // ── /search SkillHub ─────────────────────────────────────────────────────
16500
+ case "search": {
16501
+ if (!arg) {
16502
+ console.log("\u7528\u6CD5: /search <\u5173\u952E\u8BCD> [--hub=bgi|clawhub|tencent]");
16503
+ console.log(source_default.dim("\u793A\u4F8B: /search rnaseq"));
16504
+ console.log(source_default.dim(" /search \u86CB\u767D\u8D28\u7ED3\u6784\u9884\u6D4B --hub=tencent"));
16505
+ console.log(source_default.dim(" /search genomics --hub=clawhub"));
16506
+ console.log(source_default.dim("\n\u9ED8\u8BA4\u641C\u7D22 BGI \u5185\u7F51 SkillHub (http://172.16.218.40:8080)"));
16507
+ break;
16508
+ }
16509
+ let hubKey = "bgi";
16510
+ const hubMatch = arg.match(/--hub=(\w+)/);
16511
+ const query = arg.replace(/--hub=\w+/g, "").trim();
16512
+ if (hubMatch) {
16513
+ const hk = hubMatch[1];
16514
+ if (hk in SKILLHUB_HUBS) hubKey = hk;
16515
+ else {
16516
+ console.log(source_default.red(`\u672A\u77E5 hub: ${hubMatch[1]}\uFF0C\u53EF\u9009: bgi, clawhub, tencent`));
16517
+ break;
16518
+ }
16519
+ }
16520
+ if (!query) {
16521
+ console.log(source_default.yellow("\u8BF7\u63D0\u4F9B\u641C\u7D22\u5173\u952E\u8BCD"));
16522
+ break;
16523
+ }
16524
+ const hubLabel = SKILLHUB_HUBS[hubKey].label;
16525
+ process.stdout.write(source_default.dim(`\u6B63\u5728\u641C\u7D22 ${hubLabel} SkillHub: "${query}"...
16526
+ `));
16527
+ try {
16528
+ const results = await searchSkillHub(query, hubKey, 10);
16529
+ if (results.length === 0) {
16530
+ console.log(source_default.yellow(` \u672A\u627E\u5230\u76F8\u5173 Skill\uFF0C\u8BF7\u5C1D\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD`));
16531
+ break;
16532
+ }
16533
+ _lastSearchResults = results;
16534
+ console.log(source_default.bold(`
16535
+ \u641C\u7D22\u7ED3\u679C (${hubLabel}) \u2014 \u5171 ${results.length} \u4E2A:
16536
+ `));
16537
+ results.forEach((s2, i2) => {
16538
+ const ver = s2.version ? source_default.dim(` v${s2.version}`) : "";
16539
+ const owner = s2.owner ? source_default.dim(` @${s2.owner}`) : "";
16540
+ console.log(` ${source_default.cyan(`[${i2 + 1}]`)} ${source_default.bold(s2.name)}${owner}${ver}`);
16541
+ console.log(` ${source_default.dim(s2.summary.substring(0, 90))}${s2.summary.length > 90 ? "\u2026" : ""}`);
16542
+ console.log(` ${source_default.dim(`slug: ${s2.slug}`)}`);
16543
+ console.log();
16544
+ });
16545
+ console.log(source_default.dim(`\u5B89\u88C5: /install <slug> \u6216 /install <\u5E8F\u53F7> (\u5982: /install 1)`));
16546
+ } catch (e2) {
16547
+ console.log(source_default.red(`\u641C\u7D22\u5931\u8D25: ${e2 instanceof Error ? e2.message : String(e2)}`));
16548
+ }
16549
+ break;
16550
+ }
16551
+ // ── /install from GitHub or SkillHub ──────────────────────────────────────
16421
16552
  case "install": {
16422
16553
  if (!arg) {
16423
- console.log("\u7528\u6CD5: /install <github-url>");
16554
+ console.log("\u7528\u6CD5: /install <github-url | slug | \u641C\u7D22\u5E8F\u53F7>");
16424
16555
  console.log(source_default.dim("\u793A\u4F8B: /install https://github.com/user/my-skill"));
16425
- console.log(source_default.dim(" /install user/repo (GitHub \u7B80\u5199)"));
16556
+ console.log(source_default.dim(" /install user/repo (GitHub \u7B80\u5199)"));
16557
+ console.log(source_default.dim(" /install personal-genomics (SkillHub slug)"));
16558
+ console.log(source_default.dim(" /install 2 (\u641C\u7D22\u7ED3\u679C\u5E8F\u53F7)"));
16559
+ break;
16560
+ }
16561
+ let installArg = arg;
16562
+ const searchNum = /^\d+$/.test(installArg) ? parseInt(installArg, 10) : 0;
16563
+ if (searchNum > 0 && _lastSearchResults.length > 0) {
16564
+ if (searchNum > _lastSearchResults.length) {
16565
+ console.log(source_default.red(`\u5E8F\u53F7 ${searchNum} \u8D85\u51FA\u8303\u56F4\uFF08\u5171 ${_lastSearchResults.length} \u4E2A\u7ED3\u679C\uFF09`));
16566
+ break;
16567
+ }
16568
+ const picked = _lastSearchResults[searchNum - 1];
16569
+ console.log(source_default.dim(`\u4ECE\u641C\u7D22\u7ED3\u679C\u5B89\u88C5: ${picked.name} (${picked.slug})`));
16570
+ installArg = picked.slug;
16571
+ }
16572
+ const isGitHub = installArg.includes("github.com") || installArg.includes("gitlab") || installArg.includes("bitbucket") || /^[^/]+\/[^/]+$/.test(installArg);
16573
+ if (!isGitHub && !installArg.startsWith("http")) {
16574
+ const slug = installArg.trim();
16575
+ const installTarget2 = (0, import_path5.join)(SKILLS_DIR, slug);
16576
+ if ((0, import_fs5.existsSync)(installTarget2)) {
16577
+ console.log(source_default.yellow(`Skill "${slug}" \u5DF2\u5B58\u5728\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u5148 /uninstall ${slug}`));
16578
+ break;
16579
+ }
16580
+ process.stdout.write(source_default.dim(`\u6B63\u5728\u4ECE SkillHub \u4E0B\u8F7D Skill: ${slug}...
16581
+ `));
16582
+ try {
16583
+ const skillMdContent = await downloadSkillMd(slug);
16584
+ (0, import_fs5.mkdirSync)(installTarget2, { recursive: true });
16585
+ (0, import_fs5.writeFileSync)((0, import_path5.join)(installTarget2, "SKILL.md"), skillMdContent, "utf8");
16586
+ const { name: name2, shortDesc: shortDesc2 } = parseSkillMeta(skillMdContent);
16587
+ console.log(source_default.green(`\u2713 SkillHub Skill \u5B89\u88C5\u6210\u529F!`));
16588
+ console.log(` ID: ${source_default.cyan(slug)}`);
16589
+ console.log(` \u540D\u79F0: ${name2 || slug}`);
16590
+ if (shortDesc2) console.log(` \u529F\u80FD: ${source_default.dim(shortDesc2)}`);
16591
+ console.log(source_default.dim(` \u4F7F\u7528 /sk ${slug} \u52A0\u8F7D`));
16592
+ } catch (e2) {
16593
+ const msg = e2 instanceof Error ? e2.message : String(e2);
16594
+ if (msg === "not_found") {
16595
+ console.log(source_default.red(`SkillHub \u672A\u627E\u5230 "${slug}"\uFF0C\u8BF7\u5148\u7528 /search \u641C\u7D22\u786E\u8BA4 slug`));
16596
+ } else {
16597
+ console.log(source_default.red(`\u4E0B\u8F7D\u5931\u8D25: ${msg}`));
16598
+ }
16599
+ }
16426
16600
  break;
16427
16601
  }
16428
- let repoUrl = arg;
16602
+ let repoUrl = installArg;
16429
16603
  if (!repoUrl.startsWith("http")) {
16430
16604
  repoUrl = `https://github.com/${repoUrl}`;
16431
16605
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgicli/bgicli",
3
- "version": "2.2.13",
3
+ "version": "2.2.14",
4
4
  "description": "BGI CLI — Bioinformatics AI terminal for Chinese researchers (百炼/DeepSeek/Kimi/Qwen)",
5
5
  "bin": {
6
6
  "bgi": "dist/bgi.js"