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.zh-CN.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  > [English](./README.md) | **中文**
8
8
 
9
- 一个 MCP (Model Context Protocol) **stdio** 服务器,用于为 GitHub 仓库与库文档生成“基于证据”的 preflight bundles。
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/verify/read bundles(外加 resources)
18
+ - **12 个 MCP 工具**:create/update/repair/search/evidence/trace/read/cleanup(外加 resources)
19
19
  - **去重**:避免对相同的规范化输入重复索引
20
- - **更可靠的 GitHub 获取**:可配置 git clone 超时 + GitHub archive(zipball)兜底
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
- ## Smoke test
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
- Command:
129
- - `npm run smoke`
125
+ ### 🚀 原子创建(Crash-safe)
126
+ - `tmpDir/bundles-wip/` 下构建,校验通过后原子重命名到最终目录
127
+ - 失败会自动清理临时目录,避免产生孤儿目录
128
+ - 跨文件系统自动回退到 copy+delete
130
129
 
131
- Note: the smoke test clones `octocat/Hello-World` from GitHub, so it needs internet access.
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
- List bundle IDs in storage.
137
- - Triggers: "show bundles", "查看bundle", "有哪些bundle"
145
+ 列出所有 bundle
146
+ - 触发词:「show bundles」「查看bundle」「有哪些bundle」「列出仓库」
138
147
 
139
148
  ### `preflight_create_bundle`
140
- Create a new bundle from one or more inputs.
141
- - Triggers: "index this repo", "学习这个项目", "创建bundle"
142
-
143
- Key semantics:
144
- - **De-dup by default**: if a bundle already exists for the same normalized inputs, creation is rejected.
145
- - Use `ifExists` to control behavior:
146
- - `error` (default): reject duplicate
147
- - `returnExisting`: return the existing bundle without fetching
148
- - `updateExisting`: update the existing bundle then return it
149
- - `createNew`: bypass de-duplication
150
- - GitHub ingest uses **shallow clone**; if `git clone` fails, it will fall back to **GitHub archive (zipball)**.
151
- - Supports `repos.kind: "local"` to ingest from a local directory (e.g. an extracted zip).
152
-
153
- Input (example):
154
- - `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }, { kind: "deepwiki", url: "https://deepwiki.com/owner/repo" }]`
155
- - `libraries`: `["nextjs", "react"]` (Context7; optional)
156
- - `topics`: `["routing", "api"]` (Context7 topic filter; optional)
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
- ### `preflight_read_file`
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
- ### `preflight_bundle_info`
164
- Get bundle details: repos, update time, stats.
165
- - Triggers: "bundle详情", "仓库信息"
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
- Delete/remove a bundle permanently.
169
- - Triggers: "删除bundle", "移除仓库"
176
+ 永久删除/移除一个 bundle
177
+ - 触发词:「删除bundle」「移除仓库」
170
178
 
171
179
  ### `preflight_update_bundle`
172
- Refresh/sync a bundle with latest repo changes.
173
- - Triggers: "更新bundle", "同步仓库", "刷新索引"
180
+ 用最新仓库变更刷新/同步 bundle
181
+ - 触发词:「更新bundle」「同步仓库」「刷新索引」
174
182
 
175
- Optional parameters:
176
- - `checkOnly`: If true, only check for updates without applying.
177
- - `force`: If true, force rebuild even if no changes detected.
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
- Offline repair for a bundle (no fetching): rebuild missing/empty derived artifacts.
189
- - Rebuilds `indexes/search.sqlite3`, `START_HERE.md`, `AGENTS.md`, `OVERVIEW.md` when missing/empty.
190
- - Use when: search fails due to index corruption, bundle files were partially deleted, etc.
188
+ 离线修复 bundle(无需抓取):重建缺失/为空的派生物。
189
+ - 重建 `indexes/search.sqlite3`、`START_HERE.md`、`AGENTS.md`、`OVERVIEW.md`(当缺失/为空时)
190
+ - 适用场景:搜索因索引损坏失败、bundle 文件被部分删除等
191
191
 
192
192
  ### `preflight_search_bundle`
193
- Full-text search across ingested docs/code (line-based SQLite FTS5).
194
- - Triggers: "搜索bundle", "在仓库中查找", "搜代码"
193
+ 跨已抓取的文档/代码进行全文搜索(基于行的 SQLite FTS5)。
194
+ - 触发词:「搜索bundle」「在仓库中查找」「搜代码」
195
195
 
196
- Important: **this tool is strictly read-only**.
197
- - `ensureFresh` / `maxAgeHours` are **deprecated** and will error if provided.
198
- - To update: call `preflight_update_bundle`, then search again.
199
- - To repair: call `preflight_repair_bundle`, then search again.
196
+ 重要:**此工具是严格只读的**。
197
+ - `ensureFresh` / `maxAgeHours` 已**弃用**,提供时会报错
198
+ - 更新:先调用 `preflight_update_bundle`,再搜索
199
+ - 修复:先调用 `preflight_repair_bundle`,再搜索
200
200
 
201
201
  ### `preflight_search_by_tags`
