@jokeran/frontend-code-skimmer

Frontend-Code-Skimmer: 不读全文,只看骨架;不搜字符,搜语义关联。支持 Vue2/Vue3/React Hooks
6,570
Install
npm install @jokeran/frontend-code-skimmer
Latest Version:0.8.4
Last Updated:Oct 2, 2026
Links: npm
Maintainer: jokeran

Frontend-Code-Skimmer MCP

不读全文,只看骨架;不搜字符,搜语义关联。

AI 代码助手的智能代码索引引擎,面向 Vue 2 / Vue 3 / React / 纯 TS/JS 工具模块 的结构化检索与影响分析场景。

当前版本的能力重点:

  • skimmer_query 作为唯一推荐入口:一句自然语言后端自动分派多路并行查询,一次返回符号/片段/调用链/行为/影响/数据流与组件语义流
  • 来源类问题会区分直接赋值/缓存读取、后端字段初始化、下游属性修改,避免把所有关联接口都解释成“原始来源”
  • 同一方法甚至同一行出现多次同名请求调用时,会结合赋值片段和 endpoint 精确绑定当前调用点
  • 支持 Vue 2、Vue 3、React 组件/模块索引
  • precision_mode="precise" 支持 JS / JSX / TS / TSX 的跨文件 import/export 精确绑定
  • 对 纯 TS/JS 工具类模块 提供基础符号提取(class / method / function / constant)
  • skimmer_index_health 可显示真实失败文件与错误信息,便于排障
  • skimmer_search_snippets 已支持 query intent 分类 + snippet-first 排序 + 业务文件优先

解决什么问题?

  • 一次问全貌,少绕圈子:skimmer_query 用一句自然语言聚合多维度,命中即自足返回(top-1 内联源码、附一层调用链),避免"查符号→看代码→看调用方"逐跳追加调用
  • 7000 行大文件:skimmer_get_component_outline 将其压缩为 60 行骨架,节省 95% Token
  • 自然语言第一跳太吵:skimmer_search_snippets 直接返回高相关代码片段,避免先猜函数名再二跳读文件
  • API 查询先落到 util 包装层:skimmer_search_snippets 会优先抬升 views/pages/features 等业务实现,压低 config/utils/helpers 这类通用封装
  • 函数名拼写错误:搜 changeCash 能找到 changeCashValue,自动提示 "cash 可能是 cache 的拼写错误";低分弱匹配(默认 <78%)自动折叠,不刷屏
  • 不知道函数名:skimmer_find_by_behavior 按行为搜索,搜 storage 直接列出所有操作 localStorage 的函数
  • 同名函数串台:skimmer_find_symbol / skimmer_find_by_behavior / skimmer_get_call_graph 支持 file_path 过滤
  • 修改前评估影响:skimmer_get_blast_radius 告诉你改一个函数会影响哪些地方
  • 变量数据流追踪:skimmer_trace_data_lifecycle 一次聚合声明、属性修改、参数传递、读取引用、Storage 落点 5 个维度;对 const x = this.getXxx() 这类赋值自动解析来源函数的行为标签(如缓存回显 → localStorage.getItem)
  • 原始来源不混淆:查询“某变量从哪个接口/缓存获取原始值”时,优先给出直接赋值或缓存读取,再补充后端字段初始化接口;对象别名传播后的下游请求不直接当作原始来源
  • 父子组件状态流转:查询 props、事件、v-model、Context 或 Store 通信时,可查看父组件绑定、静态 import 的子组件文件以及子端 prop/emit 定义,不必只靠调用图猜值如何传递
  • 常见局部别名不串链:params、storP 等对象别名按方法作用域隔离,减少跨方法同名变量污染
  • Vue 证据行号可直接定位:行为证据统一使用整个 .vue SFC 的真实文件行号,可直接交给 Read 或代码切片工具
  • 模板事件不断链:@click / @initReceiveAdr 等 Vue 模板事件、React onXxx JSX 事件都作为调用边入库,skimmer_get_call_graph 能查到"模板事件 → 方法"这一跳(🖼️ / ⚛️ 标记)
  • 索引过期行号偏移:skimmer_get_component_outline 和 skimmer_get_code_slice 会自动检测索引是否过期并给出警告
  • 纯 TS/JS 工具类模块也能审:支持提取 class、method、top-level function、const,适合 parser / indexer / cache / CLI / MCP 工具模块
  • 跨文件 import 关系误判少:precise 模式会识别本地 shadowing,import 名在局部作用域被参数/变量遮蔽时不会误标为精确边
  • 索引坏了怎么查:skimmer_index_health 可直接看到失败文件数量、最近失败文件和错误摘要

12 个 MCP 工具

