preflight-mcp 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/README.md +282 -27
- package/README.zh-CN.md +277 -308
- package/dist/bundle/cleanup.js +155 -0
- package/dist/bundle/deepwiki.js +1 -1
- package/dist/bundle/github.js +100 -15
- package/dist/bundle/githubArchive.js +82 -0
- package/dist/bundle/ingest.js +2 -2
- package/dist/bundle/paths.js +23 -0
- package/dist/bundle/service.js +800 -57
- package/dist/config.js +1 -0
- package/dist/context7/client.js +1 -1
- package/dist/core/concurrency-limiter.js +100 -0
- package/dist/core/scheduler.js +4 -1
- package/dist/jobs/tmp-cleanup-job.js +71 -0
- package/dist/mcp/errorKinds.js +54 -0
- package/dist/mcp/uris.js +28 -8
- package/dist/search/sqliteFts.js +68 -36
- package/dist/server/optimized-server.js +4 -0
- package/dist/server.js +498 -279
- package/dist/tools/searchByTags.js +80 -0
- package/package.json +26 -1
package/README.zh-CN.md
CHANGED
|
@@ -1,276 +1,316 @@
|
|
|
1
1
|
# preflight-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
[](https://modelcontextprotocol.io/)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> [English](./README.md) | **中文**
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
一个 MCP (Model Context Protocol) **stdio** 服务器,用于为 GitHub 仓库与库文档生成“基于证据”的 preflight bundles。
|
|
8
10
|
|
|
9
11
|
每个 bundle 包含:
|
|
10
12
|
- 仓库文档 + 代码的本地副本(规范化文本)
|
|
11
|
-
-
|
|
12
|
-
- 面向
|
|
13
|
+
- 轻量级 **全文搜索索引**(SQLite FTS5)
|
|
14
|
+
- 面向 Agent 的入口文件:`START_HERE.md`、`AGENTS.md`、`OVERVIEW.md`(仅事实,带证据指针)
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Features
|
|
15
17
|
|
|
16
|
-
- **
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
18
|
+
- **12 个 MCP 工具**:create/update/repair/search/verify/read bundles(外加 resources)
|
|
19
|
+
- **去重**:避免对相同的规范化输入重复索引
|
|
20
|
+
- **更可靠的 GitHub 获取**:可配置 git clone 超时 + GitHub archive(zipball)兜底
|
|
21
|
+
- **离线修复**:无需重新抓取,重建缺失/为空的派生物(index/guides/overview)
|
|
22
|
+
- **静态事实提取**:生成 `analysis/FACTS.json`(非 LLM)
|
|
23
|
+
- **基于证据的校验**:减少幻觉
|
|
24
|
+
- **Resources**:通过 `preflight://...` URI 读取 bundle 文件
|
|
25
|
+
- **多路径镜像备份**:云存储冗余
|
|
26
|
+
- **弹性存储**:挂载点不可用时自动故障转移
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
## Table of Contents
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
- [Requirements](#requirements)
|
|
31
|
+
- [Installation](#installation)
|
|
32
|
+
- [Quick Start](#quick-start)
|
|
33
|
+
- [Tools](#tools-12-total)
|
|
34
|
+
- [Environment Variables](#environment-variables)
|
|
35
|
+
- [Contributing](#contributing)
|
|
36
|
+
- [License](#license)
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
- `git` 命令可用(在 PATH 中)
|
|
38
|
+
## Requirements
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
- Node.js >= 18
|
|
41
|
+
- `git` available on PATH
|
|
34
42
|
|
|
35
|
-
##
|
|
43
|
+
## Installation
|
|
36
44
|
|
|
37
|
-
###
|
|
38
|
-
```bash
|
|
39
|
-
npm install
|
|
40
|
-
npm run build
|
|
41
|
-
```
|
|
45
|
+
### From npm (after published)
|
|
42
46
|
|
|
43
|
-
### 全局安装(发布到 npm 后)
|
|
44
47
|
```bash
|
|
45
48
|
npm install -g preflight-mcp
|
|
46
49
|
```
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## 🚀 使用方法
|
|
51
|
-
|
|
52
|
-
### 作为 MCP 服务器运行
|
|
53
|
-
此服务器通过 stdin/stdout 通信,通常通过 MCP 主机运行(如 mcp-hub)。
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
# 直接运行
|
|
57
|
-
preflight-mcp
|
|
58
|
-
|
|
59
|
-
# 或本地开发
|
|
60
|
-
node dist/index.js
|
|
61
|
-
```
|
|
51
|
+
### Local Development
|
|
62
52
|
|
|
63
|
-
### 运行测试
|
|
64
53
|
```bash
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
npm run smoke
|
|
70
|
-
|
|
71
|
-
# 类型检查
|
|
72
|
-
npm run typecheck
|
|
54
|
+
git clone https://github.com/jonnyhoo/preflight-mcp.git
|
|
55
|
+
cd preflight-mcp
|
|
56
|
+
npm install
|
|
57
|
+
npm run build
|
|
73
58
|
```
|
|
74
59
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## 🛠️ 工具列表(共 10 个)
|
|
80
|
-
|
|
81
|
-
### 1. `preflight_list_bundles`
|
|
82
|
-
列出存储中的所有 bundle ID。
|
|
83
|
-
|
|
84
|
-
**触发词**: "show bundles"、"查看bundle"、"有哪些bundle"、"列出仓库"
|
|
85
|
-
|
|
86
|
-
---
|
|
60
|
+
## Quick Start
|
|
87
61
|
|
|
88
|
-
###
|
|
89
|
-
从一个或多个输入创建新的 bundle。
|
|
62
|
+
### 1. Configure MCP Host (e.g., Claude Desktop)
|
|
90
63
|
|
|
91
|
-
|
|
64
|
+
在你的 MCP 配置文件中加入:
|
|
92
65
|
|
|
93
|
-
**输入示例**:
|
|
94
66
|
```json
|
|
95
67
|
{
|
|
96
|
-
"
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
68
|
+
"mcpServers": {
|
|
69
|
+
"preflight": {
|
|
70
|
+
"command": "npx",
|
|
71
|
+
"args": ["preflight-mcp"]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
102
74
|
}
|
|
103
75
|
```
|
|
104
76
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
### 3. `preflight_read_file`
|
|
108
|
-
从 bundle 读取文件(OVERVIEW.md、START_HERE.md、AGENTS.md 或任何仓库文件)。
|
|
109
|
-
|
|
110
|
-
**触发词**: "查看概览"、"项目概览"、"看README"、"show overview"
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
### 4. `preflight_bundle_info`
|
|
115
|
-
获取 bundle 详情:仓库、更新时间、统计信息。
|
|
116
|
-
|
|
117
|
-
**触发词**: "bundle详情"、"仓库信息"、"bundle info"
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
### 5. `preflight_delete_bundle`
|
|
122
|
-
永久删除/移除一个 bundle。
|
|
123
|
-
|
|
124
|
-
**触发词**: "删除bundle"、"移除仓库"、"delete bundle"
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
### 6. `preflight_update_bundle`
|
|
129
|
-
刷新/同步 bundle 与最新的仓库更改。
|
|
130
|
-
|
|
131
|
-
**触发词**: "更新bundle"、"同步仓库"、"刷新索引"
|
|
132
|
-
|
|
133
|
-
**可选参数**:
|
|
134
|
-
- `checkOnly`: 如果为 true,仅检查更新不应用
|
|
135
|
-
- `force`: 如果为 true,即使没有检测到更改也强制重建
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
### 7. `preflight_update_all_bundles`
|
|
140
|
-
批量更新所有 bundles。
|
|
141
|
-
|
|
142
|
-
**触发词**: "批量更新"、"全部刷新"、"更新所有bundle"
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
### 8. `preflight_search_bundle`
|
|
147
|
-
在已导入的文档/代码中进行全文搜索(基于行的 SQLite FTS5)。
|
|
77
|
+
或(本地开发)直接指向构建产物:
|
|
148
78
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"preflight": {
|
|
83
|
+
"command": "node",
|
|
84
|
+
"args": ["path/to/preflight-mcp/dist/index.js"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
156
89
|
|
|
157
|
-
###
|
|
158
|
-
按标签筛选后跨多个 bundle 搜索(基于行的 SQLite FTS5)。
|
|
90
|
+
### 2. Create Your First Bundle
|
|
159
91
|
|
|
160
|
-
|
|
92
|
+
对你的 AI 助手说:
|
|
161
93
|
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
- `limit`: 跨 bundle 的总命中数量上限
|
|
94
|
+
```
|
|
95
|
+
"为仓库 octocat/Hello-World 创建 bundle"
|
|
96
|
+
```
|
|
166
97
|
|
|
167
|
-
|
|
98
|
+
它会:
|
|
99
|
+
- 克隆仓库
|
|
100
|
+
- 索引所有文档与代码
|
|
101
|
+
- 生成可搜索的 SQLite FTS5 索引
|
|
102
|
+
- 生成 `START_HERE.md`、`AGENTS.md`、`OVERVIEW.md`
|
|
168
103
|
|
|
169
|
-
###
|
|
170
|
-
在 bundle 中查找声明/陈述的证据。
|
|
104
|
+
### 3. Search the Bundle
|
|
171
105
|
|
|
172
|
-
|
|
106
|
+
```
|
|
107
|
+
"在 bundle 里搜索 'GitHub'"
|
|
108
|
+
```
|
|
173
109
|
|
|
174
|
-
|
|
175
|
-
- `ensureFresh`: 如果为 true,验证前检查 bundle 是否需要更新
|
|
176
|
-
- `maxAgeHours`: 触发自动更新前的最大小时数(默认: 24)
|
|
110
|
+
### 4. Test Locally (Optional)
|
|
177
111
|
|
|
178
|
-
|
|
112
|
+
运行端到端 smoke 测试:
|
|
179
113
|
|
|
180
|
-
|
|
114
|
+
```bash
|
|
115
|
+
npm run smoke
|
|
116
|
+
```
|
|
181
117
|
|
|
118
|
+
这会测试 bundle 创建、搜索、更新等核心操作。
|
|
119
|
+
|
|
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`
|
|
127
|
+
|
|
128
|
+
Command:
|
|
129
|
+
- `npm run smoke`
|
|
130
|
+
|
|
131
|
+
Note: the smoke test clones `octocat/Hello-World` from GitHub, so it needs internet access.
|
|
132
|
+
|
|
133
|
+
## Tools (12 total)
|
|
134
|
+
|
|
135
|
+
### `preflight_list_bundles`
|
|
136
|
+
List bundle IDs in storage.
|
|
137
|
+
- Triggers: "show bundles", "查看bundle", "有哪些bundle"
|
|
138
|
+
|
|
139
|
+
### `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)
|
|
157
|
+
- `ifExists`: `"error" | "returnExisting" | "updateExisting" | "createNew"`
|
|
158
|
+
|
|
159
|
+
### `preflight_read_file`
|
|
160
|
+
Read a file from bundle (OVERVIEW.md, START_HERE.md, AGENTS.md, or any repo file).
|
|
161
|
+
- Triggers: "查看概览", "项目概览", "看README"
|
|
162
|
+
|
|
163
|
+
### `preflight_bundle_info`
|
|
164
|
+
Get bundle details: repos, update time, stats.
|
|
165
|
+
- Triggers: "bundle详情", "仓库信息"
|
|
166
|
+
|
|
167
|
+
### `preflight_delete_bundle`
|
|
168
|
+
Delete/remove a bundle permanently.
|
|
169
|
+
- Triggers: "删除bundle", "移除仓库"
|
|
170
|
+
|
|
171
|
+
### `preflight_update_bundle`
|
|
172
|
+
Refresh/sync a bundle with latest repo changes.
|
|
173
|
+
- Triggers: "更新bundle", "同步仓库", "刷新索引"
|
|
174
|
+
|
|
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.
|
|
186
|
+
|
|
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.
|
|
191
|
+
|
|
192
|
+
### `preflight_search_bundle`
|
|
193
|
+
Full-text search across ingested docs/code (line-based SQLite FTS5).
|
|
194
|
+
- Triggers: "搜索bundle", "在仓库中查找", "搜代码"
|
|
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.
|
|
200
|
+
|
|
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.
|
|
226
|
+
|
|
227
|
+
## Resources
|
|
182
228
|
### `preflight://bundles`
|
|
183
|
-
bundles
|
|
229
|
+
Static JSON listing of bundles and their main entry files.
|
|
184
230
|
|
|
185
231
|
### `preflight://bundle/{bundleId}/file/{encodedPath}`
|
|
186
|
-
|
|
232
|
+
Read a specific file inside a bundle.
|
|
187
233
|
|
|
188
|
-
|
|
234
|
+
Examples:
|
|
189
235
|
- `preflight://bundle/<id>/file/START_HERE.md`
|
|
190
236
|
- `preflight://bundle/<id>/file/repos%2Fowner%2Frepo%2Fnorm%2FREADME.md`
|
|
191
237
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
238
|
+
## Error semantics (stable, UI-friendly)
|
|
239
|
+
Most tool errors are wrapped with a stable, machine-parseable prefix:
|
|
240
|
+
- `[preflight_error kind=<kind>] <message>`
|
|
241
|
+
|
|
242
|
+
Common kinds:
|
|
243
|
+
- `bundle_not_found`
|
|
244
|
+
- `file_not_found`
|
|
245
|
+
- `invalid_path` (unsafe path traversal attempt)
|
|
246
|
+
- `permission_denied`
|
|
247
|
+
- `index_missing_or_corrupt`
|
|
248
|
+
- `deprecated_parameter`
|
|
249
|
+
- `unknown`
|
|
250
|
+
|
|
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
|
|
255
|
+
|
|
256
|
+
## Environment variables
|
|
257
|
+
### 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)
|
|
263
|
+
|
|
264
|
+
### Analysis
|
|
265
|
+
- `PREFLIGHT_ANALYSIS_MODE`: Static analysis mode - `none` or `quick` (default: `quick`). Generates `analysis/FACTS.json`.
|
|
209
266
|
|
|
210
267
|
### GitHub & Context7
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
│ └── <owner>/<repo>/
|
|
237
|
-
│ ├── norm/index.md
|
|
238
|
-
│ └── meta.json
|
|
239
|
-
└── libraries/
|
|
240
|
-
└── context7/
|
|
241
|
-
├── meta.json
|
|
242
|
-
└── docs-page-1.md
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
---
|
|
246
|
-
|
|
247
|
-
## 🔄 多设备同步与镜像备份
|
|
248
|
-
|
|
249
|
-
### 单路径(简单)
|
|
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
|
|
272
|
+
|
|
273
|
+
## Bundle layout (on disk)
|
|
274
|
+
Inside a bundle directory:
|
|
275
|
+
- `manifest.json` (includes `fingerprint`, `displayName`, `tags`, and per-repo `source`)
|
|
276
|
+
- `START_HERE.md`
|
|
277
|
+
- `AGENTS.md`
|
|
278
|
+
- `OVERVIEW.md`
|
|
279
|
+
- `indexes/search.sqlite3`
|
|
280
|
+
- **`analysis/FACTS.json`** (static analysis)
|
|
281
|
+
- `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`
|
|
285
|
+
- `libraries/context7/<...>/meta.json`
|
|
286
|
+
- `libraries/context7/<...>/docs-page-1.md` (or `topic-<topic>-page-1.md`)
|
|
287
|
+
|
|
288
|
+
## Multi-device sync & mirror backup
|
|
289
|
+
|
|
290
|
+
If you work from multiple computers or want redundant cloud backups:
|
|
291
|
+
|
|
292
|
+
### Single path (simple)
|
|
250
293
|
```powershell
|
|
251
294
|
# Windows
|
|
252
295
|
$env:PREFLIGHT_STORAGE_DIR = "D:\OneDrive\preflight-bundles"
|
|
253
296
|
```
|
|
254
|
-
|
|
255
297
|
```bash
|
|
256
298
|
# macOS/Linux
|
|
257
299
|
export PREFLIGHT_STORAGE_DIR="$HOME/Dropbox/preflight-bundles"
|
|
258
300
|
```
|
|
259
301
|
|
|
260
|
-
###
|
|
261
|
-
|
|
262
|
-
|
|
302
|
+
### Multi-path mirror (redundancy)
|
|
303
|
+
Writes to all paths, reads from first available:
|
|
263
304
|
```powershell
|
|
264
|
-
# Windows -
|
|
305
|
+
# Windows - semicolon separated
|
|
265
306
|
$env:PREFLIGHT_STORAGE_DIRS = "D:\OneDrive\preflight;E:\GoogleDrive\preflight"
|
|
266
307
|
```
|
|
267
|
-
|
|
268
308
|
```bash
|
|
269
309
|
# macOS/Linux
|
|
270
|
-
export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight
|
|
310
|
+
export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight;$HOME/Dropbox/preflight"
|
|
271
311
|
```
|
|
272
312
|
|
|
273
|
-
### MCP
|
|
313
|
+
### MCP host config (Claude Desktop)
|
|
274
314
|
```json
|
|
275
315
|
{
|
|
276
316
|
"mcpServers": {
|
|
@@ -285,122 +325,51 @@ export PREFLIGHT_STORAGE_DIRS="$HOME/OneDrive/preflight:$HOME/Dropbox/preflight"
|
|
|
285
325
|
}
|
|
286
326
|
```
|
|
287
327
|
|
|
288
|
-
###
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
-
|
|
328
|
+
### 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
|
|
293
333
|
|
|
294
|
-
###
|
|
295
|
-
-
|
|
296
|
-
-
|
|
334
|
+
### 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
|
|
297
337
|
|
|
298
|
-
|
|
338
|
+
## Contributing
|
|
299
339
|
|
|
300
|
-
|
|
340
|
+
欢迎贡献!请查看 [Contributing Guide](./CONTRIBUTING.md) 了解:
|
|
341
|
+
- 开发环境搭建
|
|
342
|
+
- 代码风格
|
|
343
|
+
- 测试要求
|
|
344
|
+
- PR 流程
|
|
301
345
|
|
|
302
|
-
|
|
303
|
-
src/
|
|
304
|
-
├── index.ts # 入口点
|
|
305
|
-
├── server.ts # MCP 服务器主文件
|
|
306
|
-
├── config.ts # 配置管理
|
|
307
|
-
├── core/
|
|
308
|
-
│ └── scheduler.ts # 任务调度系统
|
|
309
|
-
├── jobs/
|
|
310
|
-
│ ├── bundle-auto-update-job.ts # 自动更新任务
|
|
311
|
-
│ ├── health-check-job.ts # 健康检查任务
|
|
312
|
-
│ └── storage-cleanup-job.ts # 存储清理任务
|
|
313
|
-
├── storage/
|
|
314
|
-
│ ├── storage-adapter.ts # 存储抽象层
|
|
315
|
-
│ └── compression.ts # 压缩系统
|
|
316
|
-
├── logging/
|
|
317
|
-
│ └── logger.ts # 结构化日志
|
|
318
|
-
├── server/
|
|
319
|
-
│ └── optimized-server.ts # 优化服务器集成
|
|
320
|
-
├── bundle/
|
|
321
|
-
│ ├── service.ts # Bundle 服务
|
|
322
|
-
│ ├── analysis.ts # 静态分析(FACTS.json)
|
|
323
|
-
│ ├── facts.ts # 事实提取
|
|
324
|
-
│ └── ... # 其他 bundle 相关模块
|
|
325
|
-
├── search/
|
|
326
|
-
│ └── sqliteFts.ts # SQLite FTS5 搜索
|
|
327
|
-
└── mcp/
|
|
328
|
-
└── uris.ts # URI 处理
|
|
329
|
-
```
|
|
346
|
+
在贡献之前,也请阅读 [Code of Conduct](./CODE_OF_CONDUCT.md)。
|
|
330
347
|
|
|
331
|
-
|
|
348
|
+
## Support
|
|
332
349
|
|
|
333
|
-
|
|
350
|
+
如果你遇到问题或有疑问:
|
|
334
351
|
|
|
335
|
-
|
|
352
|
+
- **Issues**: [GitHub Issues](https://github.com/jonnyhoo/preflight-mcp/issues)
|
|
353
|
+
- **Discussions**: [GitHub Discussions](https://github.com/jonnyhoo/preflight-mcp/discussions)
|
|
336
354
|
|
|
337
|
-
|
|
338
|
-
# 运行所有测试
|
|
339
|
-
npm test
|
|
340
|
-
|
|
341
|
-
# 测试覆盖范围:
|
|
342
|
-
# - 调度器系统 (3 tests)
|
|
343
|
-
# - Bundle 自动更新任务 (2 tests)
|
|
344
|
-
# - 存储清理任务 (2 tests)
|
|
345
|
-
# - 健康检查任务 (2 tests)
|
|
346
|
-
# - 存储适配器系统 (4 tests)
|
|
347
|
-
# - 压缩系统 (5 tests)
|
|
348
|
-
# - 日志系统 (3 tests)
|
|
349
|
-
# - 优化服务器集成 (4 tests)
|
|
350
|
-
# - 性能基准测试 (2 tests)
|
|
351
|
-
# - 集成测试 (1 test)
|
|
352
|
-
```
|
|
355
|
+
## License
|
|
353
356
|
|
|
354
|
-
|
|
357
|
+
本项目基于 MIT License 发布,详见 [LICENSE](./LICENSE)。
|
|
355
358
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- Bundle 自动更新(每小时检查)
|
|
362
|
-
- 存储清理(每天凌晨 2 点)
|
|
363
|
-
- 健康检查(每 30 分钟)
|
|
364
|
-
3. **存储抽象层** - 支持本地和 S3 存储
|
|
365
|
-
4. **压缩系统** - 支持 Gzip、Brotli、Deflate
|
|
366
|
-
5. **结构化日志** - 多级别、文件轮转、彩色输出
|
|
367
|
-
6. **优化服务器** - 统一管理接口
|
|
368
|
-
7. **完整测试套件** - 28 个 Jest 测试
|
|
369
|
-
|
|
370
|
-
### 修复问题
|
|
371
|
-
- ESM 模块兼容性问题
|
|
372
|
-
- TypeScript 类型错误
|
|
373
|
-
- 存储适配器 require 改为 import
|
|
374
|
-
- Logger mtime Promise 处理
|
|
375
|
-
- 错误类型转换
|
|
376
|
-
|
|
377
|
-
### 依赖更新
|
|
378
|
-
- 新增: `node-cron`, `@types/node-cron`
|
|
379
|
-
- 新增开发依赖: `jest`, `ts-jest`, `@jest/globals`, `@types/jest`
|
|
359
|
+
MIT License 允许你:
|
|
360
|
+
- 商用
|
|
361
|
+
- 修改
|
|
362
|
+
- 分发
|
|
363
|
+
- 私用
|
|
380
364
|
|
|
381
|
-
|
|
365
|
+
唯一要求是保留原始版权与许可证声明。
|
|
382
366
|
|
|
383
|
-
##
|
|
367
|
+
## Acknowledgments
|
|
384
368
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
# 构建
|
|
390
|
-
npm run build
|
|
391
|
-
|
|
392
|
-
# 类型检查
|
|
393
|
-
npm run typecheck
|
|
394
|
-
|
|
395
|
-
# 运行测试
|
|
396
|
-
npm test
|
|
397
|
-
|
|
398
|
-
# Smoke 测试
|
|
399
|
-
npm run smoke
|
|
400
|
-
```
|
|
369
|
+
- Built on the [Model Context Protocol](https://modelcontextprotocol.io/)
|
|
370
|
+
- Uses SQLite FTS5 for efficient full-text search
|
|
371
|
+
- Inspired by the need for evidence-based AI assistance
|
|
401
372
|
|
|
402
373
|
---
|
|
403
374
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
MIT
|
|
375
|
+
Made with ❤️ for the AI developer community
|