@bgicli/bgicli 2.4.0 → 2.4.2
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/README.md +57 -11
- package/dist/bgi.js +26 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- ✅ **开箱即用** — `npm install -g @bgicli/bgicli` 即可
|
|
6
6
|
- ✅ **内置 889 个技能** — 21 个生信工作流 + 868 个 OpenClaw 医学技能,自动安装
|
|
7
7
|
- ✅ **智能技能路由** — 描述任务自动激活对应技能,无需手动搜索
|
|
8
|
-
- ✅ **中国 AI 服务商** — 百炼(DashScope)聚合:
|
|
8
|
+
- ✅ **中国 AI 服务商** — 百炼(DashScope)聚合:Qwen、DeepSeek、Kimi、MiniMax 等 20+ 模型
|
|
9
9
|
- ✅ **真实工具调用** — 执行 bash、读写文件、运行 R/Python 脚本
|
|
10
10
|
- ✅ **内网支持** — 可接入公司私有化部署的大模型
|
|
11
11
|
|
|
@@ -91,7 +91,7 @@ bgi # 启动
|
|
|
91
91
|
### 服务商 / 模型
|
|
92
92
|
| 命令 | 说明 |
|
|
93
93
|
|------|------|
|
|
94
|
-
| `/provider <name>` |
|
|
94
|
+
| `/provider <name>` | 切换服务商(`bailian` / `intranet` / `custom`) |
|
|
95
95
|
| `/model <name>` | 切换模型 |
|
|
96
96
|
| `/models` | 列出当前服务商所有可用模型 |
|
|
97
97
|
| `/providers` | 列出所有服务商 |
|
|
@@ -116,6 +116,34 @@ bgi # 启动
|
|
|
116
116
|
| `/save [文件名]` | 保存对话为 Markdown 文件 |
|
|
117
117
|
| `/think [on\|off]` | 切换思考模式(Qwen3 `/think` 前缀) |
|
|
118
118
|
|
|
119
|
+
### 断点与恢复
|
|
120
|
+
| 命令 | 说明 |
|
|
121
|
+
|------|------|
|
|
122
|
+
| `/checkpoint` | 保存当前对话断点(含激活的技能) |
|
|
123
|
+
| `/checkpoint save [标签]` | 保存断点并指定标签 |
|
|
124
|
+
| `/checkpoint list` | 列出本次会话所有断点 |
|
|
125
|
+
| `/checkpoint restore <id>` | 恢复到指定断点 |
|
|
126
|
+
|
|
127
|
+
> 适合长时间分析任务中途保存进度,防止意外中断丢失上下文。
|
|
128
|
+
|
|
129
|
+
### 数据库管理
|
|
130
|
+
| 命令 | 说明 |
|
|
131
|
+
|------|------|
|
|
132
|
+
| `/db list` | 列出已注册的参考数据库 |
|
|
133
|
+
| `/db add <路径> [基因组] [类型] [说明]` | 手动注册数据库路径 |
|
|
134
|
+
| `/db scan [目录]` | 自动扫描文件系统查找已知数据库 |
|
|
135
|
+
| `/db rm <id>` | 删除数据库记录 |
|
|
136
|
+
| `/db download [名称]` | 显示标准数据库下载命令 |
|
|
137
|
+
|
|
138
|
+
> 注册后 AI 可自动引用正确路径,无需每次手动指定。支持 hg38/hg19/mm10 基因组、STAR/HISAT2 索引、GTF 注释等。
|
|
139
|
+
|
|
140
|
+
### 安全扫描
|
|
141
|
+
| 命令 | 说明 |
|
|
142
|
+
|------|------|
|
|
143
|
+
| `/scan <命令>` | 扫描命令安全风险,输出 CRITICAL / HIGH / MEDIUM / LOW 等级 |
|
|
144
|
+
|
|
145
|
+
> AI 执行每条 bash 命令前均自动扫描;CRITICAL 级别命令将被拦截。
|
|
146
|
+
|
|
119
147
|
### 文件与目录
|
|
120
148
|
| 命令 | 说明 |
|
|
121
149
|
|------|------|
|
|
@@ -124,11 +152,27 @@ bgi # 启动
|
|
|
124
152
|
| `/tools` | 列出 AI 可调用的工具 |
|
|
125
153
|
| `@路径` | 消息中内嵌文件内容(如 `@data.csv 里有什么?`) |
|
|
126
154
|
|
|
155
|
+
### 会话报告与记忆
|
|
156
|
+
退出时(双击 Ctrl+C 或输入 `exit`)自动显示会话报告:
|
|
157
|
+
- 运行时长
|
|
158
|
+
- 消耗 Token(输入 / 输出)
|
|
159
|
+
- 执行命令成功 / 失败次数
|
|
160
|
+
- 可选保存会话记忆到 `~/.bgicli/memory/`
|
|
161
|
+
|
|
127
162
|
### 其他
|
|
128
163
|
| 命令 | 说明 |
|
|
129
164
|
|------|------|
|
|
130
165
|
| `/help` | 显示帮助 |
|
|
131
|
-
| `exit` / `quit` / `q` |
|
|
166
|
+
| `exit` / `quit` / `q` | 退出(显示会话报告) |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 快捷键
|
|
171
|
+
|
|
172
|
+
| 快捷键 | 说明 |
|
|
173
|
+
|--------|------|
|
|
174
|
+
| `Ctrl+C`(单次) | 中断当前 AI 任务(保留对话历史) |
|
|
175
|
+
| `Ctrl+C`(连按两次) | 退出程序(显示会话报告) |
|
|
132
176
|
|
|
133
177
|
---
|
|
134
178
|
|
|
@@ -195,14 +239,16 @@ npm link
|
|
|
195
239
|
|
|
196
240
|
```
|
|
197
241
|
bgi
|
|
198
|
-
├── src/index.ts
|
|
199
|
-
├── src/chat.ts
|
|
200
|
-
├── src/tools.ts
|
|
201
|
-
├── src/
|
|
202
|
-
├── src/
|
|
203
|
-
├── src/
|
|
204
|
-
├── src/
|
|
205
|
-
|
|
242
|
+
├── src/index.ts — CLI 主入口、命令处理、智能路由、会话管理
|
|
243
|
+
├── src/chat.ts — 流式对话引擎(工具调用循环、进度渲染)
|
|
244
|
+
├── src/tools.ts — 工具实现(bash / read_file / write_file 等)
|
|
245
|
+
├── src/security.ts — 命令安全扫描(CRITICAL / HIGH / MEDIUM / LOW)
|
|
246
|
+
├── src/databases.ts — 参考数据库注册与管理
|
|
247
|
+
├── src/skillRouter.ts — 关键词路由表(35个核心技能自动匹配)
|
|
248
|
+
├── src/prompt.ts — 生物信息学系统提示
|
|
249
|
+
├── src/providers.ts — 中国 AI 服务商配置
|
|
250
|
+
├── src/config.ts — 配置管理(~/.bgicli/config.json)
|
|
251
|
+
└── data/ — 内置数据(工作流 + Skills + Python 工具)
|
|
206
252
|
```
|
|
207
253
|
|
|
208
254
|
---
|
package/dist/bgi.js
CHANGED
|
@@ -13605,10 +13605,12 @@ var BGI_DIR = (0, import_path2.join)((0, import_os.homedir)(), ".bgicli");
|
|
|
13605
13605
|
var WORKFLOWS_DIR = (0, import_path2.join)(BGI_DIR, "workflows");
|
|
13606
13606
|
var TOOLS_DIR = (0, import_path2.join)(BGI_DIR, "tools");
|
|
13607
13607
|
var SKILLS_DIR = (0, import_path2.join)(BGI_DIR, "skills");
|
|
13608
|
+
var USER_SKILLS_DIR = (0, import_path2.join)(BGI_DIR, "user-skills");
|
|
13608
13609
|
var DATABASES_FILE = (0, import_path2.join)(BGI_DIR, "databases.json");
|
|
13610
|
+
var DATA_VERSION_FILE = (0, import_path2.join)(BGI_DIR, ".data-version");
|
|
13609
13611
|
var CONFIG_FILE = (0, import_path2.join)(BGI_DIR, "config.json");
|
|
13610
13612
|
function ensureDirs() {
|
|
13611
|
-
for (const dir of [BGI_DIR, WORKFLOWS_DIR, TOOLS_DIR, SKILLS_DIR]) {
|
|
13613
|
+
for (const dir of [BGI_DIR, WORKFLOWS_DIR, TOOLS_DIR, SKILLS_DIR, USER_SKILLS_DIR]) {
|
|
13612
13614
|
if (!(0, import_fs2.existsSync)(dir)) (0, import_fs2.mkdirSync)(dir, { recursive: true });
|
|
13613
13615
|
}
|
|
13614
13616
|
}
|
|
@@ -15999,7 +16001,7 @@ function clearCheckpoints(sessionId) {
|
|
|
15999
16001
|
|
|
16000
16002
|
// src/index.ts
|
|
16001
16003
|
var import_fs7 = require("fs");
|
|
16002
|
-
var VERSION2 = "2.4.
|
|
16004
|
+
var VERSION2 = "2.4.2";
|
|
16003
16005
|
var SKILLHUB_HUBS = {
|
|
16004
16006
|
bgi: { label: "BGI\u5185\u7F51", apiBase: "https://clawhub.ai", backend: "clawhub" },
|
|
16005
16007
|
clawhub: { label: "clawhub.ai", apiBase: "https://clawhub.ai", backend: "clawhub" },
|
|
@@ -16146,6 +16148,8 @@ function installBundledData() {
|
|
|
16146
16148
|
const bundledData = (0, import_path6.join)(__dirname, "..", "data");
|
|
16147
16149
|
if (!(0, import_fs6.existsSync)(bundledData)) return;
|
|
16148
16150
|
ensureDirs();
|
|
16151
|
+
const installedDataVersion = (0, import_fs6.existsSync)(DATA_VERSION_FILE) ? (0, import_fs6.readFileSync)(DATA_VERSION_FILE, "utf8").trim() : "";
|
|
16152
|
+
const needsUpdate = installedDataVersion !== VERSION2;
|
|
16149
16153
|
const targets = [
|
|
16150
16154
|
{ src: (0, import_path6.join)(bundledData, "workflows"), dest: WORKFLOWS_DIR, name: "Skills (\u751F\u4FE1\u5DE5\u4F5C\u6D41)" },
|
|
16151
16155
|
{ src: (0, import_path6.join)(bundledData, "skills"), dest: SKILLS_DIR, name: "Skills (\u533B\u5B66\u4E13\u79D1)" },
|
|
@@ -16155,18 +16159,24 @@ function installBundledData() {
|
|
|
16155
16159
|
for (const { src, dest, name } of targets) {
|
|
16156
16160
|
if (!(0, import_fs6.existsSync)(src)) continue;
|
|
16157
16161
|
const isEmpty = !(0, import_fs6.existsSync)(dest) || (0, import_fs6.readdirSync)(dest).length === 0;
|
|
16158
|
-
if (isEmpty) {
|
|
16162
|
+
if (isEmpty || needsUpdate) {
|
|
16159
16163
|
(0, import_fs6.mkdirSync)(dest, { recursive: true });
|
|
16160
|
-
(0, import_fs6.cpSync)(src, dest, { recursive: true });
|
|
16164
|
+
(0, import_fs6.cpSync)(src, dest, { recursive: true, force: true });
|
|
16161
16165
|
if (!installed) {
|
|
16162
|
-
process.stdout.write(source_default.dim(
|
|
16166
|
+
process.stdout.write(source_default.dim(needsUpdate && !isEmpty ? `\u66F4\u65B0\u5185\u7F6E\u6570\u636E\u5230 v${VERSION2}...
|
|
16167
|
+
` : "\u6B63\u5728\u521D\u59CB\u5316\u5185\u7F6E\u6570\u636E...\n"));
|
|
16163
16168
|
installed = true;
|
|
16164
16169
|
}
|
|
16165
|
-
process.stdout.write(source_default.green(` \u2713 ${name} \u5DF2\u5B89\u88C5
|
|
16170
|
+
process.stdout.write(source_default.green(` \u2713 ${name} \u5DF2${needsUpdate && !isEmpty ? "\u66F4\u65B0" : "\u5B89\u88C5"}
|
|
16166
16171
|
`));
|
|
16167
16172
|
}
|
|
16168
16173
|
}
|
|
16169
|
-
if (installed)
|
|
16174
|
+
if (installed) {
|
|
16175
|
+
(0, import_fs6.writeFileSync)(DATA_VERSION_FILE, VERSION2, "utf8");
|
|
16176
|
+
console.log();
|
|
16177
|
+
} else if (needsUpdate) {
|
|
16178
|
+
(0, import_fs6.writeFileSync)(DATA_VERSION_FILE, VERSION2, "utf8");
|
|
16179
|
+
}
|
|
16170
16180
|
}
|
|
16171
16181
|
function printBanner() {
|
|
16172
16182
|
console.log(source_default.cyan.bold(`
|
|
@@ -16347,6 +16357,7 @@ function collectAllSkills() {
|
|
|
16347
16357
|
};
|
|
16348
16358
|
addFrom(SKILLS_DIR, "skill");
|
|
16349
16359
|
addFrom(WORKFLOWS_DIR, "skill");
|
|
16360
|
+
addFrom(USER_SKILLS_DIR, "user");
|
|
16350
16361
|
return entries;
|
|
16351
16362
|
}
|
|
16352
16363
|
function listSkills(keyword) {
|
|
@@ -17173,7 +17184,7 @@ ${paramSummary}
|
|
|
17173
17184
|
const isGitHub = installArg.includes("github.com") || installArg.includes("gitlab") || installArg.includes("bitbucket") || /^[^/]+\/[^/]+$/.test(installArg);
|
|
17174
17185
|
if (!isGitHub && !installArg.startsWith("http")) {
|
|
17175
17186
|
const slug = installArg.trim();
|
|
17176
|
-
const installTarget2 = (0, import_path6.join)(
|
|
17187
|
+
const installTarget2 = (0, import_path6.join)(USER_SKILLS_DIR, slug);
|
|
17177
17188
|
if ((0, import_fs6.existsSync)(installTarget2)) {
|
|
17178
17189
|
console.log(source_default.yellow(`Skill "${slug}" \u5DF2\u5B58\u5728\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u5148 /uninstall ${slug}`));
|
|
17179
17190
|
break;
|
|
@@ -17213,7 +17224,7 @@ ${paramSummary}
|
|
|
17213
17224
|
repoUrl = `https://github.com/${repoUrl}`;
|
|
17214
17225
|
}
|
|
17215
17226
|
const repoName = repoUrl.replace(/\.git$/, "").split("/").pop() ?? "unknown-skill";
|
|
17216
|
-
const installTarget = (0, import_path6.join)(
|
|
17227
|
+
const installTarget = (0, import_path6.join)(USER_SKILLS_DIR, repoName);
|
|
17217
17228
|
if ((0, import_fs6.existsSync)(installTarget)) {
|
|
17218
17229
|
console.log(source_default.yellow(`Skill "${repoName}" \u5DF2\u5B58\u5728\uFF0C\u5982\u9700\u66F4\u65B0\u8BF7\u5148 /uninstall ${repoName}`));
|
|
17219
17230
|
break;
|
|
@@ -17246,7 +17257,7 @@ ${paramSummary}
|
|
|
17246
17257
|
console.log("\u7528\u6CD5: /uninstall <skill-id>");
|
|
17247
17258
|
break;
|
|
17248
17259
|
}
|
|
17249
|
-
const uninstallPath = (0, import_path6.join)(SKILLS_DIR, arg);
|
|
17260
|
+
const uninstallPath = (0, import_fs6.existsSync)((0, import_path6.join)(USER_SKILLS_DIR, arg)) ? (0, import_path6.join)(USER_SKILLS_DIR, arg) : (0, import_path6.join)(SKILLS_DIR, arg);
|
|
17250
17261
|
if (!(0, import_fs6.existsSync)(uninstallPath)) {
|
|
17251
17262
|
console.log(source_default.red(`\u672A\u627E\u5230\u5DF2\u5B89\u88C5\u7684 Skill: ${arg}`));
|
|
17252
17263
|
console.log(source_default.dim("\u6CE8\u610F: \u53EA\u80FD\u5378\u8F7D\u901A\u8FC7 /install \u5B89\u88C5\u7684\u7B2C\u4E09\u65B9 Skill"));
|
|
@@ -17651,11 +17662,14 @@ async function main() {
|
|
|
17651
17662
|
await firstRunIfNeeded(rl);
|
|
17652
17663
|
const cfg = loadConfig();
|
|
17653
17664
|
const prov = PROVIDERS[cfg.provider];
|
|
17654
|
-
const
|
|
17665
|
+
const allSkillsList = collectAllSkills();
|
|
17666
|
+
const totalSkills = allSkillsList.length;
|
|
17667
|
+
const userSkillCount = allSkillsList.filter((e2) => e2.tag === "user").length;
|
|
17668
|
+
const skillsLabel = totalSkills > 0 ? source_default.green(`${totalSkills} \u4E2A`) + (userSkillCount > 0 ? source_default.dim(` (\u542B ${userSkillCount} \u4E2A\u7528\u6237\u5B89\u88C5)`) : "") : source_default.yellow("\u672A\u5B89\u88C5");
|
|
17655
17669
|
console.log(source_default.bold.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
17656
17670
|
console.log(` ${source_default.bold("\u670D\u52A1\u5546:")} ${prov?.name ?? cfg.provider}`);
|
|
17657
17671
|
console.log(` ${source_default.bold("\u6A21\u578B:")} ${source_default.green(cfg.model)}`);
|
|
17658
|
-
console.log(` ${source_default.bold("Skills:")} ${
|
|
17672
|
+
console.log(` ${source_default.bold("Skills:")} ${skillsLabel} ${source_default.dim("(/sk \u641C\u7D22 /cat \u5206\u7C7B\u76EE\u5F55)")}`);
|
|
17659
17673
|
console.log(` ${source_default.bold("\u5DE5\u5177:")} bash \xB7 read_file \xB7 write_file \xB7 list_dir \xB7 search_files`);
|
|
17660
17674
|
console.log(` ${source_default.bold("\u65B0\u529F\u80FD:")} /sessions /resume /checkpoint /run /check-env /install /diff`);
|
|
17661
17675
|
console.log(source_default.bold.cyan("\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|