@liendev/core 0.19.5
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 +336 -0
- package/dist/config/loader.d.ts +12 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +46 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +20 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +71 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/migration-manager.d.ts +46 -0
- package/dist/config/migration-manager.d.ts.map +1 -0
- package/dist/config/migration-manager.js +119 -0
- package/dist/config/migration-manager.js.map +1 -0
- package/dist/config/migration.d.ts +20 -0
- package/dist/config/migration.d.ts.map +1 -0
- package/dist/config/migration.js +155 -0
- package/dist/config/migration.js.map +1 -0
- package/dist/config/schema.d.ts +101 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +58 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/service.d.ts +122 -0
- package/dist/config/service.d.ts.map +1 -0
- package/dist/config/service.js +477 -0
- package/dist/config/service.js.map +1 -0
- package/dist/constants.d.ts +20 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +43 -0
- package/dist/constants.js.map +1 -0
- package/dist/embeddings/cache.d.ts +45 -0
- package/dist/embeddings/cache.d.ts.map +1 -0
- package/dist/embeddings/cache.js +109 -0
- package/dist/embeddings/cache.js.map +1 -0
- package/dist/embeddings/local.d.ts +10 -0
- package/dist/embeddings/local.d.ts.map +1 -0
- package/dist/embeddings/local.js +63 -0
- package/dist/embeddings/local.js.map +1 -0
- package/dist/embeddings/types.d.ts +9 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +5 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/errors/codes.d.ts +18 -0
- package/dist/errors/codes.d.ts.map +1 -0
- package/dist/errors/codes.js +25 -0
- package/dist/errors/codes.js.map +1 -0
- package/dist/errors/index.d.ts +85 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +134 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/frameworks/detector-service.d.ts +59 -0
- package/dist/frameworks/detector-service.d.ts.map +1 -0
- package/dist/frameworks/detector-service.js +219 -0
- package/dist/frameworks/detector-service.js.map +1 -0
- package/dist/frameworks/laravel/config.d.ts +6 -0
- package/dist/frameworks/laravel/config.d.ts.map +1 -0
- package/dist/frameworks/laravel/config.js +68 -0
- package/dist/frameworks/laravel/config.js.map +1 -0
- package/dist/frameworks/laravel/detector.d.ts +6 -0
- package/dist/frameworks/laravel/detector.d.ts.map +1 -0
- package/dist/frameworks/laravel/detector.js +96 -0
- package/dist/frameworks/laravel/detector.js.map +1 -0
- package/dist/frameworks/nodejs/config.d.ts +6 -0
- package/dist/frameworks/nodejs/config.d.ts.map +1 -0
- package/dist/frameworks/nodejs/config.js +57 -0
- package/dist/frameworks/nodejs/config.js.map +1 -0
- package/dist/frameworks/nodejs/detector.d.ts +6 -0
- package/dist/frameworks/nodejs/detector.d.ts.map +1 -0
- package/dist/frameworks/nodejs/detector.js +77 -0
- package/dist/frameworks/nodejs/detector.js.map +1 -0
- package/dist/frameworks/php/config.d.ts +6 -0
- package/dist/frameworks/php/config.d.ts.map +1 -0
- package/dist/frameworks/php/config.js +53 -0
- package/dist/frameworks/php/config.js.map +1 -0
- package/dist/frameworks/php/detector.d.ts +7 -0
- package/dist/frameworks/php/detector.d.ts.map +1 -0
- package/dist/frameworks/php/detector.js +101 -0
- package/dist/frameworks/php/detector.js.map +1 -0
- package/dist/frameworks/registry.d.ts +20 -0
- package/dist/frameworks/registry.d.ts.map +1 -0
- package/dist/frameworks/registry.js +38 -0
- package/dist/frameworks/registry.js.map +1 -0
- package/dist/frameworks/shopify/config.d.ts +6 -0
- package/dist/frameworks/shopify/config.d.ts.map +1 -0
- package/dist/frameworks/shopify/config.js +50 -0
- package/dist/frameworks/shopify/config.js.map +1 -0
- package/dist/frameworks/shopify/detector.d.ts +6 -0
- package/dist/frameworks/shopify/detector.d.ts.map +1 -0
- package/dist/frameworks/shopify/detector.js +103 -0
- package/dist/frameworks/shopify/detector.js.map +1 -0
- package/dist/frameworks/types.d.ts +51 -0
- package/dist/frameworks/types.d.ts.map +1 -0
- package/dist/frameworks/types.js +21 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/git/tracker.d.ts +56 -0
- package/dist/git/tracker.d.ts.map +1 -0
- package/dist/git/tracker.js +189 -0
- package/dist/git/tracker.js.map +1 -0
- package/dist/git/utils.d.ts +60 -0
- package/dist/git/utils.d.ts.map +1 -0
- package/dist/git/utils.js +152 -0
- package/dist/git/utils.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/ast/chunker.d.ts +28 -0
- package/dist/indexer/ast/chunker.d.ts.map +1 -0
- package/dist/indexer/ast/chunker.js +268 -0
- package/dist/indexer/ast/chunker.js.map +1 -0
- package/dist/indexer/ast/complexity/cognitive.d.ts +16 -0
- package/dist/indexer/ast/complexity/cognitive.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/cognitive.js +106 -0
- package/dist/indexer/ast/complexity/cognitive.js.map +1 -0
- package/dist/indexer/ast/complexity/cyclomatic.d.ts +12 -0
- package/dist/indexer/ast/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/cyclomatic.js +61 -0
- package/dist/indexer/ast/complexity/cyclomatic.js.map +1 -0
- package/dist/indexer/ast/complexity/halstead.d.ts +55 -0
- package/dist/indexer/ast/complexity/halstead.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/halstead.js +290 -0
- package/dist/indexer/ast/complexity/halstead.js.map +1 -0
- package/dist/indexer/ast/complexity/index.d.ts +13 -0
- package/dist/indexer/ast/complexity/index.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/index.js +12 -0
- package/dist/indexer/ast/complexity/index.js.map +1 -0
- package/dist/indexer/ast/parser.d.ts +27 -0
- package/dist/indexer/ast/parser.d.ts.map +1 -0
- package/dist/indexer/ast/parser.js +103 -0
- package/dist/indexer/ast/parser.js.map +1 -0
- package/dist/indexer/ast/symbols.d.ts +17 -0
- package/dist/indexer/ast/symbols.d.ts.map +1 -0
- package/dist/indexer/ast/symbols.js +265 -0
- package/dist/indexer/ast/symbols.js.map +1 -0
- package/dist/indexer/ast/traversers/index.d.ts +19 -0
- package/dist/indexer/ast/traversers/index.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/index.js +42 -0
- package/dist/indexer/ast/traversers/index.js.map +1 -0
- package/dist/indexer/ast/traversers/php.d.ts +21 -0
- package/dist/indexer/ast/traversers/php.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/php.js +67 -0
- package/dist/indexer/ast/traversers/php.js.map +1 -0
- package/dist/indexer/ast/traversers/python.d.ts +28 -0
- package/dist/indexer/ast/traversers/python.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/python.js +67 -0
- package/dist/indexer/ast/traversers/python.js.map +1 -0
- package/dist/indexer/ast/traversers/types.d.ts +98 -0
- package/dist/indexer/ast/traversers/types.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/types.js +2 -0
- package/dist/indexer/ast/traversers/types.js.map +1 -0
- package/dist/indexer/ast/traversers/typescript.d.ts +29 -0
- package/dist/indexer/ast/traversers/typescript.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/typescript.js +88 -0
- package/dist/indexer/ast/traversers/typescript.js.map +1 -0
- package/dist/indexer/ast/types.d.ts +59 -0
- package/dist/indexer/ast/types.d.ts.map +1 -0
- package/dist/indexer/ast/types.js +2 -0
- package/dist/indexer/ast/types.js.map +1 -0
- package/dist/indexer/change-detector.d.ts +17 -0
- package/dist/indexer/change-detector.d.ts.map +1 -0
- package/dist/indexer/change-detector.js +207 -0
- package/dist/indexer/change-detector.js.map +1 -0
- package/dist/indexer/chunk-batch-processor.d.ts +103 -0
- package/dist/indexer/chunk-batch-processor.d.ts.map +1 -0
- package/dist/indexer/chunk-batch-processor.js +179 -0
- package/dist/indexer/chunk-batch-processor.js.map +1 -0
- package/dist/indexer/chunker.d.ts +10 -0
- package/dist/indexer/chunker.d.ts.map +1 -0
- package/dist/indexer/chunker.js +96 -0
- package/dist/indexer/chunker.js.map +1 -0
- package/dist/indexer/dependency-analyzer.d.ts +60 -0
- package/dist/indexer/dependency-analyzer.d.ts.map +1 -0
- package/dist/indexer/dependency-analyzer.js +261 -0
- package/dist/indexer/dependency-analyzer.js.map +1 -0
- package/dist/indexer/incremental.d.ts +47 -0
- package/dist/indexer/incremental.d.ts.map +1 -0
- package/dist/indexer/incremental.js +284 -0
- package/dist/indexer/incremental.js.map +1 -0
- package/dist/indexer/index.d.ts +80 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +364 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/json-template-chunker.d.ts +9 -0
- package/dist/indexer/json-template-chunker.d.ts.map +1 -0
- package/dist/indexer/json-template-chunker.js +83 -0
- package/dist/indexer/json-template-chunker.js.map +1 -0
- package/dist/indexer/liquid-chunker.d.ts +13 -0
- package/dist/indexer/liquid-chunker.d.ts.map +1 -0
- package/dist/indexer/liquid-chunker.js +272 -0
- package/dist/indexer/liquid-chunker.js.map +1 -0
- package/dist/indexer/manifest.d.ts +122 -0
- package/dist/indexer/manifest.d.ts.map +1 -0
- package/dist/indexer/manifest.js +262 -0
- package/dist/indexer/manifest.js.map +1 -0
- package/dist/indexer/progress-tracker.d.ts +35 -0
- package/dist/indexer/progress-tracker.d.ts.map +1 -0
- package/dist/indexer/progress-tracker.js +33 -0
- package/dist/indexer/progress-tracker.js.map +1 -0
- package/dist/indexer/scanner.d.ts +16 -0
- package/dist/indexer/scanner.d.ts.map +1 -0
- package/dist/indexer/scanner.js +159 -0
- package/dist/indexer/scanner.js.map +1 -0
- package/dist/indexer/symbol-extractor.d.ts +18 -0
- package/dist/indexer/symbol-extractor.d.ts.map +1 -0
- package/dist/indexer/symbol-extractor.js +351 -0
- package/dist/indexer/symbol-extractor.js.map +1 -0
- package/dist/indexer/types.d.ts +34 -0
- package/dist/indexer/types.d.ts.map +1 -0
- package/dist/indexer/types.js +2 -0
- package/dist/indexer/types.js.map +1 -0
- package/dist/insights/complexity-analyzer.d.ts +82 -0
- package/dist/insights/complexity-analyzer.d.ts.map +1 -0
- package/dist/insights/complexity-analyzer.js +356 -0
- package/dist/insights/complexity-analyzer.js.map +1 -0
- package/dist/insights/formatters/index.d.ts +11 -0
- package/dist/insights/formatters/index.d.ts.map +1 -0
- package/dist/insights/formatters/index.js +20 -0
- package/dist/insights/formatters/index.js.map +1 -0
- package/dist/insights/formatters/json.d.ts +7 -0
- package/dist/insights/formatters/json.d.ts.map +1 -0
- package/dist/insights/formatters/json.js +14 -0
- package/dist/insights/formatters/json.js.map +1 -0
- package/dist/insights/formatters/sarif.d.ts +6 -0
- package/dist/insights/formatters/sarif.d.ts.map +1 -0
- package/dist/insights/formatters/sarif.js +113 -0
- package/dist/insights/formatters/sarif.js.map +1 -0
- package/dist/insights/formatters/text.d.ts +6 -0
- package/dist/insights/formatters/text.d.ts.map +1 -0
- package/dist/insights/formatters/text.js +154 -0
- package/dist/insights/formatters/text.js.map +1 -0
- package/dist/insights/types.d.ts +73 -0
- package/dist/insights/types.d.ts.map +1 -0
- package/dist/insights/types.js +9 -0
- package/dist/insights/types.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/path-matching.d.ts +69 -0
- package/dist/utils/path-matching.d.ts.map +1 -0
- package/dist/utils/path-matching.js +123 -0
- package/dist/utils/path-matching.js.map +1 -0
- package/dist/utils/result.d.ts +65 -0
- package/dist/utils/result.d.ts.map +1 -0
- package/dist/utils/result.js +67 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/version.d.ts +22 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +28 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/vectordb/batch-insert.d.ts +14 -0
- package/dist/vectordb/batch-insert.d.ts.map +1 -0
- package/dist/vectordb/batch-insert.js +185 -0
- package/dist/vectordb/batch-insert.js.map +1 -0
- package/dist/vectordb/boosting/composer.d.ts +51 -0
- package/dist/vectordb/boosting/composer.d.ts.map +1 -0
- package/dist/vectordb/boosting/composer.js +65 -0
- package/dist/vectordb/boosting/composer.js.map +1 -0
- package/dist/vectordb/boosting/index.d.ts +22 -0
- package/dist/vectordb/boosting/index.d.ts.map +1 -0
- package/dist/vectordb/boosting/index.js +22 -0
- package/dist/vectordb/boosting/index.js.map +1 -0
- package/dist/vectordb/boosting/strategies.d.ts +40 -0
- package/dist/vectordb/boosting/strategies.d.ts.map +1 -0
- package/dist/vectordb/boosting/strategies.js +174 -0
- package/dist/vectordb/boosting/strategies.js.map +1 -0
- package/dist/vectordb/boosting/types.d.ts +20 -0
- package/dist/vectordb/boosting/types.d.ts.map +1 -0
- package/dist/vectordb/boosting/types.js +2 -0
- package/dist/vectordb/boosting/types.js.map +1 -0
- package/dist/vectordb/intent-classifier.d.ts +99 -0
- package/dist/vectordb/intent-classifier.d.ts.map +1 -0
- package/dist/vectordb/intent-classifier.js +193 -0
- package/dist/vectordb/intent-classifier.js.map +1 -0
- package/dist/vectordb/lancedb.d.ts +45 -0
- package/dist/vectordb/lancedb.d.ts.map +1 -0
- package/dist/vectordb/lancedb.js +203 -0
- package/dist/vectordb/lancedb.js.map +1 -0
- package/dist/vectordb/maintenance.d.ts +18 -0
- package/dist/vectordb/maintenance.d.ts.map +1 -0
- package/dist/vectordb/maintenance.js +87 -0
- package/dist/vectordb/maintenance.js.map +1 -0
- package/dist/vectordb/query.d.ts +34 -0
- package/dist/vectordb/query.d.ts.map +1 -0
- package/dist/vectordb/query.js +303 -0
- package/dist/vectordb/query.js.map +1 -0
- package/dist/vectordb/relevance.d.ts +15 -0
- package/dist/vectordb/relevance.d.ts.map +1 -0
- package/dist/vectordb/relevance.js +19 -0
- package/dist/vectordb/relevance.js.map +1 -0
- package/dist/vectordb/types.d.ts +29 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +2 -0
- package/dist/vectordb/types.js.map +1 -0
- package/dist/vectordb/version.d.ts +16 -0
- package/dist/vectordb/version.d.ts.map +1 -0
- package/dist/vectordb/version.js +40 -0
- package/dist/vectordb/version.js.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
# @liendev/core
|
|
2
|
+
|
|
3
|
+
Core indexing and analysis engine for Lien. This package provides the low-level APIs for semantic code search, complexity analysis, and framework detection.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @liendev/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import {
|
|
15
|
+
indexCodebase,
|
|
16
|
+
VectorDB,
|
|
17
|
+
ComplexityAnalyzer,
|
|
18
|
+
loadConfig,
|
|
19
|
+
} from '@liendev/core';
|
|
20
|
+
|
|
21
|
+
// Index a codebase
|
|
22
|
+
await indexCodebase({
|
|
23
|
+
rootDir: '/path/to/project',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Load the vector database
|
|
27
|
+
const db = await VectorDB.load('/path/to/project');
|
|
28
|
+
|
|
29
|
+
// Run semantic search
|
|
30
|
+
const results = await db.search('authentication logic', { limit: 10 });
|
|
31
|
+
|
|
32
|
+
// Analyze complexity
|
|
33
|
+
const config = await loadConfig('/path/to/project');
|
|
34
|
+
const analyzer = new ComplexityAnalyzer(db, config);
|
|
35
|
+
const report = await analyzer.analyze();
|
|
36
|
+
|
|
37
|
+
console.log(`Found ${report.summary.totalViolations} complexity violations`);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API Reference
|
|
41
|
+
|
|
42
|
+
### Indexing
|
|
43
|
+
|
|
44
|
+
#### `indexCodebase(options: IndexingOptions): Promise<IndexingResult>`
|
|
45
|
+
|
|
46
|
+
Index a codebase for semantic search.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
interface IndexingOptions {
|
|
50
|
+
rootDir?: string; // Root directory (default: cwd)
|
|
51
|
+
force?: boolean; // Force full reindex (default: false)
|
|
52
|
+
verbose?: boolean; // Verbose output (default: false)
|
|
53
|
+
embeddings?: EmbeddingService; // Pre-initialized embeddings
|
|
54
|
+
config?: LienConfig; // Pre-loaded config
|
|
55
|
+
onProgress?: (progress: IndexingProgress) => void; // Progress callback
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface IndexingResult {
|
|
59
|
+
filesIndexed: number;
|
|
60
|
+
chunksCreated: number;
|
|
61
|
+
timeMs: number;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Example:**
|
|
66
|
+
```typescript
|
|
67
|
+
const result = await indexCodebase({
|
|
68
|
+
rootDir: './my-project',
|
|
69
|
+
force: true,
|
|
70
|
+
onProgress: (progress) => {
|
|
71
|
+
console.log(`Indexed ${progress.filesCompleted}/${progress.totalFiles} files`);
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
console.log(`Indexed ${result.filesIndexed} files in ${result.timeMs}ms`);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Vector Database
|
|
79
|
+
|
|
80
|
+
#### `VectorDB.load(rootDir: string): Promise<VectorDB>`
|
|
81
|
+
|
|
82
|
+
Load an existing vector database.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const db = await VectorDB.load('./my-project');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### `db.search(query: string, options?: SearchOptions): Promise<SearchResult[]>`
|
|
89
|
+
|
|
90
|
+
Perform semantic search.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
interface SearchOptions {
|
|
94
|
+
limit?: number; // Max results (default: 5)
|
|
95
|
+
minScore?: number; // Min similarity score (default: 0.5)
|
|
96
|
+
fileFilter?: string[]; // Filter by file paths
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const results = await db.search('error handling', {
|
|
100
|
+
limit: 10,
|
|
101
|
+
minScore: 0.7,
|
|
102
|
+
fileFilter: ['src/utils/**'],
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Complexity Analysis
|
|
107
|
+
|
|
108
|
+
#### `new ComplexityAnalyzer(db: VectorDB, config: LienConfig)`
|
|
109
|
+
|
|
110
|
+
Create a complexity analyzer.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const config = await loadConfig('./my-project');
|
|
114
|
+
const analyzer = new ComplexityAnalyzer(db, config);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `analyzer.analyze(files?: string[]): Promise<ComplexityReport>`
|
|
118
|
+
|
|
119
|
+
Analyze code complexity. Optionally filter to specific files.
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// Analyze all files
|
|
123
|
+
const report = await analyzer.analyze();
|
|
124
|
+
|
|
125
|
+
// Analyze specific files
|
|
126
|
+
const report = await analyzer.analyze(['src/utils.ts', 'src/parser.ts']);
|
|
127
|
+
|
|
128
|
+
console.log(`${report.summary.totalViolations} violations found`);
|
|
129
|
+
console.log(`Average complexity: ${report.summary.avgComplexity}`);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Complexity Report Structure
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
interface ComplexityReport {
|
|
136
|
+
summary: {
|
|
137
|
+
filesAnalyzed: number;
|
|
138
|
+
totalViolations: number;
|
|
139
|
+
bySeverity: { error: number; warning: number };
|
|
140
|
+
avgComplexity: number;
|
|
141
|
+
maxComplexity: number;
|
|
142
|
+
};
|
|
143
|
+
files: Record<string, FileComplexityData>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface FileComplexityData {
|
|
147
|
+
violations: ComplexityViolation[];
|
|
148
|
+
dependents: string[]; // Files that import this file
|
|
149
|
+
testAssociations: string[]; // Test files covering this file
|
|
150
|
+
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface ComplexityViolation {
|
|
154
|
+
filepath: string;
|
|
155
|
+
startLine: number;
|
|
156
|
+
endLine: number;
|
|
157
|
+
symbolName: string;
|
|
158
|
+
symbolType: 'function' | 'method' | 'class' | 'file';
|
|
159
|
+
language: string;
|
|
160
|
+
complexity: number;
|
|
161
|
+
threshold: number;
|
|
162
|
+
severity: 'warning' | 'error';
|
|
163
|
+
metricType: 'cyclomatic' | 'cognitive' | 'halstead_effort' | 'halstead_bugs';
|
|
164
|
+
halsteadDetails?: HalsteadDetails;
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Configuration
|
|
169
|
+
|
|
170
|
+
#### `loadConfig(rootDir?: string): Promise<LienConfig>`
|
|
171
|
+
|
|
172
|
+
Load Lien configuration from `.lien.config.json`.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const config = await loadConfig('./my-project');
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### `saveConfig(rootDir: string, config: LienConfig): Promise<void>`
|
|
179
|
+
|
|
180
|
+
Save configuration to `.lien.config.json`.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
await saveConfig('./my-project', {
|
|
184
|
+
...config,
|
|
185
|
+
complexity: {
|
|
186
|
+
enabled: true,
|
|
187
|
+
thresholds: {
|
|
188
|
+
testPaths: 15,
|
|
189
|
+
mentalLoad: 15,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### `createDefaultConfig(): LienConfig`
|
|
196
|
+
|
|
197
|
+
Create a default configuration.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
const config = createDefaultConfig();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Framework Detection
|
|
204
|
+
|
|
205
|
+
#### `detectAllFrameworks(rootDir: string): Promise<FrameworkInstance[]>`
|
|
206
|
+
|
|
207
|
+
Detect frameworks in a project.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { detectAllFrameworks } from '@liendev/core';
|
|
211
|
+
|
|
212
|
+
const frameworks = await detectAllFrameworks('./my-project');
|
|
213
|
+
|
|
214
|
+
for (const fw of frameworks) {
|
|
215
|
+
console.log(`Found ${fw.name} at ${fw.path}`);
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Git Utilities
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import {
|
|
223
|
+
isGitRepo,
|
|
224
|
+
getCurrentBranch,
|
|
225
|
+
getCurrentCommit,
|
|
226
|
+
getChangedFiles,
|
|
227
|
+
} from '@liendev/core';
|
|
228
|
+
|
|
229
|
+
const isGit = await isGitRepo('./my-project');
|
|
230
|
+
const branch = await getCurrentBranch('./my-project');
|
|
231
|
+
const commit = await getCurrentCommit('./my-project');
|
|
232
|
+
const changed = await getChangedFiles('./my-project');
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Advanced Usage
|
|
236
|
+
|
|
237
|
+
### Warm Workers (Cloud/Action Use)
|
|
238
|
+
|
|
239
|
+
Keep embeddings loaded between requests for better performance:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { LocalEmbeddings, indexCodebase } from '@liendev/core';
|
|
243
|
+
|
|
244
|
+
// Initialize once
|
|
245
|
+
const embeddings = new LocalEmbeddings();
|
|
246
|
+
await embeddings.initialize();
|
|
247
|
+
|
|
248
|
+
// Reuse across multiple indexing operations
|
|
249
|
+
for (const project of projects) {
|
|
250
|
+
await indexCodebase({
|
|
251
|
+
rootDir: project.path,
|
|
252
|
+
embeddings, // Reuse warm embeddings
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Custom Embedding Service
|
|
258
|
+
|
|
259
|
+
Implement `EmbeddingService` interface for custom embeddings:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
interface EmbeddingService {
|
|
263
|
+
initialize(): Promise<void>;
|
|
264
|
+
embed(texts: string[]): Promise<number[][]>;
|
|
265
|
+
getDimension(): number;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
class CustomEmbeddings implements EmbeddingService {
|
|
269
|
+
async initialize() { /* ... */ }
|
|
270
|
+
async embed(texts: string[]) { /* ... */ }
|
|
271
|
+
getDimension() { return 768; }
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
await indexCodebase({
|
|
275
|
+
embeddings: new CustomEmbeddings(),
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Progress Tracking
|
|
280
|
+
|
|
281
|
+
Monitor indexing progress in real-time:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
await indexCodebase({
|
|
285
|
+
rootDir: './large-project',
|
|
286
|
+
onProgress: (progress) => {
|
|
287
|
+
const pct = (progress.filesCompleted / progress.totalFiles * 100).toFixed(1);
|
|
288
|
+
console.log(`[${pct}%] ${progress.filesCompleted}/${progress.totalFiles} files`);
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Supported Languages
|
|
294
|
+
|
|
295
|
+
- TypeScript / JavaScript
|
|
296
|
+
- Python
|
|
297
|
+
- PHP
|
|
298
|
+
|
|
299
|
+
More languages coming soon!
|
|
300
|
+
|
|
301
|
+
## Performance
|
|
302
|
+
|
|
303
|
+
- **Embeddings**: Local transformer model (~50ms per chunk)
|
|
304
|
+
- **Vector DB**: LanceDB (Apache Arrow, SIMD-optimized)
|
|
305
|
+
- **Chunking**: AST-based with fallback to line-based
|
|
306
|
+
- **Indexing**: ~1000 LOC/sec on typical hardware
|
|
307
|
+
|
|
308
|
+
## Architecture
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
@liendev/core
|
|
312
|
+
āāā indexer/ # Code scanning, chunking, AST parsing
|
|
313
|
+
āāā embeddings/ # Local embeddings (transformers.js)
|
|
314
|
+
āāā vectordb/ # LanceDB wrapper
|
|
315
|
+
āāā insights/ # Complexity analysis
|
|
316
|
+
āāā config/ # Configuration management
|
|
317
|
+
āāā frameworks/ # Framework detection
|
|
318
|
+
āāā git/ # Git utilities
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Who Uses This?
|
|
322
|
+
|
|
323
|
+
- **@liendev/cli** - CLI and MCP server
|
|
324
|
+
- **@liendev/action** - GitHub Action
|
|
325
|
+
- **@liendev/cloud** - Cloud backend (private)
|
|
326
|
+
- **Third-party integrations** - Your custom tools!
|
|
327
|
+
|
|
328
|
+
## License
|
|
329
|
+
|
|
330
|
+
MIT
|
|
331
|
+
|
|
332
|
+
## Links
|
|
333
|
+
|
|
334
|
+
- [Main Lien Repository](https://github.com/getlien/lien)
|
|
335
|
+
- [Documentation](https://lien.dev)
|
|
336
|
+
- [Issues](https://github.com/getlien/lien/issues)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { LienConfig } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated Use ConfigService.load() instead. This function is kept for backward compatibility.
|
|
4
|
+
* @see ConfigService
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadConfig(rootDir?: string): Promise<LienConfig>;
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated Use ConfigService.exists() instead. This function is kept for backward compatibility.
|
|
9
|
+
* @see ConfigService
|
|
10
|
+
*/
|
|
11
|
+
export declare function configExists(rootDir?: string): Promise<boolean>;
|
|
12
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAiB,MAAM,aAAa,CAAC;AAIxD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAuBrF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAQpF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { defaultConfig } from './schema.js';
|
|
4
|
+
import { deepMergeConfig } from './merge.js';
|
|
5
|
+
import { MigrationManager } from './migration-manager.js';
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use ConfigService.load() instead. This function is kept for backward compatibility.
|
|
8
|
+
* @see ConfigService
|
|
9
|
+
*/
|
|
10
|
+
export async function loadConfig(rootDir = process.cwd()) {
|
|
11
|
+
const configPath = path.join(rootDir, '.lien.config.json');
|
|
12
|
+
try {
|
|
13
|
+
const configContent = await fs.readFile(configPath, 'utf-8');
|
|
14
|
+
const userConfig = JSON.parse(configContent);
|
|
15
|
+
// Check if migration is needed
|
|
16
|
+
const migrationManager = new MigrationManager(rootDir);
|
|
17
|
+
if (await migrationManager.needsMigration()) {
|
|
18
|
+
console.log('š Migrating config from v0.2.0 to v0.3.0...');
|
|
19
|
+
return await migrationManager.autoMigrate();
|
|
20
|
+
}
|
|
21
|
+
// Use the shared merge function for consistency
|
|
22
|
+
return deepMergeConfig(defaultConfig, userConfig);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error.code === 'ENOENT') {
|
|
26
|
+
// Config doesn't exist, return defaults
|
|
27
|
+
return defaultConfig;
|
|
28
|
+
}
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use ConfigService.exists() instead. This function is kept for backward compatibility.
|
|
34
|
+
* @see ConfigService
|
|
35
|
+
*/
|
|
36
|
+
export async function configExists(rootDir = process.cwd()) {
|
|
37
|
+
const configPath = path.join(rootDir, '.lien.config.json');
|
|
38
|
+
try {
|
|
39
|
+
await fs.access(configPath);
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAc,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB,OAAO,CAAC,GAAG,EAAE;IAC9D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAE3D,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAE7C,+BAA+B;QAC/B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,MAAM,gBAAgB,CAAC,cAAc,EAAE,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;YAC5D,OAAO,MAAM,gBAAgB,CAAC,WAAW,EAAE,CAAC;QAC9C,CAAC;QAED,gDAAgD;QAChD,OAAO,eAAe,CAAC,aAAa,EAAE,UAAiC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,wCAAwC;YACxC,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB,OAAO,CAAC,GAAG,EAAE;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LienConfig } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Deep merges user config with defaults, preserving user customizations.
|
|
4
|
+
* User values always take precedence over defaults.
|
|
5
|
+
*
|
|
6
|
+
* @param defaults - The default configuration
|
|
7
|
+
* @param user - The user's partial configuration
|
|
8
|
+
* @returns Complete merged configuration
|
|
9
|
+
*/
|
|
10
|
+
export declare function deepMergeConfig(defaults: LienConfig, user: Partial<LienConfig>): LienConfig;
|
|
11
|
+
/**
|
|
12
|
+
* Detects new fields that exist in the 'after' config but not in the 'before' config.
|
|
13
|
+
* Returns a list of human-readable field paths.
|
|
14
|
+
*
|
|
15
|
+
* @param before - The existing config (potentially missing fields)
|
|
16
|
+
* @param after - The complete config with all fields
|
|
17
|
+
* @returns Array of new field paths (e.g., ["mcp.autoIndexOnFirstRun", "gitDetection"])
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectNewFields(before: Record<string, any>, after: Record<string, any>): string[];
|
|
20
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAgC3F;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,CAwBjG"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep merges user config with defaults, preserving user customizations.
|
|
3
|
+
* User values always take precedence over defaults.
|
|
4
|
+
*
|
|
5
|
+
* @param defaults - The default configuration
|
|
6
|
+
* @param user - The user's partial configuration
|
|
7
|
+
* @returns Complete merged configuration
|
|
8
|
+
*/
|
|
9
|
+
export function deepMergeConfig(defaults, user) {
|
|
10
|
+
return {
|
|
11
|
+
version: user.version ?? defaults.version,
|
|
12
|
+
core: {
|
|
13
|
+
...defaults.core,
|
|
14
|
+
...user.core,
|
|
15
|
+
},
|
|
16
|
+
chunking: {
|
|
17
|
+
...defaults.chunking,
|
|
18
|
+
...user.chunking,
|
|
19
|
+
},
|
|
20
|
+
mcp: {
|
|
21
|
+
...defaults.mcp,
|
|
22
|
+
...user.mcp,
|
|
23
|
+
},
|
|
24
|
+
gitDetection: {
|
|
25
|
+
...defaults.gitDetection,
|
|
26
|
+
...user.gitDetection,
|
|
27
|
+
},
|
|
28
|
+
fileWatching: {
|
|
29
|
+
...defaults.fileWatching,
|
|
30
|
+
...user.fileWatching,
|
|
31
|
+
},
|
|
32
|
+
complexity: user.complexity ? {
|
|
33
|
+
enabled: user.complexity.enabled ?? defaults.complexity?.enabled ?? true,
|
|
34
|
+
thresholds: {
|
|
35
|
+
...defaults.complexity?.thresholds,
|
|
36
|
+
...(user.complexity.thresholds || {}),
|
|
37
|
+
},
|
|
38
|
+
} : defaults.complexity,
|
|
39
|
+
frameworks: user.frameworks ?? defaults.frameworks,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Detects new fields that exist in the 'after' config but not in the 'before' config.
|
|
44
|
+
* Returns a list of human-readable field paths.
|
|
45
|
+
*
|
|
46
|
+
* @param before - The existing config (potentially missing fields)
|
|
47
|
+
* @param after - The complete config with all fields
|
|
48
|
+
* @returns Array of new field paths (e.g., ["mcp.autoIndexOnFirstRun", "gitDetection"])
|
|
49
|
+
*/
|
|
50
|
+
export function detectNewFields(before, after) {
|
|
51
|
+
const newFields = [];
|
|
52
|
+
// Check top-level sections
|
|
53
|
+
for (const key of Object.keys(after)) {
|
|
54
|
+
if (!(key in before)) {
|
|
55
|
+
newFields.push(key);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Check nested fields for object sections
|
|
59
|
+
if (typeof after[key] === 'object' && after[key] !== null && !Array.isArray(after[key])) {
|
|
60
|
+
const beforeSection = before[key] || {};
|
|
61
|
+
const afterSection = after[key];
|
|
62
|
+
for (const nestedKey of Object.keys(afterSection)) {
|
|
63
|
+
if (!(nestedKey in beforeSection)) {
|
|
64
|
+
newFields.push(`${key}.${nestedKey}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return newFields;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/config/merge.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,QAAoB,EAAE,IAAyB;IAC7E,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;QACzC,IAAI,EAAE;YACJ,GAAG,QAAQ,CAAC,IAAI;YAChB,GAAG,IAAI,CAAC,IAAI;SACb;QACD,QAAQ,EAAE;YACR,GAAG,QAAQ,CAAC,QAAQ;YACpB,GAAG,IAAI,CAAC,QAAQ;SACjB;QACD,GAAG,EAAE;YACH,GAAG,QAAQ,CAAC,GAAG;YACf,GAAG,IAAI,CAAC,GAAG;SACZ;QACD,YAAY,EAAE;YACZ,GAAG,QAAQ,CAAC,YAAY;YACxB,GAAG,IAAI,CAAC,YAAY;SACrB;QACD,YAAY,EAAE;YACZ,GAAG,QAAQ,CAAC,YAAY;YACxB,GAAG,IAAI,CAAC,YAAY;SACrB;QACD,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;YAC5B,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,QAAQ,CAAC,UAAU,EAAE,OAAO,IAAI,IAAI;YACxE,UAAU,EAAE;gBACV,GAAG,QAAQ,CAAC,UAAU,EAAE,UAAU;gBAClC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;aACtC;SACF,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;KACnD,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,MAA2B,EAAE,KAA0B;IACrF,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,2BAA2B;IAC3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAC;YACrB,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QAED,0CAA0C;QAC1C,IAAI,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxF,MAAM,aAAa,GAAI,MAAM,CAAC,GAAG,CAAyB,IAAI,EAAE,CAAC;YACjE,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAwB,CAAC;YAEvD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClD,IAAI,CAAC,CAAC,SAAS,IAAI,aAAa,CAAC,EAAE,CAAC;oBAClC,SAAS,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LienConfig } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* Result of a migration operation
|
|
4
|
+
*/
|
|
5
|
+
export interface MigrationResult {
|
|
6
|
+
migrated: boolean;
|
|
7
|
+
backupPath?: string;
|
|
8
|
+
config: LienConfig;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Centralized migration orchestration service
|
|
12
|
+
*
|
|
13
|
+
* Handles all config migration scenarios:
|
|
14
|
+
* - Auto-migration during config loading
|
|
15
|
+
* - Interactive upgrade via CLI
|
|
16
|
+
* - Migration status checking
|
|
17
|
+
*/
|
|
18
|
+
export declare class MigrationManager {
|
|
19
|
+
private readonly rootDir;
|
|
20
|
+
private readonly targetVersion;
|
|
21
|
+
constructor(rootDir?: string, targetVersion?: string);
|
|
22
|
+
/**
|
|
23
|
+
* Get the config file path
|
|
24
|
+
*/
|
|
25
|
+
private getConfigPath;
|
|
26
|
+
/**
|
|
27
|
+
* Check if the current config needs migration
|
|
28
|
+
*/
|
|
29
|
+
needsMigration(): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Perform silent migration (for auto-migration during load)
|
|
32
|
+
* Returns the migrated config without user interaction
|
|
33
|
+
*/
|
|
34
|
+
autoMigrate(): Promise<LienConfig>;
|
|
35
|
+
/**
|
|
36
|
+
* Perform interactive upgrade (for CLI upgrade command)
|
|
37
|
+
* Provides detailed feedback and handles edge cases
|
|
38
|
+
*/
|
|
39
|
+
upgradeInteractive(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Perform migration and return result
|
|
42
|
+
* Used when programmatic access to migration result is needed
|
|
43
|
+
*/
|
|
44
|
+
migrate(): Promise<MigrationResult>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=migration-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-manager.d.ts","sourceRoot":"","sources":["../../src/config/migration-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAiB,MAAM,aAAa,CAAC;AAKxD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBADb,OAAO,GAAE,MAAsB,EAC/B,aAAa,GAAE,MAA+B;IAGjE;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAYxC;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,UAAU,CAAC;IAYxC;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA+DzC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;CAG1C"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { defaultConfig } from './schema.js';
|
|
5
|
+
import { needsMigration, migrateConfig, migrateConfigFile } from './migration.js';
|
|
6
|
+
import { deepMergeConfig, detectNewFields } from './merge.js';
|
|
7
|
+
import { CURRENT_CONFIG_VERSION } from '../constants.js';
|
|
8
|
+
/**
|
|
9
|
+
* Centralized migration orchestration service
|
|
10
|
+
*
|
|
11
|
+
* Handles all config migration scenarios:
|
|
12
|
+
* - Auto-migration during config loading
|
|
13
|
+
* - Interactive upgrade via CLI
|
|
14
|
+
* - Migration status checking
|
|
15
|
+
*/
|
|
16
|
+
export class MigrationManager {
|
|
17
|
+
rootDir;
|
|
18
|
+
targetVersion;
|
|
19
|
+
constructor(rootDir = process.cwd(), targetVersion = CURRENT_CONFIG_VERSION) {
|
|
20
|
+
this.rootDir = rootDir;
|
|
21
|
+
this.targetVersion = targetVersion;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get the config file path
|
|
25
|
+
*/
|
|
26
|
+
getConfigPath() {
|
|
27
|
+
return path.join(this.rootDir, '.lien.config.json');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if the current config needs migration
|
|
31
|
+
*/
|
|
32
|
+
async needsMigration() {
|
|
33
|
+
try {
|
|
34
|
+
const configPath = this.getConfigPath();
|
|
35
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
36
|
+
const config = JSON.parse(content);
|
|
37
|
+
return needsMigration(config);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
// If config doesn't exist or can't be read, no migration needed
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Perform silent migration (for auto-migration during load)
|
|
46
|
+
* Returns the migrated config without user interaction
|
|
47
|
+
*/
|
|
48
|
+
async autoMigrate() {
|
|
49
|
+
const result = await migrateConfigFile(this.rootDir);
|
|
50
|
+
if (result.migrated && result.backupPath) {
|
|
51
|
+
const backupFilename = path.basename(result.backupPath);
|
|
52
|
+
console.log(`ā
Migration complete! Backup saved as ${backupFilename}`);
|
|
53
|
+
console.log('š Your config now uses the framework-based structure.');
|
|
54
|
+
}
|
|
55
|
+
return result.config;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Perform interactive upgrade (for CLI upgrade command)
|
|
59
|
+
* Provides detailed feedback and handles edge cases
|
|
60
|
+
*/
|
|
61
|
+
async upgradeInteractive() {
|
|
62
|
+
const configPath = this.getConfigPath();
|
|
63
|
+
try {
|
|
64
|
+
// 1. Read existing config
|
|
65
|
+
const existingContent = await fs.readFile(configPath, 'utf-8');
|
|
66
|
+
const existingConfig = JSON.parse(existingContent);
|
|
67
|
+
// 2. Check if any changes are needed
|
|
68
|
+
const migrationNeeded = needsMigration(existingConfig);
|
|
69
|
+
const newFields = migrationNeeded ? [] : detectNewFields(existingConfig, defaultConfig);
|
|
70
|
+
const hasChanges = migrationNeeded || newFields.length > 0;
|
|
71
|
+
if (!hasChanges) {
|
|
72
|
+
console.log(chalk.green('ā Config is already up to date'));
|
|
73
|
+
console.log(chalk.dim('No changes needed'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
// 3. Backup existing config (only if changes are needed)
|
|
77
|
+
const backupPath = `${configPath}.backup`;
|
|
78
|
+
await fs.copyFile(configPath, backupPath);
|
|
79
|
+
// 4. Perform upgrade
|
|
80
|
+
let upgradedConfig;
|
|
81
|
+
let migrated = false;
|
|
82
|
+
if (migrationNeeded) {
|
|
83
|
+
console.log(chalk.blue(`š Migrating config from v0.2.0 to v${this.targetVersion}...`));
|
|
84
|
+
upgradedConfig = migrateConfig(existingConfig, this.targetVersion);
|
|
85
|
+
migrated = true;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Just merge with defaults for current version configs
|
|
89
|
+
upgradedConfig = deepMergeConfig(defaultConfig, existingConfig);
|
|
90
|
+
console.log(chalk.dim('\nNew options added:'));
|
|
91
|
+
newFields.forEach(field => console.log(chalk.dim(' ā¢'), chalk.bold(field)));
|
|
92
|
+
}
|
|
93
|
+
// 5. Write upgraded config
|
|
94
|
+
await fs.writeFile(configPath, JSON.stringify(upgradedConfig, null, 2) + '\n', 'utf-8');
|
|
95
|
+
// 6. Show results
|
|
96
|
+
console.log(chalk.green('ā Config upgraded successfully'));
|
|
97
|
+
console.log(chalk.dim('Backup saved to:'), backupPath);
|
|
98
|
+
if (migrated) {
|
|
99
|
+
console.log(chalk.dim('\nš Your config now uses the framework-based structure.'));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error.code === 'ENOENT') {
|
|
104
|
+
console.log(chalk.red('Error: No config file found'));
|
|
105
|
+
console.log(chalk.dim('Run'), chalk.bold('lien init'), chalk.dim('to create a config file'));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Perform migration and return result
|
|
113
|
+
* Used when programmatic access to migration result is needed
|
|
114
|
+
*/
|
|
115
|
+
async migrate() {
|
|
116
|
+
return migrateConfigFile(this.rootDir);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=migration-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-manager.js","sourceRoot":"","sources":["../../src/config/migration-manager.ts"],"names":[],"mappings":"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"}
|