iter(g150): ua info 反查所属配方

查完 props 顺手给出「这个组件出现在哪几条配方」,把两套入口接上。
--json 与 MCP get_component 的组件级返回同步带 recipes 字段。
This commit is contained in:
HIsheR
2026-10-26 15:50:44 +08:00
parent 1455f82602
commit 04f6df87f5
2 changed files with 21 additions and 2 deletions
+13 -2
View File
@@ -146,6 +146,14 @@ function formatComponent(pkg, comp) {
return lines.join('\n');
}
/*** 反查某组件出现在哪些配方里:查参数时顺带给出「它通常和谁一起用」的组合线索 ***/
function recipesFor(compId) {
const re = new RegExp(`\\b${compId}\\b`);
return parseRecipes()
.filter((r) => re.test(`${r.code}\n${r.text}`))
.map((r) => ({ id: r.id, title: r.title }));
}
/*** 编辑距离(截断版):只用来给拼错的名字找相近候选,超过 3 直接当无建议 ***/
function editDistance(a, b) {
const prev = Array.from({ length: b.length + 1 }, (_, j) => j);
@@ -219,7 +227,10 @@ function cmdInfo(name, args = []) {
console.error(`not found: ${name}(包名与组件 id 都没命中)${near.length ? `;相近:${near.join(' / ')}` : ''}`);
return process.exit(1);
}
console.log(asJson ? JSON.stringify({ package: hit.pkg.name, ...hit.comp }, null, 2) : formatComponent(hit.pkg, hit.comp));
if (asJson) return console.log(JSON.stringify({ package: hit.pkg.name, ...hit.comp, recipes: recipesFor(hit.comp.id) }, null, 2));
const related = recipesFor(hit.comp.id);
const tail = related.length ? `\n\n出现在配方:${related.map((r) => `${r.id}(${r.title})`).join('、')}(ua mcp 的 get_recipe 可取骨架)` : '';
console.log(formatComponent(hit.pkg, hit.comp) + tail);
}
// ---- 静态文档站生成 ----
@@ -586,7 +597,7 @@ function cmdMcp() {
if (p) return p;
const hit = collectComponents(packages).find((x) => x.comp.id === args.name); // 退化到组件级查询
if (!hit) throw new Error(`not found: ${args.name}`);
return { package: hit.pkg.name, ...hit.comp };
return { package: hit.pkg.name, ...hit.comp, recipes: recipesFor(hit.comp.id) };
}
if (name === 'search_components') {
const q = String(args.query ?? '').toLowerCase();