bfi-cli 0.1.87 → 0.1.89

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
@@ -9299,8 +9299,7 @@ function printHelp$1() {
9299
9299
  全局: --json / --dry-run / --token <tok>
9300
9300
 
9301
9301
  输出: 每个微服务的 code/名称/类型/部门/负责人/Jira 项目 + repos 列表
9302
- (repo 字段可直接作为 bfi-code-search context 的 repo 参数;
9303
- 与 BCS list_repos 名单核对,个别仓为 org__repo 形态时用备选值)
9302
+ (repo 为 BCS 图谱仓库名(git 地址末段),可直接作 bfi-code-search context 的 repo 参数)
9304
9303
 
9305
9304
  示例:
9306
9305
  bfi ms yonbip-scm-stock
@@ -9340,7 +9339,7 @@ async function runMs(args, globalOpts) {
9340
9339
  if (!rows.length) return `无匹配微服务(total=${d.total ?? 0})`;
9341
9340
  return rows.map((r) => {
9342
9341
  const repos = r.repos ?? [];
9343
- const repoLines = repos.map((x) => ` - ${x.repo}${x.repo_qualified && x.repo_qualified !== x.repo ? ` (备选: ${x.repo_qualified})` : ""} (${x.git_url}${x.branch ? ` @${x.branch}` : ""})`).join("\n");
9342
+ const repoLines = repos.map((x) => ` - ${x.repo} (${x.git_url}${x.branch ? ` @${x.branch}` : ""})`).join("\n");
9344
9343
  return [
9345
9344
  `${r.code} ${r.name} [${r.type || "-"}]`,
9346
9345
  ` 部门: ${r.department || "-"} | 开发: ${r.developer_name || "-"} | 架构: ${r.architect_name || "-"} | Jira: ${r.jira_project_name || "-"}`,
@@ -90,10 +90,86 @@ function loadGlobalConfig() {
90
90
  }
91
91
  return null;
92
92
  }
93
+ function resolveApiBase() {
94
+ return process.env.BFI_API_BASE || "http://172.20.35.178:8901";
95
+ }
93
96
  function resolveToken() {
94
97
  if (process.env.BFI_TOKEN) return process.env.BFI_TOKEN;
95
98
  return loadGlobalConfig()?.token ?? null;
96
99
  }
100
+ const LOCAL_TOOL_NAMES = ["microservice_repo"];
101
+ const LOCAL_TOOLS = [{
102
+ name: "microservice_repo",
103
+ description: "微服务编码→仓库映射(代码定位前置:微服务编码≠仓库名,勿猜 repo)。返回该微服务的 BCS 图谱仓库名(裸名,可直接作 context/query 的 repo 参数)及 git 地址/分支/部门/负责人/Jira 项目。编码来源:事件监听的 microServiceCode 字段、异常栈包名线索、服务名。注意:zoekt_search 的 repo 是 org__repo 形态(如 SEM__EPM_BP),喂给图谱系前须去掉 org__ 前缀。",
104
+ inputSchema: {
105
+ type: "object",
106
+ properties: {
107
+ code: {
108
+ type: "string",
109
+ description: "微服务编码(如 yonbip-scm-stock;bfi 侧模糊匹配,精确行排前)"
110
+ },
111
+ name: {
112
+ type: "string",
113
+ description: "微服务中文名模糊查询(可选,如 库存)"
114
+ },
115
+ size: {
116
+ type: "number",
117
+ description: "返回行数上限(默认 20)"
118
+ }
119
+ }
120
+ }
121
+ }];
122
+ async function microserviceRepo(args) {
123
+ const code = String(args?.code ?? "").trim();
124
+ const name = String(args?.name ?? "").trim();
125
+ if (!code && !name) return errResult("microservice_repo 需要 code 或 name —— 例 { \"code\": \"yonbip-scm-stock\" }", "invalid_params");
126
+ const token = resolveToken();
127
+ if (!token) return errResult("未找到 bfi token:请先执行 `bfi auth login --token <sk-token>`(token 获取地址 https://bfi.yyuap.com/user/profile),或设置 BFI_TOKEN 环境变量", "unauthorized");
128
+ let resp;
129
+ try {
130
+ resp = await fetch(`${resolveApiBase()}/bficli/api/v2/code/microservice`, {
131
+ method: "POST",
132
+ headers: {
133
+ "Content-Type": "application/json",
134
+ Authorization: `Bearer ${token}`
135
+ },
136
+ body: JSON.stringify({
137
+ code,
138
+ name,
139
+ use_status: "1",
140
+ page: 1,
141
+ size: Number(args?.size ?? 20)
142
+ })
143
+ });
144
+ } catch (e) {
145
+ return errResult(`bfi-api 不可达:${e instanceof Error ? e.message : String(e)}`, "unreachable");
146
+ }
147
+ if (resp.status === 401 || resp.status === 403) return errResult("v2 token 无效或过期:请重新 `bfi auth login --token <token>`", "unauthorized");
148
+ const body = await resp.json().catch(() => null);
149
+ if (!body || body.code !== 0) return errResult(`bfi-api 返回异常:${body?.msg ?? resp.status}`, "upstream_error");
150
+ return { content: [{
151
+ type: "text",
152
+ text: JSON.stringify(body.data, null, 2)
153
+ }] };
154
+ }
155
+ function errResult(message, errorKind) {
156
+ return {
157
+ content: [{
158
+ type: "text",
159
+ text: JSON.stringify({
160
+ ok: false,
161
+ error_kind: errorKind,
162
+ message
163
+ }, null, 2)
164
+ }],
165
+ isError: true
166
+ };
167
+ }
168
+ async function callLocalTool(name, args) {
169
+ if (!LOCAL_TOOL_NAMES.includes(name)) return null;
170
+ if (name === "microservice_repo") return microserviceRepo(args);
171
+ return null;
172
+ }
97
173
  function textResult(payload, isError = false) {
98
174
  return {
99
175
  content: [{
@@ -117,15 +193,20 @@ function buildServer(remote) {
117
193
  "· 规则链:rule_chain(单据动作有效规则链)/ rule_impact(规则被哪些链使用)/ rule_search(模糊搜规则/单据)",
118
194
  "· 内容检索:zoekt_search(跨 309 仓文本/正则/行级,毫秒级——搜字面量/URL/配置值/报错文案);read_file / grep(单仓工作区文件读取与文本检索——定位到仓后取原文片段用)",
119
195
  "· 多仓契约组:group_list(组清单)/ group_sync(契约同步);组内可跨仓 trace(repo 传 \"@组名\")",
196
+ "· 微服务→仓库:microservice_repo(本地工具)——微服务编码映射 BCS 图谱仓库名(裸名,直接作 context 的 repo 参数);编码来源:事件监听 microServiceCode/异常栈包名",
197
+ "· ⚠️ 仓名两套形态:zoekt_search 用 org__repo(SEM__EPM_BP),图谱系用裸名(EPM_BP)——zoekt 结果喂 context 前去掉 org__ 前缀",
120
198
  "· 佐证纪律:多候选必须让用户确认;trace 结果校验仓库归属;检索结果不是完整源码,结合行号取源码片段引用;跨仓 trace 仅覆盖契约可提取的调用形态,\"无路径\"不等于\"无调用\""
121
199
  ].join("\n")
122
200
  });
123
201
  server.setRequestHandler(ListToolsRequestSchema, async () => {
124
- return { tools: await bcs.listTools() };
202
+ const tools = await bcs.listTools();
203
+ return { tools: [...LOCAL_TOOLS, ...tools] };
125
204
  });
126
205
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
127
206
  const { name, arguments: args } = request.params;
128
207
  try {
208
+ const local = await callLocalTool(name, args);
209
+ if (local) return local;
129
210
  return await bcs.callTool(name, args);
130
211
  } catch (e) {
131
212
  return textResult({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bfi-cli",
3
- "version": "0.1.87",
3
+ "version": "0.1.89",
4
4
  "description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
5
5
  "type": "module",
6
6
  "bin": {