@pratik7368patil/anchor-core 0.1.28 → 0.1.30
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/dist/index.d.ts +12 -0
- package/dist/index.js +147 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/db/schema.sql +14 -0
package/dist/index.d.ts
CHANGED
|
@@ -781,6 +781,18 @@ type CodeIndexProgress = {
|
|
|
781
781
|
repo: string;
|
|
782
782
|
chunks: number;
|
|
783
783
|
patterns: number;
|
|
784
|
+
} | {
|
|
785
|
+
stage: "deleting_code_fts";
|
|
786
|
+
repo: string;
|
|
787
|
+
current: number;
|
|
788
|
+
total: number;
|
|
789
|
+
chunks: number;
|
|
790
|
+
} | {
|
|
791
|
+
stage: "deleting_architecture_fts";
|
|
792
|
+
repo: string;
|
|
793
|
+
current: number;
|
|
794
|
+
total: number;
|
|
795
|
+
patterns: number;
|
|
784
796
|
} | {
|
|
785
797
|
stage: "writing_code_files";
|
|
786
798
|
repo: string;
|
package/dist/index.js
CHANGED
|
@@ -707,6 +707,21 @@ CREATE INDEX IF NOT EXISTS idx_org_consumers_provider ON org_api_consumers(org,
|
|
|
707
707
|
CREATE INDEX IF NOT EXISTS idx_org_consumers_consumer ON org_api_consumers(org, consumer_repo);
|
|
708
708
|
CREATE INDEX IF NOT EXISTS idx_org_anomalies_org ON org_anomaly_events(org, severity);
|
|
709
709
|
CREATE INDEX IF NOT EXISTS idx_org_graph_state_status ON org_graph_state(org, last_status);
|
|
710
|
+
|
|
711
|
+
-- Foreign-key indexes backing per-repo / per-PR bulk deletes and re-index scans.
|
|
712
|
+
-- Without these, replaceCodeIndex/deleteExistingPrData full-scan each table per repo/PR.
|
|
713
|
+
CREATE INDEX IF NOT EXISTS idx_code_chunks_repo ON code_chunks(repo_id);
|
|
714
|
+
CREATE INDEX IF NOT EXISTS idx_code_files_repo ON code_files(repo_id);
|
|
715
|
+
CREATE INDEX IF NOT EXISTS idx_code_imports_repo ON code_imports(repo_id);
|
|
716
|
+
CREATE INDEX IF NOT EXISTS idx_test_files_repo ON test_files(repo_id);
|
|
717
|
+
CREATE INDEX IF NOT EXISTS idx_test_links_repo ON test_links(repo_id);
|
|
718
|
+
CREATE INDEX IF NOT EXISTS idx_architecture_components_repo ON architecture_components(repo_id);
|
|
719
|
+
CREATE INDEX IF NOT EXISTS idx_architecture_patterns_repo ON architecture_patterns(repo_id);
|
|
720
|
+
CREATE INDEX IF NOT EXISTS idx_architecture_map_edges_repo ON architecture_map_edges(repo_id);
|
|
721
|
+
CREATE INDEX IF NOT EXISTS idx_wisdom_units_repo ON wisdom_units(repo_id);
|
|
722
|
+
CREATE INDEX IF NOT EXISTS idx_regression_events_repo ON regression_events(repo_id);
|
|
723
|
+
CREATE INDEX IF NOT EXISTS idx_pr_files_pr ON pr_files(pr_id);
|
|
724
|
+
CREATE INDEX IF NOT EXISTS idx_pr_comments_pr ON pr_comments(pr_id);
|
|
710
725
|
`;
|
|
711
726
|
|
|
712
727
|
// src/rules/team-rules.ts
|
|
@@ -1695,9 +1710,28 @@ function calculateCoverage(input) {
|
|
|
1695
1710
|
|
|
1696
1711
|
// src/db/database.ts
|
|
1697
1712
|
var CODE_WRITE_PROGRESS_INTERVAL = 150;
|
|
1713
|
+
var FTS_DELETE_BATCH_SIZE = 500;
|
|
1698
1714
|
function shouldEmitCodeWriteProgress(current, total) {
|
|
1699
1715
|
return current === 0 || current === 1 || current === total || current % CODE_WRITE_PROGRESS_INTERVAL === 0;
|
|
1700
1716
|
}
|
|
1717
|
+
function shouldEmitFtsDeleteProgress(current, total) {
|
|
1718
|
+
return current === 0 || current === 1 || current === total || current % FTS_DELETE_BATCH_SIZE === 0;
|
|
1719
|
+
}
|
|
1720
|
+
function deleteFtsRowsByRowId(db, ftsTable, rowIds, onProgress) {
|
|
1721
|
+
if (rowIds.length === 0) {
|
|
1722
|
+
onProgress?.(0, 0);
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
const deleteRow = db.prepare(`DELETE FROM ${ftsTable} WHERE rowid = ?`);
|
|
1726
|
+
onProgress?.(0, rowIds.length);
|
|
1727
|
+
for (const [index, rowId] of rowIds.entries()) {
|
|
1728
|
+
deleteRow.run(rowId);
|
|
1729
|
+
const current = index + 1;
|
|
1730
|
+
if (shouldEmitFtsDeleteProgress(current, rowIds.length)) {
|
|
1731
|
+
onProgress?.(current, rowIds.length);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1701
1735
|
function defaultDatabasePath(cwd) {
|
|
1702
1736
|
return path4.join(cwd, ".anchor", "index.sqlite");
|
|
1703
1737
|
}
|
|
@@ -1707,14 +1741,22 @@ function openAnchorDatabase(cwd, databasePath = defaultDatabasePath(cwd)) {
|
|
|
1707
1741
|
db.pragma("busy_timeout = 5000");
|
|
1708
1742
|
db.pragma("journal_mode = WAL");
|
|
1709
1743
|
db.pragma("foreign_keys = ON");
|
|
1744
|
+
applyPerformancePragmas(db);
|
|
1710
1745
|
return db;
|
|
1711
1746
|
}
|
|
1712
1747
|
function openAnchorDatabaseReadOnly(databasePath) {
|
|
1713
1748
|
const db = new Database(databasePath, { readonly: true, fileMustExist: true });
|
|
1714
1749
|
db.pragma("busy_timeout = 5000");
|
|
1715
1750
|
db.pragma("foreign_keys = ON");
|
|
1751
|
+
applyPerformancePragmas(db);
|
|
1716
1752
|
return db;
|
|
1717
1753
|
}
|
|
1754
|
+
function applyPerformancePragmas(db) {
|
|
1755
|
+
db.pragma("synchronous = NORMAL");
|
|
1756
|
+
db.pragma("cache_size = -65536");
|
|
1757
|
+
db.pragma("mmap_size = 268435456");
|
|
1758
|
+
db.pragma("temp_store = MEMORY");
|
|
1759
|
+
}
|
|
1718
1760
|
function initializeSchema(db) {
|
|
1719
1761
|
db.exec(SCHEMA_SQL);
|
|
1720
1762
|
ensureColumn(db, "sync_state", "history_coverage", "TEXT");
|
|
@@ -1882,9 +1924,12 @@ function clearGraphQLFetchCheckpoint(db, repo, scope) {
|
|
|
1882
1924
|
).run((/* @__PURE__ */ new Date()).toISOString(), repo);
|
|
1883
1925
|
}
|
|
1884
1926
|
function deleteExistingPrData(db, prId) {
|
|
1885
|
-
db.prepare(
|
|
1886
|
-
|
|
1887
|
-
|
|
1927
|
+
const wisdomRowIds = db.prepare("SELECT rowid FROM wisdom_units WHERE pr_id = ?").all(prId);
|
|
1928
|
+
deleteFtsRowsByRowId(
|
|
1929
|
+
db,
|
|
1930
|
+
"wisdom_units_fts",
|
|
1931
|
+
wisdomRowIds.map((row) => row.rowid)
|
|
1932
|
+
);
|
|
1888
1933
|
db.prepare("DELETE FROM regression_events WHERE pr_id = ?").run(prId);
|
|
1889
1934
|
db.prepare("DELETE FROM wisdom_units WHERE pr_id = ?").run(prId);
|
|
1890
1935
|
db.prepare("DELETE FROM pr_comments WHERE pr_id = ?").run(prId);
|
|
@@ -1996,11 +2041,11 @@ function upsertPullRequest(db, pr, wisdomUnits, regressionEvents = []) {
|
|
|
1996
2041
|
);
|
|
1997
2042
|
const insertFts = db.prepare(
|
|
1998
2043
|
`INSERT INTO wisdom_units_fts
|
|
1999
|
-
(unitId, sanitizedText, filePaths, symbols, prTitle, prBody, category)
|
|
2000
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
2044
|
+
(rowid, unitId, sanitizedText, filePaths, symbols, prTitle, prBody, category)
|
|
2045
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2001
2046
|
);
|
|
2002
2047
|
for (const unit of wisdomUnits) {
|
|
2003
|
-
insertWisdom.run(
|
|
2048
|
+
const wisdomInsert = insertWisdom.run(
|
|
2004
2049
|
unit.id,
|
|
2005
2050
|
repoId,
|
|
2006
2051
|
prRow.id,
|
|
@@ -2019,6 +2064,7 @@ function upsertPullRequest(db, pr, wisdomUnits, regressionEvents = []) {
|
|
|
2019
2064
|
unit.confidence
|
|
2020
2065
|
);
|
|
2021
2066
|
insertFts.run(
|
|
2067
|
+
Number(wisdomInsert.lastInsertRowid),
|
|
2022
2068
|
unit.id,
|
|
2023
2069
|
unit.sanitizedText,
|
|
2024
2070
|
unit.filePaths.join(" "),
|
|
@@ -2075,22 +2121,31 @@ function replaceCodeIndex(db, repo, codeFiles, codeChunks, skippedFiles, cwd, ar
|
|
|
2075
2121
|
});
|
|
2076
2122
|
options.onProgress?.({ stage: "writing_code_index", repo, phase: "Writing code index" });
|
|
2077
2123
|
const transaction = db.transaction(() => {
|
|
2078
|
-
const
|
|
2079
|
-
const
|
|
2124
|
+
const existingChunkRowIds = db.prepare("SELECT rowid FROM code_chunks WHERE repo_id = ?").all(repoId);
|
|
2125
|
+
const existingPatternRowIds = db.prepare("SELECT rowid FROM architecture_patterns WHERE repo_id = ?").all(repoId);
|
|
2080
2126
|
options.onProgress?.({
|
|
2081
2127
|
stage: "deleting_existing_code_index",
|
|
2082
2128
|
repo,
|
|
2083
|
-
chunks:
|
|
2084
|
-
patterns:
|
|
2129
|
+
chunks: existingChunkRowIds.length,
|
|
2130
|
+
patterns: existingPatternRowIds.length
|
|
2085
2131
|
});
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2132
|
+
deleteFtsRowsByRowId(
|
|
2133
|
+
db,
|
|
2134
|
+
"code_chunks_fts",
|
|
2135
|
+
existingChunkRowIds.map((row) => row.rowid),
|
|
2136
|
+
(current, total) => options.onProgress?.({
|
|
2137
|
+
stage: "deleting_code_fts",
|
|
2138
|
+
repo,
|
|
2139
|
+
current,
|
|
2140
|
+
total,
|
|
2141
|
+
chunks: existingChunkRowIds.length
|
|
2142
|
+
})
|
|
2143
|
+
);
|
|
2089
2144
|
db.prepare("DELETE FROM code_chunks WHERE repo_id = ?").run(repoId);
|
|
2090
2145
|
db.prepare("DELETE FROM code_files WHERE repo_id = ?").run(repoId);
|
|
2091
2146
|
db.prepare("DELETE FROM test_links WHERE repo_id = ? AND reason != 'PR co-change'").run(repoId);
|
|
2092
2147
|
db.prepare("DELETE FROM test_files WHERE repo_id = ?").run(repoId);
|
|
2093
|
-
deleteExistingArchitectureData(db, repoId);
|
|
2148
|
+
deleteExistingArchitectureData(db, repoId, repo, existingPatternRowIds, options);
|
|
2094
2149
|
const insertFile = db.prepare(
|
|
2095
2150
|
`INSERT INTO code_files
|
|
2096
2151
|
(repo_id, path, language, size_bytes, content_hash, updated_at)
|
|
@@ -2132,8 +2187,8 @@ function replaceCodeIndex(db, repo, codeFiles, codeChunks, skippedFiles, cwd, ar
|
|
|
2132
2187
|
);
|
|
2133
2188
|
const insertFts = db.prepare(
|
|
2134
2189
|
`INSERT INTO code_chunks_fts
|
|
2135
|
-
(chunkId, sanitizedText, filePath, symbols, language)
|
|
2136
|
-
VALUES (?, ?, ?, ?, ?)`
|
|
2190
|
+
(rowid, chunkId, sanitizedText, filePath, symbols, language)
|
|
2191
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
2137
2192
|
);
|
|
2138
2193
|
options.onProgress?.({
|
|
2139
2194
|
stage: "writing_code_chunks",
|
|
@@ -2146,7 +2201,7 @@ function replaceCodeIndex(db, repo, codeFiles, codeChunks, skippedFiles, cwd, ar
|
|
|
2146
2201
|
for (const [index, chunk] of codeChunks.entries()) {
|
|
2147
2202
|
const fileId = fileIds.get(chunk.filePath);
|
|
2148
2203
|
if (!fileId) continue;
|
|
2149
|
-
insertChunk.run(
|
|
2204
|
+
const chunkInsert = insertChunk.run(
|
|
2150
2205
|
chunk.id,
|
|
2151
2206
|
repoId,
|
|
2152
2207
|
fileId,
|
|
@@ -2161,6 +2216,7 @@ function replaceCodeIndex(db, repo, codeFiles, codeChunks, skippedFiles, cwd, ar
|
|
|
2161
2216
|
chunk.updatedAt
|
|
2162
2217
|
);
|
|
2163
2218
|
insertFts.run(
|
|
2219
|
+
Number(chunkInsert.lastInsertRowid),
|
|
2164
2220
|
chunk.id,
|
|
2165
2221
|
chunk.sanitizedText,
|
|
2166
2222
|
chunk.filePath,
|
|
@@ -2222,10 +2278,19 @@ function replaceCodeIndex(db, repo, codeFiles, codeChunks, skippedFiles, cwd, ar
|
|
|
2222
2278
|
databasePath: defaultDatabasePath(cwd)
|
|
2223
2279
|
};
|
|
2224
2280
|
}
|
|
2225
|
-
function deleteExistingArchitectureData(db, repoId) {
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2281
|
+
function deleteExistingArchitectureData(db, repoId, repo, patternRowIds, options = {}) {
|
|
2282
|
+
deleteFtsRowsByRowId(
|
|
2283
|
+
db,
|
|
2284
|
+
"architecture_patterns_fts",
|
|
2285
|
+
patternRowIds.map((row) => row.rowid),
|
|
2286
|
+
(current, total) => options.onProgress?.({
|
|
2287
|
+
stage: "deleting_architecture_fts",
|
|
2288
|
+
repo,
|
|
2289
|
+
current,
|
|
2290
|
+
total,
|
|
2291
|
+
patterns: patternRowIds.length
|
|
2292
|
+
})
|
|
2293
|
+
);
|
|
2229
2294
|
db.prepare("DELETE FROM architecture_patterns WHERE repo_id = ?").run(repoId);
|
|
2230
2295
|
db.prepare("DELETE FROM architecture_components WHERE repo_id = ?").run(repoId);
|
|
2231
2296
|
db.prepare("DELETE FROM code_imports WHERE repo_id = ?").run(repoId);
|
|
@@ -2308,8 +2373,8 @@ function insertArchitectureData(db, repoId, repo, architecture, options = {}) {
|
|
|
2308
2373
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
2309
2374
|
);
|
|
2310
2375
|
const insertFts = db.prepare(
|
|
2311
|
-
`INSERT INTO architecture_patterns_fts (patternId, summary, area, sourceFiles, symbols)
|
|
2312
|
-
VALUES (?, ?, ?, ?, ?)`
|
|
2376
|
+
`INSERT INTO architecture_patterns_fts (rowid, patternId, summary, area, sourceFiles, symbols)
|
|
2377
|
+
VALUES (?, ?, ?, ?, ?, ?)`
|
|
2313
2378
|
);
|
|
2314
2379
|
options.onProgress?.({
|
|
2315
2380
|
stage: "writing_architecture_data",
|
|
@@ -2319,7 +2384,7 @@ function insertArchitectureData(db, repoId, repo, architecture, options = {}) {
|
|
|
2319
2384
|
kind: "patterns"
|
|
2320
2385
|
});
|
|
2321
2386
|
for (const [index, pattern] of architecture.patterns.entries()) {
|
|
2322
|
-
insertPattern.run(
|
|
2387
|
+
const patternInsert = insertPattern.run(
|
|
2323
2388
|
pattern.id,
|
|
2324
2389
|
repoId,
|
|
2325
2390
|
pattern.repo,
|
|
@@ -2333,6 +2398,7 @@ function insertArchitectureData(db, repoId, repo, architecture, options = {}) {
|
|
|
2333
2398
|
pattern.createdAt
|
|
2334
2399
|
);
|
|
2335
2400
|
insertFts.run(
|
|
2401
|
+
Number(patternInsert.lastInsertRowid),
|
|
2336
2402
|
pattern.id,
|
|
2337
2403
|
pattern.sanitizedSummary,
|
|
2338
2404
|
pattern.area,
|
|
@@ -2921,14 +2987,24 @@ function buildRelatedTestIndex(allPaths) {
|
|
|
2921
2987
|
const testPaths = allPaths.filter((candidate) => isTestFilePath(candidate));
|
|
2922
2988
|
const byBase = /* @__PURE__ */ new Map();
|
|
2923
2989
|
const byDirectory = /* @__PURE__ */ new Map();
|
|
2990
|
+
const byDotPrefix = /* @__PURE__ */ new Map();
|
|
2924
2991
|
for (const testPath of testPaths) {
|
|
2925
2992
|
addToStringMap(byBase, testBaseFor(testPath), testPath);
|
|
2926
|
-
const
|
|
2927
|
-
for (let index = 1; index <=
|
|
2928
|
-
addToStringMap(byDirectory,
|
|
2993
|
+
const dirSegments = path6.posix.dirname(testPath).split("/").filter(Boolean);
|
|
2994
|
+
for (let index = 1; index <= dirSegments.length; index += 1) {
|
|
2995
|
+
addToStringMap(byDirectory, dirSegments.slice(0, index).join("/"), testPath);
|
|
2996
|
+
}
|
|
2997
|
+
const pathSegments2 = testPath.split("/");
|
|
2998
|
+
const dotPrefixes = /* @__PURE__ */ new Set();
|
|
2999
|
+
for (let i = 1; i < pathSegments2.length; i += 1) {
|
|
3000
|
+
const segment = pathSegments2[i] ?? "";
|
|
3001
|
+
for (let dot = segment.indexOf("."); dot >= 0; dot = segment.indexOf(".", dot + 1)) {
|
|
3002
|
+
dotPrefixes.add(segment.slice(0, dot));
|
|
3003
|
+
}
|
|
2929
3004
|
}
|
|
3005
|
+
for (const prefix of dotPrefixes) addToStringMap(byDotPrefix, prefix, testPath);
|
|
2930
3006
|
}
|
|
2931
|
-
return { testPaths, byBase, byDirectory };
|
|
3007
|
+
return { testPaths, byBase, byDirectory, byDotPrefix };
|
|
2932
3008
|
}
|
|
2933
3009
|
function relatedTestsFor(filePath, index) {
|
|
2934
3010
|
if (isTestFilePath(filePath)) return [];
|
|
@@ -2945,8 +3021,8 @@ function relatedTestsFor(filePath, index) {
|
|
|
2945
3021
|
if (parsed.dir) {
|
|
2946
3022
|
for (const testPath of index.byDirectory.get(parsed.dir) ?? []) add(testPath);
|
|
2947
3023
|
}
|
|
2948
|
-
for (const testPath of index.
|
|
2949
|
-
|
|
3024
|
+
for (const testPath of index.byDotPrefix.get(basename) ?? []) {
|
|
3025
|
+
add(testPath);
|
|
2950
3026
|
if (related.length >= 8) break;
|
|
2951
3027
|
}
|
|
2952
3028
|
return related.slice(0, 8);
|
|
@@ -4094,8 +4170,7 @@ function symbolMatch2(unit, querySymbols) {
|
|
|
4094
4170
|
const lower = symbol.toLowerCase();
|
|
4095
4171
|
if (unitSymbols.includes(lower)) best = Math.max(best, 1);
|
|
4096
4172
|
else if (text.includes(`\`${lower}\``)) best = Math.max(best, 1);
|
|
4097
|
-
else if (
|
|
4098
|
-
best = Math.max(best, 0.66);
|
|
4173
|
+
else if (symbolBoundaryRegex(lower).test(text)) best = Math.max(best, 0.66);
|
|
4099
4174
|
else if (unitSymbols.some((candidate) => candidate.includes(lower) || lower.includes(candidate))) {
|
|
4100
4175
|
best = Math.max(best, 0.35);
|
|
4101
4176
|
}
|
|
@@ -4178,6 +4253,15 @@ function scoreUnit(unit, input, duplicateCount, repeatedEvidenceCount, freshness
|
|
|
4178
4253
|
function escapeRegExp(value) {
|
|
4179
4254
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4180
4255
|
}
|
|
4256
|
+
var symbolBoundaryRegexCache = /* @__PURE__ */ new Map();
|
|
4257
|
+
function symbolBoundaryRegex(lower) {
|
|
4258
|
+
let regex = symbolBoundaryRegexCache.get(lower);
|
|
4259
|
+
if (!regex) {
|
|
4260
|
+
regex = new RegExp(`\\b${escapeRegExp(lower)}\\b`, "i");
|
|
4261
|
+
symbolBoundaryRegexCache.set(lower, regex);
|
|
4262
|
+
}
|
|
4263
|
+
return regex;
|
|
4264
|
+
}
|
|
4181
4265
|
function loadCandidates(db, input) {
|
|
4182
4266
|
const ftsQuery = buildFtsQuery(input);
|
|
4183
4267
|
const categories = "categories" in input ? input.categories ?? [] : [];
|
|
@@ -4213,9 +4297,11 @@ function loadClaimRepetitionCounts(db) {
|
|
|
4213
4297
|
}
|
|
4214
4298
|
return new Map([...grouped.entries()].map(([key, prs]) => [key, prs.size]));
|
|
4215
4299
|
}
|
|
4216
|
-
function loadFeedbackAdjustments(db) {
|
|
4217
|
-
const rows = db.prepare("SELECT result_id, rating FROM feedback_events").all();
|
|
4300
|
+
function loadFeedbackAdjustments(db, resultIds) {
|
|
4218
4301
|
const adjustments = /* @__PURE__ */ new Map();
|
|
4302
|
+
if (resultIds.length === 0) return adjustments;
|
|
4303
|
+
const placeholders = resultIds.map(() => "?").join(", ");
|
|
4304
|
+
const rows = db.prepare(`SELECT result_id, rating FROM feedback_events WHERE result_id IN (${placeholders})`).all(...resultIds);
|
|
4219
4305
|
for (const row of rows) {
|
|
4220
4306
|
const delta = row.rating === "useful" ? 0.03 : -0.03;
|
|
4221
4307
|
adjustments.set(row.result_id, (adjustments.get(row.result_id) ?? 0) + delta);
|
|
@@ -4235,7 +4321,10 @@ function rankWisdomUnits(db, input) {
|
|
|
4235
4321
|
const candidates = loadCandidates(db, input);
|
|
4236
4322
|
const codeSnapshot = loadCurrentCodeSnapshot(db);
|
|
4237
4323
|
const repetitionCounts = loadClaimRepetitionCounts(db);
|
|
4238
|
-
const feedbackAdjustments = loadFeedbackAdjustments(
|
|
4324
|
+
const feedbackAdjustments = loadFeedbackAdjustments(
|
|
4325
|
+
db,
|
|
4326
|
+
candidates.map((unit) => unit.id)
|
|
4327
|
+
);
|
|
4239
4328
|
const duplicates = /* @__PURE__ */ new Map();
|
|
4240
4329
|
for (const unit of candidates) {
|
|
4241
4330
|
const key = claimKeyFor(unit.category, unit.sanitizedText);
|
|
@@ -9897,8 +9986,9 @@ function queryTerms(input) {
|
|
|
9897
9986
|
function matchesRepo(repo, repos) {
|
|
9898
9987
|
return !repos || repos.length === 0 || repos.includes(repo);
|
|
9899
9988
|
}
|
|
9900
|
-
function rowScore(input, text, files, symbols) {
|
|
9989
|
+
function rowScore(input, text, files, symbols, lowerTerms) {
|
|
9901
9990
|
let score = 0;
|
|
9991
|
+
const lowerText = text.toLowerCase();
|
|
9902
9992
|
for (const file of input.files ?? []) {
|
|
9903
9993
|
if (files.includes(file)) score += 5;
|
|
9904
9994
|
else if (files.some((candidate) => candidate.endsWith(`/${file.split("/").pop() ?? file}`)))
|
|
@@ -9906,10 +9996,10 @@ function rowScore(input, text, files, symbols) {
|
|
|
9906
9996
|
}
|
|
9907
9997
|
for (const symbol of input.symbols ?? []) {
|
|
9908
9998
|
if (symbols.includes(symbol)) score += 4;
|
|
9909
|
-
else if (
|
|
9999
|
+
else if (lowerText.includes(symbol.toLowerCase())) score += 1;
|
|
9910
10000
|
}
|
|
9911
|
-
for (const term of
|
|
9912
|
-
if (
|
|
10001
|
+
for (const term of lowerTerms) {
|
|
10002
|
+
if (lowerText.includes(term)) score += 0.5;
|
|
9913
10003
|
}
|
|
9914
10004
|
return score;
|
|
9915
10005
|
}
|
|
@@ -9920,9 +10010,10 @@ function getWisdom(db, input, limit) {
|
|
|
9920
10010
|
ORDER BY confidence DESC, created_at DESC
|
|
9921
10011
|
LIMIT 500`
|
|
9922
10012
|
).all();
|
|
10013
|
+
const lowerTerms = queryTerms(input).map((term) => term.toLowerCase());
|
|
9923
10014
|
return rows.filter((row) => matchesRepo(row.repo, input.repos)).map((row) => ({
|
|
9924
10015
|
row,
|
|
9925
|
-
score: rowScore(input, row.sanitized_text, parseStringArray(row.file_paths_json), [])
|
|
10016
|
+
score: rowScore(input, row.sanitized_text, parseStringArray(row.file_paths_json), [], lowerTerms)
|
|
9926
10017
|
})).filter((item) => item.score > 0 || (input.files ?? []).length === 0).sort((a, b) => b.score - a.score || b.row.confidence - a.row.confidence).slice(0, limit).map((item) => item.row);
|
|
9927
10018
|
}
|
|
9928
10019
|
function getCodeEvidence(db, input, limit) {
|
|
@@ -9932,13 +10023,15 @@ function getCodeEvidence(db, input, limit) {
|
|
|
9932
10023
|
ORDER BY updated_at DESC
|
|
9933
10024
|
LIMIT 800`
|
|
9934
10025
|
).all();
|
|
10026
|
+
const lowerTerms = queryTerms(input).map((term) => term.toLowerCase());
|
|
9935
10027
|
return rows.filter((row) => matchesRepo(row.repo, input.repos)).map((row) => ({
|
|
9936
10028
|
row,
|
|
9937
10029
|
score: rowScore(
|
|
9938
10030
|
input,
|
|
9939
10031
|
row.sanitized_text,
|
|
9940
10032
|
[row.file_path],
|
|
9941
|
-
parseStringArray(row.symbols_json)
|
|
10033
|
+
parseStringArray(row.symbols_json),
|
|
10034
|
+
lowerTerms
|
|
9942
10035
|
)
|
|
9943
10036
|
})).filter((item) => item.score > 0).sort((a, b) => b.score - a.score).slice(0, limit).map((item) => item.row);
|
|
9944
10037
|
}
|
|
@@ -9949,23 +10042,30 @@ function getArchitecture(db, input, limit) {
|
|
|
9949
10042
|
ORDER BY confidence DESC, created_at DESC
|
|
9950
10043
|
LIMIT 300`
|
|
9951
10044
|
).all();
|
|
10045
|
+
const lowerTerms = queryTerms(input).map((term) => term.toLowerCase());
|
|
9952
10046
|
return rows.filter((row) => matchesRepo(row.repo, input.repos)).map((row) => ({
|
|
9953
10047
|
row,
|
|
9954
|
-
score: rowScore(
|
|
10048
|
+
score: rowScore(
|
|
10049
|
+
input,
|
|
10050
|
+
row.summary_sanitized,
|
|
10051
|
+
parseStringArray(row.source_files_json),
|
|
10052
|
+
[],
|
|
10053
|
+
lowerTerms
|
|
10054
|
+
)
|
|
9955
10055
|
})).filter((item) => item.score > 0 || (input.files ?? []).length === 0).sort((a, b) => b.score - a.score || b.row.confidence - a.row.confidence).slice(0, limit).map((item) => item.row);
|
|
9956
10056
|
}
|
|
9957
10057
|
function findOrgApiConsumers(db, config, input) {
|
|
9958
10058
|
initializeSchema(db);
|
|
10059
|
+
const repoClause = input.repo ? " AND (provider_repo = ? OR consumer_repo = ?)" : "";
|
|
10060
|
+
const repoParams = input.repo ? [input.repo, input.repo] : [];
|
|
9959
10061
|
const rows = db.prepare(
|
|
9960
10062
|
`SELECT provider_repo, provider_path, consumer_repo, consumer_path, contract, evidence_json, confidence
|
|
9961
10063
|
FROM org_api_consumers
|
|
9962
|
-
WHERE org =
|
|
10064
|
+
WHERE org = ?${repoClause}
|
|
9963
10065
|
ORDER BY confidence DESC`
|
|
9964
|
-
).all(config.org);
|
|
10066
|
+
).all(config.org, ...repoParams);
|
|
9965
10067
|
const limit = Math.max(1, Math.min(input.maxResults ?? 8, 25));
|
|
9966
|
-
return rows.filter(
|
|
9967
|
-
(row) => !input.repo || row.provider_repo === input.repo || row.consumer_repo === input.repo
|
|
9968
|
-
).filter((row) => {
|
|
10068
|
+
return rows.filter((row) => {
|
|
9969
10069
|
const files = input.files ?? [];
|
|
9970
10070
|
if (files.length === 0 && !input.query) return true;
|
|
9971
10071
|
return files.some((file) => row.provider_path === file || row.consumer_path === file) || Boolean(input.query && row.contract.toLowerCase().includes(input.query.toLowerCase()));
|