@jokeran/frontend-code-skimmer
v0.4.8
Published
Frontend-Code-Skimmer: 不读全文,只看骨架;不搜字符,搜语义关联。支持 Vue2/Vue3/React Hooks
Downloads
1,543
Readme
Frontend-Code-Skimmer MCP
不读全文,只看骨架;不搜字符,搜语义关联。
AI 代码助手的智能代码索引引擎,面向 Vue 2 / Vue 3 / React / 纯 TS/JS 工具模块 的结构化检索与影响分析场景。
当前版本的能力重点:
- 支持 Vue 2、Vue 3、React 组件/模块索引
precision_mode="precise"支持 JS / JSX / TS / TSX 的跨文件 import/export 精确绑定- 对 纯 TS/JS 工具类模块 提供基础符号提取(class / method / function / constant)
skimmer_index_health可显示真实失败文件与错误信息,便于排障
解决什么问题?
- 7000 行大文件:
skimmer_get_component_outline将其压缩为 60 行骨架,节省 95% Token - 函数名拼写错误:搜
changeCash能找到changeCashValue,自动提示 "cash 可能是 cache 的拼写错误" - 不知道函数名:
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 落点 4 个维度 - 索引过期行号偏移:
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_index_project | 初始化/更新代码索引(支持 force: true 全量重建) |
| skimmer_get_component_outline | ⭐ 获取文件骨架(极致 Token 节省,自动检测索引过期) |
| skimmer_find_symbol | 智能符号搜索(精确 → FTS5 → Levenshtein 三层,支持拼写错误) |
| skimmer_get_code_slice | 精准代码切片(只取一个函数,自动检测行号偏移) |
| skimmer_trace_assignments | 变量赋值链路追踪(轻量降级工具,AST 优先) |
| skimmer_trace_property_changes | 对象属性修改追踪(轻量降级工具) |
| 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 | 项目整体概览(文件数、符号数、框架分布) |
最近增强 / 稳定性说明
- 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可查看最近失败文件和错误,而不是只看总量
安装
方式一:npx 直接使用(推荐)
无需克隆仓库,直接在 MCP 配置中使用:
{
"mcpServers": {
"frontend-code-skimmer": {
"command": "npx",
"args": ["-y", "@jokeran/frontend-code-skimmer"]
}
}
}方式二:本地克隆构建
git clone <this-repo>
cd frontend-code-skimmer
npm install
npm run build配置(Cursor / Claude Desktop)
npx 安装(推荐)
{
"mcpServers": {
"frontend-code-skimmer": {
"command": "npx",
"args": ["-y", "@jokeran/frontend-code-skimmer"],
"autoApprove": [
"skimmer_index_project", "skimmer_get_component_outline",
"skimmer_find_symbol", "skimmer_get_code_slice",
"skimmer_trace_assignments", "skimmer_trace_property_changes",
"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_index_project", "skimmer_get_component_outline",
"skimmer_find_symbol", "skimmer_get_code_slice",
"skimmer_trace_assignments", "skimmer_trace_property_changes",
"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 秒)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]4. 查找操作本地存储的函数
调用 skimmer_find_by_behavior({ category: "storage", operation: "setItem", file_path: "src/views/apply/index.vue" })
→ 列出所有写入 localStorage 的函数,带文件位置5. ⭐ 变量完整数据流追踪(首选)
调用 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 写入)6. 追踪变量赋值与属性修改(轻量降级)
skimmer_trace_assignments({ variable: "changeResult", file_path: "src/views/apply/index.vue" })
skimmer_trace_property_changes({ object: "params", property: "receiveAdr", file_path: "src/views/apply/index.vue" })说明:
- 绝大多数场景推荐优先用
skimmer_trace_data_lifecycle,上面两个工具仅在只需查看单一维度时使用。 skimmer_trace_assignments使用 AST 优先(正则兜底),可稳定识别this.xxx = ...、obj[prop] = ...等赋值。
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,否则会自动降级到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:只重算当前文件 preciseimport_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. 索引行号不准怎么办?
行号偏移的根本原因通常是索引未及时更新。排查步骤:
skimmer_get_component_outline返回⚠️ [索引已过期]→ 立即执行第 3 步skimmer_get_code_slice返回⚠️ [行号偏移]→ 说明代码切片位置不对- 强制重建:
skimmer_index_project({ project_path: "...", force: true })
当前增量索引使用 mtime + 文件大小 做快速跳过,能覆盖大多数变更场景;如果你的编辑器或同步工具存在极端时间戳行为,仍建议在异常时执行
force: true全量重建。
11. 索引坏了怎么排障?
skimmer_index_health({ project_path: "/work/project-a" })可直接看到:
- 已索引文件数 / 符号数 / 关系数 / 行为数
- 最后索引时间
- 失败文件数量
- 最近失败文件和错误信息
- watcher 是否活跃
- 数据库大小与路径
当你发现“文件明明在,但工具查不到”时,先看这里,而不是只看总文件数。
框架支持
| 类型 | 解析方式 | 支持范围 | 说明 |
| ---- | -------- | -------- | ---- |
| Vue 2 | vue-template-compiler + @babel/parser | Options API | 适合 SFC 组件骨架、行为标签、调用关系 |
| 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 / sessionStoragenetwork:axios / fetchrouter:$router / useRouter / navigatevuex:$store / useStore / dispatch / commitdom:document / $refs / $nextTickevent:$emit / EventBustimer:setTimeout / setIntervali18n:$t / useI18n
