@liendev/lien 0.12.0 → 0.13.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/CURSOR_RULES_TEMPLATE.md +109 -0
- package/dist/index.js +668 -79
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -9,11 +9,39 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/utils/version.ts
|
|
13
|
+
import { createRequire } from "module";
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
|
+
import { dirname, join } from "path";
|
|
16
|
+
function getPackageVersion() {
|
|
17
|
+
return packageJson.version;
|
|
18
|
+
}
|
|
19
|
+
var __filename, __dirname, require2, packageJson;
|
|
20
|
+
var init_version = __esm({
|
|
21
|
+
"src/utils/version.ts"() {
|
|
22
|
+
"use strict";
|
|
23
|
+
__filename = fileURLToPath(import.meta.url);
|
|
24
|
+
__dirname = dirname(__filename);
|
|
25
|
+
require2 = createRequire(import.meta.url);
|
|
26
|
+
try {
|
|
27
|
+
packageJson = require2(join(__dirname, "../package.json"));
|
|
28
|
+
} catch {
|
|
29
|
+
try {
|
|
30
|
+
packageJson = require2(join(__dirname, "../../package.json"));
|
|
31
|
+
} catch {
|
|
32
|
+
console.warn("[Lien] Warning: Could not load package.json, using fallback version");
|
|
33
|
+
packageJson = { version: "0.0.0-unknown" };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
12
39
|
// src/constants.ts
|
|
13
40
|
var DEFAULT_CHUNK_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CONCURRENCY, DEFAULT_EMBEDDING_BATCH_SIZE, EMBEDDING_MICRO_BATCH_SIZE, VECTOR_DB_MAX_BATCH_SIZE, VECTOR_DB_MIN_BATCH_SIZE, EMBEDDING_DIMENSIONS, DEFAULT_EMBEDDING_MODEL, DEFAULT_PORT, VERSION_CHECK_INTERVAL_MS, DEFAULT_GIT_POLL_INTERVAL_MS, DEFAULT_DEBOUNCE_MS, CURRENT_CONFIG_VERSION, INDEX_FORMAT_VERSION;
|
|
14
41
|
var init_constants = __esm({
|
|
15
42
|
"src/constants.ts"() {
|
|
16
43
|
"use strict";
|
|
44
|
+
init_version();
|
|
17
45
|
DEFAULT_CHUNK_SIZE = 75;
|
|
18
46
|
DEFAULT_CHUNK_OVERLAP = 10;
|
|
19
47
|
DEFAULT_CONCURRENCY = 4;
|
|
@@ -27,8 +55,8 @@ var init_constants = __esm({
|
|
|
27
55
|
VERSION_CHECK_INTERVAL_MS = 2e3;
|
|
28
56
|
DEFAULT_GIT_POLL_INTERVAL_MS = 1e4;
|
|
29
57
|
DEFAULT_DEBOUNCE_MS = 1e3;
|
|
30
|
-
CURRENT_CONFIG_VERSION =
|
|
31
|
-
INDEX_FORMAT_VERSION =
|
|
58
|
+
CURRENT_CONFIG_VERSION = getPackageVersion();
|
|
59
|
+
INDEX_FORMAT_VERSION = 2;
|
|
32
60
|
}
|
|
33
61
|
});
|
|
34
62
|
|
|
@@ -52,6 +80,12 @@ var init_schema = __esm({
|
|
|
52
80
|
concurrency: DEFAULT_CONCURRENCY,
|
|
53
81
|
embeddingBatchSize: DEFAULT_EMBEDDING_BATCH_SIZE
|
|
54
82
|
},
|
|
83
|
+
chunking: {
|
|
84
|
+
useAST: true,
|
|
85
|
+
// AST-based chunking enabled by default (v0.13.0)
|
|
86
|
+
astFallback: "line-based"
|
|
87
|
+
// Fallback to line-based on errors
|
|
88
|
+
},
|
|
55
89
|
mcp: {
|
|
56
90
|
port: DEFAULT_PORT,
|
|
57
91
|
transport: "stdio",
|
|
@@ -80,6 +114,10 @@ function deepMergeConfig(defaults, user) {
|
|
|
80
114
|
...defaults.core,
|
|
81
115
|
...user.core
|
|
82
116
|
},
|
|
117
|
+
chunking: {
|
|
118
|
+
...defaults.chunking,
|
|
119
|
+
...user.chunking
|
|
120
|
+
},
|
|
83
121
|
mcp: {
|
|
84
122
|
...defaults.mcp,
|
|
85
123
|
...user.mcp
|
|
@@ -125,7 +163,10 @@ function needsMigration(config) {
|
|
|
125
163
|
if (!config) {
|
|
126
164
|
return false;
|
|
127
165
|
}
|
|
128
|
-
if (config.frameworks !== void 0) {
|
|
166
|
+
if (config.frameworks !== void 0 && !config.chunking) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
if (config.frameworks !== void 0 && config.chunking !== void 0) {
|
|
129
170
|
return false;
|
|
130
171
|
}
|
|
131
172
|
if (config.indexing !== void 0) {
|
|
@@ -138,12 +179,16 @@ function needsMigration(config) {
|
|
|
138
179
|
}
|
|
139
180
|
function migrateConfig(oldConfig) {
|
|
140
181
|
const newConfig = {
|
|
141
|
-
version:
|
|
182
|
+
version: CURRENT_CONFIG_VERSION,
|
|
142
183
|
core: {
|
|
143
|
-
chunkSize: oldConfig.indexing?.chunkSize ?? defaultConfig.core.chunkSize,
|
|
144
|
-
chunkOverlap: oldConfig.indexing?.chunkOverlap ?? defaultConfig.core.chunkOverlap,
|
|
145
|
-
concurrency: oldConfig.indexing?.concurrency ?? defaultConfig.core.concurrency,
|
|
146
|
-
embeddingBatchSize: oldConfig.indexing?.embeddingBatchSize ?? defaultConfig.core.embeddingBatchSize
|
|
184
|
+
chunkSize: oldConfig.indexing?.chunkSize ?? oldConfig.core?.chunkSize ?? defaultConfig.core.chunkSize,
|
|
185
|
+
chunkOverlap: oldConfig.indexing?.chunkOverlap ?? oldConfig.core?.chunkOverlap ?? defaultConfig.core.chunkOverlap,
|
|
186
|
+
concurrency: oldConfig.indexing?.concurrency ?? oldConfig.core?.concurrency ?? defaultConfig.core.concurrency,
|
|
187
|
+
embeddingBatchSize: oldConfig.indexing?.embeddingBatchSize ?? oldConfig.core?.embeddingBatchSize ?? defaultConfig.core.embeddingBatchSize
|
|
188
|
+
},
|
|
189
|
+
chunking: {
|
|
190
|
+
useAST: oldConfig.chunking?.useAST ?? defaultConfig.chunking.useAST,
|
|
191
|
+
astFallback: oldConfig.chunking?.astFallback ?? defaultConfig.chunking.astFallback
|
|
147
192
|
},
|
|
148
193
|
mcp: {
|
|
149
194
|
port: oldConfig.mcp?.port ?? defaultConfig.mcp.port,
|
|
@@ -158,9 +203,9 @@ function migrateConfig(oldConfig) {
|
|
|
158
203
|
enabled: oldConfig.fileWatching?.enabled ?? defaultConfig.fileWatching.enabled,
|
|
159
204
|
debounceMs: oldConfig.fileWatching?.debounceMs ?? defaultConfig.fileWatching.debounceMs
|
|
160
205
|
},
|
|
161
|
-
frameworks: []
|
|
206
|
+
frameworks: oldConfig.frameworks ?? []
|
|
162
207
|
};
|
|
163
|
-
if (oldConfig.indexing) {
|
|
208
|
+
if (oldConfig.indexing && newConfig.frameworks.length === 0) {
|
|
164
209
|
const genericFramework = {
|
|
165
210
|
name: "generic",
|
|
166
211
|
path: ".",
|
|
@@ -180,7 +225,7 @@ function migrateConfig(oldConfig) {
|
|
|
180
225
|
}
|
|
181
226
|
};
|
|
182
227
|
newConfig.frameworks.push(genericFramework);
|
|
183
|
-
} else {
|
|
228
|
+
} else if (newConfig.frameworks.length === 0) {
|
|
184
229
|
const genericFramework = {
|
|
185
230
|
name: "generic",
|
|
186
231
|
path: ".",
|
|
@@ -207,6 +252,7 @@ var init_migration = __esm({
|
|
|
207
252
|
"src/config/migration.ts"() {
|
|
208
253
|
"use strict";
|
|
209
254
|
init_schema();
|
|
255
|
+
init_constants();
|
|
210
256
|
}
|
|
211
257
|
});
|
|
212
258
|
|
|
@@ -875,7 +921,7 @@ async function readVersionFile(indexPath) {
|
|
|
875
921
|
}
|
|
876
922
|
}
|
|
877
923
|
var VERSION_FILE;
|
|
878
|
-
var
|
|
924
|
+
var init_version2 = __esm({
|
|
879
925
|
"src/vectordb/version.ts"() {
|
|
880
926
|
"use strict";
|
|
881
927
|
VERSION_FILE = ".lien-index-version";
|
|
@@ -1305,9 +1351,501 @@ var init_symbol_extractor = __esm({
|
|
|
1305
1351
|
}
|
|
1306
1352
|
});
|
|
1307
1353
|
|
|
1354
|
+
// src/indexer/ast/parser.ts
|
|
1355
|
+
import Parser from "tree-sitter";
|
|
1356
|
+
import TypeScript from "tree-sitter-typescript";
|
|
1357
|
+
import JavaScript from "tree-sitter-javascript";
|
|
1358
|
+
import { extname } from "path";
|
|
1359
|
+
function getParser(language) {
|
|
1360
|
+
if (!parserCache.has(language)) {
|
|
1361
|
+
const parser = new Parser();
|
|
1362
|
+
const grammar = languageConfig[language];
|
|
1363
|
+
if (!grammar) {
|
|
1364
|
+
throw new Error(`No grammar available for language: ${language}`);
|
|
1365
|
+
}
|
|
1366
|
+
parser.setLanguage(grammar);
|
|
1367
|
+
parserCache.set(language, parser);
|
|
1368
|
+
}
|
|
1369
|
+
return parserCache.get(language);
|
|
1370
|
+
}
|
|
1371
|
+
function detectLanguage2(filePath) {
|
|
1372
|
+
const ext = extname(filePath).slice(1).toLowerCase();
|
|
1373
|
+
switch (ext) {
|
|
1374
|
+
case "ts":
|
|
1375
|
+
case "tsx":
|
|
1376
|
+
return "typescript";
|
|
1377
|
+
case "js":
|
|
1378
|
+
case "jsx":
|
|
1379
|
+
case "mjs":
|
|
1380
|
+
case "cjs":
|
|
1381
|
+
return "javascript";
|
|
1382
|
+
default:
|
|
1383
|
+
return null;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
function isASTSupported(filePath) {
|
|
1387
|
+
return detectLanguage2(filePath) !== null;
|
|
1388
|
+
}
|
|
1389
|
+
function parseAST(content, language) {
|
|
1390
|
+
try {
|
|
1391
|
+
const parser = getParser(language);
|
|
1392
|
+
const tree = parser.parse(content);
|
|
1393
|
+
if (tree.rootNode.hasError) {
|
|
1394
|
+
return {
|
|
1395
|
+
tree,
|
|
1396
|
+
error: "Parse completed with errors"
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
return { tree };
|
|
1400
|
+
} catch (error) {
|
|
1401
|
+
return {
|
|
1402
|
+
tree: null,
|
|
1403
|
+
error: error instanceof Error ? error.message : "Unknown parse error"
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
var parserCache, languageConfig;
|
|
1408
|
+
var init_parser = __esm({
|
|
1409
|
+
"src/indexer/ast/parser.ts"() {
|
|
1410
|
+
"use strict";
|
|
1411
|
+
parserCache = /* @__PURE__ */ new Map();
|
|
1412
|
+
languageConfig = {
|
|
1413
|
+
typescript: TypeScript.typescript,
|
|
1414
|
+
javascript: JavaScript
|
|
1415
|
+
// Use proper JavaScript parser
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
// src/indexer/ast/symbols.ts
|
|
1421
|
+
function extractSymbolInfo(node, content, parentClass) {
|
|
1422
|
+
const type = node.type;
|
|
1423
|
+
if (type === "function_declaration" || type === "function") {
|
|
1424
|
+
const nameNode = node.childForFieldName("name");
|
|
1425
|
+
if (!nameNode) return null;
|
|
1426
|
+
return {
|
|
1427
|
+
name: nameNode.text,
|
|
1428
|
+
type: parentClass ? "method" : "function",
|
|
1429
|
+
startLine: node.startPosition.row + 1,
|
|
1430
|
+
endLine: node.endPosition.row + 1,
|
|
1431
|
+
parentClass,
|
|
1432
|
+
signature: extractSignature(node, content),
|
|
1433
|
+
parameters: extractParameters(node, content),
|
|
1434
|
+
returnType: extractReturnType(node, content),
|
|
1435
|
+
complexity: calculateComplexity(node)
|
|
1436
|
+
};
|
|
1437
|
+
}
|
|
1438
|
+
if (type === "arrow_function" || type === "function_expression") {
|
|
1439
|
+
const parent = node.parent;
|
|
1440
|
+
let name = "anonymous";
|
|
1441
|
+
if (parent?.type === "variable_declarator") {
|
|
1442
|
+
const nameNode = parent.childForFieldName("name");
|
|
1443
|
+
name = nameNode?.text || "anonymous";
|
|
1444
|
+
}
|
|
1445
|
+
return {
|
|
1446
|
+
name,
|
|
1447
|
+
type: parentClass ? "method" : "function",
|
|
1448
|
+
startLine: node.startPosition.row + 1,
|
|
1449
|
+
endLine: node.endPosition.row + 1,
|
|
1450
|
+
parentClass,
|
|
1451
|
+
signature: extractSignature(node, content),
|
|
1452
|
+
parameters: extractParameters(node, content),
|
|
1453
|
+
complexity: calculateComplexity(node)
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
if (type === "method_definition") {
|
|
1457
|
+
const nameNode = node.childForFieldName("name");
|
|
1458
|
+
if (!nameNode) return null;
|
|
1459
|
+
return {
|
|
1460
|
+
name: nameNode.text,
|
|
1461
|
+
type: "method",
|
|
1462
|
+
startLine: node.startPosition.row + 1,
|
|
1463
|
+
endLine: node.endPosition.row + 1,
|
|
1464
|
+
parentClass,
|
|
1465
|
+
signature: extractSignature(node, content),
|
|
1466
|
+
parameters: extractParameters(node, content),
|
|
1467
|
+
returnType: extractReturnType(node, content),
|
|
1468
|
+
complexity: calculateComplexity(node)
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
if (type === "class_declaration") {
|
|
1472
|
+
const nameNode = node.childForFieldName("name");
|
|
1473
|
+
if (!nameNode) return null;
|
|
1474
|
+
return {
|
|
1475
|
+
name: nameNode.text,
|
|
1476
|
+
type: "class",
|
|
1477
|
+
startLine: node.startPosition.row + 1,
|
|
1478
|
+
endLine: node.endPosition.row + 1,
|
|
1479
|
+
signature: `class ${nameNode.text}`
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
if (type === "interface_declaration") {
|
|
1483
|
+
const nameNode = node.childForFieldName("name");
|
|
1484
|
+
if (!nameNode) return null;
|
|
1485
|
+
return {
|
|
1486
|
+
name: nameNode.text,
|
|
1487
|
+
type: "interface",
|
|
1488
|
+
startLine: node.startPosition.row + 1,
|
|
1489
|
+
endLine: node.endPosition.row + 1,
|
|
1490
|
+
signature: `interface ${nameNode.text}`
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
return null;
|
|
1494
|
+
}
|
|
1495
|
+
function extractSignature(node, content) {
|
|
1496
|
+
const startLine = node.startPosition.row;
|
|
1497
|
+
const lines = content.split("\n");
|
|
1498
|
+
let signature = lines[startLine] || "";
|
|
1499
|
+
let currentLine = startLine;
|
|
1500
|
+
while (currentLine < node.endPosition.row && !signature.includes("{") && !signature.includes("=>")) {
|
|
1501
|
+
currentLine++;
|
|
1502
|
+
signature += " " + (lines[currentLine] || "");
|
|
1503
|
+
}
|
|
1504
|
+
signature = signature.split("{")[0].split("=>")[0].trim();
|
|
1505
|
+
if (signature.length > 200) {
|
|
1506
|
+
signature = signature.substring(0, 197) + "...";
|
|
1507
|
+
}
|
|
1508
|
+
return signature;
|
|
1509
|
+
}
|
|
1510
|
+
function extractParameters(node, _content) {
|
|
1511
|
+
const parameters = [];
|
|
1512
|
+
const paramsNode = node.childForFieldName("parameters");
|
|
1513
|
+
if (!paramsNode) return parameters;
|
|
1514
|
+
for (let i = 0; i < paramsNode.namedChildCount; i++) {
|
|
1515
|
+
const param = paramsNode.namedChild(i);
|
|
1516
|
+
if (param) {
|
|
1517
|
+
parameters.push(param.text);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
return parameters;
|
|
1521
|
+
}
|
|
1522
|
+
function extractReturnType(node, _content) {
|
|
1523
|
+
const returnTypeNode = node.childForFieldName("return_type");
|
|
1524
|
+
if (!returnTypeNode) return void 0;
|
|
1525
|
+
return returnTypeNode.text;
|
|
1526
|
+
}
|
|
1527
|
+
function calculateComplexity(node) {
|
|
1528
|
+
let complexity = 1;
|
|
1529
|
+
const decisionPoints = [
|
|
1530
|
+
"if_statement",
|
|
1531
|
+
"while_statement",
|
|
1532
|
+
"do_statement",
|
|
1533
|
+
// do...while loops
|
|
1534
|
+
"for_statement",
|
|
1535
|
+
"for_in_statement",
|
|
1536
|
+
"for_of_statement",
|
|
1537
|
+
// for...of loops
|
|
1538
|
+
"switch_case",
|
|
1539
|
+
"catch_clause",
|
|
1540
|
+
"ternary_expression",
|
|
1541
|
+
"binary_expression"
|
|
1542
|
+
// For && and ||
|
|
1543
|
+
];
|
|
1544
|
+
function traverse(n) {
|
|
1545
|
+
if (decisionPoints.includes(n.type)) {
|
|
1546
|
+
if (n.type === "binary_expression") {
|
|
1547
|
+
const operator = n.childForFieldName("operator");
|
|
1548
|
+
if (operator && (operator.text === "&&" || operator.text === "||")) {
|
|
1549
|
+
complexity++;
|
|
1550
|
+
}
|
|
1551
|
+
} else {
|
|
1552
|
+
complexity++;
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
for (let i = 0; i < n.namedChildCount; i++) {
|
|
1556
|
+
const child = n.namedChild(i);
|
|
1557
|
+
if (child) traverse(child);
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
traverse(node);
|
|
1561
|
+
return complexity;
|
|
1562
|
+
}
|
|
1563
|
+
function extractImports(rootNode) {
|
|
1564
|
+
const imports = [];
|
|
1565
|
+
function traverse(node) {
|
|
1566
|
+
if (node.type === "import_statement") {
|
|
1567
|
+
const sourceNode = node.childForFieldName("source");
|
|
1568
|
+
if (sourceNode) {
|
|
1569
|
+
const importPath = sourceNode.text.replace(/['"]/g, "");
|
|
1570
|
+
imports.push(importPath);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
if (node === rootNode) {
|
|
1574
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1575
|
+
const child = node.namedChild(i);
|
|
1576
|
+
if (child) traverse(child);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
traverse(rootNode);
|
|
1581
|
+
return imports;
|
|
1582
|
+
}
|
|
1583
|
+
var init_symbols = __esm({
|
|
1584
|
+
"src/indexer/ast/symbols.ts"() {
|
|
1585
|
+
"use strict";
|
|
1586
|
+
}
|
|
1587
|
+
});
|
|
1588
|
+
|
|
1589
|
+
// src/indexer/ast/chunker.ts
|
|
1590
|
+
function chunkByAST(filepath, content, options = {}) {
|
|
1591
|
+
const { minChunkSize = 5 } = options;
|
|
1592
|
+
const language = detectLanguage2(filepath);
|
|
1593
|
+
if (!language) {
|
|
1594
|
+
throw new Error(`Unsupported language for file: ${filepath}`);
|
|
1595
|
+
}
|
|
1596
|
+
const parseResult = parseAST(content, language);
|
|
1597
|
+
if (!parseResult.tree) {
|
|
1598
|
+
throw new Error(`Failed to parse ${filepath}: ${parseResult.error}`);
|
|
1599
|
+
}
|
|
1600
|
+
const chunks = [];
|
|
1601
|
+
const lines = content.split("\n");
|
|
1602
|
+
const rootNode = parseResult.tree.rootNode;
|
|
1603
|
+
const fileImports = extractImports(rootNode);
|
|
1604
|
+
const topLevelNodes = findTopLevelNodes(rootNode);
|
|
1605
|
+
for (const node of topLevelNodes) {
|
|
1606
|
+
let actualNode = node;
|
|
1607
|
+
if (node.type === "lexical_declaration" || node.type === "variable_declaration") {
|
|
1608
|
+
const funcNode = findActualFunctionNode(node);
|
|
1609
|
+
if (funcNode) {
|
|
1610
|
+
actualNode = funcNode;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
let parentClassName;
|
|
1614
|
+
if (actualNode.type === "method_definition") {
|
|
1615
|
+
parentClassName = findParentClassName(actualNode);
|
|
1616
|
+
}
|
|
1617
|
+
const symbolInfo = extractSymbolInfo(actualNode, content, parentClassName);
|
|
1618
|
+
const nodeContent = getNodeContent(node, lines);
|
|
1619
|
+
chunks.push(createChunk(filepath, node, nodeContent, symbolInfo, fileImports, language));
|
|
1620
|
+
}
|
|
1621
|
+
const coveredRanges = topLevelNodes.map((n) => ({
|
|
1622
|
+
start: n.startPosition.row,
|
|
1623
|
+
end: n.endPosition.row
|
|
1624
|
+
}));
|
|
1625
|
+
const uncoveredChunks = extractUncoveredCode(
|
|
1626
|
+
lines,
|
|
1627
|
+
coveredRanges,
|
|
1628
|
+
filepath,
|
|
1629
|
+
minChunkSize,
|
|
1630
|
+
fileImports,
|
|
1631
|
+
language
|
|
1632
|
+
);
|
|
1633
|
+
chunks.push(...uncoveredChunks);
|
|
1634
|
+
chunks.sort((a, b) => a.metadata.startLine - b.metadata.startLine);
|
|
1635
|
+
return chunks;
|
|
1636
|
+
}
|
|
1637
|
+
function findParentClassName(methodNode) {
|
|
1638
|
+
let current = methodNode.parent;
|
|
1639
|
+
while (current) {
|
|
1640
|
+
if (current.type === "class_declaration") {
|
|
1641
|
+
const nameNode = current.childForFieldName("name");
|
|
1642
|
+
return nameNode?.text;
|
|
1643
|
+
}
|
|
1644
|
+
current = current.parent;
|
|
1645
|
+
}
|
|
1646
|
+
return void 0;
|
|
1647
|
+
}
|
|
1648
|
+
function findTopLevelNodes(rootNode) {
|
|
1649
|
+
const nodes = [];
|
|
1650
|
+
const targetTypes = [
|
|
1651
|
+
"function_declaration",
|
|
1652
|
+
"function",
|
|
1653
|
+
// Note: 'class_declaration' is NOT included here - we extract methods individually
|
|
1654
|
+
"interface_declaration",
|
|
1655
|
+
"method_definition",
|
|
1656
|
+
"lexical_declaration",
|
|
1657
|
+
// For const/let with arrow functions
|
|
1658
|
+
"variable_declaration"
|
|
1659
|
+
// For var with functions
|
|
1660
|
+
];
|
|
1661
|
+
function traverse(node, depth) {
|
|
1662
|
+
if ((node.type === "lexical_declaration" || node.type === "variable_declaration") && depth === 0) {
|
|
1663
|
+
const hasFunction = findFunctionInDeclaration(node);
|
|
1664
|
+
if (hasFunction) {
|
|
1665
|
+
nodes.push(node);
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (depth <= 1 && targetTypes.includes(node.type)) {
|
|
1670
|
+
nodes.push(node);
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
if (node.type === "class_body") {
|
|
1674
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1675
|
+
const child = node.namedChild(i);
|
|
1676
|
+
if (child) traverse(child, depth);
|
|
1677
|
+
}
|
|
1678
|
+
return;
|
|
1679
|
+
}
|
|
1680
|
+
if (node.type === "class_declaration") {
|
|
1681
|
+
const body = node.childForFieldName("body");
|
|
1682
|
+
if (body) {
|
|
1683
|
+
traverse(body, depth + 1);
|
|
1684
|
+
}
|
|
1685
|
+
return;
|
|
1686
|
+
}
|
|
1687
|
+
if (node.type === "program" || node.type === "export_statement") {
|
|
1688
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
1689
|
+
const child = node.namedChild(i);
|
|
1690
|
+
if (child) traverse(child, depth);
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
traverse(rootNode, 0);
|
|
1695
|
+
return nodes;
|
|
1696
|
+
}
|
|
1697
|
+
function findFunctionInDeclaration(node) {
|
|
1698
|
+
const functionTypes = ["arrow_function", "function_expression", "function"];
|
|
1699
|
+
function search(n, depth) {
|
|
1700
|
+
if (depth > 3) return false;
|
|
1701
|
+
if (functionTypes.includes(n.type)) {
|
|
1702
|
+
return true;
|
|
1703
|
+
}
|
|
1704
|
+
for (let i = 0; i < n.childCount; i++) {
|
|
1705
|
+
const child = n.child(i);
|
|
1706
|
+
if (child && search(child, depth + 1)) {
|
|
1707
|
+
return true;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
return false;
|
|
1711
|
+
}
|
|
1712
|
+
return search(node, 0);
|
|
1713
|
+
}
|
|
1714
|
+
function findActualFunctionNode(node) {
|
|
1715
|
+
const functionTypes = ["arrow_function", "function_expression", "function"];
|
|
1716
|
+
function search(n, depth) {
|
|
1717
|
+
if (depth > 3) return null;
|
|
1718
|
+
if (functionTypes.includes(n.type)) {
|
|
1719
|
+
return n;
|
|
1720
|
+
}
|
|
1721
|
+
for (let i = 0; i < n.childCount; i++) {
|
|
1722
|
+
const child = n.child(i);
|
|
1723
|
+
if (child) {
|
|
1724
|
+
const result = search(child, depth + 1);
|
|
1725
|
+
if (result) return result;
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
return null;
|
|
1729
|
+
}
|
|
1730
|
+
return search(node, 0);
|
|
1731
|
+
}
|
|
1732
|
+
function getNodeContent(node, lines) {
|
|
1733
|
+
const startLine = node.startPosition.row;
|
|
1734
|
+
const endLine = node.endPosition.row;
|
|
1735
|
+
return lines.slice(startLine, endLine + 1).join("\n");
|
|
1736
|
+
}
|
|
1737
|
+
function createChunk(filepath, node, content, symbolInfo, imports, language) {
|
|
1738
|
+
const symbols = {
|
|
1739
|
+
functions: [],
|
|
1740
|
+
classes: [],
|
|
1741
|
+
interfaces: []
|
|
1742
|
+
};
|
|
1743
|
+
if (symbolInfo?.name) {
|
|
1744
|
+
if (symbolInfo.type === "function" || symbolInfo.type === "method") {
|
|
1745
|
+
symbols.functions.push(symbolInfo.name);
|
|
1746
|
+
} else if (symbolInfo.type === "class") {
|
|
1747
|
+
symbols.classes.push(symbolInfo.name);
|
|
1748
|
+
} else if (symbolInfo.type === "interface") {
|
|
1749
|
+
symbols.interfaces.push(symbolInfo.name);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
return {
|
|
1753
|
+
content,
|
|
1754
|
+
metadata: {
|
|
1755
|
+
file: filepath,
|
|
1756
|
+
startLine: node.startPosition.row + 1,
|
|
1757
|
+
endLine: node.endPosition.row + 1,
|
|
1758
|
+
type: symbolInfo == null ? "block" : symbolInfo.type === "class" ? "class" : "function",
|
|
1759
|
+
language,
|
|
1760
|
+
// Legacy symbols field for backward compatibility
|
|
1761
|
+
symbols,
|
|
1762
|
+
// New AST-derived metadata
|
|
1763
|
+
symbolName: symbolInfo?.name,
|
|
1764
|
+
symbolType: symbolInfo?.type,
|
|
1765
|
+
parentClass: symbolInfo?.parentClass,
|
|
1766
|
+
complexity: symbolInfo?.complexity,
|
|
1767
|
+
parameters: symbolInfo?.parameters,
|
|
1768
|
+
signature: symbolInfo?.signature,
|
|
1769
|
+
imports
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
function extractUncoveredCode(lines, coveredRanges, filepath, minChunkSize, imports, language) {
|
|
1774
|
+
const chunks = [];
|
|
1775
|
+
let currentStart = 0;
|
|
1776
|
+
coveredRanges.sort((a, b) => a.start - b.start);
|
|
1777
|
+
for (const range of coveredRanges) {
|
|
1778
|
+
if (currentStart < range.start) {
|
|
1779
|
+
const uncoveredLines = lines.slice(currentStart, range.start);
|
|
1780
|
+
const content = uncoveredLines.join("\n").trim();
|
|
1781
|
+
if (content.length > 0 && uncoveredLines.length >= minChunkSize) {
|
|
1782
|
+
chunks.push({
|
|
1783
|
+
content,
|
|
1784
|
+
metadata: {
|
|
1785
|
+
file: filepath,
|
|
1786
|
+
startLine: currentStart + 1,
|
|
1787
|
+
endLine: range.start,
|
|
1788
|
+
type: "block",
|
|
1789
|
+
language,
|
|
1790
|
+
// Empty symbols for uncovered code (imports, exports, etc.)
|
|
1791
|
+
symbols: { functions: [], classes: [], interfaces: [] },
|
|
1792
|
+
imports
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
currentStart = range.end + 1;
|
|
1798
|
+
}
|
|
1799
|
+
if (currentStart < lines.length) {
|
|
1800
|
+
const uncoveredLines = lines.slice(currentStart);
|
|
1801
|
+
const content = uncoveredLines.join("\n").trim();
|
|
1802
|
+
if (content.length > 0 && uncoveredLines.length >= minChunkSize) {
|
|
1803
|
+
chunks.push({
|
|
1804
|
+
content,
|
|
1805
|
+
metadata: {
|
|
1806
|
+
file: filepath,
|
|
1807
|
+
startLine: currentStart + 1,
|
|
1808
|
+
endLine: lines.length,
|
|
1809
|
+
type: "block",
|
|
1810
|
+
language,
|
|
1811
|
+
// Empty symbols for uncovered code (imports, exports, etc.)
|
|
1812
|
+
symbols: { functions: [], classes: [], interfaces: [] },
|
|
1813
|
+
imports
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
return chunks;
|
|
1819
|
+
}
|
|
1820
|
+
function shouldUseAST(filepath) {
|
|
1821
|
+
return isASTSupported(filepath);
|
|
1822
|
+
}
|
|
1823
|
+
var init_chunker = __esm({
|
|
1824
|
+
"src/indexer/ast/chunker.ts"() {
|
|
1825
|
+
"use strict";
|
|
1826
|
+
init_parser();
|
|
1827
|
+
init_symbols();
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
|
|
1308
1831
|
// src/indexer/chunker.ts
|
|
1309
1832
|
function chunkFile(filepath, content, options = {}) {
|
|
1310
|
-
const { chunkSize = 75, chunkOverlap = 10 } = options;
|
|
1833
|
+
const { chunkSize = 75, chunkOverlap = 10, useAST = true, astFallback = "line-based" } = options;
|
|
1834
|
+
if (useAST && shouldUseAST(filepath)) {
|
|
1835
|
+
try {
|
|
1836
|
+
return chunkByAST(filepath, content, {
|
|
1837
|
+
minChunkSize: Math.floor(chunkSize / 10)
|
|
1838
|
+
});
|
|
1839
|
+
} catch (error) {
|
|
1840
|
+
if (astFallback === "error") {
|
|
1841
|
+
throw new Error(`AST chunking failed for ${filepath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1842
|
+
}
|
|
1843
|
+
console.warn(`AST chunking failed for ${filepath}, falling back to line-based:`, error);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
return chunkByLines(filepath, content, chunkSize, chunkOverlap);
|
|
1847
|
+
}
|
|
1848
|
+
function chunkByLines(filepath, content, chunkSize, chunkOverlap) {
|
|
1311
1849
|
const lines = content.split("\n");
|
|
1312
1850
|
const chunks = [];
|
|
1313
1851
|
const language = detectLanguage(filepath);
|
|
@@ -1340,11 +1878,12 @@ function chunkFile(filepath, content, options = {}) {
|
|
|
1340
1878
|
}
|
|
1341
1879
|
return chunks;
|
|
1342
1880
|
}
|
|
1343
|
-
var
|
|
1881
|
+
var init_chunker2 = __esm({
|
|
1344
1882
|
"src/indexer/chunker.ts"() {
|
|
1345
1883
|
"use strict";
|
|
1346
1884
|
init_scanner();
|
|
1347
1885
|
init_symbol_extractor();
|
|
1886
|
+
init_chunker();
|
|
1348
1887
|
}
|
|
1349
1888
|
});
|
|
1350
1889
|
|
|
@@ -1606,7 +2145,7 @@ var init_lancedb = __esm({
|
|
|
1606
2145
|
"src/vectordb/lancedb.ts"() {
|
|
1607
2146
|
"use strict";
|
|
1608
2147
|
init_types();
|
|
1609
|
-
|
|
2148
|
+
init_version2();
|
|
1610
2149
|
init_errors();
|
|
1611
2150
|
init_relevance();
|
|
1612
2151
|
init_intent_classifier();
|
|
@@ -1691,7 +2230,15 @@ var init_lancedb = __esm({
|
|
|
1691
2230
|
// Ensure arrays have at least empty string for Arrow type inference
|
|
1692
2231
|
functionNames: batch.metadatas[i].symbols?.functions && batch.metadatas[i].symbols.functions.length > 0 ? batch.metadatas[i].symbols.functions : [""],
|
|
1693
2232
|
classNames: batch.metadatas[i].symbols?.classes && batch.metadatas[i].symbols.classes.length > 0 ? batch.metadatas[i].symbols.classes : [""],
|
|
1694
|
-
interfaceNames: batch.metadatas[i].symbols?.interfaces && batch.metadatas[i].symbols.interfaces.length > 0 ? batch.metadatas[i].symbols.interfaces : [""]
|
|
2233
|
+
interfaceNames: batch.metadatas[i].symbols?.interfaces && batch.metadatas[i].symbols.interfaces.length > 0 ? batch.metadatas[i].symbols.interfaces : [""],
|
|
2234
|
+
// AST-derived metadata (v0.13.0)
|
|
2235
|
+
symbolName: batch.metadatas[i].symbolName || "",
|
|
2236
|
+
symbolType: batch.metadatas[i].symbolType || "",
|
|
2237
|
+
parentClass: batch.metadatas[i].parentClass || "",
|
|
2238
|
+
complexity: batch.metadatas[i].complexity || 0,
|
|
2239
|
+
parameters: batch.metadatas[i].parameters && batch.metadatas[i].parameters.length > 0 ? batch.metadatas[i].parameters : [""],
|
|
2240
|
+
signature: batch.metadatas[i].signature || "",
|
|
2241
|
+
imports: batch.metadatas[i].imports && batch.metadatas[i].imports.length > 0 ? batch.metadatas[i].imports : [""]
|
|
1695
2242
|
}));
|
|
1696
2243
|
if (!this.table) {
|
|
1697
2244
|
this.table = await this.db.createTable(this.tableName, records);
|
|
@@ -1746,7 +2293,15 @@ var init_lancedb = __esm({
|
|
|
1746
2293
|
startLine: r.startLine,
|
|
1747
2294
|
endLine: r.endLine,
|
|
1748
2295
|
type: r.type,
|
|
1749
|
-
language: r.language
|
|
2296
|
+
language: r.language,
|
|
2297
|
+
// AST-derived metadata (v0.13.0)
|
|
2298
|
+
symbolName: r.symbolName || void 0,
|
|
2299
|
+
symbolType: r.symbolType,
|
|
2300
|
+
parentClass: r.parentClass || void 0,
|
|
2301
|
+
complexity: r.complexity || void 0,
|
|
2302
|
+
parameters: r.parameters && r.parameters.length > 0 && r.parameters[0] !== "" ? r.parameters : void 0,
|
|
2303
|
+
signature: r.signature || void 0,
|
|
2304
|
+
imports: r.imports && r.imports.length > 0 && r.imports[0] !== "" ? r.imports : void 0
|
|
1750
2305
|
},
|
|
1751
2306
|
score: boostedScore,
|
|
1752
2307
|
relevance: calculateRelevance(boostedScore)
|
|
@@ -1819,7 +2374,15 @@ var init_lancedb = __esm({
|
|
|
1819
2374
|
startLine: r.startLine,
|
|
1820
2375
|
endLine: r.endLine,
|
|
1821
2376
|
type: r.type,
|
|
1822
|
-
language: r.language
|
|
2377
|
+
language: r.language,
|
|
2378
|
+
// AST-derived metadata (v0.13.0)
|
|
2379
|
+
symbolName: r.symbolName || void 0,
|
|
2380
|
+
symbolType: r.symbolType,
|
|
2381
|
+
parentClass: r.parentClass || void 0,
|
|
2382
|
+
complexity: r.complexity || void 0,
|
|
2383
|
+
parameters: r.parameters && r.parameters.length > 0 && r.parameters[0] !== "" ? r.parameters : void 0,
|
|
2384
|
+
signature: r.signature || void 0,
|
|
2385
|
+
imports: r.imports && r.imports.length > 0 && r.imports[0] !== "" ? r.imports : void 0
|
|
1823
2386
|
},
|
|
1824
2387
|
score,
|
|
1825
2388
|
relevance: calculateRelevance(score)
|
|
@@ -1849,12 +2412,43 @@ var init_lancedb = __esm({
|
|
|
1849
2412
|
return false;
|
|
1850
2413
|
}
|
|
1851
2414
|
const symbols = symbolType === "function" ? r.functionNames || [] : symbolType === "class" ? r.classNames || [] : symbolType === "interface" ? r.interfaceNames || [] : [...r.functionNames || [], ...r.classNames || [], ...r.interfaceNames || []];
|
|
1852
|
-
|
|
2415
|
+
const astSymbolName = r.symbolName || "";
|
|
2416
|
+
if (symbols.length === 0 && !astSymbolName) {
|
|
1853
2417
|
return false;
|
|
1854
2418
|
}
|
|
1855
2419
|
if (pattern) {
|
|
1856
2420
|
const regex = new RegExp(pattern, "i");
|
|
1857
|
-
|
|
2421
|
+
const matchesOldSymbols = symbols.some((s) => regex.test(s));
|
|
2422
|
+
const matchesASTSymbol = regex.test(astSymbolName);
|
|
2423
|
+
const nameMatches = matchesOldSymbols || matchesASTSymbol;
|
|
2424
|
+
if (!nameMatches) return false;
|
|
2425
|
+
if (symbolType) {
|
|
2426
|
+
if (r.symbolType) {
|
|
2427
|
+
if (symbolType === "function") {
|
|
2428
|
+
return r.symbolType === "function" || r.symbolType === "method";
|
|
2429
|
+
} else if (symbolType === "class") {
|
|
2430
|
+
return r.symbolType === "class";
|
|
2431
|
+
} else if (symbolType === "interface") {
|
|
2432
|
+
return r.symbolType === "interface";
|
|
2433
|
+
}
|
|
2434
|
+
return false;
|
|
2435
|
+
}
|
|
2436
|
+
return nameMatches;
|
|
2437
|
+
}
|
|
2438
|
+
return nameMatches;
|
|
2439
|
+
}
|
|
2440
|
+
if (symbolType) {
|
|
2441
|
+
if (r.symbolType) {
|
|
2442
|
+
if (symbolType === "function") {
|
|
2443
|
+
return r.symbolType === "function" || r.symbolType === "method";
|
|
2444
|
+
} else if (symbolType === "class") {
|
|
2445
|
+
return r.symbolType === "class";
|
|
2446
|
+
} else if (symbolType === "interface") {
|
|
2447
|
+
return r.symbolType === "interface";
|
|
2448
|
+
}
|
|
2449
|
+
return false;
|
|
2450
|
+
}
|
|
2451
|
+
return symbols.length > 0 && symbols.some((s) => s.length > 0 && s !== "");
|
|
1858
2452
|
}
|
|
1859
2453
|
return true;
|
|
1860
2454
|
});
|
|
@@ -1872,7 +2466,15 @@ var init_lancedb = __esm({
|
|
|
1872
2466
|
functions: r.functionNames || [],
|
|
1873
2467
|
classes: r.classNames || [],
|
|
1874
2468
|
interfaces: r.interfaceNames || []
|
|
1875
|
-
}
|
|
2469
|
+
},
|
|
2470
|
+
// AST-derived metadata (v0.13.0)
|
|
2471
|
+
symbolName: r.symbolName || void 0,
|
|
2472
|
+
symbolType: r.symbolType,
|
|
2473
|
+
parentClass: r.parentClass || void 0,
|
|
2474
|
+
complexity: r.complexity || void 0,
|
|
2475
|
+
parameters: r.parameters && r.parameters.length > 0 && r.parameters[0] !== "" ? r.parameters : void 0,
|
|
2476
|
+
signature: r.signature || void 0,
|
|
2477
|
+
imports: r.imports && r.imports.length > 0 && r.imports[0] !== "" ? r.imports : void 0
|
|
1876
2478
|
},
|
|
1877
2479
|
score,
|
|
1878
2480
|
relevance: calculateRelevance(score)
|
|
@@ -2023,33 +2625,6 @@ var init_lancedb = __esm({
|
|
|
2023
2625
|
}
|
|
2024
2626
|
});
|
|
2025
2627
|
|
|
2026
|
-
// src/utils/version.ts
|
|
2027
|
-
import { createRequire as createRequire2 } from "module";
|
|
2028
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2029
|
-
import { dirname as dirname2, join as join2 } from "path";
|
|
2030
|
-
function getPackageVersion() {
|
|
2031
|
-
return packageJson2.version;
|
|
2032
|
-
}
|
|
2033
|
-
var __filename3, __dirname3, require3, packageJson2;
|
|
2034
|
-
var init_version2 = __esm({
|
|
2035
|
-
"src/utils/version.ts"() {
|
|
2036
|
-
"use strict";
|
|
2037
|
-
__filename3 = fileURLToPath3(import.meta.url);
|
|
2038
|
-
__dirname3 = dirname2(__filename3);
|
|
2039
|
-
require3 = createRequire2(import.meta.url);
|
|
2040
|
-
try {
|
|
2041
|
-
packageJson2 = require3(join2(__dirname3, "../package.json"));
|
|
2042
|
-
} catch {
|
|
2043
|
-
try {
|
|
2044
|
-
packageJson2 = require3(join2(__dirname3, "../../package.json"));
|
|
2045
|
-
} catch {
|
|
2046
|
-
console.warn("[Lien] Warning: Could not load package.json, using fallback version");
|
|
2047
|
-
packageJson2 = { version: "0.0.0-unknown" };
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
});
|
|
2052
|
-
|
|
2053
2628
|
// src/indexer/manifest.ts
|
|
2054
2629
|
var manifest_exports = {};
|
|
2055
2630
|
__export(manifest_exports, {
|
|
@@ -2062,7 +2637,7 @@ var init_manifest = __esm({
|
|
|
2062
2637
|
"src/indexer/manifest.ts"() {
|
|
2063
2638
|
"use strict";
|
|
2064
2639
|
init_constants();
|
|
2065
|
-
|
|
2640
|
+
init_version();
|
|
2066
2641
|
MANIFEST_FILE = "manifest.json";
|
|
2067
2642
|
ManifestManager = class {
|
|
2068
2643
|
manifestPath;
|
|
@@ -2622,9 +3197,13 @@ import fs14 from "fs/promises";
|
|
|
2622
3197
|
async function processFileContent(filepath, content, embeddings, config, verbose) {
|
|
2623
3198
|
const chunkSize = isModernConfig(config) ? config.core.chunkSize : isLegacyConfig(config) ? config.indexing.chunkSize : 75;
|
|
2624
3199
|
const chunkOverlap = isModernConfig(config) ? config.core.chunkOverlap : isLegacyConfig(config) ? config.indexing.chunkOverlap : 10;
|
|
3200
|
+
const useAST = isModernConfig(config) ? config.chunking.useAST : true;
|
|
3201
|
+
const astFallback = isModernConfig(config) ? config.chunking.astFallback : "line-based";
|
|
2625
3202
|
const chunks = chunkFile(filepath, content, {
|
|
2626
3203
|
chunkSize,
|
|
2627
|
-
chunkOverlap
|
|
3204
|
+
chunkOverlap,
|
|
3205
|
+
useAST,
|
|
3206
|
+
astFallback
|
|
2628
3207
|
});
|
|
2629
3208
|
if (chunks.length === 0) {
|
|
2630
3209
|
if (verbose) {
|
|
@@ -2775,7 +3354,7 @@ async function indexMultipleFiles(filepaths, vectorDB, embeddings, config, optio
|
|
|
2775
3354
|
var init_incremental = __esm({
|
|
2776
3355
|
"src/indexer/incremental.ts"() {
|
|
2777
3356
|
"use strict";
|
|
2778
|
-
|
|
3357
|
+
init_chunker2();
|
|
2779
3358
|
init_schema();
|
|
2780
3359
|
init_manifest();
|
|
2781
3360
|
init_constants();
|
|
@@ -3037,9 +3616,13 @@ async function indexCodebase(options = {}) {
|
|
|
3037
3616
|
const content = await fs15.readFile(file, "utf-8");
|
|
3038
3617
|
const chunkSize = isModernConfig(config) ? config.core.chunkSize : 75;
|
|
3039
3618
|
const chunkOverlap = isModernConfig(config) ? config.core.chunkOverlap : 10;
|
|
3619
|
+
const useAST = isModernConfig(config) ? config.chunking.useAST : true;
|
|
3620
|
+
const astFallback = isModernConfig(config) ? config.chunking.astFallback : "line-based";
|
|
3040
3621
|
const chunks = chunkFile(file, content, {
|
|
3041
3622
|
chunkSize,
|
|
3042
|
-
chunkOverlap
|
|
3623
|
+
chunkOverlap,
|
|
3624
|
+
useAST,
|
|
3625
|
+
astFallback
|
|
3043
3626
|
});
|
|
3044
3627
|
if (chunks.length === 0) {
|
|
3045
3628
|
processedFiles++;
|
|
@@ -3117,11 +3700,11 @@ var init_indexer = __esm({
|
|
|
3117
3700
|
"src/indexer/index.ts"() {
|
|
3118
3701
|
"use strict";
|
|
3119
3702
|
init_scanner();
|
|
3120
|
-
|
|
3703
|
+
init_chunker2();
|
|
3121
3704
|
init_local();
|
|
3122
3705
|
init_lancedb();
|
|
3123
3706
|
init_service();
|
|
3124
|
-
|
|
3707
|
+
init_version2();
|
|
3125
3708
|
init_schema();
|
|
3126
3709
|
init_manifest();
|
|
3127
3710
|
init_change_detector();
|
|
@@ -3142,27 +3725,27 @@ init_schema();
|
|
|
3142
3725
|
init_merge();
|
|
3143
3726
|
import fs5 from "fs/promises";
|
|
3144
3727
|
import path5 from "path";
|
|
3145
|
-
import { fileURLToPath as
|
|
3728
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3146
3729
|
import chalk2 from "chalk";
|
|
3147
3730
|
import inquirer from "inquirer";
|
|
3148
3731
|
|
|
3149
3732
|
// src/utils/banner.ts
|
|
3150
3733
|
import figlet from "figlet";
|
|
3151
3734
|
import chalk from "chalk";
|
|
3152
|
-
import { createRequire } from "module";
|
|
3153
|
-
import { fileURLToPath } from "url";
|
|
3154
|
-
import { dirname, join } from "path";
|
|
3155
|
-
var
|
|
3156
|
-
var
|
|
3157
|
-
var
|
|
3158
|
-
var
|
|
3735
|
+
import { createRequire as createRequire2 } from "module";
|
|
3736
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3737
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
3738
|
+
var __filename2 = fileURLToPath2(import.meta.url);
|
|
3739
|
+
var __dirname2 = dirname2(__filename2);
|
|
3740
|
+
var require3 = createRequire2(import.meta.url);
|
|
3741
|
+
var packageJson2;
|
|
3159
3742
|
try {
|
|
3160
|
-
|
|
3743
|
+
packageJson2 = require3(join2(__dirname2, "../package.json"));
|
|
3161
3744
|
} catch {
|
|
3162
|
-
|
|
3745
|
+
packageJson2 = require3(join2(__dirname2, "../../package.json"));
|
|
3163
3746
|
}
|
|
3164
|
-
var PACKAGE_NAME =
|
|
3165
|
-
var VERSION =
|
|
3747
|
+
var PACKAGE_NAME = packageJson2.name;
|
|
3748
|
+
var VERSION = packageJson2.version;
|
|
3166
3749
|
function wrapInBox(text, footer, padding = 1) {
|
|
3167
3750
|
const lines = text.split("\n").filter((line) => line.trim().length > 0);
|
|
3168
3751
|
const maxLength = Math.max(...lines.map((line) => line.length));
|
|
@@ -3711,8 +4294,9 @@ async function scanSubdirectories(rootDir, relativePath, results, visited, depth
|
|
|
3711
4294
|
}
|
|
3712
4295
|
|
|
3713
4296
|
// src/cli/init.ts
|
|
3714
|
-
|
|
3715
|
-
var
|
|
4297
|
+
init_constants();
|
|
4298
|
+
var __filename3 = fileURLToPath3(import.meta.url);
|
|
4299
|
+
var __dirname3 = path5.dirname(__filename3);
|
|
3716
4300
|
async function initCommand(options = {}) {
|
|
3717
4301
|
const rootDir = options.path || process.cwd();
|
|
3718
4302
|
const configPath = path5.join(rootDir, ".lien.config.json");
|
|
@@ -3857,7 +4441,7 @@ async function createNewConfig(rootDir, options) {
|
|
|
3857
4441
|
try {
|
|
3858
4442
|
const cursorRulesDir = path5.join(rootDir, ".cursor");
|
|
3859
4443
|
await fs5.mkdir(cursorRulesDir, { recursive: true });
|
|
3860
|
-
const templatePath = path5.join(
|
|
4444
|
+
const templatePath = path5.join(__dirname3, "../CURSOR_RULES_TEMPLATE.md");
|
|
3861
4445
|
const rulesPath = path5.join(cursorRulesDir, "rules");
|
|
3862
4446
|
let targetPath;
|
|
3863
4447
|
let isDirectory = false;
|
|
@@ -3945,23 +4529,28 @@ Customizing ${frameworkName} settings:`));
|
|
|
3945
4529
|
}
|
|
3946
4530
|
async function upgradeConfig(configPath) {
|
|
3947
4531
|
try {
|
|
3948
|
-
const backupPath = `${configPath}.backup`;
|
|
3949
|
-
await fs5.copyFile(configPath, backupPath);
|
|
3950
4532
|
const existingContent = await fs5.readFile(configPath, "utf-8");
|
|
3951
4533
|
const existingConfig = JSON.parse(existingContent);
|
|
4534
|
+
const migrationNeeded = needsMigration(existingConfig);
|
|
4535
|
+
const newFields = migrationNeeded ? [] : detectNewFields(existingConfig, defaultConfig);
|
|
4536
|
+
const hasChanges = migrationNeeded || newFields.length > 0;
|
|
4537
|
+
if (!hasChanges) {
|
|
4538
|
+
console.log(chalk2.green("\u2713 Config is already up to date"));
|
|
4539
|
+
console.log(chalk2.dim("No changes needed"));
|
|
4540
|
+
return;
|
|
4541
|
+
}
|
|
4542
|
+
const backupPath = `${configPath}.backup`;
|
|
4543
|
+
await fs5.copyFile(configPath, backupPath);
|
|
3952
4544
|
let upgradedConfig;
|
|
3953
4545
|
let migrated = false;
|
|
3954
|
-
if (
|
|
3955
|
-
console.log(chalk2.blue(
|
|
4546
|
+
if (migrationNeeded) {
|
|
4547
|
+
console.log(chalk2.blue(`\u{1F504} Migrating config from v0.2.0 to v${CURRENT_CONFIG_VERSION}...`));
|
|
3956
4548
|
upgradedConfig = migrateConfig(existingConfig);
|
|
3957
4549
|
migrated = true;
|
|
3958
4550
|
} else {
|
|
3959
|
-
const newFields = detectNewFields(existingConfig, defaultConfig);
|
|
3960
4551
|
upgradedConfig = deepMergeConfig(defaultConfig, existingConfig);
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
newFields.forEach((field) => console.log(chalk2.dim(" \u2022"), chalk2.bold(field)));
|
|
3964
|
-
}
|
|
4552
|
+
console.log(chalk2.dim("\nNew options added:"));
|
|
4553
|
+
newFields.forEach((field) => console.log(chalk2.dim(" \u2022"), chalk2.bold(field)));
|
|
3965
4554
|
}
|
|
3966
4555
|
await fs5.writeFile(
|
|
3967
4556
|
configPath,
|
|
@@ -3982,7 +4571,7 @@ async function upgradeConfig(configPath) {
|
|
|
3982
4571
|
// src/cli/status.ts
|
|
3983
4572
|
init_service();
|
|
3984
4573
|
init_utils();
|
|
3985
|
-
|
|
4574
|
+
init_version2();
|
|
3986
4575
|
import chalk3 from "chalk";
|
|
3987
4576
|
import fs9 from "fs/promises";
|
|
3988
4577
|
import path9 from "path";
|