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.md
CHANGED
|
@@ -15,12 +15,11 @@ Each bundle contains:
|
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
|
-
- **12 MCP tools** to create/update/repair/search/
|
|
18
|
+
- **12 MCP tools** to create/update/repair/search/read bundles, generate evidence graphs, and manage trace links
|
|
19
19
|
- **De-duplication**: prevent repeated indexing of the same normalized inputs
|
|
20
20
|
- **Resilient GitHub fetching**: configurable git clone timeout + GitHub archive (zipball) fallback
|
|
21
21
|
- **Offline repair**: rebuild missing/empty derived artifacts (index/guides/overview) without re-fetching
|
|
22
22
|
- **Static facts extraction** via `analysis/FACTS.json` (non-LLM)
|
|
23
|
-
- **Evidence-based verification** to reduce hallucinations
|
|
24
23
|
- **Resources** to read bundle files via `preflight://...` URIs
|
|
25
24
|
- **Multi-path mirror backup** for cloud storage redundancy
|
|
26
25
|
- **Resilient storage** with automatic failover when mounts are unavailable
|
|
@@ -28,75 +27,6 @@ Each bundle contains:
|
|
|
28
27
|
- **Fast background deletion** with 100-300x performance improvement
|
|
29
28
|
- **Auto-cleanup** on startup for historical orphan bundles
|
|
30
29
|
|
|
31
|
-
## Architecture Improvements (v0.1.2)
|
|
32
|
-
|
|
33
|
-
### 🚀 Atomic Bundle Creation
|
|
34
|
-
**Problem**: Bundle creation failures could leave incomplete orphan directories.
|
|
35
|
-
|
|
36
|
-
**Solution**: Temporary directory + atomic rename pattern:
|
|
37
|
-
1. Create bundle in `tmpDir/bundles-wip/` (invisible to list)
|
|
38
|
-
2. Validate completeness before making visible
|
|
39
|
-
3. Atomic rename/move to final location
|
|
40
|
-
4. Automatic cleanup on any failure
|
|
41
|
-
|
|
42
|
-
**Benefits**:
|
|
43
|
-
- ✅ Zero orphan bundles
|
|
44
|
-
- 🔒 Crash-safe (temp dirs auto-cleaned)
|
|
45
|
-
- 📏 Validation before visibility
|
|
46
|
-
- 🔄 Cross-filesystem fallback
|
|
47
|
-
|
|
48
|
-
### ⚡ Fast Background Deletion
|
|
49
|
-
**Problem**: Deleting large bundles could timeout (10+ seconds).
|
|
50
|
-
|
|
51
|
-
**Solution**: Rename + background deletion:
|
|
52
|
-
1. Instant rename to `.deleting.{timestamp}` (<100ms)
|
|
53
|
-
2. Background deletion (fire-and-forget)
|
|
54
|
-
3. Automatic cleanup of `.deleting` dirs on startup
|
|
55
|
-
|
|
56
|
-
**Benefits**:
|
|
57
|
-
- ⚡ 100-300x faster response (<100ms)
|
|
58
|
-
- 🔄 No blocking operations
|
|
59
|
-
- 👁️ Invisible to list (non-UUID format)
|
|
60
|
-
- 🛡️ Fallback to direct delete on rename failure
|
|
61
|
-
|
|
62
|
-
### 🔧 Auto-Cleanup on Startup
|
|
63
|
-
**Problem**: Historical orphan bundles need manual cleanup.
|
|
64
|
-
|
|
65
|
-
**Solution**: Automatic cleanup on MCP server startup:
|
|
66
|
-
1. Scans storage directories for invalid bundles
|
|
67
|
-
2. Checks manifest.json validity
|
|
68
|
-
3. Deletes orphans older than 1 hour (safety margin)
|
|
69
|
-
4. Cleans `.deleting` residues
|
|
70
|
-
|
|
71
|
-
**Benefits**:
|
|
72
|
-
- 🤖 Fully automatic
|
|
73
|
-
- 🛡️ Safe with 1-hour age threshold
|
|
74
|
-
- ⚡ Fast when no orphans (<10ms)
|
|
75
|
-
- 🚫 Non-blocking background execution
|
|
76
|
-
|
|
77
|
-
### 🧹 Manual Cleanup Tool
|
|
78
|
-
**New Tool**: `preflight_cleanup_orphans`
|
|
79
|
-
|
|
80
|
-
Manually trigger orphan cleanup with full control:
|
|
81
|
-
```json
|
|
82
|
-
{
|
|
83
|
-
"dryRun": true, // Only report, don't delete
|
|
84
|
-
"minAgeHours": 1 // Age threshold
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### 🔍 UUID Validation
|
|
89
|
-
List and cleanup now strictly filter by UUID format:
|
|
90
|
-
- ✅ Only valid UUID v4 bundle IDs
|
|
91
|
-
- 🚫 Filters out system directories (`#recycle`, `tmp`)
|
|
92
|
-
- 🚫 Filters out `.deleting` directories
|
|
93
|
-
- 🛡️ Protects user custom directories
|
|
94
|
-
|
|
95
|
-
For technical details, see:
|
|
96
|
-
- [ISSUES_ANALYSIS.md](./ISSUES_ANALYSIS.md) - Root cause analysis
|
|
97
|
-
- [IMPLEMENTATION_SUMMARY.md](./IMPLEMENTATION_SUMMARY.md) - Implementation details
|
|
98
|
-
- [CLEANUP_STRATEGY.md](./CLEANUP_STRATEGY.md) - MCP-specific cleanup design
|
|
99
|
-
|
|
100
30
|
## Table of Contents
|
|
101
31
|
|
|
102
32
|
- [Requirements](#requirements)
|
|
@@ -187,29 +117,14 @@ Run end-to-end smoke test:
|
|
|
187
117
|
npm run smoke
|
|
188
118
|
```
|
|
189
119
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
## Smoke test
|
|
193
|
-
Runs an end-to-end stdio client that:
|
|
194
|
-
- spawns the server
|
|
195
|
-
- calls `preflight_create_bundle`
|
|
196
|
-
- reads `preflight://bundles` and `START_HERE.md`
|
|
197
|
-
- searches the bundle
|
|
198
|
-
- calls `preflight_update_bundle`
|
|
199
|
-
|
|
200
|
-
Command:
|
|
201
|
-
- `npm run smoke`
|
|
202
|
-
|
|
203
|
-
Note: the smoke test clones `octocat/Hello-World` from GitHub, so it needs internet access.
|
|
204
|
-
|
|
205
|
-
## Tools (13 total)
|
|
120
|
+
## Tools (12 total)
|
|
206
121
|
|
|
207
122
|
### `preflight_list_bundles`
|
|
208
123
|
List bundle IDs in storage.
|
|
209
124
|
- Triggers: "show bundles", "查看bundle", "有哪些bundle"
|
|
210
125
|
|
|
211
126
|
### `preflight_create_bundle`
|
|
212
|
-
Create a new bundle from
|
|
127
|
+
Create a new bundle from GitHub repos or local directories.
|
|
213
128
|
- Triggers: "index this repo", "学习这个项目", "创建bundle"
|
|
214
129
|
|
|
215
130
|
Key semantics:
|
|
@@ -220,21 +135,20 @@ Key semantics:
|
|
|
220
135
|
- `updateExisting`: update the existing bundle then return it
|
|
221
136
|
- `createNew`: bypass de-duplication
|
|
222
137
|
- GitHub ingest uses **shallow clone**; if `git clone` fails, it will fall back to **GitHub archive (zipball)**.
|
|
223
|
-
- Supports `repos.kind: "local"` to ingest from a local directory
|
|
138
|
+
- Supports `repos.kind: "local"` to ingest from a local directory.
|
|
224
139
|
|
|
225
140
|
Input (example):
|
|
226
|
-
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }
|
|
141
|
+
- `repos`: `[{ kind: "github", repo: "owner/repo" }, { kind: "local", repo: "owner/repo", path: "/path/to/dir" }]`
|
|
227
142
|
- `libraries`: `["nextjs", "react"]` (Context7; optional)
|
|
228
143
|
- `topics`: `["routing", "api"]` (Context7 topic filter; optional)
|
|
229
144
|
- `ifExists`: `"error" | "returnExisting" | "updateExisting" | "createNew"`
|
|
230
145
|
|
|
231
|
-
|
|
232
|
-
Read a file from bundle (OVERVIEW.md, START_HERE.md, AGENTS.md, or any repo file).
|
|
233
|
-
- Triggers: "查看概览", "项目概览", "看README"
|
|
146
|
+
**Note**: If the bundle contains code files, consider using `preflight_evidence_dependency_graph` for dependency analysis or `preflight_trace_upsert` for trace links.
|
|
234
147
|
|
|
235
|
-
### `
|
|
236
|
-
|
|
237
|
-
- Triggers: "bundle详情", "仓库信息"
|
|
148
|
+
### `preflight_read_file`
|
|
149
|
+
Read a file from bundle (OVERVIEW.md, START_HERE.md, AGENTS.md, manifest.json, or any repo file).
|
|
150
|
+
- Triggers: "查看概览", "项目概览", "看README", "bundle详情", "bundle状态", "仓库信息"
|
|
151
|
+
- Use `file: "manifest.json"` to get bundle metadata (repos, timestamps, tags, etc.)
|
|
238
152
|
|
|
239
153
|
### `preflight_delete_bundle`
|
|
240
154
|
Delete/remove a bundle permanently.
|
|
@@ -248,14 +162,6 @@ Optional parameters:
|
|
|
248
162
|
- `checkOnly`: If true, only check for updates without applying.
|
|
249
163
|
- `force`: If true, force rebuild even if no changes detected.
|
|
250
164
|
|
|
251
|
-
### `preflight_update_all_bundles`
|
|
252
|
-
Batch update all bundles at once.
|
|
253
|
-
- Triggers: "批量更新", "全部刷新"
|
|
254
|
-
|
|
255
|
-
### `preflight_find_bundle`
|
|
256
|
-
Check whether a bundle already exists for the given inputs (no fetching, no changes).
|
|
257
|
-
- Use when your UI/agent wants to decide whether to create/update.
|
|
258
|
-
|
|
259
165
|
### `preflight_repair_bundle`
|
|
260
166
|
Offline repair for a bundle (no fetching): rebuild missing/empty derived artifacts.
|
|
261
167
|
- Rebuilds `indexes/search.sqlite3`, `START_HERE.md`, `AGENTS.md`, `OVERVIEW.md` when missing/empty.
|
|
@@ -266,13 +172,12 @@ Full-text search across ingested docs/code (line-based SQLite FTS5).
|
|
|
266
172
|
- Triggers: "搜索bundle", "在仓库中查找", "搜代码"
|
|
267
173
|
|
|
268
174
|
Important: **this tool is strictly read-only**.
|
|
269
|
-
- `ensureFresh` / `maxAgeHours` are **deprecated** and will error if provided.
|
|
270
175
|
- To update: call `preflight_update_bundle`, then search again.
|
|
271
176
|
- To repair: call `preflight_repair_bundle`, then search again.
|
|
272
177
|
|
|
273
178
|
### `preflight_search_by_tags`
|
|
274
179
|
Search across multiple bundles filtered by tags (line-based SQLite FTS5).
|
|
275
|
-
- Triggers: "search in MCP bundles", "
|
|
180
|
+
- Triggers: "search in MCP bundles", "在MCP项目中搜索", "搜索所有agent"
|
|
276
181
|
|
|
277
182
|
Notes:
|
|
278
183
|
- This tool is read-only and **does not auto-repair**.
|
|
@@ -283,18 +188,17 @@ Optional parameters:
|
|
|
283
188
|
- `scope`: Search scope (`docs`, `code`, or `all`)
|
|
284
189
|
- `limit`: Max total hits across all bundles
|
|
285
190
|
|
|
286
|
-
|
|
287
|
-
-
|
|
288
|
-
-
|
|
191
|
+
### `preflight_evidence_dependency_graph`
|
|
192
|
+
Generate an evidence-based dependency graph for a target file/symbol (imports + callers).
|
|
193
|
+
- Deterministic output with source ranges for edges.
|
|
194
|
+
- Uses Tree-sitter parsing when `PREFLIGHT_AST_ENGINE=wasm`; falls back to regex extraction otherwise.
|
|
195
|
+
- Emits `imports` edges (file → module) and, when resolvable, `imports_resolved` edges (file → internal file).
|
|
289
196
|
|
|
290
|
-
### `
|
|
291
|
-
|
|
292
|
-
- Triggers: "验证说法", "找证据", "这个对吗"
|
|
197
|
+
### `preflight_trace_upsert`
|
|
198
|
+
Upsert traceability links (commit↔ticket, symbol↔test, code↔doc, etc.) for a bundle.
|
|
293
199
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
- To update: call `preflight_update_bundle`, then verify again.
|
|
297
|
-
- To repair: call `preflight_repair_bundle`, then verify again.
|
|
200
|
+
### `preflight_trace_query`
|
|
201
|
+
Query traceability links (fast when `bundleId` is provided; can scan across bundles when omitted).
|
|
298
202
|
|
|
299
203
|
### `preflight_cleanup_orphans`
|
|
300
204
|
Remove incomplete or corrupted bundles (bundles without valid manifest.json).
|
|
@@ -304,14 +208,10 @@ Parameters:
|
|
|
304
208
|
- `dryRun` (default: true): Only report orphans without deleting
|
|
305
209
|
- `minAgeHours` (default: 1): Only clean bundles older than N hours
|
|
306
210
|
|
|
307
|
-
Output:
|
|
308
|
-
- `totalFound`: Number of orphan bundles found
|
|
309
|
-
- `totalCleaned`: Number of orphan bundles deleted
|
|
310
|
-
- `details`: Per-directory breakdown
|
|
311
|
-
|
|
312
211
|
Note: This is also automatically executed on server startup (background, non-blocking).
|
|
313
212
|
|
|
314
213
|
## Resources
|
|
214
|
+
|
|
315
215
|
### `preflight://bundles`
|
|
316
216
|
Static JSON listing of bundles and their main entry files.
|
|
317
217
|
|
|
@@ -323,6 +223,7 @@ Examples:
|
|
|
323
223
|
- `preflight://bundle/<id>/file/repos%2Fowner%2Frepo%2Fnorm%2FREADME.md`
|
|
324
224
|
|
|
325
225
|
## Error semantics (stable, UI-friendly)
|
|
226
|
+
|
|
326
227
|
Most tool errors are wrapped with a stable, machine-parseable prefix:
|
|
327
228
|
- `[preflight_error kind=<kind>] <message>`
|
|
328
229
|
|
|
@@ -332,7 +233,6 @@ Common kinds:
|
|
|
332
233
|
- `invalid_path` (unsafe path traversal attempt)
|
|
333
234
|
- `permission_denied`
|
|
334
235
|
- `index_missing_or_corrupt`
|
|
335
|
-
- `deprecated_parameter`
|
|
336
236
|
- `unknown`
|
|
337
237
|
|
|
338
238
|
This is designed so UIs/agents can reliably decide whether to:
|
|
@@ -341,6 +241,7 @@ This is designed so UIs/agents can reliably decide whether to:
|
|
|
341
241
|
- prompt the user for a different bundleId/path
|
|
342
242
|
|
|
343
243
|
## Environment variables
|
|
244
|
+
|
|
344
245
|
### Storage
|
|
345
246
|
- `PREFLIGHT_STORAGE_DIR`: bundle storage dir (default: `~/.preflight-mcp/bundles`)
|
|
346
247
|
- `PREFLIGHT_STORAGE_DIRS`: **multi-path mirror backup** (semicolon-separated, e.g., `D:\cloud1\preflight;E:\cloud2\preflight`)
|
|
@@ -348,8 +249,14 @@ This is designed so UIs/agents can reliably decide whether to:
|
|
|
348
249
|
- `PREFLIGHT_MAX_FILE_BYTES`: max bytes per file (default: 512 KiB)
|
|
349
250
|
- `PREFLIGHT_MAX_TOTAL_BYTES`: max bytes per repo ingest (default: 50 MiB)
|
|
350
251
|
|
|
351
|
-
### Analysis
|
|
352
|
-
- `PREFLIGHT_ANALYSIS_MODE`: Static analysis mode - `none`
|
|
252
|
+
### Analysis & evidence
|
|
253
|
+
- `PREFLIGHT_ANALYSIS_MODE`: Static analysis mode - `none` | `quick` | `full` (default: `full`). Controls generation of `analysis/FACTS.json`.
|
|
254
|
+
- `PREFLIGHT_AST_ENGINE`: AST engine used by some evidence tools - `wasm` (default) or `native`.
|
|
255
|
+
|
|
256
|
+
### Built-in HTTP API
|
|
257
|
+
- `PREFLIGHT_HTTP_ENABLED`: enable/disable REST API (default: true)
|
|
258
|
+
- `PREFLIGHT_HTTP_HOST`: REST listen host (default: 127.0.0.1)
|
|
259
|
+
- `PREFLIGHT_HTTP_PORT`: REST listen port (default: 37123)
|
|
353
260
|
|
|
354
261
|
### GitHub & Context7
|
|
355
262
|
- `GITHUB_TOKEN`: optional; used for GitHub API/auth patterns and GitHub archive fallback (public repos usually work without it)
|
|
@@ -358,19 +265,19 @@ This is designed so UIs/agents can reliably decide whether to:
|
|
|
358
265
|
- `CONTEXT7_MCP_URL`: optional; defaults to Context7 MCP endpoint
|
|
359
266
|
|
|
360
267
|
## Bundle layout (on disk)
|
|
268
|
+
|
|
361
269
|
Inside a bundle directory:
|
|
362
270
|
- `manifest.json` (includes `fingerprint`, `displayName`, `tags`, and per-repo `source`)
|
|
363
271
|
- `START_HERE.md`
|
|
364
272
|
- `AGENTS.md`
|
|
365
273
|
- `OVERVIEW.md`
|
|
366
274
|
- `indexes/search.sqlite3`
|
|
367
|
-
-
|
|
275
|
+
- `analysis/FACTS.json` (static analysis)
|
|
276
|
+
- `trace/trace.sqlite3` (traceability links; created on demand)
|
|
368
277
|
- `repos/<owner>/<repo>/raw/...`
|
|
369
278
|
- `repos/<owner>/<repo>/norm/...` (GitHub/local snapshots)
|
|
370
|
-
- `deepwiki/<owner>/<repo>/norm/index.md` (DeepWiki sources)
|
|
371
|
-
- `deepwiki/<owner>/<repo>/meta.json`
|
|
372
279
|
- `libraries/context7/<...>/meta.json`
|
|
373
|
-
- `libraries/context7/<...>/docs-page-1.md`
|
|
280
|
+
- `libraries/context7/<...>/docs-page-1.md`
|
|
374
281
|
|
|
375
282
|
## Multi-device sync & mirror backup
|
|
376
283
|
|
|
@@ -444,20 +351,6 @@ If you encounter any issues or have questions:
|
|
|
444
351
|
|
|
445
352
|
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
446
353
|
|
|
447
|
-
The MIT License allows you to:
|
|
448
|
-
- Use commercially
|
|
449
|
-
- Modify
|
|
450
|
-
- Distribute
|
|
451
|
-
- Use privately
|
|
452
|
-
|
|
453
|
-
With the only requirement being to include the original copyright and license notice.
|
|
454
|
-
|
|
455
|
-
## Acknowledgments
|
|
456
|
-
|
|
457
|
-
- Built on the [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
458
|
-
- Uses SQLite FTS5 for efficient full-text search
|
|
459
|
-
- Inspired by the need for evidence-based AI assistance
|
|
460
|
-
|
|
461
354
|
---
|
|
462
355
|
|
|
463
356
|
Made with ❤️ for the AI developer community
|