preflight-dev 3.1.0 → 3.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.
Files changed (57) hide show
  1. package/README.md +77 -16
  2. package/dist/cli/init.js +0 -48
  3. package/dist/cli/init.js.map +1 -1
  4. package/dist/index.js +7 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/contracts.d.ts +27 -0
  7. package/dist/lib/contracts.js +309 -0
  8. package/dist/lib/contracts.js.map +1 -0
  9. package/dist/lib/patterns.d.ts +38 -0
  10. package/dist/lib/patterns.js +176 -0
  11. package/dist/lib/patterns.js.map +1 -0
  12. package/dist/lib/triage.d.ts +2 -0
  13. package/dist/lib/triage.js.map +1 -1
  14. package/dist/profiles.js +4 -0
  15. package/dist/profiles.js.map +1 -1
  16. package/dist/tools/check-patterns.d.ts +2 -0
  17. package/dist/tools/check-patterns.js +33 -0
  18. package/dist/tools/check-patterns.js.map +1 -0
  19. package/dist/tools/clarify-intent.js +9 -1
  20. package/dist/tools/clarify-intent.js.map +1 -1
  21. package/dist/tools/enrich-agent-task.js +132 -3
  22. package/dist/tools/enrich-agent-task.js.map +1 -1
  23. package/dist/tools/estimate-cost.d.ts +2 -0
  24. package/dist/tools/estimate-cost.js +261 -0
  25. package/dist/tools/estimate-cost.js.map +1 -0
  26. package/dist/tools/generate-scorecard.js +466 -14
  27. package/dist/tools/generate-scorecard.js.map +1 -1
  28. package/dist/tools/log-correction.js +7 -1
  29. package/dist/tools/log-correction.js.map +1 -1
  30. package/dist/tools/onboard-project.js +10 -1
  31. package/dist/tools/onboard-project.js.map +1 -1
  32. package/dist/tools/preflight-check.js +16 -0
  33. package/dist/tools/preflight-check.js.map +1 -1
  34. package/dist/tools/scope-work.js +6 -0
  35. package/dist/tools/scope-work.js.map +1 -1
  36. package/dist/tools/search-contracts.d.ts +2 -0
  37. package/dist/tools/search-contracts.js +46 -0
  38. package/dist/tools/search-contracts.js.map +1 -0
  39. package/dist/tools/session-stats.js +2 -0
  40. package/dist/tools/session-stats.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/index.ts +7 -0
  43. package/src/lib/contracts.ts +354 -0
  44. package/src/lib/patterns.ts +210 -0
  45. package/src/lib/triage.ts +2 -0
  46. package/src/profiles.ts +4 -0
  47. package/src/tools/check-patterns.ts +43 -0
  48. package/src/tools/clarify-intent.ts +10 -1
  49. package/src/tools/enrich-agent-task.ts +150 -3
  50. package/src/tools/estimate-cost.ts +332 -0
  51. package/src/tools/generate-scorecard.ts +541 -14
  52. package/src/tools/log-correction.ts +8 -1
  53. package/src/tools/onboard-project.ts +10 -1
  54. package/src/tools/preflight-check.ts +19 -0
  55. package/src/tools/scope-work.ts +7 -0
  56. package/src/tools/search-contracts.ts +61 -0
  57. package/src/tools/session-stats.ts +2 -0
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  **Preflight checks for your AI coding prompts.**
6
6
 
7
- An 18-tool MCP server for Claude Code that catches ambiguous instructions before they cost you 2-3x in wrong→fix cycles — plus semantic search across your entire session history.
7
+ A 24-tool MCP server for Claude Code that catches ambiguous instructions before they cost you 2-3x in wrong→fix cycles — plus semantic search across your entire session history.
8
8
 
