bfi-cli 0.1.79 → 0.1.81
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/cli.mjs +50 -2
- package/dist/mcp-db/main.mjs +7 -0
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -8243,7 +8243,11 @@ async function runYmc(args, globalOpts) {
|
|
|
8243
8243
|
return;
|
|
8244
8244
|
}
|
|
8245
8245
|
if (sub === "help") {
|
|
8246
|
-
|
|
8246
|
+
if (!rest[0]) {
|
|
8247
|
+
printHelp$2();
|
|
8248
|
+
return;
|
|
8249
|
+
}
|
|
8250
|
+
printCommandHelp(rest[0]);
|
|
8247
8251
|
return;
|
|
8248
8252
|
}
|
|
8249
8253
|
if (flag(rest, "--help") || flag(rest, "-h")) {
|
|
@@ -8854,7 +8858,7 @@ const HELP = {
|
|
|
8854
8858
|
注意:业务关键词检索必须 applicationname: 限定目标服务(共享路径 URL 全平台都有);
|
|
8855
8859
|
traceid/spanid 检索例外(全局唯一)。非索引字段(logger/requesturl)不能进检索语法,只能在 SELECT 里引用。`,
|
|
8856
8860
|
"sls-grep": `bfi ymc sls-grep "<关键词>" -e <env> -t <time> [--json]
|
|
8857
|
-
SLS
|
|
8861
|
+
SLS 全文检索聚合(每组计数精确不封顶;组数上限 500——实测 2026-09-17:计数不受限,仅组数受 SLS 默认 LIMIT 约束,服务端已放宽)。`,
|
|
8858
8862
|
slowsql: `bfi ymc slowsql -t <time> -e <env> [--sql-str <表名或片段>] [--md5 <指纹>] [--trace-id <id>] [--app <appCode>] [--no-profiler] [--page N] [--page-size N] [--json]
|
|
8859
8863
|
慢 SQL 告警明细(耗时降序;摘要含 服务/耗时/行数/SQL 前段/指纹/调用栈首帧)。
|
|
8860
8864
|
参数:
|
|
@@ -9187,6 +9191,43 @@ async function runEvent(args, globalOpts) {
|
|
|
9187
9191
|
console.error(`未知子命令: ${sub}。运行 bfi event --help`);
|
|
9188
9192
|
process.exit(1);
|
|
9189
9193
|
}
|
|
9194
|
+
async function runDb(args, globalOpts) {
|
|
9195
|
+
const sub = args[0];
|
|
9196
|
+
const rest = args.slice(1);
|
|
9197
|
+
if (!sub || sub === "--help" || sub === "-h") {
|
|
9198
|
+
console.log(`bfi db — DB 取证辅助命令
|
|
9199
|
+
|
|
9200
|
+
用法:
|
|
9201
|
+
bfi db tenant-locate <租户编码> # 按租户定位分库/实例(ywb 实时查询)
|
|
9202
|
+
返回 env_code(可直接用于 db_execute/db_explain,如 core1_3)+ dbhost + 数据中心 + 租户中文名
|
|
9203
|
+
触发场景:① 表名带租户后缀(tb_dimindex_qyic8c7o)② SQL 中 ytenant_id/tenant_id = 值,
|
|
9204
|
+
且目标分库未知——先定位再连,禁止分库盲枚举
|
|
9205
|
+
找不到租户返回 found=false(正常情况)
|
|
9206
|
+
全局: --json / --dry-run / --token <tok>`);
|
|
9207
|
+
return;
|
|
9208
|
+
}
|
|
9209
|
+
if (sub !== "tenant-locate") {
|
|
9210
|
+
console.error(`未知子命令: ${sub}。运行 bfi db --help`);
|
|
9211
|
+
process.exit(1);
|
|
9212
|
+
}
|
|
9213
|
+
const tenantId = positionals(rest)[0];
|
|
9214
|
+
if (!tenantId) {
|
|
9215
|
+
console.error("用法: bfi db tenant-locate <租户编码>(如 t78xbvzp)");
|
|
9216
|
+
process.exit(1);
|
|
9217
|
+
}
|
|
9218
|
+
const jsonMode = flag(rest, "--json");
|
|
9219
|
+
const dryRun = flag(rest, "--dry-run");
|
|
9220
|
+
const api = new YmcApi(globalOpts.token ?? null, void 0, dryRun);
|
|
9221
|
+
if (!dryRun && !api.token) {
|
|
9222
|
+
console.error("未认证。先运行:bfi auth login --token <sk-token>(或传 --token)");
|
|
9223
|
+
process.exit(1);
|
|
9224
|
+
}
|
|
9225
|
+
emit(await api.call("db/tenant-locate", { tenant_id: tenantId }), jsonMode, (data) => {
|
|
9226
|
+
const d = data;
|
|
9227
|
+
if (!d.found) return `未找到租户 ${tenantId}(ywb 无记录,非表不存在)——${d.note ?? ""}`;
|
|
9228
|
+
return d.matches.map((m) => `✓ ${m.env_code ?? "(无法识别 env_code)"} | ${m.tenant_group_name ?? ""} | ${m.tenant_ds_name}\n dbhost=${m.dbhost} dc=${m.dc} 租户名=${m.tenant_name ?? ""}`).join("\n");
|
|
9229
|
+
});
|
|
9230
|
+
}
|
|
9190
9231
|
function loadSourceMapConsumer() {
|
|
9191
9232
|
return createRequire(import.meta.url)("source-map").SourceMapConsumer;
|
|
9192
9233
|
}
|
|
@@ -9602,6 +9643,10 @@ ${BOLD}━━━ 观测查询(ymc)━━━${RESET}
|
|
|
9602
9643
|
ymc dump-list / call <route> 诊断文件 / 通用端点透传
|
|
9603
9644
|
(-e env: test/daily/pre/core1-4/commldev;-t: 10m/2h/3d/4w)
|
|
9604
9645
|
|
|
9646
|
+
${BOLD}━━━ DB 取证辅助(db)━━━${RESET}
|
|
9647
|
+
db tenant-locate <租户> 按租户定位分库/实例(表名带租户后缀或 SQL 有
|
|
9648
|
+
ytenant_id 条件且分库未知时,先定位再连)
|
|
9649
|
+
|
|
9605
9650
|
${BOLD}━━━ 配置 ━━━${RESET}
|
|
9606
9651
|
config get [key] 查看配置
|
|
9607
9652
|
config set <key> <value> [--global] 设置配置
|
|
@@ -9875,6 +9920,9 @@ async function main() {
|
|
|
9875
9920
|
case "event":
|
|
9876
9921
|
await runEvent(restArgs, globalOpts);
|
|
9877
9922
|
break;
|
|
9923
|
+
case "db":
|
|
9924
|
+
await runDb(restArgs, globalOpts);
|
|
9925
|
+
break;
|
|
9878
9926
|
case "auth":
|
|
9879
9927
|
if (restArgs[0] === "logout") await runLogout();
|
|
9880
9928
|
else if (restArgs[0] === "whoami") await runWhoami(globalOpts);
|
package/dist/mcp-db/main.mjs
CHANGED
|
@@ -209,6 +209,9 @@ async function explainSql(envCode, sql, fetchImpl) {
|
|
|
209
209
|
sql: requireParam("sql", sql)
|
|
210
210
|
}, fetchImpl);
|
|
211
211
|
}
|
|
212
|
+
async function locateTenant(tenantId, fetchImpl) {
|
|
213
|
+
return post("/bficli/api/v2/db/tenant-locate", { tenant_id: tenantId }, fetchImpl);
|
|
214
|
+
}
|
|
212
215
|
function textResult(payload, isError = false) {
|
|
213
216
|
return {
|
|
214
217
|
content: [{
|
|
@@ -252,6 +255,10 @@ function buildServer() {
|
|
|
252
255
|
]).optional().describe("环境类型过滤")
|
|
253
256
|
}
|
|
254
257
|
}, wrap((args) => listEnvs(args.keyword, args.env_type)));
|
|
258
|
+
server.registerTool("db_tenant_locate", {
|
|
259
|
+
description: "按租户编码定位其所在分库/实例(ywb 实时查询)。返回 env_code(可直接用于 db_execute/db_explain,如 core1_3 / core1_yonyou)+ tenant_ds_name + dbhost + 数据中心 + 租户中文名。触发场景:① 表名带租户后缀(tb_dimindex_qyic8c7o)② SQL 中 ytenant_id/tenant_id = 值,且目标分库未知——先定位再连,禁止分库盲枚举。找不到租户返回 found=false(正常,回退按 SQL 线索定位)。",
|
|
260
|
+
inputSchema: { tenant_id: z.string().min(1, "tenant_id 不能为空:从表名后缀或 SQL 的 ytenant_id/tenant_id 值提取").describe("租户编码(如 t78xbvzp / qyic8c7o)") }
|
|
261
|
+
}, wrap((args) => locateTenant(args.tenant_id)));
|
|
255
262
|
server.registerTool("db_execute", {
|
|
256
263
|
description: "在指定环境执行单条 SQL(只读取证)。仅 SELECT/WITH/SHOW/DESC/EXPLAIN;DML/DDL 需环境显式授权位否则 permission_denied。行数上限默认 200。非 mysql 库自动翻译(mysql 语法输入即可)。诊断场景优先 db_explain。",
|
|
257
264
|
inputSchema: {
|