bfi-cli 0.1.74 → 0.1.75
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 +300 -4
- package/package.json +4 -3
package/dist/cli.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { require_picocolors } from "./_chunks/libs/picocolors.mjs";
|
|
|
6
6
|
import { addSkillToLocalLock, addSkillToLock, computeSkillFolderHash, discoverSkills, dismissPrompt, filterSkills, getAllLockedSkills, getGitHubToken, getLastSelectedAgents, getSkillDisplayName, getSkillFromLock, isPromptDismissed, parseFrontmatter, parseSkillMd, readLocalLock, readSkillLock, removeSkillFromLock, sanitizeMetadata, saveSelectedAgents, stripTerminalEscapes } from "./_chunks/skills.mjs";
|
|
7
7
|
import { esm_default } from "./_chunks/libs/simple-git.mjs";
|
|
8
8
|
import { EVE_SUBAGENTS_DIR, agents, detectInstalledAgents, getEveSubagents, getNonUniversalAgents, getUniversalAgents, getVisibleUniversalAgents, isUniversalAgent } from "./_chunks/agents.mjs";
|
|
9
|
+
import { createRequire } from "node:module";
|
|
9
10
|
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
10
11
|
import { basename, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "path";
|
|
11
12
|
import { fileURLToPath } from "url";
|
|
@@ -8239,7 +8240,7 @@ async function runYmc(args, globalOpts) {
|
|
|
8239
8240
|
const token = globalOpts.token;
|
|
8240
8241
|
const api = new YmcApi(token ?? null, void 0, dryRun);
|
|
8241
8242
|
if (!sub || sub === "--help" || sub === "-h") {
|
|
8242
|
-
printHelp();
|
|
8243
|
+
printHelp$1();
|
|
8243
8244
|
return;
|
|
8244
8245
|
}
|
|
8245
8246
|
if (sub === "help") {
|
|
@@ -8805,7 +8806,7 @@ async function runYmc(args, globalOpts) {
|
|
|
8805
8806
|
}
|
|
8806
8807
|
default:
|
|
8807
8808
|
console.error(`未知子命令:${sub}`);
|
|
8808
|
-
printHelp();
|
|
8809
|
+
printHelp$1();
|
|
8809
8810
|
process.exit(1);
|
|
8810
8811
|
}
|
|
8811
8812
|
}
|
|
@@ -8936,11 +8937,11 @@ function printCommandHelp(cmd) {
|
|
|
8936
8937
|
if (h) console.log(h);
|
|
8937
8938
|
else {
|
|
8938
8939
|
console.error(`未知子命令:${cmd}`);
|
|
8939
|
-
printHelp();
|
|
8940
|
+
printHelp$1();
|
|
8940
8941
|
process.exit(1);
|
|
8941
8942
|
}
|
|
8942
8943
|
}
|
|
8943
|
-
function printHelp() {
|
|
8944
|
+
function printHelp$1() {
|
|
8944
8945
|
console.log(`
|
|
8945
8946
|
bfi ymc — 观测查询(v2 API:YMC/Kibana/SLS/trace)
|
|
8946
8947
|
|
|
@@ -8984,6 +8985,298 @@ bfi ymc — 观测查询(v2 API:YMC/Kibana/SLS/trace)
|
|
|
8984
8985
|
详细帮助:bfi ymc help <命令>(或 bfi ymc <命令> -h)——含参数说明/默认值/示例。
|
|
8985
8986
|
`);
|
|
8986
8987
|
}
|
|
8988
|
+
function loadSourceMapConsumer() {
|
|
8989
|
+
return createRequire(import.meta.url)("source-map").SourceMapConsumer;
|
|
8990
|
+
}
|
|
8991
|
+
function parseErrorLog(log) {
|
|
8992
|
+
const out = {
|
|
8993
|
+
mdf: null,
|
|
8994
|
+
errorType: "",
|
|
8995
|
+
errorMessage: "",
|
|
8996
|
+
frames: []
|
|
8997
|
+
};
|
|
8998
|
+
const code = log.match(/\b(E\d{5})\b/);
|
|
8999
|
+
const kind = log.match(/\[([^\]]{2,20}错误)\]/);
|
|
9000
|
+
const diwork = log.match(/diworkCode:\s*([^\]]+)\]/);
|
|
9001
|
+
const method = log.match(/\[([a-zA-Z_$][\w$]*(?:\.[\w$$.]+)+)\]\s*:/);
|
|
9002
|
+
const event = log.match(/execute\[([^\]]+)\]/);
|
|
9003
|
+
const bill = log.match(/\[([^\]]+)\]\s*\[[^\]]{2,20}错误\]/);
|
|
9004
|
+
if (code && log.includes("【MDF】")) out.mdf = {
|
|
9005
|
+
code: code[1],
|
|
9006
|
+
billName: bill?.[1] ?? "",
|
|
9007
|
+
errorKind: kind?.[1] ?? "",
|
|
9008
|
+
diworkCode: diwork?.[1]?.trim() ?? "",
|
|
9009
|
+
method: method?.[1] ?? "",
|
|
9010
|
+
event: event?.[1] ?? ""
|
|
9011
|
+
};
|
|
9012
|
+
const errMatches = [...log.matchAll(/(TypeError|ReferenceError|SyntaxError|RangeError)\s*:\s*([^\n\r]+)/g)];
|
|
9013
|
+
if (errMatches.length > 0) {
|
|
9014
|
+
const last = errMatches[errMatches.length - 1];
|
|
9015
|
+
out.errorType = last[1];
|
|
9016
|
+
out.errorMessage = `${last[1]}: ${last[2].trim()}`;
|
|
9017
|
+
}
|
|
9018
|
+
for (const m of log.matchAll(/(https?:\/\/[^\s()"']+?\.min\.js):(\d+):(\d+)/g)) out.frames.push({
|
|
9019
|
+
index: out.frames.length,
|
|
9020
|
+
url: m[1],
|
|
9021
|
+
line: Number(m[2]),
|
|
9022
|
+
col: Number(m[3])
|
|
9023
|
+
});
|
|
9024
|
+
return out;
|
|
9025
|
+
}
|
|
9026
|
+
function pickFrame(frames) {
|
|
9027
|
+
const ext = frames.findIndex((f) => /\/extend\.\d+\.[a-f0-9]+/.test(f.url));
|
|
9028
|
+
return ext !== -1 ? ext : 0;
|
|
9029
|
+
}
|
|
9030
|
+
function resolveSourceMappingUrl(jsUrl, comment) {
|
|
9031
|
+
if (/^https?:\/\//.test(comment)) return comment;
|
|
9032
|
+
return `${jsUrl.replace(/\/[^/]*$/, "")}/${comment.replace(/^\.?\//, "")}`;
|
|
9033
|
+
}
|
|
9034
|
+
function webpackSourceInfo(source) {
|
|
9035
|
+
const m = source.match(/^webpack:\/\/([^/]+)\/(.+)$/);
|
|
9036
|
+
if (!m) return {
|
|
9037
|
+
repo: "",
|
|
9038
|
+
filePath: source.replace(/^webpack:\/\//, "")
|
|
9039
|
+
};
|
|
9040
|
+
return {
|
|
9041
|
+
repo: m[1],
|
|
9042
|
+
filePath: m[2].replace(/^\.\//, "")
|
|
9043
|
+
};
|
|
9044
|
+
}
|
|
9045
|
+
function extractContext(content, line, ctx) {
|
|
9046
|
+
const lines = content.split("\n");
|
|
9047
|
+
const start = Math.max(1, line - ctx);
|
|
9048
|
+
const end = Math.min(lines.length, line + ctx);
|
|
9049
|
+
const width = String(end).length;
|
|
9050
|
+
const out = [];
|
|
9051
|
+
for (let i = start; i <= end; i++) {
|
|
9052
|
+
const mark = i === line ? " --> " : " ";
|
|
9053
|
+
out.push(`${mark}${String(i).padStart(width)} | ${lines[i - 1]}`);
|
|
9054
|
+
}
|
|
9055
|
+
return out.join("\n");
|
|
9056
|
+
}
|
|
9057
|
+
const UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36";
|
|
9058
|
+
function httpGet(url, redirects = 0) {
|
|
9059
|
+
return new Promise((resolve, reject) => {
|
|
9060
|
+
if (redirects > 5) {
|
|
9061
|
+
reject(/* @__PURE__ */ new Error(`重定向超过 5 次: ${url}`));
|
|
9062
|
+
return;
|
|
9063
|
+
}
|
|
9064
|
+
const req = (url.startsWith("https://") ? https : http).get(url, {
|
|
9065
|
+
headers: {
|
|
9066
|
+
"user-agent": UA,
|
|
9067
|
+
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
|
9068
|
+
cookie: "debug=true"
|
|
9069
|
+
},
|
|
9070
|
+
timeout: 6e4
|
|
9071
|
+
}, (res) => {
|
|
9072
|
+
const status = res.statusCode ?? 0;
|
|
9073
|
+
const loc = res.headers.location;
|
|
9074
|
+
if (status >= 300 && status < 400 && loc) {
|
|
9075
|
+
res.resume();
|
|
9076
|
+
httpGet(new URL(loc, url).toString(), redirects + 1).then(resolve, reject);
|
|
9077
|
+
return;
|
|
9078
|
+
}
|
|
9079
|
+
const chunks = [];
|
|
9080
|
+
res.on("data", (c) => chunks.push(c));
|
|
9081
|
+
res.on("end", () => resolve({
|
|
9082
|
+
status,
|
|
9083
|
+
body: Buffer.concat(chunks)
|
|
9084
|
+
}));
|
|
9085
|
+
});
|
|
9086
|
+
req.on("timeout", () => req.destroy(/* @__PURE__ */ new Error(`下载超时(60s): ${url}`)));
|
|
9087
|
+
req.on("error", reject);
|
|
9088
|
+
});
|
|
9089
|
+
}
|
|
9090
|
+
async function downloadTo(url, file, what) {
|
|
9091
|
+
const { status, body } = await httpGet(url);
|
|
9092
|
+
if (status !== 200 || body.length === 0) throw new Error(`${what}下载失败(HTTP ${status}): ${url}\n若 sourcemap 被剥离,降级:按 JS 文件名走 bfi-code-search 内容搜索定位`);
|
|
9093
|
+
fs.writeFileSync(file, body);
|
|
9094
|
+
return body.length;
|
|
9095
|
+
}
|
|
9096
|
+
function cacheDirFor(jsUrl, root) {
|
|
9097
|
+
const u = new URL(jsUrl);
|
|
9098
|
+
return path$1.join(root || path$1.join(os$1.homedir(), ".bfi", "fe-locate", "cache"), u.host, path$1.dirname(u.pathname).replace(/^\/|\/$/g, ""));
|
|
9099
|
+
}
|
|
9100
|
+
function readStdin() {
|
|
9101
|
+
return new Promise((resolve, reject) => {
|
|
9102
|
+
let data = "";
|
|
9103
|
+
process.stdin.setEncoding("utf-8");
|
|
9104
|
+
process.stdin.on("data", (c) => {
|
|
9105
|
+
data += c;
|
|
9106
|
+
});
|
|
9107
|
+
process.stdin.on("end", () => resolve(data));
|
|
9108
|
+
process.stdin.on("error", reject);
|
|
9109
|
+
});
|
|
9110
|
+
}
|
|
9111
|
+
function parseSourceMappingComment(jsContent) {
|
|
9112
|
+
const m = jsContent.slice(-3e3).match(/\/\/# sourceMappingURL=(\S+)/);
|
|
9113
|
+
if (!m) throw new Error("JS 文件末尾未找到 //# sourceMappingURL= 注释(构建未产出 sourcemap)");
|
|
9114
|
+
return m[1];
|
|
9115
|
+
}
|
|
9116
|
+
async function locateInMap(mapFile, line, col) {
|
|
9117
|
+
const consumer = await new (loadSourceMapConsumer())(JSON.parse(fs.readFileSync(mapFile, "utf-8")));
|
|
9118
|
+
try {
|
|
9119
|
+
let pos = consumer.originalPositionFor({
|
|
9120
|
+
line,
|
|
9121
|
+
column: Math.max(0, col - 1)
|
|
9122
|
+
});
|
|
9123
|
+
if (!pos?.source) pos = consumer.originalPositionFor({
|
|
9124
|
+
line,
|
|
9125
|
+
column: col
|
|
9126
|
+
});
|
|
9127
|
+
if (!pos?.source) throw new Error(`sourcemap 中无该位置映射(line=${line}, col=${col})——JS 与 map 版本可能不一致`);
|
|
9128
|
+
const content = pos.source ? consumer.sourceContentFor(pos.source, true) : null;
|
|
9129
|
+
return {
|
|
9130
|
+
source: pos.source,
|
|
9131
|
+
line: pos.line ?? 0,
|
|
9132
|
+
column: pos.column ?? 0,
|
|
9133
|
+
name: pos.name ?? "",
|
|
9134
|
+
content
|
|
9135
|
+
};
|
|
9136
|
+
} finally {
|
|
9137
|
+
consumer.destroy?.();
|
|
9138
|
+
}
|
|
9139
|
+
}
|
|
9140
|
+
function printHelp() {
|
|
9141
|
+
console.log(`bfi fe-locate — 前端错误定位(sourcemap 还原)
|
|
9142
|
+
|
|
9143
|
+
用法:
|
|
9144
|
+
bfi fe-locate "<错误日志>" # 单参数(控制台报错栈粘贴)
|
|
9145
|
+
cat error.log | bfi fe-locate --stdin # 长日志走 stdin(推荐,免转义)
|
|
9146
|
+
|
|
9147
|
+
选项:
|
|
9148
|
+
--json 结构化 JSON 输出(定位结果+全部帧+上下文)
|
|
9149
|
+
--stdin 从标准输入读取错误日志
|
|
9150
|
+
--context <N> 源码上下文行数(默认 5)
|
|
9151
|
+
--frame <N> 指定第 N 帧定位(1-based;默认智能选帧:extend 业务帧优先)
|
|
9152
|
+
--no-cache 强制重新下载 JS/sourcemap
|
|
9153
|
+
|
|
9154
|
+
示例:
|
|
9155
|
+
bfi fe-locate "TypeError: e.get(...).setValue is not a function at y (https://static-dc-core1.yonyoucloud.com/static/mdf/udinghuo/latest/javascripts/extend.23.xxx.min.js:1:100358)"`);
|
|
9156
|
+
}
|
|
9157
|
+
function printResult(r, ctxLines) {
|
|
9158
|
+
const err = r.error;
|
|
9159
|
+
const mdf = r.mdf;
|
|
9160
|
+
console.log("═══ bfi fe-locate — 前端错误定位 ═══\n");
|
|
9161
|
+
if (mdf) console.log(`【MDF 头】${mdf.code} | 单据:${mdf.billName} | 类型:${mdf.errorKind} | diworkCode:${mdf.diworkCode} | 方法:${mdf.method} | 事件:${mdf.event}`);
|
|
9162
|
+
console.log(`【错误】${err.type}: ${err.message}`);
|
|
9163
|
+
const frames = r.frames;
|
|
9164
|
+
const sel = r.selected;
|
|
9165
|
+
console.log(`【选帧】第 ${sel.index} 帧(${sel.reason}): ${path$1.basename(String(sel.url))}:${sel.line}:${sel.col}(共 ${frames.length} 帧)`);
|
|
9166
|
+
console.log(`【压缩 JS】${r.jsUrl}`);
|
|
9167
|
+
const resolved = r.resolved;
|
|
9168
|
+
if (resolved) {
|
|
9169
|
+
console.log("\n── sourcemap 还原 ──");
|
|
9170
|
+
console.log(`原始文件: ${resolved.source}`);
|
|
9171
|
+
const info = resolved.webpack;
|
|
9172
|
+
if (info.repo) console.log(`包内仓库: ${info.repo}(注:包内仓库名≠GitLab 仓库名,远程定位按文件名搜索)`);
|
|
9173
|
+
console.log(`文件路径: ${info.filePath}`);
|
|
9174
|
+
console.log(`位置: 行 ${resolved.line}, 列 ${resolved.column}`);
|
|
9175
|
+
if (resolved.name) console.log(`函数名: ${resolved.name}`);
|
|
9176
|
+
if (ctxLines) {
|
|
9177
|
+
console.log(`\n── 源码上下文(sourcemap sourcesContent,±${r.context} 行)──`);
|
|
9178
|
+
console.log(ctxLines);
|
|
9179
|
+
}
|
|
9180
|
+
console.log("\n── 下一步 ──");
|
|
9181
|
+
console.log(`· 远程仓库: SourceGraph 精确文件名搜索 "${path$1.basename(info.filePath)}"(bfi-code-search)`);
|
|
9182
|
+
console.log("· 归因分析: 对照 bfi-diagnose-engine references/fe-error-attribution.md");
|
|
9183
|
+
console.log("· 数据格式类根因(接口返回变化)→ deep 档联动 bfi ymc ingress/trace 取证");
|
|
9184
|
+
}
|
|
9185
|
+
console.log(`\n缓存: ${r.cacheDir}`);
|
|
9186
|
+
}
|
|
9187
|
+
async function runFeLocate(args, globalOpts) {
|
|
9188
|
+
if (!args.length || flag(args, "--help") || flag(args, "-h")) {
|
|
9189
|
+
printHelp();
|
|
9190
|
+
return;
|
|
9191
|
+
}
|
|
9192
|
+
const jsonMode = flag(args, "--json");
|
|
9193
|
+
const noCache = flag(args, "--no-cache");
|
|
9194
|
+
const ctxN = Number(opt(args, "--context") ?? 5) || 5;
|
|
9195
|
+
const frameN = opt(args, "--frame");
|
|
9196
|
+
let log = positionals(args)[0] ?? "";
|
|
9197
|
+
if (!log && flag(args, "--stdin")) log = await readStdin();
|
|
9198
|
+
if (!log && !process.stdin.isTTY) log = await readStdin();
|
|
9199
|
+
if (!log.trim()) {
|
|
9200
|
+
console.error("缺少错误日志参数。粘贴控制台报错栈,或 cat error.log | bfi fe-locate --stdin");
|
|
9201
|
+
process.exit(1);
|
|
9202
|
+
}
|
|
9203
|
+
const parsed = parseErrorLog(log);
|
|
9204
|
+
if (parsed.frames.length === 0) {
|
|
9205
|
+
console.error("未在日志中找到压缩 JS 帧(https://...xxx.min.js:行:列)。请确认粘贴的是浏览器控制台报错栈。");
|
|
9206
|
+
process.exit(1);
|
|
9207
|
+
}
|
|
9208
|
+
const selIdx = frameN ? Math.max(0, Number(frameN) - 1) : pickFrame(parsed.frames);
|
|
9209
|
+
const selReason = frameN ? "--frame 指定" : parsed.frames[selIdx] && /\/extend\.\d+\./.test(parsed.frames[selIdx].url) ? "extend 业务帧优先" : "默认第一帧";
|
|
9210
|
+
if (selIdx >= parsed.frames.length) {
|
|
9211
|
+
console.error(`--frame ${frameN} 超出范围(共 ${parsed.frames.length} 帧)`);
|
|
9212
|
+
process.exit(1);
|
|
9213
|
+
}
|
|
9214
|
+
const frame = parsed.frames[selIdx];
|
|
9215
|
+
const cDir = cacheDirFor(frame.url, globalOpts["fe-cache-dir"]);
|
|
9216
|
+
fs.mkdirSync(cDir, { recursive: true });
|
|
9217
|
+
const jsFile = path$1.join(cDir, "error.min.js");
|
|
9218
|
+
const mapFile = path$1.join(cDir, "error.min.js.map");
|
|
9219
|
+
const metaFile = path$1.join(cDir, "meta.json");
|
|
9220
|
+
let sourceMappingURL = "";
|
|
9221
|
+
if (!noCache && fs.existsSync(metaFile)) try {
|
|
9222
|
+
sourceMappingURL = JSON.parse(fs.readFileSync(metaFile, "utf-8")).sourceMappingUrl ?? "";
|
|
9223
|
+
} catch {}
|
|
9224
|
+
if (sourceMappingURL && fs.existsSync(mapFile)) console.error(`[缓存命中] ${cDir}`);
|
|
9225
|
+
else {
|
|
9226
|
+
const jsSize = await downloadTo(frame.url, jsFile, "压缩 JS");
|
|
9227
|
+
console.error(`[下载] 压缩 JS(${(jsSize / 1024).toFixed(0)} KB)`);
|
|
9228
|
+
const comment = parseSourceMappingComment(fs.readFileSync(jsFile, "utf-8"));
|
|
9229
|
+
sourceMappingURL = resolveSourceMappingUrl(frame.url, comment);
|
|
9230
|
+
console.error(`[解析] sourceMappingURL → ${sourceMappingURL}`);
|
|
9231
|
+
const mapSize = await downloadTo(sourceMappingURL, mapFile, "sourcemap");
|
|
9232
|
+
console.error(`[下载] sourcemap(${(mapSize / 1024).toFixed(0)} KB)`);
|
|
9233
|
+
fs.writeFileSync(metaFile, JSON.stringify({
|
|
9234
|
+
jsUrl: frame.url,
|
|
9235
|
+
sourceMappingUrl: sourceMappingURL,
|
|
9236
|
+
downloadedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9237
|
+
}, null, 2));
|
|
9238
|
+
}
|
|
9239
|
+
const located = await locateInMap(mapFile, frame.line, frame.col);
|
|
9240
|
+
const webpack = webpackSourceInfo(located.source);
|
|
9241
|
+
const ctxLines = located.content ? extractContext(located.content, located.line, ctxN) : null;
|
|
9242
|
+
const result = {
|
|
9243
|
+
error: {
|
|
9244
|
+
type: parsed.errorType,
|
|
9245
|
+
message: parsed.errorMessage
|
|
9246
|
+
},
|
|
9247
|
+
mdf: parsed.mdf,
|
|
9248
|
+
frames: parsed.frames,
|
|
9249
|
+
selected: {
|
|
9250
|
+
...frame,
|
|
9251
|
+
index: selIdx + 1,
|
|
9252
|
+
reason: selReason
|
|
9253
|
+
},
|
|
9254
|
+
jsUrl: frame.url,
|
|
9255
|
+
sourceMappingURL,
|
|
9256
|
+
resolved: {
|
|
9257
|
+
source: located.source,
|
|
9258
|
+
webpack,
|
|
9259
|
+
line: located.line,
|
|
9260
|
+
column: located.column,
|
|
9261
|
+
name: located.name
|
|
9262
|
+
},
|
|
9263
|
+
context: ctxN,
|
|
9264
|
+
contextText: ctxLines,
|
|
9265
|
+
cacheDir: cDir,
|
|
9266
|
+
locatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
9267
|
+
};
|
|
9268
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\D/g, "").slice(0, 14);
|
|
9269
|
+
const runDir = path$1.join(cDir, stamp);
|
|
9270
|
+
fs.mkdirSync(runDir, { recursive: true });
|
|
9271
|
+
fs.writeFileSync(path$1.join(runDir, "error.log"), log);
|
|
9272
|
+
fs.writeFileSync(path$1.join(runDir, "result.json"), JSON.stringify(result, null, 2));
|
|
9273
|
+
if (jsonMode) {
|
|
9274
|
+
console.log(JSON.stringify(result, null, 2));
|
|
9275
|
+
return;
|
|
9276
|
+
}
|
|
9277
|
+
printResult(result, ctxLines);
|
|
9278
|
+
console.log(`\n结果已存: ${path$1.join(runDir, "result.json")}`);
|
|
9279
|
+
}
|
|
8987
9280
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8988
9281
|
function getVersion() {
|
|
8989
9282
|
try {
|
|
@@ -9374,6 +9667,9 @@ async function main() {
|
|
|
9374
9667
|
case "ymc":
|
|
9375
9668
|
await runYmc(restArgs, globalOpts);
|
|
9376
9669
|
break;
|
|
9670
|
+
case "fe-locate":
|
|
9671
|
+
await runFeLocate(restArgs, globalOpts);
|
|
9672
|
+
break;
|
|
9377
9673
|
case "auth":
|
|
9378
9674
|
if (restArgs[0] === "logout") await runLogout();
|
|
9379
9675
|
else if (restArgs[0] === "whoami") await runWhoami(globalOpts);
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bfi-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.75",
|
|
4
4
|
"description": "用友大业财BFI统一命令行工具,支持技能,技能包,元数据,UI元数据等",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"bfi": "
|
|
8
|
-
"bfi-db-mcp": "
|
|
7
|
+
"bfi": "bin/bfi.js",
|
|
8
|
+
"bfi-db-mcp": "bin/bfi-db-mcp.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
51
51
|
"@vercel/detect-agent": "^1.2.3",
|
|
52
52
|
"mysql2": "^3.14.0",
|
|
53
|
+
"source-map": "^0.7.4",
|
|
53
54
|
"yaml": "^2.8.3",
|
|
54
55
|
"zod": "^3.25.0"
|
|
55
56
|
}
|