9
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
10
10
  [![MCP](https://img.shields.io/badge/MCP-Compatible-blueviolet)](https://modelcontextprotocol.io/)
@@ -29,13 +29,15 @@ The pattern is always the same: vague prompt → Claude guesses → wrong output
29
29
 
30
30
  ## The Solution
31
31
 
32
- 18 tools in 3 categories that run as an MCP server inside Claude Code:
32
+ 24 tools in 4 categories that run as an MCP server inside Claude Code:
33
33
 
34
34
  | Category | What it does |
35
35
  |----------|-------------|
36
+ | ✈️ **Preflight Core** (1 tool) | Unified entry point — triages every prompt, chains the right checks automatically |
36
37
  | 🎯 **Prompt Discipline** (12 tools) | Catches vague prompts, enforces structure, prevents waste |
37
38
  | 🔍 **Timeline Intelligence** (4 tools) | LanceDB vector search across months of session history |
38
- | **Verification & Hygiene** (2 tools) | Type-check, test, and audit before declaring done |
39
+ | 📊 **Analysis & Reporting** (4 tools) | Scorecards, cost estimation, session stats, pattern detection |
40
+ | ✅ **Verification & Hygiene** (3 tools) | Type-check, test, audit, and contract search |
39
41
 
40
42
  ## Before / After
41
43
 
@@ -56,20 +58,33 @@ The pattern is always the same: vague prompt → Claude guesses → wrong output
56
58
 
57
59
  ## Quick Start
58
60
 
61
+ ### Option A: Claude Code CLI (fastest)
62
+
63
+ ```bash
64
+ claude mcp add preflight -- npx tsx /path/to/preflight/src/index.ts
65
+ ```
66
+
67
+ Or with environment variables:
68
+
69
+ ```bash
70
+ claude mcp add preflight -e CLAUDE_PROJECT_DIR=/path/to/your/project -- npx tsx /path/to/preflight/src/index.ts
71
+ ```
72
+
73
+ ### Option B: Clone & configure manually
74
+
59
75
  **1. Clone & install:**
60
76
  ```bash
61
77
  git clone https://github.com/TerminalGravity/preflight.git
62
78
  cd preflight && npm install
63
79
  ```
64
80
 
65
- **2. Add to your Claude Code config** (`.claude/settings.json` or project `.mcp.json`):
81
+ **2. Add to your project's `.mcp.json`:**
66
82
  ```json
67
83
  {
68
84
  "mcpServers": {
69
85
  "preflight": {
70
86
  "command": "npx",
71
87
  "args": ["tsx", "/path/to/preflight/src/index.ts"],
72
- "cwd": "/path/to/preflight",
73
88
  "env": {
74
89
  "CLAUDE_PROJECT_DIR": "/path/to/your/project"
75
90
  }
@@ -78,23 +93,30 @@ cd preflight && npm install
78
93
  }
79
94
  ```
80
95
 
81
- **3. Restart Claude Code.** That's it. The tools activate automatically.
96
+ **3. Restart Claude Code.** The tools activate automatically.
82
97
 
83
98
  ## Tool Reference
84
99
 
100
+ ### ✈️ Preflight Core
101
+
102
+ | Tool | What it does |
103
+ |------|-------------|
104
+ | `preflight_check` | **The main entry point.** Triages your prompt (trivial → multi-step), then chains the right checks automatically. One tool to rule them all. |
105
+
85
106
  ### 🎯 Prompt Discipline
86
107
 
87
108
  | Tool | What it does |
88
109
  |------|-------------|
89
110
  | `scope_work` | Creates structured execution plans before coding starts |
90
111
  | `clarify_intent` | Gathers project context to disambiguate vague prompts |
91
- | `enrich_agent_task` | Enriches sub-agent tasks with file paths and patterns |
112
+ | `enrich_agent_task` | Enriches sub-agent tasks with file paths, patterns, and cross-service context |
92
113
  | `sharpen_followup` | Resolves "fix it" / "do the others" to actual file targets |
93
114
  | `token_audit` | Detects waste patterns, grades your session A–F |
94
115
  | `sequence_tasks` | Orders tasks by dependency, locality, and risk |
95
116
  | `checkpoint` | Save game before compaction — commits + resumption notes |
96
117
  | `check_session_health` | Monitors uncommitted files, time since commit, turn count |
97
118
  | `log_correction` | Tracks corrections and identifies recurring error patterns |
119
+ | `check_patterns` | Checks prompts against learned correction patterns — warns about known pitfalls |
98
120
  | `session_handoff` | Generates handoff briefs for new sessions |
99
121
  | `what_changed` | Summarizes diffs since last checkpoint |
100
122
 
@@ -102,17 +124,27 @@ cd preflight && npm install
102
124
 
103
125
  | Tool | What it does |
104
126
  |------|-------------|
105
- | `onboard_project` | Indexes a project's session history into LanceDB vectors |
106
- | `search_history` | Semantic search across all indexed sessions |
127
+ | `onboard_project` | Indexes a project's session history + contracts into per-project LanceDB |
128
+ | `search_history` | Semantic search with scope: current project, related, or all |
107
129
  | `timeline` | Chronological view of events across sessions |
108
130
  | `scan_sessions` | Live scanning of active session data |
109
131
 
132
+ ### 📊 Analysis & Reporting
133
+
134
+ | Tool | What it does |
135
+ |------|-------------|
136
+ | `generate_scorecard` | 12-category report card — session, trend (week/month), or cross-project comparative. PDF or markdown. |
137
+ | `estimate_cost` | Token usage, dollar cost, waste from corrections, preflight savings |
138
+ | `session_stats` | Lightweight session analysis — no embeddings needed |
139
+ | `prompt_score` | Gamified A–F grading on specificity, scope, actionability, done-condition |
140
+
110
141
  ### ✅ Verification & Hygiene
111
142
 
112
143
  | Tool | What it does |
113
144
  |------|-------------|
114
145
  | `verify_completion` | Runs type check + tests + build before declaring done |
115
146
  | `audit_workspace` | Finds stale/missing workspace docs vs git activity |
147
+ | `search_contracts` | Search API contracts, types, and schemas across current and related projects |
116
148
 
117
149
  ## Timeline Intelligence
118
150
 
@@ -133,13 +165,13 @@ No data leaves your machine. Embeddings run locally by default (Xenova/transform
133
165
  ```
134
166
  Claude Code ←→ MCP Protocol ←→ preflight server
135
167
 
136
- ┌─────────────────┼─────────────────┐
137
-
138
- Discipline Tools Timeline Tools Verification
139
- (12 tools) (4 tools) (2 tools)
140
-
141
- LanceDB
142
- (local vectors)
168
+ ┌───────────┬───────────┼───────────┬──────────┐
169
+ │ │
170
+ Preflight Discipline Timeline Analysis Verify
171
+ Core (1) Tools (12) Tools (4) Tools (4) (3)
172
+ │ │
173
+ Smart Triage Patterns LanceDB .preflight/
174
+ Classification Learning (per-project) (project config)
143
175
 
144
176
  ~/.claude/projects/
145
177
  (session JSONL files)
@@ -147,6 +179,34 @@ Claude Code ←→ MCP Protocol ←→ preflight server
147
179
 
148
180
  ## Configuration
149
181
 
182
+ ### Project Config (`.preflight/`)
183
+
184
+ Drop a `.preflight/` directory in your project root for team-shared config:
185
+
186
+ ```yaml
187
+ # .preflight/config.yml
188
+ profile: standard
189
+ related_projects:
190
+ - path: /path/to/auth-service
191
+ alias: auth-service
192
+ - path: /path/to/notifications
193
+ alias: notifications
194
+ thresholds:
195
+ session_stale_minutes: 30
196
+ max_tool_calls_before_checkpoint: 100
197
+ ```
198
+
199
+ ```yaml
200
+ # .preflight/triage.yml
201
+ rules:
202
+ always_check: [rewards, permissions, migration]
203
+ skip: [commit, format, lint]
204
+ cross_service_keywords: [auth, notification, event]
205
+ strictness: standard
206
+ ```
207
+
208
+ No config? No problem — everything works with zero configuration. Config just lets teams customize.
209
+
150
210
  ### Embedding Providers
151
211
 
152
212
  | Provider | Setup | Speed | Quality |
@@ -160,6 +220,7 @@ Claude Code ←→ MCP Protocol ←→ preflight server
160
220
  |----------|-------------|---------|
161
221
  | `CLAUDE_PROJECT_DIR` | Project root to monitor | Required |
162
222
  | `OPENAI_API_KEY` | OpenAI key for embeddings | (uses local Xenova) |
223
+ | `PREFLIGHT_RELATED` | Comma-separated related project paths | (none) |
163
224
 
164
225
  ## Contributing
165
226
 
package/dist/cli/init.js CHANGED
@@ -95,54 +95,6 @@ async function main() {
95
95
  env,
96
96
  };
97
97
  await writeFile(mcpPath, JSON.stringify(config, null, 2) + "\n");
98
- // Offer to create .preflight/ config directory
99
- const preflightDir = join(process.cwd(), ".preflight");
100
- if (!existsSync(preflightDir)) {
101
- const createConfig = await ask("\nCreate .preflight/ config directory with template files? [y/N]: ");
102
- if (createConfig.trim().toLowerCase() === "y") {
103
- await mkdir(preflightDir, { recursive: true });
104
- const configYml = `# Preflight configuration
105
- profile: ${profile}
106
-
107
- related_projects: []
108
- # - path: /path/to/related/project
109
- # alias: project-name
110
-
111
- thresholds:
112
- session_stale_minutes: 30
113
- max_tool_calls_before_checkpoint: 100
114
- correction_pattern_threshold: 3
115
-
116
- embeddings:
117
- provider: local
118
- `;
119
- const triageYml = `# Triage rules for prompt classification
120
- rules:
121
- always_check:
122
- - rewards
123
- - permissions
124
- - migration
125
- - schema
126
- skip:
127
- - commit
128
- - format
129
- - lint
130
- cross_service_keywords:
131
- - auth
132
- - notification
133
- - event
134
- - webhook
135
-
136
- strictness: standard
137
- `;
138
- await writeFile(join(preflightDir, "config.yml"), configYml);
139
- await writeFile(join(preflightDir, "triage.yml"), triageYml);
140
- console.log("✅ Created .preflight/config.yml and .preflight/triage.yml");
141
- }
142
- }
143
- else {
144
- console.log("\n.preflight/ directory already exists — skipping.");
145
- }
146
98
  console.log(`\n✅ preflight added! (profile: ${profile})`);
147
99
  console.log("Restart Claude Code to connect.\n");
148
100
  rl.close();
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -27,6 +27,8 @@ import { registerCheckpoint } from "./tools/checkpoint.js";
27
27
  import { registerSessionHealth } from "./tools/session-health.js";
28
28
  // Category 9: Error Recovery
29
29
  import { registerLogCorrection } from "./tools/log-correction.js";
30
+ // Category 9b: Pattern Learning
31
+ import { registerCheckPatterns } from "./tools/check-patterns.js";
30
32
  // Category 10: Workspace Hygiene
31
33
  import { registerAuditWorkspace } from "./tools/audit-workspace.js";
32
34
  // Category 11: Cross-Session Continuity
@@ -43,6 +45,8 @@ import { registerSearchHistory } from "./tools/search-history.js";
43
45
  import { registerTimeline } from "./tools/timeline-view.js";
44
46
  import { registerScanSessions } from "./tools/scan-sessions.js";
45
47
  import { registerGenerateScorecard } from "./tools/generate-scorecard.js";
48
+ import { registerSearchContracts } from "./tools/search-contracts.js";
49
+ import { registerEstimateCost } from "./tools/estimate-cost.js";
46
50
  // Validate related projects from config
47
51
  function validateRelatedProjects() {
48
52
  const config = getConfig();
@@ -81,6 +85,7 @@ const toolRegistry = [
81
85
  ["checkpoint", registerCheckpoint],
82
86
  ["check_session_health", registerSessionHealth],
83
87
  ["log_correction", registerLogCorrection],
88
+ ["check_patterns", registerCheckPatterns],
84
89
  ["audit_workspace", registerAuditWorkspace],
85
90
  ["session_handoff", registerSessionHandoff],
86
91
  ["what_changed", registerWhatChanged],
@@ -92,6 +97,8 @@ const toolRegistry = [
92
97
  ["timeline_view", registerTimeline],
93
98
  ["scan_sessions", registerScanSessions],
94
99
  ["generate_scorecard", registerGenerateScorecard],
100
+ ["estimate_cost", registerEstimateCost],
101
+ ["search_contracts", registerSearchContracts],
95
102
  ];
96
103
  let registered = 0;
97
104
  for (const [name, register] of toolRegistry) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface Contract {
2
+ name: string;
3
+ kind: "interface" | "type" | "enum" | "route" | "schema" | "event" | "model";
4
+ file: string;
5
+ definition: string;
6
+ project: string;
7
+ extractedAt: string;
8
+ }
9
+ /** Scan a project directory and extract all contracts */
10
+ export declare function extractContracts(projectDir: string): Contract[];
11
+ /** Load manual contract definitions from .preflight/contracts/ */
12
+ export declare function loadManualContracts(projectDir: string): Contract[];
13
+ /** Load stored contracts for a project */
14
+ export declare function loadContracts(projectHash: string): Contract[];
15
+ /** Save contracts to storage */
16
+ export declare function saveContracts(projectHash: string, contracts: Contract[]): void;
17
+ /** Search contracts by query string (simple relevance scoring) */
18
+ export declare function searchContracts(query: string, contracts: Contract[]): Contract[];
19
+ /** Extract and save contracts for a project, merging with manual definitions */
20
+ export declare function extractAndSaveContracts(projectDir: string): {
21
+ count: number;
22
+ hash: string;
23
+ };
24
+ /** Load all contracts for a list of project directories */
25
+ export declare function loadAllContracts(projectDirs: string[]): Contract[];
26
+ /** Format contracts for display in tool output */
27
+ export declare function formatContracts(contracts: Contract[], limit?: number): string;
@@ -0,0 +1,309 @@
1
+ // =============================================================================
2
+ // Cross-Service Contract Registry
3
+ // =============================================================================
4
+ // Extracts, stores, and searches API contracts, types, and schemas
5
+ // across projects for fast cross-service context lookups.
6
+ // =============================================================================
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, statSync } from "fs";
8
+ import { join, resolve, relative, basename, extname } from "path";
9
+ import { createHash } from "crypto";
10
+ import { homedir } from "os";
11
+ import { load as yamlLoad } from "js-yaml";
12
+ // --- Helpers ---
13
+ const PREFLIGHT_DIR = join(homedir(), ".preflight");
14
+ const PROJECTS_DIR = join(PREFLIGHT_DIR, "projects");
15
+ function hashProjectDir(projectDir) {
16
+ return createHash("sha256").update(resolve(projectDir)).digest("hex").slice(0, 12);
17
+ }
18
+ function contractsPath(projectHash) {
19
+ return join(PROJECTS_DIR, projectHash, "contracts.json");
20
+ }
21
+ // --- File Discovery ---
22
+ /** Recursively find files matching patterns, skipping node_modules/.git/dist */
23
+ function findFiles(dir, patterns, maxDepth = 8, depth = 0) {
24
+ if (depth > maxDepth)
25
+ return [];
26
+ const results = [];
27
+ let entries;
28
+ try {
29
+ entries = readdirSync(dir);
30
+ }
31
+ catch {
32
+ return results;
33
+ }
34
+ for (const entry of entries) {
35
+ if (entry === "node_modules" || entry === ".git" || entry === "dist" || entry === ".next" || entry === "build")
36
+ continue;
37
+ const full = join(dir, entry);
38
+ let st;
39
+ try {
40
+ st = statSync(full);
41
+ }
42
+ catch {
43
+ continue;
44
+ }
45
+ if (st.isDirectory()) {
46
+ results.push(...findFiles(full, patterns, maxDepth, depth + 1));
47
+ }
48
+ else if (patterns.some(p => p.test(full))) {
49
+ results.push(full);
50
+ }
51
+ }
52
+ return results;
53
+ }
54
+ // --- Extraction ---
55
+ const TS_CONTRACT_PATTERNS = [
56
+ // types.ts, types/*.ts, interfaces.ts, *.d.ts
57
+ /\/types\.ts$/, /\/types\/[^/]+\.ts$/, /\/interfaces\.ts$/, /\.d\.ts$/,
58
+ // API routes
59
+ /\/api\/.*\.ts$/, /\/routes\/.*\.ts$/,
60
+ // Event schemas
61
+ /\/events\/.*\.ts$/, /\/schemas\/.*\.ts$/,
62
+ ];
63
+ const PRISMA_PATTERN = /prisma\/schema\.prisma$/;
64
+ const OPENAPI_PATTERN = /\/(openapi\.ya?ml|swagger\.json)$/;
65
+ /** Extract TypeScript interfaces, types, and enums from source */
66
+ function extractTsContracts(content, filePath, projectDir) {
67
+ const contracts = [];
68
+ const relPath = relative(projectDir, filePath);
69
+ const now = new Date().toISOString();
70
+ // Match: export interface Foo { ... }
71
+ const interfaceRe = /export\s+interface\s+(\w+)(?:\s+extends\s+[^{]+)?\s*\{[^}]*(?:\{[^}]*\}[^}]*)*\}/g;
72
+ for (const m of content.matchAll(interfaceRe)) {
73
+ contracts.push({ name: m[1], kind: "interface", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
74
+ }
75
+ // Match: export type Foo = ...
76
+ const typeRe = /export\s+type\s+(\w+)\s*(?:<[^>]*>)?\s*=[^;]+;/g;
77
+ for (const m of content.matchAll(typeRe)) {
78
+ contracts.push({ name: m[1], kind: "type", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
79
+ }
80
+ // Match: export enum Foo { ... }
81
+ const enumRe = /export\s+enum\s+(\w+)\s*\{[^}]*\}/g;
82
+ for (const m of content.matchAll(enumRe)) {
83
+ contracts.push({ name: m[1], kind: "enum", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
84
+ }
85
+ // Detect route definitions (Next.js/Express patterns)
86
+ const isRouteFile = /\/(api|routes)\//.test(filePath);
87
+ if (isRouteFile) {
88
+ // export async function GET/POST/PUT/DELETE/PATCH
89
+ const routeRe = /export\s+(?:async\s+)?function\s+(GET|POST|PUT|DELETE|PATCH|handler)\b[^{]*\{/g;
90
+ for (const m of content.matchAll(routeRe)) {
91
+ const routeName = `${m[1]} ${relPath.replace(/\.(ts|js)$/, "")}`;
92
+ const defStart = m.index;
93
+ contracts.push({ name: routeName, kind: "route", file: relPath, definition: content.slice(defStart, defStart + 500), project: projectDir, extractedAt: now });
94
+ }
95
+ // router.get/post/put/delete
96
+ const expressRe = /router\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g;
97
+ for (const m of content.matchAll(expressRe)) {
98
+ contracts.push({ name: `${m[1].toUpperCase()} ${m[2]}`, kind: "route", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
99
+ }
100
+ }
101
+ return contracts;
102
+ }
103
+ /** Extract Prisma models */
104
+ function extractPrismaContracts(content, filePath, projectDir) {
105
+ const contracts = [];
106
+ const relPath = relative(projectDir, filePath);
107
+ const now = new Date().toISOString();
108
+ const modelRe = /model\s+(\w+)\s*\{[^}]*\}/g;
109
+ for (const m of content.matchAll(modelRe)) {
110
+ contracts.push({ name: m[1], kind: "model", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
111
+ }
112
+ const enumRe = /enum\s+(\w+)\s*\{[^}]*\}/g;
113
+ for (const m of content.matchAll(enumRe)) {
114
+ contracts.push({ name: m[1], kind: "enum", file: relPath, definition: m[0].slice(0, 500), project: projectDir, extractedAt: now });
115
+ }
116
+ return contracts;
117
+ }
118
+ /** Extract from OpenAPI/Swagger specs */
119
+ function extractOpenApiContracts(content, filePath, projectDir) {
120
+ const contracts = [];
121
+ const relPath = relative(projectDir, filePath);
122
+ const now = new Date().toISOString();
123
+ try {
124
+ const spec = filePath.endsWith(".json") ? JSON.parse(content) : yamlLoad(content);
125
+ if (spec?.paths) {
126
+ for (const [path, methods] of Object.entries(spec.paths)) {
127
+ for (const method of Object.keys(methods)) {
128
+ if (["get", "post", "put", "delete", "patch"].includes(method)) {
129
+ const op = methods[method];
130
+ const name = `${method.toUpperCase()} ${path}`;
131
+ const def = JSON.stringify({ summary: op.summary, parameters: op.parameters, requestBody: op.requestBody }, null, 2);
132
+ contracts.push({ name, kind: "route", file: relPath, definition: def.slice(0, 500), project: projectDir, extractedAt: now });
133
+ }
134
+ }
135
+ }
136
+ }
137
+ if (spec?.components?.schemas) {
138
+ for (const [name, schema] of Object.entries(spec.components.schemas)) {
139
+ contracts.push({ name, kind: "schema", file: relPath, definition: JSON.stringify(schema, null, 2).slice(0, 500), project: projectDir, extractedAt: now });
140
+ }
141
+ }
142
+ }
143
+ catch {
144
+ // Invalid spec, skip
145
+ }
146
+ return contracts;
147
+ }
148
+ // --- Public API ---
149
+ /** Scan a project directory and extract all contracts */
150
+ export function extractContracts(projectDir) {
151
+ const absDir = resolve(projectDir);
152
+ const contracts = [];
153
+ // TypeScript files
154
+ const tsFiles = findFiles(absDir, TS_CONTRACT_PATTERNS);
155
+ for (const file of tsFiles) {
156
+ try {
157
+ const content = readFileSync(file, "utf-8");
158
+ contracts.push(...extractTsContracts(content, file, absDir));
159
+ }
160
+ catch { /* skip unreadable */ }
161
+ }
162
+ // Prisma
163
+ const prismaFiles = findFiles(absDir, [PRISMA_PATTERN], 3);
164
+ for (const file of prismaFiles) {
165
+ try {
166
+ const content = readFileSync(file, "utf-8");
167
+ contracts.push(...extractPrismaContracts(content, file, absDir));
168
+ }
169
+ catch { /* skip */ }
170
+ }
171
+ // OpenAPI
172
+ const openApiFiles = findFiles(absDir, [OPENAPI_PATTERN], 5);
173
+ for (const file of openApiFiles) {
174
+ try {
175
+ const content = readFileSync(file, "utf-8");
176
+ contracts.push(...extractOpenApiContracts(content, file, absDir));
177
+ }
178
+ catch { /* skip */ }
179
+ }
180
+ return contracts;
181
+ }
182
+ /** Load manual contract definitions from .preflight/contracts/ */
183
+ export function loadManualContracts(projectDir) {
184
+ const contractsDir = join(projectDir, ".preflight", "contracts");
185
+ if (!existsSync(contractsDir))
186
+ return [];
187
+ const contracts = [];
188
+ const now = new Date().toISOString();
189
+ let entries;
190
+ try {
191
+ entries = readdirSync(contractsDir);
192
+ }
193
+ catch {
194
+ return [];
195
+ }
196
+ for (const entry of entries) {
197
+ if (![".yml", ".yaml"].includes(extname(entry)))
198
+ continue;
199
+ const filePath = join(contractsDir, entry);
200
+ try {
201
+ const content = readFileSync(filePath, "utf-8");
202
+ const items = yamlLoad(content);
203
+ if (!Array.isArray(items))
204
+ continue;
205
+ for (const item of items) {
206
+ if (!item.name || !item.kind)
207
+ continue;
208
+ const def = item.fields
209
+ ? `${item.description || ""}\nFields: ${item.fields.map(f => `${f.name}: ${f.type}${f.required ? " (required)" : ""}`).join(", ")}`
210
+ : item.description || "";
211
+ contracts.push({
212
+ name: item.name,
213
+ kind: item.kind,
214
+ file: `.preflight/contracts/${entry}`,
215
+ definition: def.trim().slice(0, 500),
216
+ project: resolve(projectDir),
217
+ extractedAt: now,
218
+ });
219
+ }
220
+ }
221
+ catch { /* skip invalid */ }
222
+ }
223
+ return contracts;
224
+ }
225
+ /** Load stored contracts for a project */
226
+ export function loadContracts(projectHash) {
227
+ const p = contractsPath(projectHash);
228
+ if (!existsSync(p))
229
+ return [];
230
+ try {
231
+ return JSON.parse(readFileSync(p, "utf-8"));
232
+ }
233
+ catch {
234
+ return [];
235
+ }
236
+ }
237
+ /** Save contracts to storage */
238
+ export function saveContracts(projectHash, contracts) {
239
+ const dir = join(PROJECTS_DIR, projectHash);
240
+ mkdirSync(dir, { recursive: true });
241
+ writeFileSync(contractsPath(projectHash), JSON.stringify(contracts, null, 2));
242
+ }
243
+ /** Search contracts by query string (simple relevance scoring) */
244
+ export function searchContracts(query, contracts) {
245
+ const terms = query.toLowerCase().split(/\s+/).filter(t => t.length > 1);
246
+ if (terms.length === 0)
247
+ return contracts;
248
+ const scored = contracts.map(c => {
249
+ const nameL = c.name.toLowerCase();
250
+ const defL = c.definition.toLowerCase();
251
+ const fileL = c.file.toLowerCase();
252
+ let score = 0;
253
+ for (const term of terms) {
254
+ // Exact name match is highest
255
+ if (nameL === term)
256
+ score += 10;
257
+ // Name contains term
258
+ else if (nameL.includes(term))
259
+ score += 5;
260
+ // File contains term
261
+ if (fileL.includes(term))
262
+ score += 2;
263
+ // Definition contains term
264
+ if (defL.includes(term))
265
+ score += 1;
266
+ }
267
+ return { contract: c, score };
268
+ });
269
+ return scored
270
+ .filter(s => s.score > 0)
271
+ .sort((a, b) => b.score - a.score)
272
+ .map(s => s.contract);
273
+ }
274
+ /** Extract and save contracts for a project, merging with manual definitions */
275
+ export function extractAndSaveContracts(projectDir) {
276
+ const absDir = resolve(projectDir);
277
+ const hash = hashProjectDir(absDir);
278
+ const autoContracts = extractContracts(absDir);
279
+ const manualContracts = loadManualContracts(absDir);
280
+ // Manual contracts take precedence (same name = manual wins)
281
+ const manualNames = new Set(manualContracts.map(c => c.name));
282
+ const merged = [
283
+ ...manualContracts,
284
+ ...autoContracts.filter(c => !manualNames.has(c.name)),
285
+ ];
286
+ saveContracts(hash, merged);
287
+ return { count: merged.length, hash };
288
+ }
289
+ /** Load all contracts for a list of project directories */
290
+ export function loadAllContracts(projectDirs) {
291
+ const all = [];
292
+ for (const dir of projectDirs) {
293
+ const hash = hashProjectDir(resolve(dir));
294
+ all.push(...loadContracts(hash));
295
+ }
296
+ return all;
297
+ }
298
+ /** Format contracts for display in tool output */
299
+ export function formatContracts(contracts, limit = 10) {
300
+ if (contracts.length === 0)
301
+ return "";
302
+ const lines = contracts.slice(0, limit).map(c => {
303
+ const proj = basename(c.project);
304
+ const defPreview = c.definition.split("\n")[0].slice(0, 120);
305
+ return `From ${proj}: ${c.kind} ${c.name} — ${defPreview} (${c.file})`;
306
+ });
307
+ return lines.join("\n");
308
+ }
309
+ //# sourceMappingURL=contracts.js.map