@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.
Files changed (298) hide show
  1. package/README.md +336 -0
  2. package/dist/config/loader.d.ts +12 -0
  3. package/dist/config/loader.d.ts.map +1 -0
  4. package/dist/config/loader.js +46 -0
  5. package/dist/config/loader.js.map +1 -0
  6. package/dist/config/merge.d.ts +20 -0
  7. package/dist/config/merge.d.ts.map +1 -0
  8. package/dist/config/merge.js +71 -0
  9. package/dist/config/merge.js.map +1 -0
  10. package/dist/config/migration-manager.d.ts +46 -0
  11. package/dist/config/migration-manager.d.ts.map +1 -0
  12. package/dist/config/migration-manager.js +119 -0
  13. package/dist/config/migration-manager.js.map +1 -0
  14. package/dist/config/migration.d.ts +20 -0
  15. package/dist/config/migration.d.ts.map +1 -0
  16. package/dist/config/migration.js +155 -0
  17. package/dist/config/migration.js.map +1 -0
  18. package/dist/config/schema.d.ts +101 -0
  19. package/dist/config/schema.d.ts.map +1 -0
  20. package/dist/config/schema.js +58 -0
  21. package/dist/config/schema.js.map +1 -0
  22. package/dist/config/service.d.ts +122 -0
  23. package/dist/config/service.d.ts.map +1 -0
  24. package/dist/config/service.js +477 -0
  25. package/dist/config/service.js.map +1 -0
  26. package/dist/constants.d.ts +20 -0
  27. package/dist/constants.d.ts.map +1 -0
  28. package/dist/constants.js +43 -0
  29. package/dist/constants.js.map +1 -0
  30. package/dist/embeddings/cache.d.ts +45 -0
  31. package/dist/embeddings/cache.d.ts.map +1 -0
  32. package/dist/embeddings/cache.js +109 -0
  33. package/dist/embeddings/cache.js.map +1 -0
  34. package/dist/embeddings/local.d.ts +10 -0
  35. package/dist/embeddings/local.d.ts.map +1 -0
  36. package/dist/embeddings/local.js +63 -0
  37. package/dist/embeddings/local.js.map +1 -0
  38. package/dist/embeddings/types.d.ts +9 -0
  39. package/dist/embeddings/types.d.ts.map +1 -0
  40. package/dist/embeddings/types.js +5 -0
  41. package/dist/embeddings/types.js.map +1 -0
  42. package/dist/errors/codes.d.ts +18 -0
  43. package/dist/errors/codes.d.ts.map +1 -0
  44. package/dist/errors/codes.js +25 -0
  45. package/dist/errors/codes.js.map +1 -0
  46. package/dist/errors/index.d.ts +85 -0
  47. package/dist/errors/index.d.ts.map +1 -0
  48. package/dist/errors/index.js +134 -0
  49. package/dist/errors/index.js.map +1 -0
  50. package/dist/frameworks/detector-service.d.ts +59 -0
  51. package/dist/frameworks/detector-service.d.ts.map +1 -0
  52. package/dist/frameworks/detector-service.js +219 -0
  53. package/dist/frameworks/detector-service.js.map +1 -0
  54. package/dist/frameworks/laravel/config.d.ts +6 -0
  55. package/dist/frameworks/laravel/config.d.ts.map +1 -0
  56. package/dist/frameworks/laravel/config.js +68 -0
  57. package/dist/frameworks/laravel/config.js.map +1 -0
  58. package/dist/frameworks/laravel/detector.d.ts +6 -0
  59. package/dist/frameworks/laravel/detector.d.ts.map +1 -0
  60. package/dist/frameworks/laravel/detector.js +96 -0
  61. package/dist/frameworks/laravel/detector.js.map +1 -0
  62. package/dist/frameworks/nodejs/config.d.ts +6 -0
  63. package/dist/frameworks/nodejs/config.d.ts.map +1 -0
  64. package/dist/frameworks/nodejs/config.js +57 -0
  65. package/dist/frameworks/nodejs/config.js.map +1 -0
  66. package/dist/frameworks/nodejs/detector.d.ts +6 -0
  67. package/dist/frameworks/nodejs/detector.d.ts.map +1 -0
  68. package/dist/frameworks/nodejs/detector.js +77 -0
  69. package/dist/frameworks/nodejs/detector.js.map +1 -0
  70. package/dist/frameworks/php/config.d.ts +6 -0
  71. package/dist/frameworks/php/config.d.ts.map +1 -0
  72. package/dist/frameworks/php/config.js +53 -0
  73. package/dist/frameworks/php/config.js.map +1 -0
  74. package/dist/frameworks/php/detector.d.ts +7 -0
  75. package/dist/frameworks/php/detector.d.ts.map +1 -0
  76. package/dist/frameworks/php/detector.js +101 -0
  77. package/dist/frameworks/php/detector.js.map +1 -0
  78. package/dist/frameworks/registry.d.ts +20 -0
  79. package/dist/frameworks/registry.d.ts.map +1 -0
  80. package/dist/frameworks/registry.js +38 -0
  81. package/dist/frameworks/registry.js.map +1 -0
  82. package/dist/frameworks/shopify/config.d.ts +6 -0
  83. package/dist/frameworks/shopify/config.d.ts.map +1 -0
  84. package/dist/frameworks/shopify/config.js +50 -0
  85. package/dist/frameworks/shopify/config.js.map +1 -0
  86. package/dist/frameworks/shopify/detector.d.ts +6 -0
  87. package/dist/frameworks/shopify/detector.d.ts.map +1 -0
  88. package/dist/frameworks/shopify/detector.js +103 -0
  89. package/dist/frameworks/shopify/detector.js.map +1 -0
  90. package/dist/frameworks/types.d.ts +51 -0
  91. package/dist/frameworks/types.d.ts.map +1 -0
  92. package/dist/frameworks/types.js +21 -0
  93. package/dist/frameworks/types.js.map +1 -0
  94. package/dist/git/tracker.d.ts +56 -0
  95. package/dist/git/tracker.d.ts.map +1 -0
  96. package/dist/git/tracker.js +189 -0
  97. package/dist/git/tracker.js.map +1 -0
  98. package/dist/git/utils.d.ts +60 -0
  99. package/dist/git/utils.d.ts.map +1 -0
  100. package/dist/git/utils.js +152 -0
  101. package/dist/git/utils.js.map +1 -0
  102. package/dist/index.d.ts +77 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +95 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/indexer/ast/chunker.d.ts +28 -0
  107. package/dist/indexer/ast/chunker.d.ts.map +1 -0
  108. package/dist/indexer/ast/chunker.js +268 -0
  109. package/dist/indexer/ast/chunker.js.map +1 -0
  110. package/dist/indexer/ast/complexity/cognitive.d.ts +16 -0
  111. package/dist/indexer/ast/complexity/cognitive.d.ts.map +1 -0
  112. package/dist/indexer/ast/complexity/cognitive.js +106 -0
  113. package/dist/indexer/ast/complexity/cognitive.js.map +1 -0
  114. package/dist/indexer/ast/complexity/cyclomatic.d.ts +12 -0
  115. package/dist/indexer/ast/complexity/cyclomatic.d.ts.map +1 -0
  116. package/dist/indexer/ast/complexity/cyclomatic.js +61 -0
  117. package/dist/indexer/ast/complexity/cyclomatic.js.map +1 -0
  118. package/dist/indexer/ast/complexity/halstead.d.ts +55 -0
  119. package/dist/indexer/ast/complexity/halstead.d.ts.map +1 -0
  120. package/dist/indexer/ast/complexity/halstead.js +290 -0
  121. package/dist/indexer/ast/complexity/halstead.js.map +1 -0
  122. package/dist/indexer/ast/complexity/index.d.ts +13 -0
  123. package/dist/indexer/ast/complexity/index.d.ts.map +1 -0
  124. package/dist/indexer/ast/complexity/index.js +12 -0
  125. package/dist/indexer/ast/complexity/index.js.map +1 -0
  126. package/dist/indexer/ast/parser.d.ts +27 -0
  127. package/dist/indexer/ast/parser.d.ts.map +1 -0
  128. package/dist/indexer/ast/parser.js +103 -0
  129. package/dist/indexer/ast/parser.js.map +1 -0
  130. package/dist/indexer/ast/symbols.d.ts +17 -0
  131. package/dist/indexer/ast/symbols.d.ts.map +1 -0
  132. package/dist/indexer/ast/symbols.js +265 -0
  133. package/dist/indexer/ast/symbols.js.map +1 -0
  134. package/dist/indexer/ast/traversers/index.d.ts +19 -0
  135. package/dist/indexer/ast/traversers/index.d.ts.map +1 -0
  136. package/dist/indexer/ast/traversers/index.js +42 -0
  137. package/dist/indexer/ast/traversers/index.js.map +1 -0
  138. package/dist/indexer/ast/traversers/php.d.ts +21 -0
  139. package/dist/indexer/ast/traversers/php.d.ts.map +1 -0
  140. package/dist/indexer/ast/traversers/php.js +67 -0
  141. package/dist/indexer/ast/traversers/php.js.map +1 -0
  142. package/dist/indexer/ast/traversers/python.d.ts +28 -0
  143. package/dist/indexer/ast/traversers/python.d.ts.map +1 -0
  144. package/dist/indexer/ast/traversers/python.js +67 -0
  145. package/dist/indexer/ast/traversers/python.js.map +1 -0
  146. package/dist/indexer/ast/traversers/types.d.ts +98 -0
  147. package/dist/indexer/ast/traversers/types.d.ts.map +1 -0
  148. package/dist/indexer/ast/traversers/types.js +2 -0
  149. package/dist/indexer/ast/traversers/types.js.map +1 -0
  150. package/dist/indexer/ast/traversers/typescript.d.ts +29 -0
  151. package/dist/indexer/ast/traversers/typescript.d.ts.map +1 -0
  152. package/dist/indexer/ast/traversers/typescript.js +88 -0
  153. package/dist/indexer/ast/traversers/typescript.js.map +1 -0
  154. package/dist/indexer/ast/types.d.ts +59 -0
  155. package/dist/indexer/ast/types.d.ts.map +1 -0
  156. package/dist/indexer/ast/types.js +2 -0
  157. package/dist/indexer/ast/types.js.map +1 -0
  158. package/dist/indexer/change-detector.d.ts +17 -0
  159. package/dist/indexer/change-detector.d.ts.map +1 -0
  160. package/dist/indexer/change-detector.js +207 -0
  161. package/dist/indexer/change-detector.js.map +1 -0
  162. package/dist/indexer/chunk-batch-processor.d.ts +103 -0
  163. package/dist/indexer/chunk-batch-processor.d.ts.map +1 -0
  164. package/dist/indexer/chunk-batch-processor.js +179 -0
  165. package/dist/indexer/chunk-batch-processor.js.map +1 -0
  166. package/dist/indexer/chunker.d.ts +10 -0
  167. package/dist/indexer/chunker.d.ts.map +1 -0
  168. package/dist/indexer/chunker.js +96 -0
  169. package/dist/indexer/chunker.js.map +1 -0
  170. package/dist/indexer/dependency-analyzer.d.ts +60 -0
  171. package/dist/indexer/dependency-analyzer.d.ts.map +1 -0
  172. package/dist/indexer/dependency-analyzer.js +261 -0
  173. package/dist/indexer/dependency-analyzer.js.map +1 -0
  174. package/dist/indexer/incremental.d.ts +47 -0
  175. package/dist/indexer/incremental.d.ts.map +1 -0
  176. package/dist/indexer/incremental.js +284 -0
  177. package/dist/indexer/incremental.js.map +1 -0
  178. package/dist/indexer/index.d.ts +80 -0
  179. package/dist/indexer/index.d.ts.map +1 -0
  180. package/dist/indexer/index.js +364 -0
  181. package/dist/indexer/index.js.map +1 -0
  182. package/dist/indexer/json-template-chunker.d.ts +9 -0
  183. package/dist/indexer/json-template-chunker.d.ts.map +1 -0
  184. package/dist/indexer/json-template-chunker.js +83 -0
  185. package/dist/indexer/json-template-chunker.js.map +1 -0
  186. package/dist/indexer/liquid-chunker.d.ts +13 -0
  187. package/dist/indexer/liquid-chunker.d.ts.map +1 -0
  188. package/dist/indexer/liquid-chunker.js +272 -0
  189. package/dist/indexer/liquid-chunker.js.map +1 -0
  190. package/dist/indexer/manifest.d.ts +122 -0
  191. package/dist/indexer/manifest.d.ts.map +1 -0
  192. package/dist/indexer/manifest.js +262 -0
  193. package/dist/indexer/manifest.js.map +1 -0
  194. package/dist/indexer/progress-tracker.d.ts +35 -0
  195. package/dist/indexer/progress-tracker.d.ts.map +1 -0
  196. package/dist/indexer/progress-tracker.js +33 -0
  197. package/dist/indexer/progress-tracker.js.map +1 -0
  198. package/dist/indexer/scanner.d.ts +16 -0
  199. package/dist/indexer/scanner.d.ts.map +1 -0
  200. package/dist/indexer/scanner.js +159 -0
  201. package/dist/indexer/scanner.js.map +1 -0
  202. package/dist/indexer/symbol-extractor.d.ts +18 -0
  203. package/dist/indexer/symbol-extractor.d.ts.map +1 -0
  204. package/dist/indexer/symbol-extractor.js +351 -0
  205. package/dist/indexer/symbol-extractor.js.map +1 -0
  206. package/dist/indexer/types.d.ts +34 -0
  207. package/dist/indexer/types.d.ts.map +1 -0
  208. package/dist/indexer/types.js +2 -0
  209. package/dist/indexer/types.js.map +1 -0
  210. package/dist/insights/complexity-analyzer.d.ts +82 -0
  211. package/dist/insights/complexity-analyzer.d.ts.map +1 -0
  212. package/dist/insights/complexity-analyzer.js +356 -0
  213. package/dist/insights/complexity-analyzer.js.map +1 -0
  214. package/dist/insights/formatters/index.d.ts +11 -0
  215. package/dist/insights/formatters/index.d.ts.map +1 -0
  216. package/dist/insights/formatters/index.js +20 -0
  217. package/dist/insights/formatters/index.js.map +1 -0
  218. package/dist/insights/formatters/json.d.ts +7 -0
  219. package/dist/insights/formatters/json.d.ts.map +1 -0
  220. package/dist/insights/formatters/json.js +14 -0
  221. package/dist/insights/formatters/json.js.map +1 -0
  222. package/dist/insights/formatters/sarif.d.ts +6 -0
  223. package/dist/insights/formatters/sarif.d.ts.map +1 -0
  224. package/dist/insights/formatters/sarif.js +113 -0
  225. package/dist/insights/formatters/sarif.js.map +1 -0
  226. package/dist/insights/formatters/text.d.ts +6 -0
  227. package/dist/insights/formatters/text.d.ts.map +1 -0
  228. package/dist/insights/formatters/text.js +154 -0
  229. package/dist/insights/formatters/text.js.map +1 -0
  230. package/dist/insights/types.d.ts +73 -0
  231. package/dist/insights/types.d.ts.map +1 -0
  232. package/dist/insights/types.js +9 -0
  233. package/dist/insights/types.js.map +1 -0
  234. package/dist/types/index.d.ts +14 -0
  235. package/dist/types/index.d.ts.map +1 -0
  236. package/dist/types/index.js +8 -0
  237. package/dist/types/index.js.map +1 -0
  238. package/dist/utils/path-matching.d.ts +69 -0
  239. package/dist/utils/path-matching.d.ts.map +1 -0
  240. package/dist/utils/path-matching.js +123 -0
  241. package/dist/utils/path-matching.js.map +1 -0
  242. package/dist/utils/result.d.ts +65 -0
  243. package/dist/utils/result.d.ts.map +1 -0
  244. package/dist/utils/result.js +67 -0
  245. package/dist/utils/result.js.map +1 -0
  246. package/dist/utils/version.d.ts +22 -0
  247. package/dist/utils/version.d.ts.map +1 -0
  248. package/dist/utils/version.js +28 -0
  249. package/dist/utils/version.js.map +1 -0
  250. package/dist/vectordb/batch-insert.d.ts +14 -0
  251. package/dist/vectordb/batch-insert.d.ts.map +1 -0
  252. package/dist/vectordb/batch-insert.js +185 -0
  253. package/dist/vectordb/batch-insert.js.map +1 -0
  254. package/dist/vectordb/boosting/composer.d.ts +51 -0
  255. package/dist/vectordb/boosting/composer.d.ts.map +1 -0
  256. package/dist/vectordb/boosting/composer.js +65 -0
  257. package/dist/vectordb/boosting/composer.js.map +1 -0
  258. package/dist/vectordb/boosting/index.d.ts +22 -0
  259. package/dist/vectordb/boosting/index.d.ts.map +1 -0
  260. package/dist/vectordb/boosting/index.js +22 -0
  261. package/dist/vectordb/boosting/index.js.map +1 -0
  262. package/dist/vectordb/boosting/strategies.d.ts +40 -0
  263. package/dist/vectordb/boosting/strategies.d.ts.map +1 -0
  264. package/dist/vectordb/boosting/strategies.js +174 -0
  265. package/dist/vectordb/boosting/strategies.js.map +1 -0
  266. package/dist/vectordb/boosting/types.d.ts +20 -0
  267. package/dist/vectordb/boosting/types.d.ts.map +1 -0
  268. package/dist/vectordb/boosting/types.js +2 -0
  269. package/dist/vectordb/boosting/types.js.map +1 -0
  270. package/dist/vectordb/intent-classifier.d.ts +99 -0
  271. package/dist/vectordb/intent-classifier.d.ts.map +1 -0
  272. package/dist/vectordb/intent-classifier.js +193 -0
  273. package/dist/vectordb/intent-classifier.js.map +1 -0
  274. package/dist/vectordb/lancedb.d.ts +45 -0
  275. package/dist/vectordb/lancedb.d.ts.map +1 -0
  276. package/dist/vectordb/lancedb.js +203 -0
  277. package/dist/vectordb/lancedb.js.map +1 -0
  278. package/dist/vectordb/maintenance.d.ts +18 -0
  279. package/dist/vectordb/maintenance.d.ts.map +1 -0
  280. package/dist/vectordb/maintenance.js +87 -0
  281. package/dist/vectordb/maintenance.js.map +1 -0
  282. package/dist/vectordb/query.d.ts +34 -0
  283. package/dist/vectordb/query.d.ts.map +1 -0
  284. package/dist/vectordb/query.js +303 -0
  285. package/dist/vectordb/query.js.map +1 -0
  286. package/dist/vectordb/relevance.d.ts +15 -0
  287. package/dist/vectordb/relevance.d.ts.map +1 -0
  288. package/dist/vectordb/relevance.js +19 -0
  289. package/dist/vectordb/relevance.js.map +1 -0
  290. package/dist/vectordb/types.d.ts +29 -0
  291. package/dist/vectordb/types.d.ts.map +1 -0
  292. package/dist/vectordb/types.js +2 -0
  293. package/dist/vectordb/types.js.map +1 -0
  294. package/dist/vectordb/version.d.ts +16 -0
  295. package/dist/vectordb/version.d.ts.map +1 -0
  296. package/dist/vectordb/version.js +40 -0
  297. package/dist/vectordb/version.js.map +1 -0
  298. 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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"}