k0ntext 3.0.0 β 3.1.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 +159 -3
- package/dist/agents/drift-agent.d.ts +114 -0
- package/dist/agents/drift-agent.d.ts.map +1 -0
- package/dist/agents/drift-agent.js +324 -0
- package/dist/agents/drift-agent.js.map +1 -0
- package/dist/agents/fact-check-agent.d.ts +103 -0
- package/dist/agents/fact-check-agent.d.ts.map +1 -0
- package/dist/agents/fact-check-agent.js +273 -0
- package/dist/agents/fact-check-agent.js.map +1 -0
- package/dist/cli/commands/cleanup.d.ts.map +1 -1
- package/dist/cli/commands/cleanup.js +77 -5
- package/dist/cli/commands/cleanup.js.map +1 -1
- package/dist/cli/commands/cross-sync.d.ts +10 -0
- package/dist/cli/commands/cross-sync.d.ts.map +1 -0
- package/dist/cli/commands/cross-sync.js +398 -0
- package/dist/cli/commands/cross-sync.js.map +1 -0
- package/dist/cli/commands/drift-detect.d.ts +10 -0
- package/dist/cli/commands/drift-detect.d.ts.map +1 -0
- package/dist/cli/commands/drift-detect.js +120 -0
- package/dist/cli/commands/drift-detect.js.map +1 -0
- package/dist/cli/commands/fact-check.d.ts +10 -0
- package/dist/cli/commands/fact-check.d.ts.map +1 -0
- package/dist/cli/commands/fact-check.js +105 -0
- package/dist/cli/commands/fact-check.js.map +1 -0
- package/dist/cli/commands/hooks.d.ts +13 -0
- package/dist/cli/commands/hooks.d.ts.map +1 -0
- package/dist/cli/commands/hooks.js +216 -0
- package/dist/cli/commands/hooks.js.map +1 -0
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +278 -12
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/index.js +33 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/config/models.d.ts +112 -0
- package/dist/config/models.d.ts.map +1 -0
- package/dist/config/models.js +116 -0
- package/dist/config/models.js.map +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +2 -2
- package/dist/db/client.js.map +1 -1
- package/dist/embeddings/openrouter.d.ts +8 -0
- package/dist/embeddings/openrouter.d.ts.map +1 -1
- package/dist/embeddings/openrouter.js +16 -6
- package/dist/embeddings/openrouter.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/drift-agent.ts +430 -0
- package/src/agents/fact-check-agent.ts +348 -0
- package/src/cli/commands/cleanup.ts +86 -5
- package/src/cli/commands/cross-sync.ts +473 -0
- package/src/cli/commands/drift-detect.ts +139 -0
- package/src/cli/commands/fact-check.ts +127 -0
- package/src/cli/commands/hooks.ts +244 -0
- package/src/cli/generate.ts +286 -12
- package/src/cli/index.ts +36 -8
- package/src/config/models.ts +136 -0
- package/src/db/client.ts +4 -3
- package/src/embeddings/openrouter.ts +19 -7
- package/templates/map/claude.md +82 -0
- package/templates/map/cline.md +37 -0
- package/templates/map/copilot.md +31 -0
- package/templates/map/cursor.md +39 -0
- package/templates/map/gemini.md +47 -0
package/README.md
CHANGED
|
@@ -73,6 +73,7 @@ K0ntext uses native SQLite extensions for high-performance vector search.
|
|
|
73
73
|
- Tech stack detection and documentation
|
|
74
74
|
- Workflow discovery and categorization
|
|
75
75
|
- Automatic context generation
|
|
76
|
+
- **Centralized model configuration** (v3.1.0) - Single source of truth for all AI operations
|
|
76
77
|
|
|
77
78
|
### π Semantic Search
|
|
78
79
|
- Vector database (sqlite-vec) for intelligent code retrieval
|
|
@@ -85,6 +86,29 @@ K0ntext uses native SQLite extensions for high-performance vector search.
|
|
|
85
86
|
- Automatic synchronization between tool configurations
|
|
86
87
|
- Change detection with SHA256 hashing
|
|
87
88
|
- Sync status monitoring
|
|
89
|
+
- **Intelligent cross-sync** (v3.1.0) - AI-powered propagation of changes across tools
|
|
90
|
+
|
|
91
|
+
### π€ Git Hooks Automation (v3.1.0)
|
|
92
|
+
- **Pre-commit workflow** - Automatic context maintenance
|
|
93
|
+
- Drift detection on every commit
|
|
94
|
+
- Automatic cross-sync when drift detected
|
|
95
|
+
- Updated context files auto-added to commits
|
|
96
|
+
|
|
97
|
+
### π― Drift Detection (v3.1.0)
|
|
98
|
+
- **AI-powered semantic analysis** - Detect when documentation diverges from code
|
|
99
|
+
- Replaces hash-based checks with intelligent understanding
|
|
100
|
+
- Severity-based reporting (high/medium/low)
|
|
101
|
+
- Automatic fix suggestions
|
|
102
|
+
|
|
103
|
+
### π Fact-Checking (v3.1.0)
|
|
104
|
+
- Validate documentation accuracy against codebase
|
|
105
|
+
- Identify outdated APIs, wrong file paths, missing dependencies
|
|
106
|
+
- Confidence scoring for each claim
|
|
107
|
+
|
|
108
|
+
### πΊοΈ Map-Based Context (v3.1.0)
|
|
109
|
+
- Concise, structured context files
|
|
110
|
+
- Reduce hallucination through precise references
|
|
111
|
+
- Alternative to verbose documentation format
|
|
88
112
|
|
|
89
113
|
### π€ MCP Server
|
|
90
114
|
- **10 Tools:** search_context, get_item, add_knowledge, analyze, get_tool_configs, query_graph, get_stats
|
|
@@ -92,7 +116,7 @@ K0ntext uses native SQLite extensions for high-performance vector search.
|
|
|
92
116
|
- Real-time context access for AI assistants
|
|
93
117
|
- Knowledge graph traversal
|
|
94
118
|
|
|
95
|
-
### π οΈ Complete CLI (
|
|
119
|
+
### π οΈ Complete CLI (18 Commands)
|
|
96
120
|
- `init` - Initialize with intelligent analysis
|
|
97
121
|
- `generate` - Generate context files for all tools
|
|
98
122
|
- `mcp` - Start MCP server
|
|
@@ -106,10 +130,17 @@ K0ntext uses native SQLite extensions for high-performance vector search.
|
|
|
106
130
|
- `index` - Index codebase
|
|
107
131
|
- `search` - Search indexed content
|
|
108
132
|
- `stats` - View database statistics
|
|
133
|
+
- **`drift-detect`** - AI-powered documentation drift detection
|
|
134
|
+
- **`cross-sync`** - Intelligent sync across all AI tools
|
|
135
|
+
- **`hooks`** - Git hooks management (install/uninstall/status)
|
|
136
|
+
- **`fact-check`** - Validate documentation accuracy
|
|
137
|
+
- `generate --map` - Generate concise map-based context files
|
|
109
138
|
|
|
110
139
|
### π Smart Agents
|
|
111
140
|
- **CleanupAgent** - Remove conflicting AI tool folders (.cursor, .windsurf, .cline, etc.)
|
|
112
141
|
- **PerformanceMonitorAgent** - Track database performance and suggest optimizations
|
|
142
|
+
- **DriftAgent** (v3.1.0) - AI-powered documentation drift detection
|
|
143
|
+
- **FactCheckAgent** (v3.1.0) - Validate documentation accuracy against codebase
|
|
113
144
|
|
|
114
145
|
### ποΈ SQLite Storage
|
|
115
146
|
- Persistent database with SHA256 change detection
|
|
@@ -159,6 +190,7 @@ k0ntext generate -v
|
|
|
159
190
|
**Options:**
|
|
160
191
|
- `-ai, --ai <tools>` - Specific tools (comma-separated)
|
|
161
192
|
- `--force` - Force regenerate all files
|
|
193
|
+
- `--map` - Use concise map-based format (new in v3.1.0)
|
|
162
194
|
- `-v, --verbose` - Show detailed output
|
|
163
195
|
|
|
164
196
|
#### `k0ntext mcp`
|
|
@@ -218,6 +250,7 @@ k0ntext cleanup -v
|
|
|
218
250
|
**Options:**
|
|
219
251
|
- `--dry-run` - Show what would be removed
|
|
220
252
|
- `--keep <folders>` - Folders to keep (comma-separated)
|
|
253
|
+
- `--ai` - Use AI to intelligently analyze which folders can be safely removed (new in v3.1.0)
|
|
221
254
|
- `-v, --verbose` - Show detailed output
|
|
222
255
|
|
|
223
256
|
#### `k0ntext validate`
|
|
@@ -362,6 +395,128 @@ k0ntext stats
|
|
|
362
395
|
k0ntext stats | grep "Context Items"
|
|
363
396
|
```
|
|
364
397
|
|
|
398
|
+
### v3.1.0 New Commands
|
|
399
|
+
|
|
400
|
+
#### `k0ntext drift-detect`
|
|
401
|
+
AI-powered documentation drift detection using semantic analysis.
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
# Detect drift in all context files
|
|
405
|
+
k0ntext drift-detect
|
|
406
|
+
|
|
407
|
+
# Detect drift in specific paths
|
|
408
|
+
k0ntext drift-detect -p CLAUDE.md,.cursorrules
|
|
409
|
+
|
|
410
|
+
# Check up to 20 files
|
|
411
|
+
k0ntext drift-detect --max-files 20
|
|
412
|
+
|
|
413
|
+
# Strict mode (fails on any drift)
|
|
414
|
+
k0ntext drift-detect --strict
|
|
415
|
+
|
|
416
|
+
# Verbose output
|
|
417
|
+
k0ntext drift-detect -v
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Options:**
|
|
421
|
+
- `--fix` - Automatically fix detected drift (experimental)
|
|
422
|
+
- `--strict` - Fail on any drift detected
|
|
423
|
+
- `-p, --paths <paths>` - Comma-separated paths to check
|
|
424
|
+
- `--max-files <number>` - Maximum files to check (default: 50)
|
|
425
|
+
- `--model <model>` - Override model (not recommended)
|
|
426
|
+
- `-v, --verbose` - Show detailed output
|
|
427
|
+
|
|
428
|
+
#### `k0ntext cross-sync`
|
|
429
|
+
Intelligently synchronize context across all AI tools after drift detection.
|
|
430
|
+
|
|
431
|
+
```bash
|
|
432
|
+
# Sync all affected files
|
|
433
|
+
k0ntext cross-sync
|
|
434
|
+
|
|
435
|
+
# Dry run to see what would be synced
|
|
436
|
+
k0ntext cross-sync --dry-run
|
|
437
|
+
|
|
438
|
+
# Sync to specific tools only
|
|
439
|
+
k0ntext cross-sync --to claude,cursor
|
|
440
|
+
|
|
441
|
+
# Sync from specific files
|
|
442
|
+
k0ntext cross-sync --affected CLAUDE.md,.cursorrules
|
|
443
|
+
|
|
444
|
+
# Verbose output with details
|
|
445
|
+
k0ntext cross-sync -v
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Options:**
|
|
449
|
+
- `--dry-run` - Show what would be synced without making changes
|
|
450
|
+
- `--from <tool>` - Sync only from specific tool
|
|
451
|
+
- `--to <tools>` - Sync only to specific tools (comma-separated)
|
|
452
|
+
- `--affected <files>` - Comma-separated list of affected files
|
|
453
|
+
- `-v, --verbose` - Show detailed sync output
|
|
454
|
+
|
|
455
|
+
#### `k0ntext hooks`
|
|
456
|
+
Manage git hooks for automatic context synchronization.
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
# Install git hooks
|
|
460
|
+
k0ntext hooks install
|
|
461
|
+
|
|
462
|
+
# Install with force (overwrite existing)
|
|
463
|
+
k0ntext hooks install -f
|
|
464
|
+
|
|
465
|
+
# Uninstall git hooks
|
|
466
|
+
k0ntext hooks uninstall
|
|
467
|
+
|
|
468
|
+
# Check hooks status
|
|
469
|
+
k0ntext hooks status
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Subcommands:**
|
|
473
|
+
- `install` - Install pre-commit hook for automatic workflow
|
|
474
|
+
- `uninstall` - Remove installed hooks
|
|
475
|
+
- `status` - Show hook installation status
|
|
476
|
+
|
|
477
|
+
**Install Options:**
|
|
478
|
+
- `-f, --force` - Overwrite existing hooks
|
|
479
|
+
- `--skip-backup` - Skip backing up existing hooks
|
|
480
|
+
|
|
481
|
+
#### `k0ntext fact-check [files...]`
|
|
482
|
+
Validate documentation accuracy using AI analysis.
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
# Check all documentation files
|
|
486
|
+
k0ntext fact-check
|
|
487
|
+
|
|
488
|
+
# Check specific files
|
|
489
|
+
k0ntext fact-check CLAUDE.md .cursorrules
|
|
490
|
+
|
|
491
|
+
# Set minimum confidence threshold
|
|
492
|
+
k0ntext fact-check --min-confidence 0.7
|
|
493
|
+
|
|
494
|
+
# Verbose output
|
|
495
|
+
k0ntext fact-check -v
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
**Options:**
|
|
499
|
+
- `--fix` - Automatically fix detected issues (experimental)
|
|
500
|
+
- `-v, --verbose` - Show detailed output
|
|
501
|
+
- `--min-confidence <number>` - Minimum confidence to report (0-1, default: 0.5)
|
|
502
|
+
|
|
503
|
+
### Git Hooks Workflow (v3.1.0)
|
|
504
|
+
|
|
505
|
+
When you install hooks with `k0ntext hooks install`, the pre-commit hook automatically:
|
|
506
|
+
|
|
507
|
+
1. **Autosync** - Sync context from source of truth
|
|
508
|
+
2. **Validate** - Check for context errors
|
|
509
|
+
3. **Drift Detect** - AI-powered drift detection
|
|
510
|
+
4. **Cross-Sync** - Update all AI tool contexts if drift found
|
|
511
|
+
5. **Auto-Add** - Include updated context files in commit
|
|
512
|
+
|
|
513
|
+
**Skip hooks temporarily:**
|
|
514
|
+
```bash
|
|
515
|
+
K0NTEXT_SKIP_HOOKS=1 git commit -m "message"
|
|
516
|
+
# or
|
|
517
|
+
git commit --no-verify -m "message"
|
|
518
|
+
```
|
|
519
|
+
|
|
365
520
|
## π€ MCP Server Usage
|
|
366
521
|
|
|
367
522
|
### Start the Server
|
|
@@ -467,11 +622,12 @@ Each AI tool has its own configuration file path:
|
|
|
467
622
|
```
|
|
468
623
|
k0ntext/
|
|
469
624
|
βββ src/ # TypeScript source
|
|
470
|
-
β βββ cli/ # CLI commands (
|
|
625
|
+
β βββ cli/ # CLI commands (18 commands)
|
|
626
|
+
β βββ config/ # Centralized configuration (v3.1.0)
|
|
471
627
|
β βββ db/ # SQLite database client
|
|
472
628
|
β βββ analyzer/ # Intelligent codebase analysis
|
|
473
629
|
β βββ embeddings/ # OpenRouter integration
|
|
474
|
-
β βββ agents/ # Smart agents (Cleanup, Performance)
|
|
630
|
+
β βββ agents/ # Smart agents (Cleanup, Performance, Drift, FactCheck)
|
|
475
631
|
β βββ mcp.ts # MCP server implementation
|
|
476
632
|
βββ agents/ # Agent definitions
|
|
477
633
|
βββ skills/ # RPI workflow skills
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drift Detection Agent
|
|
3
|
+
*
|
|
4
|
+
* Uses AI to detect when documentation drifts from the actual codebase.
|
|
5
|
+
* This is the core of intelligent drift detection for k0ntext v3.1.0.
|
|
6
|
+
*
|
|
7
|
+
* @version 3.1.0
|
|
8
|
+
*/
|
|
9
|
+
import { OpenRouterClient } from '../embeddings/openrouter.js';
|
|
10
|
+
/**
|
|
11
|
+
* A detected drift issue
|
|
12
|
+
*/
|
|
13
|
+
export interface DriftIssue {
|
|
14
|
+
/** The file where drift was detected */
|
|
15
|
+
file: string;
|
|
16
|
+
/** Severity level */
|
|
17
|
+
severity: 'low' | 'medium' | 'high';
|
|
18
|
+
/** What the documentation says */
|
|
19
|
+
expected: string;
|
|
20
|
+
/** What the actual codebase has */
|
|
21
|
+
actual: string;
|
|
22
|
+
/** Suggested fix (optional) */
|
|
23
|
+
suggestion?: string;
|
|
24
|
+
/** Line number where drift occurs (optional) */
|
|
25
|
+
line?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of drift detection
|
|
29
|
+
*/
|
|
30
|
+
export interface DriftResult {
|
|
31
|
+
/** All detected drifts */
|
|
32
|
+
drifts: DriftIssue[];
|
|
33
|
+
/** Number of drifts automatically fixed */
|
|
34
|
+
fixed: number;
|
|
35
|
+
/** Files checked */
|
|
36
|
+
filesChecked: number;
|
|
37
|
+
/** Time taken in milliseconds */
|
|
38
|
+
duration: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Configuration for the drift agent
|
|
42
|
+
*/
|
|
43
|
+
export interface DriftAgentConfig {
|
|
44
|
+
/** OpenRouter client for AI analysis */
|
|
45
|
+
openRouter: OpenRouterClient;
|
|
46
|
+
/** Model override (not recommended) */
|
|
47
|
+
model?: string;
|
|
48
|
+
/** Whether to fail on any drift */
|
|
49
|
+
strict?: boolean;
|
|
50
|
+
/** Project root directory */
|
|
51
|
+
projectRoot: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Drift Detection Agent
|
|
55
|
+
*
|
|
56
|
+
* Analyzes documentation files and compares them against the actual
|
|
57
|
+
* codebase to detect discrepancies using AI semantic analysis.
|
|
58
|
+
*/
|
|
59
|
+
export declare class DriftAgent {
|
|
60
|
+
private openRouter;
|
|
61
|
+
private model;
|
|
62
|
+
private strict;
|
|
63
|
+
private projectRoot;
|
|
64
|
+
constructor(config: DriftAgentConfig);
|
|
65
|
+
/**
|
|
66
|
+
* Detect drift across all context files
|
|
67
|
+
*/
|
|
68
|
+
detectDrift(options: {
|
|
69
|
+
paths?: string[];
|
|
70
|
+
autoFix?: boolean;
|
|
71
|
+
maxFiles?: number;
|
|
72
|
+
}): Promise<DriftResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Check a single file for drift
|
|
75
|
+
*/
|
|
76
|
+
private checkFileForDrift;
|
|
77
|
+
/**
|
|
78
|
+
* Get the drift detection system prompt
|
|
79
|
+
*/
|
|
80
|
+
private getDriftDetectionPrompt;
|
|
81
|
+
/**
|
|
82
|
+
* Build the drift analysis prompt for a specific file
|
|
83
|
+
*/
|
|
84
|
+
private buildDriftAnalysisPrompt;
|
|
85
|
+
/**
|
|
86
|
+
* Parse the drift detection response
|
|
87
|
+
*/
|
|
88
|
+
private parseDriftResponse;
|
|
89
|
+
/**
|
|
90
|
+
* Get relevant source code samples for comparison
|
|
91
|
+
*/
|
|
92
|
+
private getRelevantSourceSamples;
|
|
93
|
+
/**
|
|
94
|
+
* Discover source files in the project
|
|
95
|
+
*/
|
|
96
|
+
private discoverSourceFiles;
|
|
97
|
+
/**
|
|
98
|
+
* Get all context files to check
|
|
99
|
+
*/
|
|
100
|
+
private getContextFiles;
|
|
101
|
+
/**
|
|
102
|
+
* Attempt to fix drift in a file
|
|
103
|
+
*/
|
|
104
|
+
private fixDrift;
|
|
105
|
+
/**
|
|
106
|
+
* Close the agent and clean up resources
|
|
107
|
+
*/
|
|
108
|
+
close(): void;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Create a drift agent
|
|
112
|
+
*/
|
|
113
|
+
export declare function createDriftAgent(config: Omit<DriftAgentConfig, 'projectRoot'>): DriftAgent;
|
|
114
|
+
//# sourceMappingURL=drift-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-agent.d.ts","sourceRoot":"","sources":["../../src/agents/drift-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AA4CD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,gBAAgB;IAOpC;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,WAAW,CAAC;IAuCxB;;OAEG;YACW,iBAAiB;IAsD/B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAqBhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4B1B;;OAEG;YACW,wBAAwB;IAuCtC;;OAEG;YACW,mBAAmB;IA0BjC;;OAEG;YACW,eAAe;IAgB7B;;OAEG;YACW,QAAQ;IAQtB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,GAAG,UAAU,CAK1F"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drift Detection Agent
|
|
3
|
+
*
|
|
4
|
+
* Uses AI to detect when documentation drifts from the actual codebase.
|
|
5
|
+
* This is the core of intelligent drift detection for k0ntext v3.1.0.
|
|
6
|
+
*
|
|
7
|
+
* @version 3.1.0
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'fs/promises';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { glob } from 'glob';
|
|
12
|
+
import { MODEL_CONFIG, getModelFor } from '../config/models.js';
|
|
13
|
+
/**
|
|
14
|
+
* Default ignore patterns for file discovery
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_IGNORE = [
|
|
17
|
+
'**/node_modules/**',
|
|
18
|
+
'**/dist/**',
|
|
19
|
+
'**/build/**',
|
|
20
|
+
'**/.git/**',
|
|
21
|
+
'**/vendor/**',
|
|
22
|
+
'**/__pycache__/**',
|
|
23
|
+
'**/target/**',
|
|
24
|
+
'**/bin/**',
|
|
25
|
+
'**/obj/**',
|
|
26
|
+
'**/.next/**',
|
|
27
|
+
'**/.nuxt/**',
|
|
28
|
+
'**/*.min.js',
|
|
29
|
+
'**/*.map',
|
|
30
|
+
'**/package-lock.json',
|
|
31
|
+
'**/yarn.lock',
|
|
32
|
+
'**/pnpm-lock.yaml'
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Default context files to check for drift
|
|
36
|
+
*/
|
|
37
|
+
const DEFAULT_CONTEXT_FILES = [
|
|
38
|
+
'CLAUDE.md',
|
|
39
|
+
'CLAUDE.md.local',
|
|
40
|
+
'AI_CONTEXT.md',
|
|
41
|
+
'.github/copilot-instructions.md',
|
|
42
|
+
'.clinerules',
|
|
43
|
+
'.windsurf/rules.md',
|
|
44
|
+
'.cursorrules',
|
|
45
|
+
'.aider.conf.yml',
|
|
46
|
+
'.continue/config.json',
|
|
47
|
+
'.gemini/config.md',
|
|
48
|
+
'.claude/context/**/*.md',
|
|
49
|
+
'.claude/commands/**/*.md',
|
|
50
|
+
'docs/**/*.md',
|
|
51
|
+
'README.md'
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* Drift Detection Agent
|
|
55
|
+
*
|
|
56
|
+
* Analyzes documentation files and compares them against the actual
|
|
57
|
+
* codebase to detect discrepancies using AI semantic analysis.
|
|
58
|
+
*/
|
|
59
|
+
export class DriftAgent {
|
|
60
|
+
openRouter;
|
|
61
|
+
model;
|
|
62
|
+
strict;
|
|
63
|
+
projectRoot;
|
|
64
|
+
constructor(config) {
|
|
65
|
+
this.openRouter = config.openRouter;
|
|
66
|
+
this.model = config.model || getModelFor('DRIFT_DETECTION');
|
|
67
|
+
this.strict = config.strict ?? false;
|
|
68
|
+
this.projectRoot = config.projectRoot;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Detect drift across all context files
|
|
72
|
+
*/
|
|
73
|
+
async detectDrift(options) {
|
|
74
|
+
const startTime = Date.now();
|
|
75
|
+
const drifts = [];
|
|
76
|
+
let fixed = 0;
|
|
77
|
+
// Get list of files to check
|
|
78
|
+
const filesToCheck = options.paths
|
|
79
|
+
? options.paths
|
|
80
|
+
: await this.getContextFiles();
|
|
81
|
+
// Limit files if specified
|
|
82
|
+
const filesToProcess = options.maxFiles
|
|
83
|
+
? filesToCheck.slice(0, options.maxFiles)
|
|
84
|
+
: filesToCheck;
|
|
85
|
+
// Discover relevant source code for comparison
|
|
86
|
+
const sourceFiles = await this.discoverSourceFiles();
|
|
87
|
+
// Analyze each file for drift
|
|
88
|
+
for (const relativePath of filesToProcess) {
|
|
89
|
+
const drift = await this.checkFileForDrift(relativePath, sourceFiles);
|
|
90
|
+
if (drift) {
|
|
91
|
+
drifts.push(drift);
|
|
92
|
+
if (options.autoFix && drift.suggestion) {
|
|
93
|
+
const didFix = await this.fixDrift(relativePath, drift);
|
|
94
|
+
if (didFix)
|
|
95
|
+
fixed++;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
drifts,
|
|
101
|
+
fixed,
|
|
102
|
+
filesChecked: filesToProcess.length,
|
|
103
|
+
duration: Date.now() - startTime
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Check a single file for drift
|
|
108
|
+
*/
|
|
109
|
+
async checkFileForDrift(relativePath, sourceFiles) {
|
|
110
|
+
const fullPath = path.join(this.projectRoot, relativePath);
|
|
111
|
+
try {
|
|
112
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
113
|
+
// Get relevant source file samples for comparison
|
|
114
|
+
const relevantSource = await this.getRelevantSourceSamples(relativePath, sourceFiles);
|
|
115
|
+
// Use AI to analyze drift
|
|
116
|
+
const analysis = await this.openRouter.chat([
|
|
117
|
+
{
|
|
118
|
+
role: 'system',
|
|
119
|
+
content: this.getDriftDetectionPrompt()
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
role: 'user',
|
|
123
|
+
content: this.buildDriftAnalysisPrompt(relativePath, content, relevantSource)
|
|
124
|
+
}
|
|
125
|
+
], {
|
|
126
|
+
model: this.model,
|
|
127
|
+
temperature: MODEL_CONFIG.ANALYSIS_TEMPERATURE,
|
|
128
|
+
maxTokens: MODEL_CONFIG.DRIFT_MAX_TOKENS
|
|
129
|
+
});
|
|
130
|
+
// Parse JSON response
|
|
131
|
+
const result = this.parseDriftResponse(analysis);
|
|
132
|
+
if (result && result.hasDrift) {
|
|
133
|
+
return {
|
|
134
|
+
file: relativePath,
|
|
135
|
+
severity: result.severity || 'medium',
|
|
136
|
+
expected: result.expected || 'Documentation does not match current code',
|
|
137
|
+
actual: result.actual || 'Code has changed',
|
|
138
|
+
suggestion: result.suggestion,
|
|
139
|
+
line: result.line
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
// If analysis fails, log but don't fail the entire process
|
|
146
|
+
console.error(`Failed to analyze ${relativePath}: ${error instanceof Error ? error.message : error}`);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get the drift detection system prompt
|
|
152
|
+
*/
|
|
153
|
+
getDriftDetectionPrompt() {
|
|
154
|
+
return `You are a drift detection expert for AI context engineering.
|
|
155
|
+
|
|
156
|
+
Your task is to analyze if documentation accurately reflects the current codebase state.
|
|
157
|
+
|
|
158
|
+
Look for these types of drift:
|
|
159
|
+
1. **File references** - Documentation mentions files that don't exist or have moved
|
|
160
|
+
2. **API signatures** - Function/method signatures that have changed
|
|
161
|
+
3. **Architecture changes** - Structural changes not reflected in docs
|
|
162
|
+
4. **Workflow changes** - Process changes not documented
|
|
163
|
+
5. **Configuration changes** - Settings/options that have changed
|
|
164
|
+
|
|
165
|
+
Respond with valid JSON only (no markdown formatting):
|
|
166
|
+
{
|
|
167
|
+
"hasDrift": boolean,
|
|
168
|
+
"severity": "low" | "medium" | "high",
|
|
169
|
+
"expected": "what the documentation claims",
|
|
170
|
+
"actual": "what the actual code has",
|
|
171
|
+
"suggestion": "how to fix the documentation",
|
|
172
|
+
"line": number (if applicable)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
Severity guidelines:
|
|
176
|
+
- high: Breaking changes, missing files, incorrect API signatures
|
|
177
|
+
- medium: Changed workflows, outdated architecture descriptions
|
|
178
|
+
- low: Minor inconsistencies, outdated examples`;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Build the drift analysis prompt for a specific file
|
|
182
|
+
*/
|
|
183
|
+
buildDriftAnalysisPrompt(docPath, docContent, sourceSamples) {
|
|
184
|
+
let prompt = `Check for drift in: ${docPath}\n\n`;
|
|
185
|
+
prompt += `## Documentation Content\n${docContent}\n\n`;
|
|
186
|
+
if (sourceSamples.length > 0) {
|
|
187
|
+
prompt += `## Relevant Source Code Samples\n`;
|
|
188
|
+
prompt += `Use these to verify documentation accuracy:\n\n`;
|
|
189
|
+
for (const sample of sourceSamples.slice(0, 5)) { // Limit to 5 samples
|
|
190
|
+
prompt += `---\n${sample}\n---\n`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
prompt += `\nAnalyze the documentation against the code samples and identify any discrepancies.`;
|
|
194
|
+
return prompt;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Parse the drift detection response
|
|
198
|
+
*/
|
|
199
|
+
parseDriftResponse(response) {
|
|
200
|
+
try {
|
|
201
|
+
// Try direct parse first
|
|
202
|
+
return JSON.parse(response);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Try to extract JSON from response
|
|
206
|
+
const start = response.indexOf('{');
|
|
207
|
+
const end = response.lastIndexOf('}');
|
|
208
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
209
|
+
try {
|
|
210
|
+
const jsonSubstring = response.slice(start, end + 1);
|
|
211
|
+
return JSON.parse(jsonSubstring);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Still failed, return null
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get relevant source code samples for comparison
|
|
222
|
+
*/
|
|
223
|
+
async getRelevantSourceSamples(docPath, sourceFiles) {
|
|
224
|
+
const samples = [];
|
|
225
|
+
const maxSampleSize = 2000; // bytes
|
|
226
|
+
// Extract file references from doc path
|
|
227
|
+
const docName = path.basename(docPath, '.md').toLowerCase();
|
|
228
|
+
// Find related source files
|
|
229
|
+
const relatedFiles = sourceFiles.filter(file => {
|
|
230
|
+
const lowerFile = file.toLowerCase();
|
|
231
|
+
// Files that might be related to this doc
|
|
232
|
+
if (docName.includes('claude') && lowerFile.includes('claude'))
|
|
233
|
+
return true;
|
|
234
|
+
if (docName.includes('readme') && (lowerFile.includes('index') || lowerFile.includes('main')))
|
|
235
|
+
return true;
|
|
236
|
+
return true; // Include all for now, could be smarter
|
|
237
|
+
}).slice(0, 10); // Limit to 10 files
|
|
238
|
+
for (const file of relatedFiles) {
|
|
239
|
+
try {
|
|
240
|
+
const fullPath = path.join(this.projectRoot, file);
|
|
241
|
+
const stats = await fs.stat(fullPath);
|
|
242
|
+
if (stats.isFile() && stats.size < maxSampleSize * 2) {
|
|
243
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
244
|
+
const truncated = content.length > maxSampleSize
|
|
245
|
+
? content.slice(0, maxSampleSize) + '\n... [truncated]'
|
|
246
|
+
: content;
|
|
247
|
+
samples.push(`### ${file}\n${truncated}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// Skip files that can't be read
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return samples;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Discover source files in the project
|
|
258
|
+
*/
|
|
259
|
+
async discoverSourceFiles() {
|
|
260
|
+
const patterns = [
|
|
261
|
+
'**/*.ts',
|
|
262
|
+
'**/*.tsx',
|
|
263
|
+
'**/*.js',
|
|
264
|
+
'**/*.jsx',
|
|
265
|
+
'**/*.py',
|
|
266
|
+
'**/*.go',
|
|
267
|
+
'**/*.rs',
|
|
268
|
+
'**/*.java'
|
|
269
|
+
];
|
|
270
|
+
const allFiles = [];
|
|
271
|
+
for (const pattern of patterns) {
|
|
272
|
+
const files = await glob(pattern, {
|
|
273
|
+
cwd: this.projectRoot,
|
|
274
|
+
ignore: DEFAULT_IGNORE,
|
|
275
|
+
absolute: false
|
|
276
|
+
});
|
|
277
|
+
allFiles.push(...files);
|
|
278
|
+
}
|
|
279
|
+
return allFiles;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Get all context files to check
|
|
283
|
+
*/
|
|
284
|
+
async getContextFiles() {
|
|
285
|
+
const files = [];
|
|
286
|
+
for (const pattern of DEFAULT_CONTEXT_FILES) {
|
|
287
|
+
const matched = await glob(pattern, {
|
|
288
|
+
cwd: this.projectRoot,
|
|
289
|
+
ignore: DEFAULT_IGNORE,
|
|
290
|
+
absolute: false
|
|
291
|
+
});
|
|
292
|
+
files.push(...matched);
|
|
293
|
+
}
|
|
294
|
+
// Deduplicate
|
|
295
|
+
return Array.from(new Set(files));
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Attempt to fix drift in a file
|
|
299
|
+
*/
|
|
300
|
+
async fixDrift(relativePath, drift) {
|
|
301
|
+
// For now, just log what would be fixed
|
|
302
|
+
// Auto-fixing requires careful implementation to avoid breaking things
|
|
303
|
+
console.log(`Would fix drift in ${relativePath}:`);
|
|
304
|
+
console.log(` ${drift.suggestion || 'No suggestion available'}`);
|
|
305
|
+
return false; // Not implementing auto-fix yet
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Close the agent and clean up resources
|
|
309
|
+
*/
|
|
310
|
+
close() {
|
|
311
|
+
// OpenRouterClient has its own cache management
|
|
312
|
+
// Nothing to clean up here for now
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Create a drift agent
|
|
317
|
+
*/
|
|
318
|
+
export function createDriftAgent(config) {
|
|
319
|
+
return new DriftAgent({
|
|
320
|
+
...config,
|
|
321
|
+
projectRoot: process.cwd()
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=drift-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-agent.js","sourceRoot":"","sources":["../../src/agents/drift-agent.ts"],"names":[],"mappings":"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"}
|