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 CHANGED
@@ -8243,7 +8243,11 @@ async function runYmc(args, globalOpts) {
8243
8243
  return;
8244
8244
  }
8245
8245
  if (sub === "help") {
8246
- printCommandHelp(rest[0] || "");
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 全文检索聚合(每组计数)。注意:计数上限 100 可能封顶,影响面/精确计数用 sls-raw + GROUP BY。`,
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);
@@ -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: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfi-cli",
3
- "version": "0.1.79",
3
+ "version": "0.1.81",
4
4
  "description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
5
5
  "type": "module",
6
6
  "bin": {