preflight-mcp 0.1.2 → 0.1.3
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/README.md +35 -142
- package/README.zh-CN.md +141 -124
- package/dist/ast/treeSitter.js +588 -0
- package/dist/bundle/analysis.js +47 -0
- package/dist/bundle/context7.js +65 -36
- package/dist/bundle/facts.js +829 -0
- package/dist/bundle/githubArchive.js +49 -28
- package/dist/bundle/overview.js +226 -48
- package/dist/bundle/service.js +27 -126
- package/dist/config.js +29 -3
- package/dist/context7/client.js +5 -2
- package/dist/evidence/dependencyGraph.js +826 -0
- package/dist/http/server.js +109 -0
- package/dist/search/sqliteFts.js +150 -10
- package/dist/server.js +84 -295
- package/dist/trace/service.js +108 -0
- package/dist/trace/store.js +170 -0
- package/package.json +4 -2
- package/dist/bundle/deepwiki.js +0 -206
package/README.zh-CN.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
> [English](./README.md) | **中文**
|
|
8
8
|
|
|
9
|
-
一个 MCP (Model Context Protocol) **stdio** 服务器,用于为 GitHub
|
|
9
|
+
一个 MCP (Model Context Protocol) **stdio** 服务器,用于为 GitHub 仓库与库文档生成"基于证据"的 preflight bundles。
|
|
10
10
|
|
|
11
11
|
每个 bundle 包含:
|
|
12
12
|
- 仓库文档 + 代码的本地副本(规范化文本)
|
|
@@ -15,21 +15,24 @@
|
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
|
-
- **12 个 MCP 工具**:create/update/repair/search/
|
|
18
|
+
- **12 个 MCP 工具**:create/update/repair/search/evidence/trace/read/cleanup(外加 resources)
|
|
19
19
|
- **去重**:避免对相同的规范化输入重复索引
|
|
20
|
-
-
|
|
20
|
+
- **可靠的 GitHub 获取**:可配置 git clone 超时 + GitHub archive(zipball)兜底
|
|
21
21
|
- **离线修复**:无需重新抓取,重建缺失/为空的派生物(index/guides/overview)
|
|
22
22
|
- **静态事实提取**:生成 `analysis/FACTS.json`(非 LLM)
|
|
23
|
-
- **基于证据的校验**:减少幻觉
|
|
24
23
|
- **Resources**:通过 `preflight://...` URI 读取 bundle 文件
|
|
25
24
|
- **多路径镜像备份**:云存储冗余
|
|
26
25
|
- **弹性存储**:挂载点不可用时自动故障转移
|
|
26
|
+
- **原子创建 + 零孤儿**:临时目录 + 原子重命名,崩溃安全
|
|
27
|
+
- **后台快速删除**:<100ms 响应,实际删除在后台进行
|
|
28
|
+
- **启动自动清理**:历史孤儿目录自动清理(非阻塞)
|
|
27
29
|
|
|
28
30
|
## Table of Contents
|
|
29
31
|
|
|
30
32
|
- [Requirements](#requirements)
|
|
31
33
|
- [Installation](#installation)
|
|
32
34
|
- [Quick Start](#quick-start)
|
|
35
|
+
- [Architecture](#architecture)
|
|
33
36
|
- [Tools](#tools-12-total)
|
|
34
37
|
- [Environment Variables](#environment-variables)
|
|
35
38
|
- [Contributing](#contributing)
|
|
@@ -117,177 +120,191 @@ npm run smoke
|
|
|
117
120
|
|
|
118
121
|
这会测试 bundle 创建、搜索、更新等核心操作。
|
|
119
122
|
|
|
120
|
-
##
|
|
121
|
-
Runs an end-to-end stdio client that:
|
|
122
|
-
- spawns the server
|
|
123
|
-
- calls `preflight_create_bundle`
|
|
124
|
-
- reads `preflight://bundles` and `START_HERE.md`
|
|
125
|
-
- searches the bundle
|
|
126
|
-
- calls `preflight_update_bundle`
|
|
123
|
+
## Architecture
|
|
127
124
|
|
|
128
|
-
|
|
129
|
-
- `
|
|
125
|
+
### 🚀 原子创建(Crash-safe)
|
|
126
|
+
- 在 `tmpDir/bundles-wip/` 下构建,校验通过后原子重命名到最终目录
|
|
127
|
+
- 失败会自动清理临时目录,避免产生孤儿目录
|
|
128
|
+
- 跨文件系统自动回退到 copy+delete
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
### ⚡ 后台删除(Fast Delete)
|
|
131
|
+
- 先将目录重命名为 `.deleting.{timestamp}`,响应<100ms
|
|
132
|
+
- 真正的删除在后台完成;启动时会清理残留的 `.deleting` 目录
|
|
133
|
+
|
|
134
|
+
### 🧹 启动自动清理(Auto-Cleanup)
|
|
135
|
+
- 启动时后台扫描并清理无效 bundle(无有效 manifest.json)
|
|
136
|
+
- 仅清理超过 1 小时的目录(安全阈值),非阻塞执行
|
|
137
|
+
|
|
138
|
+
### 🔍 UUID 严格校验
|
|
139
|
+
- 列表与清理逻辑只接受 UUID v4 作为 bundleId
|
|
140
|
+
- 会自动过滤 `#recycle`、`tmp`、`.deleting` 等非 bundle 目录
|
|
132
141
|
|
|
133
142
|
## Tools (12 total)
|
|
134
143
|
|
|
135
144
|
### `preflight_list_bundles`
|
|
136
|
-
|
|
137
|
-
-
|
|
145
|
+
列出所有 bundle。
|
|
146
|
+
- 触发词:「show bundles」「查看bundle」「有哪些bundle」「列出仓库」
|
|
138
147
|
|
|
139
148
|
### `preflight_create_bundle`
|
|
140
|
-
|
|
141
|
-
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
- `error
|
|
147
|
-
- `returnExisting
|
|
148
|
-
- `updateExisting
|
|
149
|
-
- `createNew
|
|
150
|
-
- GitHub
|
|
151
|
-
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }
|
|
155
|
-
- `libraries`: `["nextjs", "react"]
|
|
156
|
-
- `topics`: `["routing", "api"]
|
|
149
|
+
从一个或多个输入创建新 bundle。
|
|
150
|
+
- 触发词:「index this repo」「学习这个项目」「创建bundle」
|
|
151
|
+
|
|
152
|
+
关键语义:
|
|
153
|
+
- **默认去重**:如果相同规范化输入的 bundle 已存在,默认拒绝创建
|
|
154
|
+
- 使用 `ifExists` 控制行为:
|
|
155
|
+
- `error`(默认):拒绝重复
|
|
156
|
+
- `returnExisting`:返回已存在的 bundle,不抓取(可替代原 `preflight_find_bundle`)
|
|
157
|
+
- `updateExisting`:更新已存在的 bundle 后返回
|
|
158
|
+
- `createNew`:绕过去重
|
|
159
|
+
- GitHub 抓取使用**浅克隆**;如果 `git clone` 失败,会回退到 **GitHub archive (zipball)**
|
|
160
|
+
- 支持 `repos.kind: "local"` 从本地目录(如解压后的 zip)抓取
|
|
161
|
+
|
|
162
|
+
输入示例:
|
|
163
|
+
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }]`
|
|
164
|
+
- `libraries`: `["nextjs", "react"]`(Context7;可选)
|
|
165
|
+
- `topics`: `["routing", "api"]`(Context7 主题过滤;可选)
|
|
157
166
|
- `ifExists`: `"error" | "returnExisting" | "updateExisting" | "createNew"`
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
Read a file from bundle (OVERVIEW.md, START_HERE.md, AGENTS.md, or any repo file).
|
|
161
|
-
- Triggers: "查看概览", "项目概览", "看README"
|
|
168
|
+
**💡 提示**:对于代码仓库,创建 bundle 后可进一步使用 `preflight_evidence_dependency_graph` 获取依赖图,或使用 `preflight_trace_upsert` 记录代码←→需求/测试的追溯链接。
|
|
162
169
|
|
|
163
|
-
### `
|
|
164
|
-
|
|
165
|
-
-
|
|
170
|
+
### `preflight_read_file`
|
|
171
|
+
从 bundle 读取文件(OVERVIEW.md、START_HERE.md、AGENTS.md、manifest.json 或任何仓库文件)。
|
|
172
|
+
- 触发词:「查看概览」「项目概览」「看README」「bundle详情」「bundle状态」「仓库信息」
|
|
173
|
+
- **注意**:使用 `file="manifest.json"` 可获取完整的 bundle 元信息(替代原 `preflight_bundle_info`)
|
|
166
174
|
|
|
167
175
|
### `preflight_delete_bundle`
|
|
168
|
-
|
|
169
|
-
-
|
|
176
|
+
永久删除/移除一个 bundle。
|
|
177
|
+
- 触发词:「删除bundle」「移除仓库」
|
|
170
178
|
|
|
171
179
|
### `preflight_update_bundle`
|
|
172
|
-
|
|
173
|
-
-
|
|
180
|
+
用最新仓库变更刷新/同步 bundle。
|
|
181
|
+
- 触发词:「更新bundle」「同步仓库」「刷新索引」
|
|
174
182
|
|
|
175
|
-
|
|
176
|
-
- `checkOnly
|
|
177
|
-
- `force
|
|
178
|
-
|
|
179
|
-
### `preflight_update_all_bundles`
|
|
180
|
-
Batch update all bundles at once.
|
|
181
|
-
- Triggers: "批量更新", "全部刷新"
|
|
182
|
-
|
|
183
|
-
### `preflight_find_bundle`
|
|
184
|
-
Check whether a bundle already exists for the given inputs (no fetching, no changes).
|
|
185
|
-
- Use when your UI/agent wants to decide whether to create/update.
|
|
183
|
+
可选参数:
|
|
184
|
+
- `checkOnly`:如为 true,仅检查是否有更新,不实际应用
|
|
185
|
+
- `force`:如为 true,即使未检测到变更也强制重建
|
|
186
186
|
|
|
187
187
|
### `preflight_repair_bundle`
|
|
188
|
-
|
|
189
|
-
-
|
|
190
|
-
-
|
|
188
|
+
离线修复 bundle(无需抓取):重建缺失/为空的派生物。
|
|
189
|
+
- 重建 `indexes/search.sqlite3`、`START_HERE.md`、`AGENTS.md`、`OVERVIEW.md`(当缺失/为空时)
|
|
190
|
+
- 适用场景:搜索因索引损坏失败、bundle 文件被部分删除等
|
|
191
191
|
|
|
192
192
|
### `preflight_search_bundle`
|
|
193
|
-
|
|
194
|
-
-
|
|
193
|
+
跨已抓取的文档/代码进行全文搜索(基于行的 SQLite FTS5)。
|
|
194
|
+
- 触发词:「搜索bundle」「在仓库中查找」「搜代码」
|
|
195
195
|
|
|
196
|
-
|
|
197
|
-
- `ensureFresh` / `maxAgeHours`
|
|
198
|
-
-
|
|
199
|
-
-
|
|
196
|
+
重要:**此工具是严格只读的**。
|
|
197
|
+
- `ensureFresh` / `maxAgeHours` 已**弃用**,提供时会报错
|
|
198
|
+
- 更新:先调用 `preflight_update_bundle`,再搜索
|
|
199
|
+
- 修复:先调用 `preflight_repair_bundle`,再搜索
|
|
200
200
|
|
|
201
201
|
### `preflight_search_by_tags`
|
|
202
|
-
|
|
203
|
-
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
- `tags
|
|
211
|
-
- `scope
|
|
212
|
-
- `limit
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
202
|
+
跨多个 bundle 按标签过滤搜索(基于行的 SQLite FTS5)。
|
|
203
|
+
- 触发词:「search in MCP bundles」「search in all bundles」「在MCP项目中搜索」「搜索所有agent」
|
|
204
|
+
|
|
205
|
+
说明:
|
|
206
|
+
- 此工具是只读的,**不会自动修复**
|
|
207
|
+
- 如果某些 bundle 搜索失败(如索引缺失/损坏),会在 `warnings` 中报告
|
|
208
|
+
|
|
209
|
+
可选参数:
|
|
210
|
+
- `tags`:按标签过滤 bundle(如 `["mcp", "agents"]`)
|
|
211
|
+
- `scope`:搜索范围(`docs`、`code` 或 `all`)
|
|
212
|
+
- `limit`:跨所有 bundle 的最大命中数
|
|
213
|
+
|
|
214
|
+
### `preflight_evidence_dependency_graph`
|
|
215
|
+
生成目标文件/符号的「基于证据」的依赖图(imports + callers)。
|
|
216
|
+
- 输出确定性(best-effort),并为每条边提供可追溯 source range
|
|
217
|
+
- `PREFLIGHT_AST_ENGINE=wasm` 时使用 Tree-sitter;否则回退到正则抽取
|
|
218
|
+
- 既输出 `imports`(file → module),也会在可解析时输出 `imports_resolved`(file → file)
|
|
219
|
+
|
|
220
|
+
### `preflight_trace_upsert`
|
|
221
|
+
写入/更新 bundle 级 traceability links(commit↔ticket、symbol↔test、code↔doc 等)。
|
|
222
|
+
|
|
223
|
+
### `preflight_trace_query`
|
|
224
|
+
查询 traceability links(提供 `bundleId` 时更快;省略时可跨 bundle 扫描,带上限)。
|
|
225
|
+
|
|
226
|
+
### `preflight_cleanup_orphans`
|
|
227
|
+
删除不完整或损坏的 bundle(缺少有效 manifest.json)。
|
|
228
|
+
- 触发词:「清理孤儿bundle」「删除坏目录」
|
|
229
|
+
- 参数:
|
|
230
|
+
- `dryRun`(默认 true):仅报告不删除
|
|
231
|
+
- `minAgeHours`(默认 1):只清理超过 N 小时的目录
|
|
232
|
+
- 输出:`totalFound`, `totalCleaned`, `details`
|
|
233
|
+
- 说明:服务启动时也会自动执行后台清理(非阻塞)
|
|
226
234
|
|
|
227
235
|
## Resources
|
|
236
|
+
|
|
228
237
|
### `preflight://bundles`
|
|
229
|
-
|
|
238
|
+
静态 JSON,列出所有 bundle 及其主入口文件。
|
|
230
239
|
|
|
231
240
|
### `preflight://bundle/{bundleId}/file/{encodedPath}`
|
|
232
|
-
|
|
241
|
+
读取 bundle 内的特定文件。
|
|
233
242
|
|
|
234
|
-
|
|
243
|
+
示例:
|
|
235
244
|
- `preflight://bundle/<id>/file/START_HERE.md`
|
|
236
245
|
- `preflight://bundle/<id>/file/repos%2Fowner%2Frepo%2Fnorm%2FREADME.md`
|
|
237
246
|
|
|
238
247
|
## Error semantics (stable, UI-friendly)
|
|
239
|
-
|
|
248
|
+
|
|
249
|
+
大多数工具错误会包装为稳定、可机器解析的前缀:
|
|
240
250
|
- `[preflight_error kind=<kind>] <message>`
|
|
241
251
|
|
|
242
|
-
|
|
252
|
+
常见 kinds:
|
|
243
253
|
- `bundle_not_found`
|
|
244
254
|
- `file_not_found`
|
|
245
|
-
- `invalid_path
|
|
255
|
+
- `invalid_path`(不安全的路径遍历尝试)
|
|
246
256
|
- `permission_denied`
|
|
247
257
|
- `index_missing_or_corrupt`
|
|
248
258
|
- `deprecated_parameter`
|
|
249
259
|
- `unknown`
|
|
250
260
|
|
|
251
|
-
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
261
|
+
这样设计是为了让 UI/agent 能可靠地决定是否:
|
|
262
|
+
- 调用 `preflight_update_bundle`
|
|
263
|
+
- 调用 `preflight_repair_bundle`
|
|
264
|
+
- 提示用户提供不同的 bundleId/path
|
|
255
265
|
|
|
256
266
|
## Environment variables
|
|
267
|
+
|
|
257
268
|
### Storage
|
|
258
|
-
- `PREFLIGHT_STORAGE_DIR
|
|
259
|
-
- `PREFLIGHT_STORAGE_DIRS
|
|
260
|
-
- `PREFLIGHT_TMP_DIR
|
|
261
|
-
- `PREFLIGHT_MAX_FILE_BYTES
|
|
262
|
-
- `PREFLIGHT_MAX_TOTAL_BYTES
|
|
269
|
+
- `PREFLIGHT_STORAGE_DIR`:bundle 存储目录(默认:`~/.preflight-mcp/bundles`)
|
|
270
|
+
- `PREFLIGHT_STORAGE_DIRS`:**多路径镜像备份**(分号分隔,如 `D:\cloud1\preflight;E:\cloud2\preflight`)
|
|
271
|
+
- `PREFLIGHT_TMP_DIR`:临时检出目录(默认:OS temp `preflight-mcp/`)
|
|
272
|
+
- `PREFLIGHT_MAX_FILE_BYTES`:单文件最大字节(默认:512 KiB)
|
|
273
|
+
- `PREFLIGHT_MAX_TOTAL_BYTES`:单仓库抓取最大字节(默认:50 MiB)
|
|
263
274
|
|
|
264
|
-
### Analysis
|
|
265
|
-
- `PREFLIGHT_ANALYSIS_MODE
|
|
275
|
+
### Analysis & evidence
|
|
276
|
+
- `PREFLIGHT_ANALYSIS_MODE`:静态分析模式 - `none` | `quick` | `full`(默认:`full`)。控制 `analysis/FACTS.json` 生成。
|
|
277
|
+
- `PREFLIGHT_AST_ENGINE`:部分证据工具使用的 AST 引擎 - `wasm`(默认)或 `native`。
|
|
278
|
+
|
|
279
|
+
### Built-in HTTP API
|
|
280
|
+
- `PREFLIGHT_HTTP_ENABLED`:启用/禁用 REST API(默认:true)
|
|
281
|
+
- `PREFLIGHT_HTTP_HOST`:REST 监听主机(默认:127.0.0.1)
|
|
282
|
+
- `PREFLIGHT_HTTP_PORT`:REST 监听端口(默认:37123)
|
|
266
283
|
|
|
267
284
|
### GitHub & Context7
|
|
268
|
-
- `GITHUB_TOKEN
|
|
269
|
-
- `PREFLIGHT_GIT_CLONE_TIMEOUT_MS
|
|
270
|
-
- `CONTEXT7_API_KEY
|
|
271
|
-
- `CONTEXT7_MCP_URL
|
|
285
|
+
- `GITHUB_TOKEN`:可选;用于 GitHub API/auth 模式和 GitHub archive 兜底(公开仓库通常不需要)
|
|
286
|
+
- `PREFLIGHT_GIT_CLONE_TIMEOUT_MS`:可选;`git clone` 最大等待时间,超时后切换到 archive(默认:5 分钟)
|
|
287
|
+
- `CONTEXT7_API_KEY`:可选;启用更高的 Context7 限制(无 key 也能运行但可能被限流)
|
|
288
|
+
- `CONTEXT7_MCP_URL`:可选;默认为 Context7 MCP 端点
|
|
272
289
|
|
|
273
290
|
## Bundle layout (on disk)
|
|
274
|
-
|
|
275
|
-
|
|
291
|
+
|
|
292
|
+
bundle 目录内部:
|
|
293
|
+
- `manifest.json`(含 `fingerprint`、`displayName`、`tags`,以及每个 repo 的 `source`)
|
|
276
294
|
- `START_HERE.md`
|
|
277
295
|
- `AGENTS.md`
|
|
278
296
|
- `OVERVIEW.md`
|
|
279
297
|
- `indexes/search.sqlite3`
|
|
280
|
-
- **`analysis/FACTS.json
|
|
298
|
+
- **`analysis/FACTS.json`**(静态分析)
|
|
299
|
+
- `trace/trace.sqlite3`(traceability links;按需创建)
|
|
281
300
|
- `repos/<owner>/<repo>/raw/...`
|
|
282
|
-
- `repos/<owner>/<repo>/norm
|
|
283
|
-
- `deepwiki/<owner>/<repo>/norm/index.md` (DeepWiki sources)
|
|
284
|
-
- `deepwiki/<owner>/<repo>/meta.json`
|
|
301
|
+
- `repos/<owner>/<repo>/norm/...`(GitHub/local 快照)
|
|
285
302
|
- `libraries/context7/<...>/meta.json`
|
|
286
|
-
- `libraries/context7/<...>/docs-page-1.md
|
|
303
|
+
- `libraries/context7/<...>/docs-page-1.md`(或 `topic-<topic>-page-1.md`)
|
|
287
304
|
|
|
288
305
|
## Multi-device sync & mirror backup
|
|
289
306
|
|
|
290
|
-
|
|
307
|
+
如果你在多台电脑上工作或需要冗余云备份:
|
|
291
308
|
|
|
292
309
|
### Single path (simple)
|
|
293
310
|
```powershell
|
|
@@ -300,9 +317,9 @@ export PREFLIGHT_STORAGE_DIR="$HOME/Dropbox/preflight-bundles"
|
|
|
300
317
|
```
|
|
301
318
|
|
|
302
319
|
### Multi-path mirror (redundancy)
|
|
303
|
-
|
|
320
|
+
写入所有路径,从第一个可用路径读取:
|
|
304
321
|
```powershell
|
|
305
|
-
# Windows -
|
|
322
|
+
# Windows - 分号分隔
|
|
306
323
|
$env:PREFLIGHT_STORAGE_DIRS = "D:\OneDrive\preflight;E:\GoogleDrive\preflight"
|
|
307
324
|
```
|
|
308
325
|
```bash
|
|
@@ -326,14 +343,14 @@ export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight;$HOME/Dropbox/preflight"
|
|
|
326
343
|
```
|
|
327
344
|
|
|
328
345
|
### Resilient storage features
|
|
329
|
-
- **Auto-failover
|
|
330
|
-
- **Mirror sync
|
|
331
|
-
- **Mount recovery
|
|
332
|
-
- **Non-blocking
|
|
346
|
+
- **Auto-failover**:如果主路径不可用,自动使用第一个可用备份
|
|
347
|
+
- **Mirror sync**:所有写入会镜像到可用备份路径
|
|
348
|
+
- **Mount recovery**:路径恢复后,下次写入时自动同步
|
|
349
|
+
- **Non-blocking**:不可用路径会被跳过,不报错
|
|
333
350
|
|
|
334
351
|
### Important notes
|
|
335
|
-
-
|
|
336
|
-
-
|
|
352
|
+
- **避免并发访问**:同一时间只在一台机器上使用(SQLite 冲突)
|
|
353
|
+
- **等待同步**:更新后,切换机器前等待云同步完成
|
|
337
354
|
|
|
338
355
|
## Contributing
|
|
339
356
|
|