preflight-mcp 0.1.9 → 0.2.1
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 +45 -5
- package/README.zh-CN.md +43 -4
- package/dist/server.js +265 -11
- package/dist/trace/store.js +48 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,10 @@ Each bundle contains:
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
18
|
- **13 MCP tools** to create/update/repair/search/read bundles, generate evidence graphs, and manage trace links
|
|
19
|
+
- **5 MCP prompts** for interactive guidance: menu, analyze guide, search guide, manage guide, trace guide
|
|
20
|
+
- **LLM-friendly outputs**: After bundle creation, prompts user to generate dependency graph for deeper analysis
|
|
21
|
+
- **Proactive trace links**: LLM automatically discovers and records code↔test, code↔doc relationships
|
|
22
|
+
- **Auto-export trace.json**: Trace links are automatically exported to JSON for direct LLM reading (no API needed)
|
|
19
23
|
- **Progress tracking**: Real-time progress reporting for long-running operations (create/update bundles)
|
|
20
24
|
- **Bundle integrity check**: Prevents operations on incomplete bundles with helpful error messages
|
|
21
25
|
- **De-duplication with in-progress lock**: Prevent duplicate bundle creation even during MCP timeouts
|
|
@@ -151,10 +155,11 @@ Input (example):
|
|
|
151
155
|
|
|
152
156
|
### `preflight_read_file`
|
|
153
157
|
Read file(s) from bundle. Two modes:
|
|
154
|
-
- **Batch mode** (omit `file`): Returns ALL key files (OVERVIEW.md, START_HERE.md, AGENTS.md, manifest.json, repo READMEs) in one call
|
|
155
|
-
- **Single file mode** (provide `file`): Returns that specific file
|
|
156
|
-
- Triggers: "查看bundle", "bundle概览", "项目信息", "show bundle"
|
|
158
|
+
- **Batch mode** (omit `file`): Returns ALL key files (OVERVIEW.md, START_HERE.md, AGENTS.md, manifest.json, deps/dependency-graph.json, repo READMEs) in one call
|
|
159
|
+
- **Single file mode** (provide `file`): Returns that specific file (e.g., `deps/dependency-graph.json` for dependency graph)
|
|
160
|
+
- Triggers: "查看bundle", "bundle概览", "项目信息", "show bundle", "读取依赖图"
|
|
157
161
|
- Use `file: "manifest.json"` to get bundle metadata (repos, timestamps, tags, etc.)
|
|
162
|
+
- Use `file: "deps/dependency-graph.json"` to read the dependency graph (generated by `preflight_evidence_dependency_graph`)
|
|
158
163
|
|
|
159
164
|
### `preflight_delete_bundle`
|
|
160
165
|
Delete/remove a bundle permanently.
|
|
@@ -203,10 +208,16 @@ Generate an evidence-based dependency graph. Two modes:
|
|
|
203
208
|
- Emits `imports` edges (file → module) and `imports_resolved` edges (file → internal file).
|
|
204
209
|
|
|
205
210
|
### `preflight_trace_upsert`
|
|
206
|
-
|
|
211
|
+
Create or update traceability links (code↔test, code↔doc, file↔requirement).
|
|
212
|
+
- **Proactive use**: LLM automatically records discovered relationships during code analysis
|
|
213
|
+
- Common link types: `tested_by`, `implements`, `documents`, `relates_to`, `depends_on`
|
|
214
|
+
- **Auto-exports** to `trace/trace.json` after each upsert for direct LLM reading
|
|
207
215
|
|
|
208
216
|
### `preflight_trace_query`
|
|
209
|
-
Query traceability links (
|
|
217
|
+
Query traceability links (code↔test, code↔doc, commit↔ticket).
|
|
218
|
+
- **Proactive use**: LLM automatically queries trace links when analyzing specific files
|
|
219
|
+
- Helps answer: "Does this code have tests?", "What requirements does this implement?"
|
|
220
|
+
- Fast when `bundleId` is provided; can scan across bundles when omitted.
|
|
210
221
|
|
|
211
222
|
### `preflight_cleanup_orphans`
|
|
212
223
|
Remove incomplete or corrupted bundles (bundles without valid manifest.json).
|
|
@@ -224,6 +235,33 @@ Check status of bundle creation/update tasks (progress tracking).
|
|
|
224
235
|
- Query by `taskId` (from error), `fingerprint`, or `repos`
|
|
225
236
|
- Shows: phase, progress percentage, message, elapsed time
|
|
226
237
|
|
|
238
|
+
## Prompts (5 total)
|
|
239
|
+
|
|
240
|
+
MCP prompts provide interactive guidance for users. Call these to get usage instructions and example prompts.
|
|
241
|
+
|
|
242
|
+
### `preflight_menu`
|
|
243
|
+
Main menu showing all Preflight features.
|
|
244
|
+
- Triggers: "preflight有什么功能", "有什么工具", "what can preflight do", "show menu"
|
|
245
|
+
|
|
246
|
+
### `preflight_analyze_guide`
|
|
247
|
+
Deep analysis guide with step-by-step workflow and copyable prompts.
|
|
248
|
+
- Shows: Bundle file structure, recommended analysis flow, example prompts
|
|
249
|
+
- Args: `projectPath` (optional)
|
|
250
|
+
|
|
251
|
+
### `preflight_search_guide`
|
|
252
|
+
Search functionality guide.
|
|
253
|
+
- Shows: Single bundle search, cross-bundle search by tags, FTS5 syntax tips
|
|
254
|
+
- Args: `bundleId` (optional)
|
|
255
|
+
|
|
256
|
+
### `preflight_manage_guide`
|
|
257
|
+
Bundle management operations guide.
|
|
258
|
+
- Shows: List, view, update, repair, delete bundle operations
|
|
259
|
+
|
|
260
|
+
### `preflight_trace_guide`
|
|
261
|
+
Traceability links guide.
|
|
262
|
+
- Shows: Query and create code↔test, code↔doc relationships
|
|
263
|
+
- Args: `bundleId` (optional)
|
|
264
|
+
|
|
227
265
|
## Resources
|
|
228
266
|
|
|
229
267
|
### `preflight://bundles`
|
|
@@ -287,7 +325,9 @@ Inside a bundle directory:
|
|
|
287
325
|
- `OVERVIEW.md`
|
|
288
326
|
- `indexes/search.sqlite3`
|
|
289
327
|
- `analysis/FACTS.json` (static analysis)
|
|
328
|
+
- `deps/dependency-graph.json` (global import graph; generated on demand)
|
|
290
329
|
- `trace/trace.sqlite3` (traceability links; created on demand)
|
|
330
|
+
- `trace/trace.json` (**NEW**: auto-exported JSON for direct LLM reading)
|
|
291
331
|
- `repos/<owner>/<repo>/raw/...`
|
|
292
332
|
- `repos/<owner>/<repo>/norm/...` (GitHub/local snapshots)
|
|
293
333
|
- `libraries/context7/<...>/meta.json`
|
package/README.zh-CN.md
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
|
-
- **
|
|
18
|
+
- **13 个 MCP 工具**:create/update/repair/search/evidence/trace/read/cleanup(外加 resources)
|
|
19
|
+
- **5 个 MCP prompts**:交互式引导(菜单、分析指南、搜索指南、管理指南、追溯指南)
|
|
19
20
|
- **去重**:避免对相同的规范化输入重复索引
|
|
20
21
|
- **可靠的 GitHub 获取**:可配置 git clone 超时 + GitHub archive(zipball)兜底
|
|
21
22
|
- **离线修复**:无需重新抓取,重建缺失/为空的派生物(index/guides/overview)
|
|
@@ -168,9 +169,12 @@ npm run smoke
|
|
|
168
169
|
**💡 提示**:对于代码仓库,创建 bundle 后可进一步使用 `preflight_evidence_dependency_graph` 获取依赖图,或使用 `preflight_trace_upsert` 记录代码←→需求/测试的追溯链接。
|
|
169
170
|
|
|
170
171
|
### `preflight_read_file`
|
|
171
|
-
从 bundle
|
|
172
|
-
-
|
|
173
|
-
-
|
|
172
|
+
从 bundle 读取文件。两种模式:
|
|
173
|
+
- **批量模式**(省略 `file`):返回所有关键文件(OVERVIEW.md、START_HERE.md、AGENTS.md、manifest.json、deps/dependency-graph.json、repo READMEs)
|
|
174
|
+
- **单文件模式**(提供 `file`):返回指定文件(如 `deps/dependency-graph.json` 获取依赖图)
|
|
175
|
+
- 触发词:「查看概览」「项目概览」「bundle详情」「读取依赖图」
|
|
176
|
+
- 使用 `file: "manifest.json"` 获取 bundle 元数据
|
|
177
|
+
- 使用 `file: "deps/dependency-graph.json"` 读取依赖图(由 `preflight_evidence_dependency_graph` 生成)
|
|
174
178
|
|
|
175
179
|
### `preflight_delete_bundle`
|
|
176
180
|
永久删除/移除一个 bundle。
|
|
@@ -232,6 +236,39 @@ npm run smoke
|
|
|
232
236
|
- 输出:`totalFound`, `totalCleaned`, `details`
|
|
233
237
|
- 说明:服务启动时也会自动执行后台清理(非阻塞)
|
|
234
238
|
|
|
239
|
+
### `preflight_get_task_status`
|
|
240
|
+
检查 bundle 创建/更新任务的状态(进度追踪)。
|
|
241
|
+
- 触发词:「查看进度」「任务状态」「下载进度」
|
|
242
|
+
- 通过 `taskId`、`fingerprint` 或 `repos` 查询
|
|
243
|
+
- 显示:阶段、进度百分比、消息、已用时间
|
|
244
|
+
|
|
245
|
+
## Prompts(5 个)
|
|
246
|
+
|
|
247
|
+
MCP prompts 提供交互式引导。调用这些 prompt 获取使用说明和示例。
|
|
248
|
+
|
|
249
|
+
### `preflight_menu`
|
|
250
|
+
主菜单,显示所有 Preflight 功能。
|
|
251
|
+
- 触发词:「preflight有什么功能」「有什么工具」「what can preflight do」
|
|
252
|
+
|
|
253
|
+
### `preflight_analyze_guide`
|
|
254
|
+
深入分析指南,包含分步流程和可复制的 prompt。
|
|
255
|
+
- 显示:Bundle 文件结构、推荐分析流程、示例 prompt
|
|
256
|
+
- 参数:`projectPath`(可选)
|
|
257
|
+
|
|
258
|
+
### `preflight_search_guide`
|
|
259
|
+
搜索功能指南。
|
|
260
|
+
- 显示:单 bundle 搜索、跨 bundle 按标签搜索、FTS5 语法提示
|
|
261
|
+
- 参数:`bundleId`(可选)
|
|
262
|
+
|
|
263
|
+
### `preflight_manage_guide`
|
|
264
|
+
Bundle 管理操作指南。
|
|
265
|
+
- 显示:列出、查看、更新、修复、删除 bundle 操作
|
|
266
|
+
|
|
267
|
+
### `preflight_trace_guide`
|
|
268
|
+
追溯链接指南。
|
|
269
|
+
- 显示:查询和创建代码↔测试、代码↔文档关系
|
|
270
|
+
- 参数:`bundleId`(可选)
|
|
271
|
+
|
|
235
272
|
## Resources
|
|
236
273
|
|
|
237
274
|
### `preflight://bundles`
|
|
@@ -296,7 +333,9 @@ bundle 目录内部:
|
|
|
296
333
|
- `OVERVIEW.md`
|
|
297
334
|
- `indexes/search.sqlite3`
|
|
298
335
|
- **`analysis/FACTS.json`**(静态分析)
|
|
336
|
+
- **`deps/dependency-graph.json`**(全局依赖图;按需生成)
|
|
299
337
|
- `trace/trace.sqlite3`(traceability links;按需创建)
|
|
338
|
+
- `trace/trace.json`(自动导出的 JSON,便于 LLM 直接读取)
|
|
300
339
|
- `repos/<owner>/<repo>/raw/...`
|
|
301
340
|
- `repos/<owner>/<repo>/norm/...`(GitHub/local 快照)
|
|
302
341
|
- `libraries/context7/<...>/meta.json`
|
package/dist/server.js
CHANGED
|
@@ -100,7 +100,7 @@ export async function startServer() {
|
|
|
100
100
|
startHttpServer(cfg);
|
|
101
101
|
const server = new McpServer({
|
|
102
102
|
name: 'preflight-mcp',
|
|
103
|
-
version: '0.1
|
|
103
|
+
version: '0.2.1',
|
|
104
104
|
description: 'Create evidence-based preflight bundles for repositories (docs + code) with SQLite FTS search.',
|
|
105
105
|
}, {
|
|
106
106
|
capabilities: {
|
|
@@ -108,6 +108,10 @@ export async function startServer() {
|
|
|
108
108
|
// We can emit list changed notifications when new bundles appear.
|
|
109
109
|
listChanged: true,
|
|
110
110
|
},
|
|
111
|
+
prompts: {
|
|
112
|
+
// We provide interactive guidance prompts.
|
|
113
|
+
listChanged: true,
|
|
114
|
+
},
|
|
111
115
|
},
|
|
112
116
|
});
|
|
113
117
|
// Resource template to read any file inside a bundle.
|
|
@@ -261,12 +265,12 @@ export async function startServer() {
|
|
|
261
265
|
server.registerTool('preflight_read_file', {
|
|
262
266
|
title: 'Read bundle file(s)',
|
|
263
267
|
description: 'Read file(s) from bundle. Two modes: ' +
|
|
264
|
-
'(1) Omit "file" param → returns ALL key files (OVERVIEW.md, START_HERE.md, AGENTS.md, manifest.json, repo READMEs) in one call. ' +
|
|
265
|
-
'(2) Provide "file" param → returns that specific file. ' +
|
|
266
|
-
'Use when: "查看bundle", "show bundle", "read overview", "bundle概览", "项目信息".',
|
|
268
|
+
'(1) Omit "file" param → returns ALL key files (OVERVIEW.md, START_HERE.md, AGENTS.md, manifest.json, deps/dependency-graph.json, repo READMEs) in one call. ' +
|
|
269
|
+
'(2) Provide "file" param → returns that specific file (e.g., "deps/dependency-graph.json" for the dependency graph). ' +
|
|
270
|
+
'Use when: "查看bundle", "show bundle", "read overview", "bundle概览", "项目信息", "读取依赖图", "show dependency graph".',
|
|
267
271
|
inputSchema: {
|
|
268
272
|
bundleId: z.string().describe('Bundle ID to read.'),
|
|
269
|
-
file: z.string().optional().describe('Specific file to read. If omitted, returns all key files
|
|
273
|
+
file: z.string().optional().describe('Specific file to read (e.g., "deps/dependency-graph.json"). If omitted, returns all key files including dependency graph if exists.'),
|
|
270
274
|
},
|
|
271
275
|
outputSchema: {
|
|
272
276
|
bundleId: z.string(),
|
|
@@ -296,7 +300,7 @@ export async function startServer() {
|
|
|
296
300
|
};
|
|
297
301
|
}
|
|
298
302
|
// Batch mode: read all key files
|
|
299
|
-
const keyFiles = ['OVERVIEW.md', 'START_HERE.md', 'AGENTS.md', 'manifest.json'];
|
|
303
|
+
const keyFiles = ['OVERVIEW.md', 'START_HERE.md', 'AGENTS.md', 'manifest.json', 'deps/dependency-graph.json'];
|
|
300
304
|
const files = {};
|
|
301
305
|
for (const file of keyFiles) {
|
|
302
306
|
try {
|
|
@@ -457,7 +461,12 @@ export async function startServer() {
|
|
|
457
461
|
textResponse += '\n';
|
|
458
462
|
}
|
|
459
463
|
textResponse += `✅ Bundle created: ${summary.bundleId}\n`;
|
|
460
|
-
textResponse += `Repos: ${summary.repos.map(r => `${r.id} (${r.source})`).join(', ')}`;
|
|
464
|
+
textResponse += `Repos: ${summary.repos.map(r => `${r.id} (${r.source})`).join(', ')}\n\n`;
|
|
465
|
+
// Prompt user for advanced analysis
|
|
466
|
+
textResponse += `📊 **Recommended next steps:**\n`;
|
|
467
|
+
textResponse += `Would you like me to generate a **global dependency graph** for deeper code analysis? ` +
|
|
468
|
+
`This will analyze import relationships across all files.\n`;
|
|
469
|
+
textResponse += `(Call \`preflight_evidence_dependency_graph\` with this bundleId to generate)`;
|
|
461
470
|
return {
|
|
462
471
|
content: [{ type: 'text', text: textResponse }],
|
|
463
472
|
structuredContent: out,
|
|
@@ -792,8 +801,9 @@ export async function startServer() {
|
|
|
792
801
|
}
|
|
793
802
|
});
|
|
794
803
|
server.registerTool('preflight_evidence_dependency_graph', {
|
|
795
|
-
title: 'Evidence: dependency graph
|
|
796
|
-
description: '
|
|
804
|
+
title: 'Evidence: dependency graph',
|
|
805
|
+
description: '**Proactive use recommended**: Generate dependency graphs to understand code structure. ' +
|
|
806
|
+
'Generate an evidence-based dependency graph. IMPORTANT: Before running, ASK the user which bundle and which file/mode they want! ' +
|
|
797
807
|
'Two modes: (1) TARGET MODE: analyze a specific file (provide target.file). (2) GLOBAL MODE: project-wide graph (omit target). ' +
|
|
798
808
|
'Do NOT automatically choose bundle or mode - confirm with user first! ' +
|
|
799
809
|
'File path must be bundle-relative: repos/{owner}/{repo}/norm/{path}.',
|
|
@@ -822,7 +832,12 @@ export async function startServer() {
|
|
|
822
832
|
});
|
|
823
833
|
server.registerTool('preflight_trace_upsert', {
|
|
824
834
|
title: 'Trace: upsert links',
|
|
825
|
-
description: '
|
|
835
|
+
description: 'Create or update traceability links (code↔test, code↔doc, file↔requirement). ' +
|
|
836
|
+
'**Proactive use recommended**: When you discover relationships during code analysis ' +
|
|
837
|
+
'(e.g., "this file has a corresponding test", "this module implements feature X"), ' +
|
|
838
|
+
'automatically create trace links to record these findings for future queries. ' +
|
|
839
|
+
'Common link types: tested_by, implements, documents, relates_to, depends_on. ' +
|
|
840
|
+
'Stores trace edges in a per-bundle SQLite database.',
|
|
826
841
|
inputSchema: TraceUpsertInputSchema,
|
|
827
842
|
outputSchema: {
|
|
828
843
|
bundleId: z.string(),
|
|
@@ -848,7 +863,11 @@ export async function startServer() {
|
|
|
848
863
|
});
|
|
849
864
|
server.registerTool('preflight_trace_query', {
|
|
850
865
|
title: 'Trace: query links',
|
|
851
|
-
description: 'Query traceability links
|
|
866
|
+
description: 'Query traceability links (code↔test, code↔doc, commit↔ticket). ' +
|
|
867
|
+
'**Proactive use recommended**: When analyzing a specific file or discussing code structure, ' +
|
|
868
|
+
'automatically query trace links to find related tests, documentation, or requirements. ' +
|
|
869
|
+
'This helps answer questions like "does this code have tests?" or "what requirements does this implement?". ' +
|
|
870
|
+
'Provide bundleId for fast queries; if omitted, scans across bundles (capped). This tool is read-only.',
|
|
852
871
|
inputSchema: TraceQueryInputSchema,
|
|
853
872
|
outputSchema: {
|
|
854
873
|
bundleId: z.string().optional(),
|
|
@@ -1033,6 +1052,241 @@ export async function startServer() {
|
|
|
1033
1052
|
throw wrapPreflightError(err);
|
|
1034
1053
|
}
|
|
1035
1054
|
});
|
|
1055
|
+
// ============================================================
|
|
1056
|
+
// PROMPTS - Interactive guidance for users
|
|
1057
|
+
// ============================================================
|
|
1058
|
+
// Main menu prompt - shows all available features
|
|
1059
|
+
server.registerPrompt('preflight_menu', {
|
|
1060
|
+
title: 'Preflight 功能菜单',
|
|
1061
|
+
description: '显示 Preflight 所有可用功能的交互式菜单。Use when: "preflight有什么功能", "有什么工具", "what can preflight do", "show menu".',
|
|
1062
|
+
}, async () => {
|
|
1063
|
+
return {
|
|
1064
|
+
messages: [
|
|
1065
|
+
{
|
|
1066
|
+
role: 'user',
|
|
1067
|
+
content: {
|
|
1068
|
+
type: 'text',
|
|
1069
|
+
text: `🛠️ **Preflight 功能菜单**
|
|
1070
|
+
|
|
1071
|
+
请选择您需要的功能:
|
|
1072
|
+
|
|
1073
|
+
**1. 📂 深入分析项目**
|
|
1074
|
+
创建 bundle 并生成全局依赖图,理解代码架构
|
|
1075
|
+
|
|
1076
|
+
**2. 🔍 搜索代码/文档**
|
|
1077
|
+
在已索引的项目中全文搜索代码和文档
|
|
1078
|
+
|
|
1079
|
+
**3. 📋 管理 bundles**
|
|
1080
|
+
列出、更新、修复、删除已有的 bundle
|
|
1081
|
+
|
|
1082
|
+
**4. 🔗 追溯链接**
|
|
1083
|
+
查询/创建代码-测试-文档之间的关联关系
|
|
1084
|
+
|
|
1085
|
+
---
|
|
1086
|
+
请输入功能编号 (1-4) 或直接描述您的需求。`,
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
],
|
|
1090
|
+
};
|
|
1091
|
+
});
|
|
1092
|
+
// Deep analysis guide prompt
|
|
1093
|
+
server.registerPrompt('preflight_analyze_guide', {
|
|
1094
|
+
title: '深入分析项目指南',
|
|
1095
|
+
description: '提供深入分析项目的操作指南和示例 prompt。Use when user selected "深入分析" or wants to analyze a project.',
|
|
1096
|
+
argsSchema: {
|
|
1097
|
+
projectPath: z.string().optional().describe('项目路径或 GitHub 仓库地址(可选)'),
|
|
1098
|
+
},
|
|
1099
|
+
}, async (args) => {
|
|
1100
|
+
const pathExample = args.projectPath || 'E:\\coding\\my-project 或 owner/repo';
|
|
1101
|
+
return {
|
|
1102
|
+
messages: [
|
|
1103
|
+
{
|
|
1104
|
+
role: 'user',
|
|
1105
|
+
content: {
|
|
1106
|
+
type: 'text',
|
|
1107
|
+
text: `📊 **深入分析项目指南**
|
|
1108
|
+
|
|
1109
|
+
**第一步:提供项目路径**
|
|
1110
|
+
- 本地路径:\`E:\\coding\\my-project\`
|
|
1111
|
+
- GitHub:\`owner/repo\` 或完整 URL
|
|
1112
|
+
|
|
1113
|
+
**第二步:复制以下完美 prompt(送给工作 LLM)**
|
|
1114
|
+
|
|
1115
|
+
\`\`\`
|
|
1116
|
+
请执行以下分析流程:
|
|
1117
|
+
|
|
1118
|
+
1. 使用 preflight_create_bundle 创建 ${pathExample} 的 bundle
|
|
1119
|
+
2. 使用 preflight_evidence_dependency_graph 生成全局依赖图
|
|
1120
|
+
3. 使用 preflight_read_file 读取 bundle 内容,分析:
|
|
1121
|
+
- OVERVIEW.md 了解项目概览
|
|
1122
|
+
- deps/dependency-graph.json 查看依赖关系
|
|
1123
|
+
- START_HERE.md 了解入口点
|
|
1124
|
+
|
|
1125
|
+
然后总结:
|
|
1126
|
+
1. 项目核心功能是什么
|
|
1127
|
+
2. 主要模块及其关系(基于依赖图)
|
|
1128
|
+
3. 代码架构特点
|
|
1129
|
+
\`\`\`
|
|
1130
|
+
|
|
1131
|
+
**Bundle 文件结构说明:**
|
|
1132
|
+
| 文件 | 内容 |
|
|
1133
|
+
|------|------|
|
|
1134
|
+
| \`OVERVIEW.md\` | 项目概览和结构总结 |
|
|
1135
|
+
| \`START_HERE.md\` | 入口文件和关键路径 |
|
|
1136
|
+
| \`AGENTS.md\` | AI Agent 使用指南 |
|
|
1137
|
+
| \`deps/dependency-graph.json\` | 依赖关系图(节点+边) |
|
|
1138
|
+
| \`manifest.json\` | bundle 元数据 |
|
|
1139
|
+
| \`repos/{owner}/{repo}/norm/\` | 规范化源代码 |
|
|
1140
|
+
|
|
1141
|
+
---
|
|
1142
|
+
💡 提示:搜索功能只能查找代码文件内容,不能搜索依赖图。要查看依赖图,请用 preflight_read_file 读取 deps/dependency-graph.json。`,
|
|
1143
|
+
},
|
|
1144
|
+
},
|
|
1145
|
+
],
|
|
1146
|
+
};
|
|
1147
|
+
});
|
|
1148
|
+
// Search guide prompt
|
|
1149
|
+
server.registerPrompt('preflight_search_guide', {
|
|
1150
|
+
title: '搜索代码/文档指南',
|
|
1151
|
+
description: '提供搜索功能的操作指南和示例 prompt。Use when user selected "搜索" or wants to search in bundles.',
|
|
1152
|
+
argsSchema: {
|
|
1153
|
+
bundleId: z.string().optional().describe('要搜索的 bundle ID(可选)'),
|
|
1154
|
+
},
|
|
1155
|
+
}, async (args) => {
|
|
1156
|
+
const bundleHint = args.bundleId ? `bundle \`${args.bundleId}\`` : '指定的 bundle';
|
|
1157
|
+
return {
|
|
1158
|
+
messages: [
|
|
1159
|
+
{
|
|
1160
|
+
role: 'user',
|
|
1161
|
+
content: {
|
|
1162
|
+
type: 'text',
|
|
1163
|
+
text: `🔍 **搜索代码/文档指南**
|
|
1164
|
+
|
|
1165
|
+
**搜索模式:**
|
|
1166
|
+
|
|
1167
|
+
**1. 单 bundle 搜索**(需要先知道 bundleId)
|
|
1168
|
+
\`\`\`
|
|
1169
|
+
在 ${bundleHint} 中搜索 "config parser"
|
|
1170
|
+
\`\`\`
|
|
1171
|
+
|
|
1172
|
+
**2. 跨 bundle 搜索**(按 tags 过滤)
|
|
1173
|
+
\`\`\`
|
|
1174
|
+
在所有 MCP 相关项目中搜索 "tool registration"
|
|
1175
|
+
在标签为 agent 的项目中搜索 "LLM"
|
|
1176
|
+
\`\`\`
|
|
1177
|
+
|
|
1178
|
+
**3. 列出所有 bundle**(不确定有哪些时)
|
|
1179
|
+
\`\`\`
|
|
1180
|
+
列出所有 bundle
|
|
1181
|
+
或: preflight list bundles
|
|
1182
|
+
\`\`\`
|
|
1183
|
+
|
|
1184
|
+
---
|
|
1185
|
+
💡 搜索支持 FTS5 全文语法,如:\`config AND parser\`、\`"exact phrase"\``,
|
|
1186
|
+
},
|
|
1187
|
+
},
|
|
1188
|
+
],
|
|
1189
|
+
};
|
|
1190
|
+
});
|
|
1191
|
+
// Manage bundles guide prompt
|
|
1192
|
+
server.registerPrompt('preflight_manage_guide', {
|
|
1193
|
+
title: '管理 bundles 指南',
|
|
1194
|
+
description: '提供 bundle 管理操作的指南。Use when user selected "管理" or wants to manage bundles.',
|
|
1195
|
+
}, async () => {
|
|
1196
|
+
return {
|
|
1197
|
+
messages: [
|
|
1198
|
+
{
|
|
1199
|
+
role: 'user',
|
|
1200
|
+
content: {
|
|
1201
|
+
type: 'text',
|
|
1202
|
+
text: `📋 **管理 Bundles 指南**
|
|
1203
|
+
|
|
1204
|
+
**常用操作:**
|
|
1205
|
+
|
|
1206
|
+
**列出所有 bundle**
|
|
1207
|
+
\`\`\`
|
|
1208
|
+
列出所有 bundle
|
|
1209
|
+
或: 查看有哪些项目已索引
|
|
1210
|
+
\`\`\`
|
|
1211
|
+
|
|
1212
|
+
**查看 bundle 详情**
|
|
1213
|
+
\`\`\`
|
|
1214
|
+
查看 bundle {bundleId} 的概览
|
|
1215
|
+
或: 读取 bundle {bundleId}
|
|
1216
|
+
\`\`\`
|
|
1217
|
+
|
|
1218
|
+
**更新 bundle**(同步最新代码)
|
|
1219
|
+
\`\`\`
|
|
1220
|
+
更新 bundle {bundleId}
|
|
1221
|
+
或: 检查 {bundleId} 是否有更新
|
|
1222
|
+
\`\`\`
|
|
1223
|
+
|
|
1224
|
+
**修复 bundle**(重建索引)
|
|
1225
|
+
\`\`\`
|
|
1226
|
+
修复 bundle {bundleId}
|
|
1227
|
+
或: 重建 {bundleId} 的搜索索引
|
|
1228
|
+
\`\`\`
|
|
1229
|
+
|
|
1230
|
+
**删除 bundle**
|
|
1231
|
+
\`\`\`
|
|
1232
|
+
删除 bundle {bundleId}
|
|
1233
|
+
\`\`\`
|
|
1234
|
+
|
|
1235
|
+
---
|
|
1236
|
+
💡 先运行「列出所有 bundle」获取 bundleId 列表`,
|
|
1237
|
+
},
|
|
1238
|
+
},
|
|
1239
|
+
],
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
1242
|
+
// Trace guide prompt
|
|
1243
|
+
server.registerPrompt('preflight_trace_guide', {
|
|
1244
|
+
title: '追溯链接指南',
|
|
1245
|
+
description: '提供代码追溯功能的操作指南。Use when user selected "追溯" or wants to trace code relationships.',
|
|
1246
|
+
argsSchema: {
|
|
1247
|
+
bundleId: z.string().optional().describe('bundle ID(可选)'),
|
|
1248
|
+
},
|
|
1249
|
+
}, async (args) => {
|
|
1250
|
+
const bundleHint = args.bundleId || '{bundleId}';
|
|
1251
|
+
return {
|
|
1252
|
+
messages: [
|
|
1253
|
+
{
|
|
1254
|
+
role: 'user',
|
|
1255
|
+
content: {
|
|
1256
|
+
type: 'text',
|
|
1257
|
+
text: `🔗 **追溯链接指南**
|
|
1258
|
+
|
|
1259
|
+
追溯功能用于建立和查询代码之间的关联关系:
|
|
1260
|
+
- 代码 ↔ 测试
|
|
1261
|
+
- 代码 ↔ 文档
|
|
1262
|
+
- 模块 ↔ 需求
|
|
1263
|
+
|
|
1264
|
+
**查询已有的追溯链接**
|
|
1265
|
+
\`\`\`
|
|
1266
|
+
查询 bundle ${bundleHint} 中 src/main.ts 的相关测试
|
|
1267
|
+
查询所有 implements 类型的追溯链接
|
|
1268
|
+
\`\`\`
|
|
1269
|
+
|
|
1270
|
+
**创建追溯链接**
|
|
1271
|
+
\`\`\`
|
|
1272
|
+
在 bundle ${bundleHint} 中创建追溯:
|
|
1273
|
+
src/parser.ts 被 tests/parser.test.ts 测试
|
|
1274
|
+
\`\`\`
|
|
1275
|
+
|
|
1276
|
+
**常用链接类型:**
|
|
1277
|
+
- \`tested_by\` - 被...测试
|
|
1278
|
+
- \`implements\` - 实现了...
|
|
1279
|
+
- \`documents\` - 文档描述了...
|
|
1280
|
+
- \`depends_on\` - 依赖于...
|
|
1281
|
+
- \`relates_to\` - 相关联
|
|
1282
|
+
|
|
1283
|
+
---
|
|
1284
|
+
💡 追溯链接会持久化存储,便于未来快速查询代码关系`,
|
|
1285
|
+
},
|
|
1286
|
+
},
|
|
1287
|
+
],
|
|
1288
|
+
};
|
|
1289
|
+
});
|
|
1036
1290
|
// Provide backward-compatible parsing of the same URI via resources/read for clients that bypass templates.
|
|
1037
1291
|
// This is a safety net: if a client gives us a fully-specified URI, we can still serve it.
|
|
1038
1292
|
server.registerResource('bundle-file-compat', 'preflight://bundle-file', {
|
package/dist/trace/store.js
CHANGED
|
@@ -98,8 +98,56 @@ export async function upsertTraceEdges(traceDbPath, edges) {
|
|
|
98
98
|
return ids;
|
|
99
99
|
});
|
|
100
100
|
const ids = tx(edges);
|
|
101
|
+
// Close DB before export (export opens its own readonly connection)
|
|
102
|
+
db.close();
|
|
103
|
+
// Auto-export to JSON after each upsert for LLM direct reading
|
|
104
|
+
try {
|
|
105
|
+
await exportTraceToJson(traceDbPath);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Non-critical: JSON export failure shouldn't block upsert
|
|
109
|
+
}
|
|
101
110
|
return { upserted: ids.length, ids };
|
|
102
111
|
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
db.close();
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Export all trace edges to a JSON file for LLM direct reading.
|
|
119
|
+
* Called automatically after upsertTraceEdges.
|
|
120
|
+
*/
|
|
121
|
+
export async function exportTraceToJson(traceDbPath) {
|
|
122
|
+
const jsonPath = traceDbPath.replace(/\.sqlite3$/, '.json');
|
|
123
|
+
const db = new Database(traceDbPath, { readonly: true });
|
|
124
|
+
try {
|
|
125
|
+
const rows = db.prepare(`
|
|
126
|
+
SELECT
|
|
127
|
+
id, source_type, source_id, target_type, target_id,
|
|
128
|
+
edge_type, confidence, method, sources_json, created_at, updated_at
|
|
129
|
+
FROM trace_edges
|
|
130
|
+
ORDER BY updated_at DESC
|
|
131
|
+
`).all();
|
|
132
|
+
const edges = rows.map((r) => ({
|
|
133
|
+
id: r.id,
|
|
134
|
+
source: { type: r.source_type, id: r.source_id },
|
|
135
|
+
target: { type: r.target_type, id: r.target_id },
|
|
136
|
+
type: r.edge_type,
|
|
137
|
+
confidence: r.confidence,
|
|
138
|
+
method: r.method,
|
|
139
|
+
sources: JSON.parse(r.sources_json || '[]'),
|
|
140
|
+
createdAt: r.created_at,
|
|
141
|
+
updatedAt: r.updated_at,
|
|
142
|
+
}));
|
|
143
|
+
const exportData = {
|
|
144
|
+
exportedAt: new Date().toISOString(),
|
|
145
|
+
totalEdges: edges.length,
|
|
146
|
+
edges,
|
|
147
|
+
};
|
|
148
|
+
await fs.writeFile(jsonPath, JSON.stringify(exportData, null, 2), 'utf8');
|
|
149
|
+
return { exported: edges.length, jsonPath };
|
|
150
|
+
}
|
|
103
151
|
finally {
|
|
104
152
|
db.close();
|
|
105
153
|
}
|