preflight-mcp 0.1.9 → 0.2.0
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 +13 -2
- package/dist/server.js +21 -6
- package/dist/trace/store.js +48 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,9 @@ 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
|
+
- **LLM-friendly outputs**: After bundle creation, prompts user to generate dependency graph for deeper analysis
|
|
20
|
+
- **Proactive trace links**: LLM automatically discovers and records code↔test, code↔doc relationships
|
|
21
|
+
- **Auto-export trace.json**: Trace links are automatically exported to JSON for direct LLM reading (no API needed)
|
|
19
22
|
- **Progress tracking**: Real-time progress reporting for long-running operations (create/update bundles)
|
|
20
23
|
- **Bundle integrity check**: Prevents operations on incomplete bundles with helpful error messages
|
|
21
24
|
- **De-duplication with in-progress lock**: Prevent duplicate bundle creation even during MCP timeouts
|
|
@@ -203,10 +206,16 @@ Generate an evidence-based dependency graph. Two modes:
|
|
|
203
206
|
- Emits `imports` edges (file → module) and `imports_resolved` edges (file → internal file).
|
|
204
207
|
|
|
205
208
|
### `preflight_trace_upsert`
|
|
206
|
-
|
|
209
|
+
Create or update traceability links (code↔test, code↔doc, file↔requirement).
|
|
210
|
+
- **Proactive use**: LLM automatically records discovered relationships during code analysis
|
|
211
|
+
- Common link types: `tested_by`, `implements`, `documents`, `relates_to`, `depends_on`
|
|
212
|
+
- **Auto-exports** to `trace/trace.json` after each upsert for direct LLM reading
|
|
207
213
|
|
|
208
214
|
### `preflight_trace_query`
|
|
209
|
-
Query traceability links (
|
|
215
|
+
Query traceability links (code↔test, code↔doc, commit↔ticket).
|
|
216
|
+
- **Proactive use**: LLM automatically queries trace links when analyzing specific files
|
|
217
|
+
- Helps answer: "Does this code have tests?", "What requirements does this implement?"
|
|
218
|
+
- Fast when `bundleId` is provided; can scan across bundles when omitted.
|
|
210
219
|
|
|
211
220
|
### `preflight_cleanup_orphans`
|
|
212
221
|
Remove incomplete or corrupted bundles (bundles without valid manifest.json).
|
|
@@ -287,7 +296,9 @@ Inside a bundle directory:
|
|
|
287
296
|
- `OVERVIEW.md`
|
|
288
297
|
- `indexes/search.sqlite3`
|
|
289
298
|
- `analysis/FACTS.json` (static analysis)
|
|
299
|
+
- `deps/dependency-graph.json` (global import graph; generated on demand)
|
|
290
300
|
- `trace/trace.sqlite3` (traceability links; created on demand)
|
|
301
|
+
- `trace/trace.json` (**NEW**: auto-exported JSON for direct LLM reading)
|
|
291
302
|
- `repos/<owner>/<repo>/raw/...`
|
|
292
303
|
- `repos/<owner>/<repo>/norm/...` (GitHub/local snapshots)
|
|
293
304
|
- `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.
|
|
103
|
+
version: '0.2.0',
|
|
104
104
|
description: 'Create evidence-based preflight bundles for repositories (docs + code) with SQLite FTS search.',
|
|
105
105
|
}, {
|
|
106
106
|
capabilities: {
|
|
@@ -457,7 +457,12 @@ export async function startServer() {
|
|
|
457
457
|
textResponse += '\n';
|
|
458
458
|
}
|
|
459
459
|
textResponse += `✅ Bundle created: ${summary.bundleId}\n`;
|
|
460
|
-
textResponse += `Repos: ${summary.repos.map(r => `${r.id} (${r.source})`).join(', ')}`;
|
|
460
|
+
textResponse += `Repos: ${summary.repos.map(r => `${r.id} (${r.source})`).join(', ')}\n\n`;
|
|
461
|
+
// Prompt user for advanced analysis
|
|
462
|
+
textResponse += `📊 **Recommended next steps:**\n`;
|
|
463
|
+
textResponse += `Would you like me to generate a **global dependency graph** for deeper code analysis? ` +
|
|
464
|
+
`This will analyze import relationships across all files.\n`;
|
|
465
|
+
textResponse += `(Call \`preflight_evidence_dependency_graph\` with this bundleId to generate)`;
|
|
461
466
|
return {
|
|
462
467
|
content: [{ type: 'text', text: textResponse }],
|
|
463
468
|
structuredContent: out,
|
|
@@ -792,8 +797,9 @@ export async function startServer() {
|
|
|
792
797
|
}
|
|
793
798
|
});
|
|
794
799
|
server.registerTool('preflight_evidence_dependency_graph', {
|
|
795
|
-
title: 'Evidence: dependency graph
|
|
796
|
-
description: '
|
|
800
|
+
title: 'Evidence: dependency graph',
|
|
801
|
+
description: '**Proactive use recommended**: Generate dependency graphs to understand code structure. ' +
|
|
802
|
+
'Generate an evidence-based dependency graph. IMPORTANT: Before running, ASK the user which bundle and which file/mode they want! ' +
|
|
797
803
|
'Two modes: (1) TARGET MODE: analyze a specific file (provide target.file). (2) GLOBAL MODE: project-wide graph (omit target). ' +
|
|
798
804
|
'Do NOT automatically choose bundle or mode - confirm with user first! ' +
|
|
799
805
|
'File path must be bundle-relative: repos/{owner}/{repo}/norm/{path}.',
|
|
@@ -822,7 +828,12 @@ export async function startServer() {
|
|
|
822
828
|
});
|
|
823
829
|
server.registerTool('preflight_trace_upsert', {
|
|
824
830
|
title: 'Trace: upsert links',
|
|
825
|
-
description: '
|
|
831
|
+
description: 'Create or update traceability links (code↔test, code↔doc, file↔requirement). ' +
|
|
832
|
+
'**Proactive use recommended**: When you discover relationships during code analysis ' +
|
|
833
|
+
'(e.g., "this file has a corresponding test", "this module implements feature X"), ' +
|
|
834
|
+
'automatically create trace links to record these findings for future queries. ' +
|
|
835
|
+
'Common link types: tested_by, implements, documents, relates_to, depends_on. ' +
|
|
836
|
+
'Stores trace edges in a per-bundle SQLite database.',
|
|
826
837
|
inputSchema: TraceUpsertInputSchema,
|
|
827
838
|
outputSchema: {
|
|
828
839
|
bundleId: z.string(),
|
|
@@ -848,7 +859,11 @@ export async function startServer() {
|
|
|
848
859
|
});
|
|
849
860
|
server.registerTool('preflight_trace_query', {
|
|
850
861
|
title: 'Trace: query links',
|
|
851
|
-
description: 'Query traceability links
|
|
862
|
+
description: 'Query traceability links (code↔test, code↔doc, commit↔ticket). ' +
|
|
863
|
+
'**Proactive use recommended**: When analyzing a specific file or discussing code structure, ' +
|
|
864
|
+
'automatically query trace links to find related tests, documentation, or requirements. ' +
|
|
865
|
+
'This helps answer questions like "does this code have tests?" or "what requirements does this implement?". ' +
|
|
866
|
+
'Provide bundleId for fast queries; if omitted, scans across bundles (capped). This tool is read-only.',
|
|
852
867
|
inputSchema: TraceQueryInputSchema,
|
|
853
868
|
outputSchema: {
|
|
854
869
|
bundleId: z.string().optional(),
|
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
|
}
|