202
- Search across multiple bundles filtered by tags (line-based SQLite FTS5).
203
- - Triggers: "search in MCP bundles", "search in all bundles", "在MCP项目中搜索", "搜索所有agent"
204
-
205
- Notes:
206
- - This tool is read-only and **does not auto-repair**.
207
- - If some bundles fail to search (e.g. missing/corrupt index), they will be reported in `warnings`.
208
-
209
- Optional parameters:
210
- - `tags`: Filter bundles by tags (e.g., `["mcp", "agents"]`)
211
- - `scope`: Search scope (`docs`, `code`, or `all`)
212
- - `limit`: Max total hits across all bundles
213
-
214
- Output additions:
215
- - `warnings?: [{ bundleId, kind, message }]` (non-fatal per-bundle errors)
216
- - `warningsTruncated?: true` if warnings were capped
217
-
218
- ### `preflight_verify_claim`
219
- Find evidence for a claim/statement in bundle.
220
- - Triggers: "验证说法", "找证据", "这个对吗"
221
-
222
- Important: **this tool is strictly read-only**.
223
- - `ensureFresh` / `maxAgeHours` are **deprecated** and will error if provided.
224
- - To update: call `preflight_update_bundle`, then verify again.
225
- - To repair: call `preflight_repair_bundle`, then verify again.
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
- Static JSON listing of bundles and their main entry files.
238
+ 静态 JSON,列出所有 bundle 及其主入口文件。
230
239
 
231
240
  ### `preflight://bundle/{bundleId}/file/{encodedPath}`
232
- Read a specific file inside a bundle.
241
+ 读取 bundle 内的特定文件。
233
242
 
234
- Examples:
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
- Most tool errors are wrapped with a stable, machine-parseable prefix:
248
+
249
+ 大多数工具错误会包装为稳定、可机器解析的前缀:
240
250
  - `[preflight_error kind=<kind>] <message>`
241
251
 
242
- Common kinds:
252
+ 常见 kinds
243
253
  - `bundle_not_found`
244
254
  - `file_not_found`
245
- - `invalid_path` (unsafe path traversal attempt)
255
+ - `invalid_path`(不安全的路径遍历尝试)
246
256
  - `permission_denied`
247
257
  - `index_missing_or_corrupt`
248
258
  - `deprecated_parameter`
249
259
  - `unknown`
250
260
 
251
- This is designed so UIs/agents can reliably decide whether to:
252
- - call `preflight_update_bundle`
253
- - call `preflight_repair_bundle`
254
- - prompt the user for a different bundleId/path
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`: bundle storage dir (default: `~/.preflight-mcp/bundles`)
259
- - `PREFLIGHT_STORAGE_DIRS`: **multi-path mirror backup** (semicolon-separated, e.g., `D:\cloud1\preflight;E:\cloud2\preflight`)
260
- - `PREFLIGHT_TMP_DIR`: temp checkout dir (default: OS temp `preflight-mcp/`)
261
- - `PREFLIGHT_MAX_FILE_BYTES`: max bytes per file (default: 512 KiB)
262
- - `PREFLIGHT_MAX_TOTAL_BYTES`: max bytes per repo ingest (default: 50 MiB)
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`: Static analysis mode - `none` or `quick` (default: `quick`). Generates `analysis/FACTS.json`.
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`: optional; used for GitHub API/auth patterns and GitHub archive fallback (public repos usually work without it)
269
- - `PREFLIGHT_GIT_CLONE_TIMEOUT_MS`: optional; max time to allow `git clone` before failing over to archive (default: 5 minutes)
270
- - `CONTEXT7_API_KEY`: optional; enables higher Context7 limits (runs without a key but may be rate-limited)
271
- - `CONTEXT7_MCP_URL`: optional; defaults to Context7 MCP endpoint
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
- Inside a bundle directory:
275
- - `manifest.json` (includes `fingerprint`, `displayName`, `tags`, and per-repo `source`)
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`** (static analysis)
298
+ - **`analysis/FACTS.json`**(静态分析)
299
+ - `trace/trace.sqlite3`(traceability links;按需创建)
281
300
  - `repos/<owner>/<repo>/raw/...`
282
- - `repos/<owner>/<repo>/norm/...` (GitHub/local snapshots)
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` (or `topic-<topic>-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
- If you work from multiple computers or want redundant cloud backups:
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
- Writes to all paths, reads from first available:
320
+ 写入所有路径,从第一个可用路径读取:
304
321
  ```powershell
305
- # Windows - semicolon separated
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**: If primary path is unavailable, automatically uses first available backup
330
- - **Mirror sync**: All writes are mirrored to available backup paths
331
- - **Mount recovery**: When a path comes back online, it syncs automatically on next write
332
- - **Non-blocking**: Unavailable paths are skipped without errors
346
+ - **Auto-failover**:如果主路径不可用,自动使用第一个可用备份
347
+ - **Mirror sync**:所有写入会镜像到可用备份路径
348
+ - **Mount recovery**:路径恢复后,下次写入时自动同步
349
+ - **Non-blocking**:不可用路径会被跳过,不报错
333
350
 
334
351
  ### Important notes
335
- - **Avoid concurrent access**: Only use on one machine at a time (SQLite conflicts)
336
- - **Wait for sync**: After updates, wait for cloud sync before switching machines
352
+ - **避免并发访问**:同一时间只在一台机器上使用(SQLite 冲突)
353
+ - **等待同步**:更新后,切换机器前等待云同步完成
337
354
 
338
355
  ## Contributing
339
356