工具 用途
skimmer_query 🚀 唯一推荐入口:自然语言智能查询;来源类问题区分直接来源、后端初始化与下游修改
skimmer_index_project 初始化/更新代码索引(支持 force: true 全量重建)
skimmer_get_component_outline 获取文件骨架(极致 Token 节省,自动检测索引过期)
skimmer_find_symbol 智能符号搜索(精确 → FTS5 → Levenshtein 三层,top-1 内联源码)
skimmer_search_snippets 代码片段搜索(snippet-first,适合自然语言第一跳)
skimmer_get_code_slice 精准代码切片(只取一个函数,自动检测行号偏移)
skimmer_find_by_behavior 按行为标签搜索(绕过命名问题)
skimmer_trace_data_lifecycle 变量完整生命周期追踪(聚合 5 维度、作用域消歧、精确绑定请求调用点)
skimmer_get_call_graph 函数调用关系图谱(支持 callers / callees / both)
skimmer_get_blast_radius 修改影响范围评估
skimmer_index_health 索引健康检查(索引文件/符号/关系/行为、失败文件、watcher、DB 大小)
skimmer_get_project_overview 项目整体概览(文件数、符号数、框架分布)

最近增强 / 稳定性说明

  • 跨组件语义值流(v0.8.2,SQLite schema v23):
    • skimmer_query 新增 semantic_flow 查询意图;自然语言提到 props、事件、父子组件、Context 或 Store 时,会直接查询语义边
    • Vue2 / Vue3 支持静态模板 prop、callback、事件绑定;Vue2 v-model 对应 value/input,Vue3 对应 modelValue/update:modelValue
    • Vue3 支持 defineProps、defineEmits、provide/inject;React Hooks 支持 JSX prop/callback、createContext/useContext、state setter、selector/dispatch/store 读写
    • 静态 import 可跨文件定位子组件;最多跟随 8 层可证明的 default-export barrel,并展示子组件定义文件和行号
    • 证据边界(2026-09-28 批次 B,待评审):语义边 evidence 记录表达式事实(exact / heuristic 等),已验证的静态组件文件记录在 target_file;MCP 单独展示文件绑定、子端 prop/事件定义,callback/事件参数映射未证明时明确停止。Vue 事件与 JSX 的条件、||、??、调用和 inline callback 保留完整原式及未证明的分支,不虚构单一路径。
    • 本地 Vue2 样本实测:apply-claim 126 文件 / 790 条语义边 / 124 条静态目标绑定;clouds-crm-front 982 文件 / 25,240 条语义边 / 1,053 条静态目标绑定
    • 升级注意:0.8.3 版本代码已增至 schema v27;旧库升级后 Vue 2/3、React、JS/TS 索引首次普通刷新会重新解析一次(补齐渲染位置及表达式证据),再次无变化不重复重建。v20–v22 历史升级会重解析已有文件一次。旧 v23 路径曾实测 126 文件约 1.12 秒、982 文件约 15.94 秒;这些数字不是 v27 性能记录
    • 后续计划、测试理由、验收指标和未覆盖边界见 NEXT_UPGRADE_ROADMAP.md
  • 组件使用关系入索引 —— React JSX / Vue 模板(v0.8.0):
    • <Button />、<Form.Item />(React)与 <pagination />、<el-button />(Vue 模板)现在都是 component_render 关系,skimmer_get_blast_radius / skimmer_get_call_graph 在组件类符号上不再大面积空结果(展示层标 🧩 组件渲染)
    • 归因规则:<Form.Item /> 归到根对象 Form(它才是被 import 进来的名字);组件内定义的 function Inner(){} / const renderItem = () => {} 各自的 JSX 归它们自己,匿名回调(items.map(i => <Row />))归外层组件
    • Vue 模板扫描前先剥离 HTML 注释、属性值与插值 → 注释掉的组件、:tip="'<el-button>'" 这类字符串不会误入关系
    • 实测:ant-design 关系 8781 → 13671(精确边占比 18.7% → 40%,call_graph 空结果 37.5% → 30%);shadcn/ui 关系 10725 → 71850(精确边 12.5% → 53.6%);vue2-admin 的 <Pagination /> 可查到精确调用方
  • 行为语义扩展到现代前端生态(v0.8.0):
    • 行为类别 8 → 18(新增 state / effect / memo / ref / context / store / data / form / realtime / worker),覆盖 useState / useEffect / useMemo / useRef / useContext / useSelector / useQuery / useMutation / useForm / useI18n 等;React.useState(...) 命名空间式调用同样识别
    • find_by_behavior 的 keyword 现在同时匹配参数值 / API 名 / 符号名,可直接搜业务词
    • 实测行为覆盖率:react-hook-form 3.8% → 48.3%|ant-design 5.0% → 31.9%|shadcn/ui 3.1% → 20.7%
  • 精确度:barrel 再导出链 + 符号表校验(v0.8.0):
    • export { X } from './y' / export * from './y' / export { default as X } from './y' 会顺着链落到真正的定义文件(最多 8 层,带去环),不再指向空壳 index.ts
    • 精确提示只写向真实存在的符号:追不到目标就保留原值(宁可不命中,不伪造)
    • 实测 ant-design 提示命中率 74.5% → 87.5%(nameMismatch 69 → 0);shadcn/ui 97.5%
  • Vue 2 覆盖补齐(v0.8.0):
    • 普通 .js / .ts 里的 mixin / 自定义指令 / 插件(export default { bind(){} }、install(Vue){})不再 0 符号,新增 directive 类别
    • SFC 的 export default { name: 'Pagination' } 映射为真实组件符号名(否则精确提示停在 ::default);<script> 顶层函数/常量入索引
    • Babel AST 的 StringLiteral 全面支持:组件名、数组式 props: ['value']、'kebab-case': fn 字符串键选项
  • 影响面与索引可观测性(v0.8.0):
    • blast_radius 区分「📤 导出符号(仓库内无调用者属正常)」与「真无人用」,并把影响面拆成「M 处调用 + K 处组件渲染」
    • 新增 max_affected_files(默认 200)控制 precise 反向依赖扩散上限,截断时明确提示(此前逐文件写 stderr,ant-design 上 674 条刷屏)
    • 索引阶段计时区分墙钟(filesPhaseMs)与并发累计(readFilesMs/parseMs/saveToDbMs),不再出现「累计 > 总耗时」的困惑;behaviorSearch 上限 200 可配并提示截断
  • 查询性能(v0.8.0):自然语言长句不再触发 Levenshtein 模糊匹配(实测占 search() 总耗时 92% 且命中恒为 0)→ TanStack Query 上 skimmer_query 23.2ms → 3.6ms
  • 升级注意(v0.8.0):新增 migration v18 持久化 symbols.is_exported,升级后会把文件指纹置空 → 老库下次索引会全量重解析一次(ant-design 约 32s,属预期);大型 monorepo 建议调大 max_affected_files
  • React Hooks 数据流与写入链路升级(v0.7.5):
    • useState setter 入符号索引:const [payData, payDataSet] = useState({}) 现在会额外产出 payDataSet [state_setter/react] 符号(symbols.state_name 记录它写入的 state,migration v17)。此前 setter 完全不进符号表,skimmer_find_symbol("payDataSet") 只能靠 FTS5 前缀匹配到 payData
    • state_write 写入口:新增 state_write 关系(handler/effect → state),skimmer_trace_data_lifecycle 的「② 属性修改」现在会列出 payDataSet(...) 调用点;skimmer_get_call_graph("payDataSet") 可反查调用者
    • Promise 回调归因:extractCallbackFunctionCalls / extractCallbackBehaviors 改为递归收集任意位置的匿名回调(IIFE、new Promise、回调内再套 Promise),修复 .then((res) => setX(res.data)) 类写入口漏检
    • data_flow 形态补齐:新增成员调用(await api.getData())、对象/数组解构、可选链与 ?? 兜底、Promise 回调写入;过滤 useState/map/filter 等噪声。真实项目数据流覆盖率 53.8% → 79.7%
    • 请求封装识别统一:network-wrappers.ts 由 React/Vue2/Vue3/工具类解析器共用;post(url) 这类变量实参保留,仅排除「字面量且不像路径」的 get('key')
    • 误报收敛:<Form onFinish={handleSubmit} /> 这类「引用 handler」不再把组件染成 wrapped_network;声明初始化归入「🌱 初始化来源」而非「❓ 未知来源」
    • JSX 内联 handler:onClick={() => payDataSet(x)} 的调用与写入口也会归因到组件
  • tsconfig paths 别名真解析 + 索引健康度升级(v0.7.04):
    • precise 模式现在会读取「最近祖先」tsconfig.json / jsconfig.json 的 compilerOptions.baseUrl + paths,支持精确映射、通配符(如 @components/*)、extends 继承链(含省略 .json 的写法和 <包名>/tsconfig.json)
    • 不再“谎报精确”:解析不到本地文件的 import(未映射别名、node_modules 裸模块)一律保留 heuristic,不再生成指向不存在文件的 precise 提示
    • 遇到 package.json / .git 项目边界即停止向上查找,嵌套子项目不会误用父项目 paths
    • 配置解析带 10s TTL 缓存,改了 tsconfig 重新索引即可生效;别名解析走缓存,裸模块解析实测约 2.4µs/次
    • skimmer_index_health 新增分维度解析覆盖率(符号/调用关系/行为/数据流 × 有产出文件占比)、precise / heuristic 边数、precise 待处理数
    • ⚠️ 行为变化:外部库/未解析别名不再计入 precise,precise 边数会下降;首次重新索引因 import 签名变化可能触发一次较多文件重算
  • 文件监听自愈 + 关闭安全(v0.7.0):
    • watcher 遇到 error(EMFILE / 权限抖动 / 临时文件竞态等瞬时故障)不再永久钉死在 errored,而是线性退避自动重建(WATCH_RESTART_DELAY_MS=2000ms × 尝试次数,上限 5 次),重建成功即恢复 running
    • 每个 watcher 实例带世代号(epoch):出错实例一旦失效,其迟到的 ready / error 事件一律被丢弃,不会错误清零重试计数,首次重建稳定记录为「第 1 次尝试」
    • 重建期间(旧 watcher 已停、新 watcher 尚未 ready,ignoreInitial 生效)发生的文件增删改会被补扫(resync) 兜底:重建实例 ready 后自动跑一次签名驱动的增量索引,补齐窗口期缺口,不会漏索引
    • 关闭安全:closeProject() / closeAll() / 进程 SIGINT|SIGTERM 退出前,都会先 await watcher.stop()(内部等待进行中的补扫收尾)再关闭数据库,杜绝补扫落库过程中触发 The database connection is not open
    • 上述行为均有回归测试覆盖(含「首次 ready 前就 error」「退避期间旧实例迟到 ready」「关闭时补扫仍在进行」三个竞态场景)
  • 调用点与证据链准确性升级(v0.6.97):
    • 同一方法内多次调用同名请求函数时,结合当前赋值片段、endpoint detail 和调用行绑定 behavior,不再简单取第一条同名调用
    • 同一行存在多个不同 endpoint 也可消歧,例如 savedData = request('/right-api') 不会误绑定同一行的 /wrong-api
    • 对象别名持久化方法作用域,避免 params、storP 等常见局部变量跨方法串链
    • Vue 2 / Vue 3 behavior 行号统一换算为整个 SFC 的真实文件行号,证据可直接用于代码定位
  • 三元表达式变量提取 + 信息屏蔽彻底解决(v0.6.9):
    • 新增 extractTernaryVariables() 支持从 (type == 1 ? cashData?.receiveAdr : cashData?.fetchAdr) 提取 cashData
    • 递归溯源引擎集成三元表达式候选项(ternary_ref),追踪优先级:函数 → 三元变量 → 普通变量 → fallback
    • 工具描述强化"不可过度信任"警告:明确"返回 0 ≠ 不存在","必须启动人工推理"
    • "未找到链路"输出增强为 10+ 行强警告 + 人工验证步骤,防止模型因工具返回空就放弃推理
    • 三层防御解决信息屏蔽问题:工具层覆盖更多表达式模式 + 描述层强制怀疑 + 输出层强警告
  • answer-first 返回(v0.6):skimmer_query 定为唯一推荐入口,命中即自足返回(top-1 内联源码 + 一层调用链摘要),命中成功不再推销其它工具;空结果自动放宽重查一次,仍空则明确告知"确认无结果 + 已尝试的查询方式",杜绝空转
  • 递归赋值溯源(v0.6.3-v0.6.8):skimmer_trace_data_lifecycle 对 const x = this.getXxx() 这类"赋值右侧是函数调用"自动递归追踪到 localStorage.getItem,打通 storageParams ← savedData ← getPageCashF() ← localStorage 完整链路;支持 || fallback 追踪
  • camelCase / v-model 模板事件入库(v0.6):Vue 模板事件提取覆盖 @initReceiveAdr(camelCase 自定义事件)、@update:modelValue(v-model 语法糖)、带修饰符事件,跨"模板事件 → 方法"的调用链不再断链
  • response_format + 参数容错(v0.6):检索类工具支持 response_format: concise|detailed(默认 concise 省 token);trace_data_lifecycle 接受 variable 的多种别名参数;find_symbol 低分弱匹配按 min_score(默认 78)折叠
  • 引用度加权排序(v0.6):find_symbol / skimmer_query 对被引用多的核心 API 加权,并对与已验证符号同文件/同目录的候选加分
  • JSX precise 生效:precise 模式不再局限于 ts/tsx,现在会对 js/jsx/ts/tsx 模块做跨文件 import/export 绑定增强
  • re-export / barrel 链扩散更完整:selective_precise=true 会把 re-export 也纳入依赖签名和反向依赖扩散,barrel 变更不再只重算当前文件
  • local shadowing 保护:若 import 名在函数局部被参数或变量重新声明,会保留 heuristic,避免把本地变量误判成跨文件精确调用
  • 工具类模块覆盖增强:新增 Tooling TS/JS Parser,能抽取 class、class method、top-level function、constant 等基础符号
  • index health 更真实:索引失败文件会持久化,skimmer_index_health 可查看最近失败文件和错误,而不是只看总量
  • snippet 搜索引入 query intent:区分 symbol_like / behavior_like / api_like / natural_language,工具输出会直接显示意图,便于调权和排障
  • 业务文件优先排序:对 views/pages/features/modules 等业务文件加分,对 config/utils/helpers/lib/shared 等通用封装降权;在真实 Vue2 项目中,localStorage setItem 已可优先命中业务页实现而不是 mUtils.js
  • 评测集已固化:仓库内有固定 snippet 回归测试,外部真实项目可通过 eval/snippet-suites/*.json + npm run eval:snippet 一键复跑;预检独立核对源码与索引,区分样本过期 STALE 与索引异常 ERROR(开发版,2026-09-28)

v0.8.3 版本进展(2026-09-29)

  • Vue 2 来源名修复保留 schema v24 升级路径;上一批 A 新增 schema v25,使 Vue 2 / Vue 3 / React 文件指纹一次性失效。下次普通索引会重解析并替换旧语义边,再次不变索引不重复重建;无需手动 force。
  • 组件绑定核对实际 default / named / alias 导出及 JSX 词法引用,支持可证明的静态 namespace 成员和 re-export;Vue 同时核对 setup 导入或 Options 注册。缺失、动态、歧义导出与局部遮蔽不再猜外部目标。
  • React setter 按声明身份对应 state,识别运行时 React useState 导入/别名并排除 type-only 与同名普通函数;Context、dispatch、store 参数遮蔽也不再借用外层绑定。
  • 批次 B(2026-09-28,已评审):schema v26 增加 semantic_edges.source_offset,文件内 UTF-16 属性/事件 offset 区分同行静态实例;source_line 对应属性行。v-model 同位置的 prop 与事件分开保留。目标查找按属性位置隔离同一行不同导出成员和局部遮蔽。语义查询焦点过滤先于数据库 80 条预算,展示最多 12 条并提示截断;确定的子文件定义使用精确路径。
  • 批次 C(2026-09-28,已评审):三个真实仓库的固定 SHA、源码指纹与人工期望形成 13 个 MCP 样本,修复前后完整原始报告只存本地 eval/results/(Git 忽略)。其中 10 个局部静态场景 PASS、3 个完整路径 BOUNDARY;不得把 BOUNDARY 当成端到端已完成。Vue 2 真实仓库中合法的换行多语句 @事件 原被 Vue 3 编译器误计为 7 个解析失败,现在仅在 Babel 证实为多条表达式语句时放行,非法事件仍失败;schema v27 对旧 Vue 2 索引执行一次性指纹失效,普通增量索引清理旧错误。
  • 批次 D(2026-09-28,已验收):Vue 3 script setup 的静态组件绑定可在 MCP skimmer_query 中展示逐项文件、行号、offset 和证据:父 prop、子 prop 声明/读取、字面量 emit、父事件绑定、handler 形参与直接 ref 写入。子端支持直接 props.value 或模板参数 emitChange(props.value) → emit('change', next)。默认/静态命名无修饰符 v-model 还支持 ref(props.visible) → watch(ref, val) → emit('update:visible', val) → 父 ref 的静态回写;输出明确标出子 ref 初始化不保证后续事件值等于原 prop。动态、分支、同名歧义或索引过期时给出边界/停止理由;父子文件哈希与当前源码不一致时只显示历史表达式与陈旧提示,不输出旧 [precise] 目标和子定义。C 的三个复杂真实路径仍为 BOUNDARY;新增 apply-claim-new 真实命名 v-model 固定样本在相同问题与 SHA 下从 1 PASS/1 BOUNDARY 提升为 2 PASS/0 BOUNDARY。
  • 批次 E 部分(2026-09-29,待整体评审):React JS/TS 的静态 JSX prop → 子端直接读取并触发 callback → 父端直接 setter / 单参数 handler → useState 写入,Vue 2 Options API 的受限 value/input v-model → 子端 data 初始化 → watch 事件 → 父 data 状态回流,均可在 MCP skimmer_query 按文件/行号/offset 查询。必须先有静态目标文件与新鲜索引;动态 spread、一般条件表达式、覆写、间接 callback/复杂 model 停止推断;条件挂载下的受限关闭控制路径单独标注;Vue 2 仅在组件挂载时发生更新,子 data 初始值不能等同后来 watch 事件值。同一固定 apply-claim Vue 2 问题由 BOUNDARY → PASS;严格逐跳样本见 vue2-jr-select-flow.json。React JS/TS 已有定向/MCP 参数值流正例;固定 oneclaim-fe 原 inline callback 仍 BOUNDARY。新增 oneclaim-fe 关闭控制样本 在固定 SHA 下为 3 PASS/0 FAIL,证明 visible 受控属性、子端事件绑定、无参数 onClose() 与父端 setShowEditDialog(false) 的静态控制路径;第三方组件是否实际触发事件未由静态分析证明,initData 参数值流仍明确停止。E 批原定的真实“prop 值 → callback 实参 → 父写入”正例仍待补齐。
  • v0.8.4(2026-10-02,缺陷修复):按全仓缺陷审计(见 bug-hunt/BUG_REPORT.md)修复 39 条已确认缺陷(5 high / 16 medium / 18 low):.vue Options API 被误判为 Vue3 特征导致整文件 0 符号、chokidar v4 下文件监听完全失效、allow_fallback_scan 降级检索不可用(提前 return + ESCAPE 语法错误)、component-outline 丢失 class/directive/export 类别、Vue 文件 import 遮蔽保护 fail-open,以及索引陈旧检测、迁移 schema 漂移、中文检索分词、路径规范化与工具契约等。行为变更:省略 project_path 且无历史项目时改为明确报错(不再静默使用服务端 cwd 建库);SKIMMER_DB 现在始终生效。npx tsc --noEmit 通过、npm test 270/270 通过。
  • 发布产物检查补齐 @vue/compiler-dom 直接依赖以修复 ESM 启动问题,并更新 Hono 生产约束;当前版本为 0.8.4,推送 v0.8.4 tag 后由 GitHub Actions 发布到 npm。功能与适用边界见 升级路线图。

真实项目 MCP 基线(批次 C)

固定样本在 eval/real-projects/;先编译测试入口,再运行对应真实仓库(需具备样本固定的来源、SHA 和干净工作区):

rtk npm run eval:real-mcp -- --suite eval/real-projects/vue3-apply-claim-new.json --project /path/to/apply-claim-new --out eval/results/vue3-now.json

若已有同一 suite 与源码快照生成的基线,再加 --baseline eval/results/vue3-before.json。评测使用 MCP 工具与临时 SQLite 数据库,报告记录完整工具响应、索引错误、环境与版本;FAIL、STALE、ERROR 或不可比较均非零退出。BOUNDARY 表示当前只证明了局部边、没有完成整条回流;原始报告可能包含业务源码,默认不入库。其他场景使用同目录的 React/Vue 2 suite,结果与适用边界见 升级路线图。

安装

方式一:npx 直接使用(推荐)

无需克隆仓库,直接在 MCP 配置中使用 npm 的 latest 版本:

{
  "mcpServers": {
    "frontend-code-skimmer": {
      "command": "npx",
      "args": ["-y", "@jokeran/frontend-code-skimmer"]
    }
  }
}

方式二:本地克隆构建

git clone <this-repo>
cd frontend-code-skimmer
# 使用 v0.8.4 版本
git checkout v0.8.4
npm install
npm run build

方式三:运行 snippet 评测集(开发调权用)

# 仓库内固定评测集
npm test

# apply-claim 真实项目相关性回归(项目路径需对应此 suite)
npm run eval:snippet -- --project /path/to/apply-claim --suite ./eval/snippet-suites/apply-claim.json

说明:

  • npm test 会跑固定 fixture 评测集,适合日常开发时快速防回归
  • npm run eval:snippet 用于真实项目相关性回归,适合调权、改 query 规则、评估业务文件优先是否生效
  • 预检检查 expectedTopSymbols、expectedTopFilePrefixes 和 topResultsMustContain;top1 的符号与路径列表均是候选集合,只要求同一条索引记录同时满足两个条件,不要求所有备选路径存在
  • 仅在独立源码清单中找不到文件或目标符号文本时标记 STALE;源码仍有候选而索引没有时标记 ERROR。文本出现在注释或字符串里也保守报 ERROR,不把解析回归静默当成过期
  • 退出码:0 = 所有样本通过;1 = 断言失败、索引/配置/读取异常;2 = 无错误但含过期样本,评测不完整。STALE 不增加 fail 数,但不代表评测通过;错误优先于过期
  • 使用临时 SQLite 数据库并在结束后关闭、清理,不覆盖项目已有 MCP 索引;suite 不能为空,topN 为 1–20 的整数
  • 这是 SearchEngine/SQLite 层评测,不等同于 MCP 端到端验收;行为有效性、真实仓库 commit 固定与前后报告比较仍待完成
  • eval/snippet-suites/*.json 只属于研发保障设施,不参与运行时主链路

配置(Cursor / Claude Desktop)

npx 安装(推荐)

{
  "mcpServers": {
    "frontend-code-skimmer": {
      "command": "npx",
      "args": ["-y", "@jokeran/frontend-code-skimmer"],
      "autoApprove": [
        "skimmer_query", "skimmer_index_project", "skimmer_get_component_outline",
        "skimmer_find_symbol", "skimmer_search_snippets", "skimmer_get_code_slice",
        "skimmer_find_by_behavior", "skimmer_trace_data_lifecycle",
        "skimmer_get_call_graph", "skimmer_get_blast_radius",
        "skimmer_index_health", "skimmer_get_project_overview"
      ]
    }
  }
}

本地构建安装

{
  "mcpServers": {
    "frontend-code-skimmer": {
      "command": "node",
      "args": ["/path/to/frontend-code-skimmer/dist/index.js"],
      "autoApprove": [
        "skimmer_query", "skimmer_index_project", "skimmer_get_component_outline",
        "skimmer_find_symbol", "skimmer_search_snippets", "skimmer_get_code_slice",
        "skimmer_find_by_behavior", "skimmer_trace_data_lifecycle",
        "skimmer_get_call_graph", "skimmer_get_blast_radius",
        "skimmer_index_health", "skimmer_get_project_overview"
      ]
    }
  }
}

不需要任何 env 配置。项目路径在每次工具调用时动态指定。

多项目工作流

优先从编辑器工作区、已打开文件和当前上下文自动推断项目根目录绝对路径,填入 project_path(无需向用户追问)。

项目 A: skimmer_index_project({ project_path: "/work/project-a" })
项目 B: skimmer_index_project({ project_path: "/work/project-b" })

→ 两个项目的索引同时缓存(最多 8 个项目,LRU 淘汰)

→ 查项目 A:
   skimmer_get_component_outline({ project_path: "/work/project-a", file_path: "src/views/home.vue" })

→ 查项目 B:
   skimmer_find_symbol({ project_path: "/work/project-b", query: "handleSubmit" })

→ 省略 project_path 时,自动使用上次操作的项目:
   skimmer_find_symbol({ query: "handleSubmit" })

→ 文件修改后强制全量重建索引:
   skimmer_index_project({ project_path: "/work/project-a", force: true })

数据库存放位置

情况 数据库位置
项目目录可写 <项目根>/.agent/skimmer_find_symbol/.skimmer-index.db
项目只读 ~/.frontend-code-skimmer/databases/<hash>_<path尾部>.db
自定义路径 SKIMMER_DB 环境变量指定的路径(仅单项目场景有效)

环境变量(全部可选)

变量 说明 默认值
SKIMMER_PROJECT 全局默认项目路径 无
SKIMMER_AUTO_INDEX 启动时自动索引默认项目(需配合上一项使用) false
SKIMMER_DB 自定义数据库路径(仅单项目场景有效) 自动
SKIMMER_MAX_OPEN_PROJECTS 最大同时打开的项目数(LRU 淘汰) 8
SKIMMER_DB_IDLE_MINUTES 项目空闲多久后自动关闭数据库连接(分钟) 30
SKIMMER_DB_TTL_DAYS 全局缓存数据库的 TTL(天),过期自动清理 14

使用示例

1. 首次使用

调用 skimmer_index_project → 等待索引完成(50 个文件约 2 秒)

1.5 ⭐ 一句话智能查询(唯一推荐入口)

调用 skimmer_query({ question: "提交按钮的数据流是怎样的" })
调用 skimmer_query({ question: "persistDraft 改了会影响哪些地方" })
调用 skimmer_query({ question: "所有写 localStorage 的地方" })
调用 skimmer_query({ question: "src/views/apply/index.vue 中 storageParams 是从哪个接口获取的原始值" })
→ 必填参数名是 question(不是 query);为容错也接受别名 query / q,内部会归一到 question
→ 来源类问题会收敛到 lifecycle/source 主链:先识别直接来源,再补充后端字段初始化来源
→ 示例结论:直接来源是 `localStorage.getItem("apply-claim/apply-cash")`;缓存缺失字段的后端初始化来源是 `/gw/generic/bx/newh5/m/queryApplyDynamicInfoFromServiceType`
→ “直接来源”和“字段初始化来源”可能不同;下游属性修改关联的 endpoint 不等于原始来源
→ 后端按意图自动分派多路并行查询,一次返回全貌(命中即内联 top-1 源码 + 一层调用链)
→ 命中成功不再推销其它工具;结果为空时自动放宽重查一次,仍空则明确告知"确认无结果 + 已尝试的查询方式"
→ 下面 2~11 的细粒度工具是本入口的"深入维度",仅在需要单维度精查时使用

2. 快速了解组件

调用 skimmer_get_component_outline({ file_path: "src/views/apply/index.vue" })
→ 返回组件所有方法、状态、行为标签的骨架视图(7000 行 → 60 行)
→ 若文件在索引后被修改,自动输出 ⚠️ [索引已过期] 警告并提示重建

3. 查找拼写错误的函数

调用 skimmer_find_symbol({ query: "changeCash" })
→ 找到 changeCashValue,提示 "cash 可能是 cache 的拼写错误"
→ 行为标签显示: [storage:localStorage.setItem]

3.5 ⭐ 自然语言第一跳代码片段搜索

调用 skimmer_search_snippets({ query: "save to cache" })
→ 直接返回 changeCacheValue / persistDraft 等高相关代码片段
→ 优先看 snippet,不必先猜函数名再调用 get_code_slice
→ 输出会显示查询意图,如 `behavior_like`

调用 skimmer_search_snippets({ query: "localStorage setItem" })
→ 直接返回 localStorage.setItem 所在实现片段
→ 显式 API 查询会识别为 `api_like`,优先按行为实现排序
→ 若同时存在业务页实现和 util 封装,默认优先业务文件

当前排序信号(面向 Agent 第一跳):

  • query intent:symbol_like / behavior_like / api_like / natural_language
  • definition boost:可执行定义(function / method / hook / lifecycle)优先于常量/元数据
  • file coherence:同一文件内多处相关命中会整体抬升
  • file role:views/pages/features/modules 业务文件优先,config/utils/helpers/lib/shared 通用封装降权
  • noise penalty:测试、mock、demo、声明文件降权

4. 查找操作本地存储的函数

调用 skimmer_find_by_behavior({ category: "storage", operation: "setItem", file_path: "src/views/apply/index.vue" })
→ 列出所有写入 localStorage 的函数,带文件位置

5. 变量完整数据流追踪(query 的深入维度)

调用 skimmer_trace_data_lifecycle({
  variable: "storageParams",
  file_path: "src/views/apply/index.vue",
  storage_api: "localStorage",
  max_depth: 2
})
→ 一次返回 5 个维度:
  ① 声明 & 整体赋值(含来源分层:初始化/缓存回显/用户交互;赋值右侧是函数调用时自动解析来源)
  ② 属性修改(object.prop = xxx,含别名展开)
  ③ 作为参数被传入的调用
  ④ template 绑定 / watch / computed / return 中的读取引用
  ⑤ Storage 落点追踪(自动顺着调用链打通到 localStorage 写入)
→ 同名请求调用会结合赋值片段、endpoint 和调用行消歧;对象别名按方法作用域隔离
→ Vue 文件中的行为证据使用整个 SFC 的真实行号,可直接定位源代码
→ variable 参数支持 variable_name / symbol_name / symbol / name 别名容错
→ 默认 concise 只列命中行;response_format: "detailed" 附前后各 2 行上下文

6. 单维度追踪(trace_data_lifecycle 已覆盖)

# 只想看某变量的赋值/属性修改,直接用 trace_data_lifecycle 并按需读对应维度即可
skimmer_trace_data_lifecycle({ variable: "changeResult", file_path: "src/views/apply/index.vue" })

说明:

  • 变量数据流一律用 skimmer_trace_data_lifecycle,它一次聚合声明、属性修改、参数传递、读取引用、Storage 落点五个维度,并对 const x = this.getXxx() 这类"赋值右侧是函数调用"自动解析来源函数的行为标签。
  • 完整生命周期中的“属性修改”可能包含对象别名传播后的下游请求;判断原始来源时按“直接赋值/缓存读取 > 后端字段初始化 > 下游属性修改”的顺序解读。
  • 如果问题本身是“从哪个接口/缓存获取原始值”,优先调用 skimmer_query 并在问题中带上相对文件路径;需要展开全部证据时再调用本工具。
  • 早期的 skimmer_trace_assignments / skimmer_trace_property_changes 两个降级工具已合并进 skimmer_trace_data_lifecycle,不再单独暴露。

7. 函数调用图谱 & 影响评估

skimmer_get_call_graph({ symbol_name: "saveToCache", direction: "both" })
skimmer_get_blast_radius({ symbol_name: "saveToCache" })

8. 精度模式(precise)

precision_mode="precise" 用于增强跨文件 import/export 绑定。

前提与边界:

  • 需要项目根目录存在 tsconfig.json 或 jsconfig.json,否则会自动降级到 heuristic
  • 会读取该配置(含最近祖先配置)的 compilerOptions.baseUrl + paths 解析别名,支持通配符与 extends 继承;遇到 package.json / .git 项目边界即停止向上查找
  • 解析不到本地文件的 import(未映射别名、node_modules 裸模块)保留 heuristic,不会伪造精确绑定
  • 当前精确绑定覆盖 JS / JSX / TS / TSX 文件
  • 适合查 import { foo } from './bar' 这类跨文件调用,不等于完整类型系统求值
  • 若 import 名在局部作用域被参数/变量遮蔽,会保留 heuristic,避免误判

示例:

skimmer_index_project({
  project_path: "/work/project-a",
  precision_mode: "precise"
})

9. 选择性 precise 重算(大项目推荐)

selective_precise=true 会在索引后只重算变更文件 + 受影响文件,降低 precise 全量成本。

当前规则:

  • body_only:只重算当前文件 precise
  • import_changed:只重算当前文件
  • export_changed / full_changed:重算当前文件 + 所有直接/间接依赖它的文件
  • re-export / barrel 链会纳入 import 签名与反向依赖扩散

示例:

skimmer_index_project({
  project_path: "/work/project-a",
  precision_mode: "precise",
  selective_precise: true,
  max_precise_files: 20
})

10. 索引行号不准怎么办?

行号偏移的根本原因通常是索引未及时更新。排查步骤:

  1. skimmer_get_component_outline 返回 ⚠️ [索引已过期] → 立即执行第 3 步
  2. skimmer_get_code_slice 返回 ⚠️ [行号偏移] → 说明代码切片位置不对
  3. 强制重建:skimmer_index_project({ project_path: "...", force: true })

当前增量索引使用 mtime + 文件大小 做快速跳过,能覆盖大多数变更场景;如果你的编辑器或同步工具存在极端时间戳行为,仍建议在异常时执行 force: true 全量重建。

11. 索引坏了怎么排障?

skimmer_index_health({ project_path: "/work/project-a" })

可直接看到:

  • 已索引文件数 / 符号数 / 关系数 / 行为数
  • 最后索引时间
  • 失败文件数量
  • 最近失败文件和错误信息
  • watcher 是否活跃
  • 数据库大小与路径

当你发现“文件明明在,但工具查不到”时,先看这里,而不是只看总文件数。

框架支持

类型 解析方式 支持范围 说明
Vue 2 @vue/compiler-sfc + @babel/parser Options API 仅解析 SFC 块和 AST,不执行模板代码;适合组件骨架、行为标签、调用关系
Vue 3 @vue/compiler-sfc + @babel/parser <script setup> + Composition API 适合现代 Vue 单文件组件分析
React @babel/parser + JSX 函数组件 + Hooks 适合组件骨架、事件入口、行为标签、调用关系
纯 TS/JS 工具模块 @babel/parser class / method / top-level function / constant 基础结构化符号提取,适合 parser / indexer / cache / CLI / MCP / util,不等于完整框架语义分析

行为检测

自动识别以下 API 调用并打上标签:

  • storage:localStorage / sessionStorage
  • network:axios / fetch
  • router:$router / useRouter / navigate
  • vuex:$store / useStore / dispatch / commit
  • dom:document / $refs / $nextTick
  • event:$emit / EventBus
  • timer:setTimeout / setInterval
  • i18n:$t / useI18n

Version History

Version Released License
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0