@monoes/monograph 1.6.0 → 1.6.2
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/src/cache/extraction-cache.d.ts +3 -1
- package/dist/src/cache/extraction-cache.d.ts.map +1 -1
- package/dist/src/cache/extraction-cache.js +10 -2
- package/dist/src/cache/extraction-cache.js.map +1 -1
- package/dist/src/graph/explain.d.ts.map +1 -1
- package/dist/src/graph/explain.js +9 -2
- package/dist/src/graph/explain.js.map +1 -1
- package/dist/src/graph/pagerank.d.ts +9 -3
- package/dist/src/graph/pagerank.d.ts.map +1 -1
- package/dist/src/graph/pagerank.js +69 -34
- package/dist/src/graph/pagerank.js.map +1 -1
- package/dist/src/mcp-tools/neighbors.d.ts +29 -3
- package/dist/src/mcp-tools/neighbors.d.ts.map +1 -1
- package/dist/src/mcp-tools/neighbors.js +85 -10
- package/dist/src/mcp-tools/neighbors.js.map +1 -1
- package/dist/src/mcp-tools/query.d.ts +8 -0
- package/dist/src/mcp-tools/query.d.ts.map +1 -1
- package/dist/src/mcp-tools/query.js +15 -9
- package/dist/src/mcp-tools/query.js.map +1 -1
- package/dist/src/mcp-tools/rename.d.ts.map +1 -1
- package/dist/src/mcp-tools/rename.js +27 -2
- package/dist/src/mcp-tools/rename.js.map +1 -1
- package/dist/src/parsers/cpp.d.ts.map +1 -1
- package/dist/src/parsers/cpp.js +12 -2
- package/dist/src/parsers/cpp.js.map +1 -1
- package/dist/src/parsers/dart.d.ts.map +1 -1
- package/dist/src/parsers/dart.js +18 -0
- package/dist/src/parsers/dart.js.map +1 -1
- package/dist/src/parsers/extractor.d.ts.map +1 -1
- package/dist/src/parsers/extractor.js +22 -8
- package/dist/src/parsers/extractor.js.map +1 -1
- package/dist/src/parsers/kotlin.d.ts +1 -1
- package/dist/src/parsers/kotlin.d.ts.map +1 -1
- package/dist/src/parsers/kotlin.js +4 -0
- package/dist/src/parsers/kotlin.js.map +1 -1
- package/dist/src/parsers/language-config.d.ts +7 -0
- package/dist/src/parsers/language-config.d.ts.map +1 -1
- package/dist/src/parsers/language-config.js +14 -1
- package/dist/src/parsers/language-config.js.map +1 -1
- package/dist/src/parsers/loader.js +17 -3
- package/dist/src/parsers/loader.js.map +1 -1
- package/dist/src/parsers/ruby.d.ts +1 -1
- package/dist/src/parsers/ruby.d.ts.map +1 -1
- package/dist/src/parsers/ruby.js +4 -0
- package/dist/src/parsers/ruby.js.map +1 -1
- package/dist/src/pipeline/index-scope.d.ts +23 -0
- package/dist/src/pipeline/index-scope.d.ts.map +1 -0
- package/dist/src/pipeline/index-scope.js +33 -0
- package/dist/src/pipeline/index-scope.js.map +1 -0
- package/dist/src/pipeline/orchestrator.d.ts +17 -0
- package/dist/src/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/src/pipeline/orchestrator.js +55 -122
- package/dist/src/pipeline/orchestrator.js.map +1 -1
- package/dist/src/pipeline/phases/communities.d.ts +78 -2
- package/dist/src/pipeline/phases/communities.d.ts.map +1 -1
- package/dist/src/pipeline/phases/communities.js +141 -9
- package/dist/src/pipeline/phases/communities.js.map +1 -1
- package/dist/src/pipeline/phases/markdown.js +6 -6
- package/dist/src/pipeline/phases/markdown.js.map +1 -1
- package/dist/src/pipeline/phases/parse.d.ts.map +1 -1
- package/dist/src/pipeline/phases/parse.js +22 -27
- package/dist/src/pipeline/phases/parse.js.map +1 -1
- package/dist/src/pipeline/phases/pdf-parse.js +5 -5
- package/dist/src/pipeline/phases/pdf-parse.js.map +1 -1
- package/dist/src/pipeline/phases/scan.d.ts.map +1 -1
- package/dist/src/pipeline/phases/scan.js +16 -1
- package/dist/src/pipeline/phases/scan.js.map +1 -1
- package/dist/src/pipeline/phases/structure.js +12 -12
- package/dist/src/pipeline/phases/structure.js.map +1 -1
- package/dist/src/pipeline/phases/variables.d.ts.map +1 -1
- package/dist/src/pipeline/phases/variables.js +2 -1
- package/dist/src/pipeline/phases/variables.js.map +1 -1
- package/dist/src/search/hybrid-query.d.ts +77 -14
- package/dist/src/search/hybrid-query.d.ts.map +1 -1
- package/dist/src/search/hybrid-query.js +81 -21
- package/dist/src/search/hybrid-query.js.map +1 -1
- package/dist/src/staleness/git-staleness.d.ts +46 -0
- package/dist/src/staleness/git-staleness.d.ts.map +1 -1
- package/dist/src/staleness/git-staleness.js +188 -24
- package/dist/src/staleness/git-staleness.js.map +1 -1
- package/dist/src/storage/fts-store.d.ts +14 -0
- package/dist/src/storage/fts-store.d.ts.map +1 -1
- package/dist/src/storage/fts-store.js +18 -3
- package/dist/src/storage/fts-store.js.map +1 -1
- package/dist/src/types.d.ts +58 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +103 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/web/api.d.ts +3 -0
- package/dist/src/web/api.d.ts.map +1 -1
- package/dist/src/web/api.js +2 -0
- package/dist/src/web/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MonographEdge, type MonographNode } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Bump this whenever the parser/extractor output format changes in a way that
|
|
4
4
|
* would make previously-cached nodes/edges stale or wrong (e.g. a parser bugfix,
|
|
@@ -15,6 +15,8 @@ export interface CacheEntry {
|
|
|
15
15
|
edges: MonographEdge[];
|
|
16
16
|
/** Extraction format version this entry was written under — see EXTRACTION_CACHE_VERSION. */
|
|
17
17
|
cacheVersion?: number;
|
|
18
|
+
/** Symbol-identity scheme this entry's node IDs were minted under — see SYMBOL_ID_VERSION. */
|
|
19
|
+
symbolIdVersion?: number;
|
|
18
20
|
}
|
|
19
21
|
export declare class ExtractionCache {
|
|
20
22
|
private readonly dir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction-cache.d.ts","sourceRoot":"","sources":["../../../src/cache/extraction-cache.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"extraction-cache.d.ts","sourceRoot":"","sources":["../../../src/cache/extraction-cache.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAqB,MAAM,aAAa,CAAC;AAExF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAU1C,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAUD,qBAAa,eAAe;IAGd,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,OAAO,CAA6C;IAE5D,YAA6B,GAAG,EAAE,MAAM,EAEvC;IAED,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGjC;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnC;IAED,OAAO,CAAC,SAAS;IAKjB;8DAC0D;IAC1D,OAAO,CAAC,WAAW;IAcnB;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ,SAA2B,GAAG,MAAM,CAqBjD;IAED;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAuB/C;IAED,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAUzD;IAED,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAoB5F;IAED,WAAW,CACT,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,EAAE,EACtB,KAAK,EAAE,aAAa,EAAE,GACrB,IAAI,CAoBN;IAED,KAAK,IAAI,IAAI,CASZ;CACF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
+
import { SYMBOL_ID_VERSION } from '../types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Bump this whenever the parser/extractor output format changes in a way that
|
|
6
7
|
* would make previously-cached nodes/edges stale or wrong (e.g. a parser bugfix,
|
|
@@ -9,6 +10,11 @@ import { join } from 'node:path';
|
|
|
9
10
|
* bumping this effectively invalidates the entire on-disk extraction cache.
|
|
10
11
|
*/
|
|
11
12
|
export const EXTRACTION_CACHE_VERSION = 1;
|
|
13
|
+
/** An entry is reusable only if BOTH the extraction format and the symbol-identity scheme match. */
|
|
14
|
+
function isCurrentVersion(entry) {
|
|
15
|
+
return (entry.cacheVersion === EXTRACTION_CACHE_VERSION &&
|
|
16
|
+
(entry.symbolIdVersion ?? 0) === SYMBOL_ID_VERSION);
|
|
17
|
+
}
|
|
12
18
|
export class ExtractionCache {
|
|
13
19
|
dir;
|
|
14
20
|
pending = [];
|
|
@@ -85,7 +91,7 @@ export class ExtractionCache {
|
|
|
85
91
|
return null;
|
|
86
92
|
try {
|
|
87
93
|
const entry = JSON.parse(readFileSync(p, 'utf-8'));
|
|
88
|
-
if (entry
|
|
94
|
+
if (!isCurrentVersion(entry))
|
|
89
95
|
return null;
|
|
90
96
|
const st = statSync(filePath);
|
|
91
97
|
if (entry.mtimeMs === st.mtimeMs && entry.size === st.size)
|
|
@@ -115,7 +121,7 @@ export class ExtractionCache {
|
|
|
115
121
|
return null;
|
|
116
122
|
try {
|
|
117
123
|
const entry = JSON.parse(readFileSync(p, 'utf-8'));
|
|
118
|
-
if (entry
|
|
124
|
+
if (!isCurrentVersion(entry))
|
|
119
125
|
return null;
|
|
120
126
|
return entry.fileHash === fileHash ? entry : null;
|
|
121
127
|
}
|
|
@@ -141,6 +147,7 @@ export class ExtractionCache {
|
|
|
141
147
|
nodes,
|
|
142
148
|
edges,
|
|
143
149
|
cacheVersion: EXTRACTION_CACHE_VERSION,
|
|
150
|
+
symbolIdVersion: SYMBOL_ID_VERSION,
|
|
144
151
|
};
|
|
145
152
|
this.writeAtomic(this.entryPath(filePath), JSON.stringify(entry));
|
|
146
153
|
}
|
|
@@ -162,6 +169,7 @@ export class ExtractionCache {
|
|
|
162
169
|
nodes,
|
|
163
170
|
edges,
|
|
164
171
|
cacheVersion: EXTRACTION_CACHE_VERSION,
|
|
172
|
+
symbolIdVersion: SYMBOL_ID_VERSION,
|
|
165
173
|
};
|
|
166
174
|
this.pending.push({ path: this.entryPath(filePath), data: JSON.stringify(entry) });
|
|
167
175
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction-cache.js","sourceRoot":"","sources":["../../../src/cache/extraction-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,UAAU,EACV,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"extraction-cache.js","sourceRoot":"","sources":["../../../src/cache/extraction-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/graph/explain.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/graph/explain.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,EAAE,OAAO,EAqEhC,CAAC;AAEF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE/D;AAED,wBAAgB,SAAS,IAAI,OAAO,EAAE,CAErC;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,EAAE,CAKjE;AAID,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,EAAE,OAAO,EA+BjC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,OAAO,EAOhC,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CA0B7D;AAED,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKpD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKnD"}
|
|
@@ -51,8 +51,15 @@ export const CHECK_RULES = [
|
|
|
51
51
|
id: 'low-cohesion',
|
|
52
52
|
name: 'Low Community Cohesion',
|
|
53
53
|
description: 'A module community with a low ratio of internal to possible edges.',
|
|
54
|
-
rationale: '
|
|
55
|
-
|
|
54
|
+
rationale: 'The members of this community are sparsely connected to each other in the clustered ' +
|
|
55
|
+
'graph. That graph is a deliberate projection — coupling edges (calls, imports, ' +
|
|
56
|
+
'inheritance) count fully, containment is down-weighted, and prose relations are ' +
|
|
57
|
+
'excluded — so the number measures structural connectivity under those weights, not ' +
|
|
58
|
+
'module quality. Weak connectivity is consistent with an arbitrary grouping, but also ' +
|
|
59
|
+
'with a genuine module whose cohesion is by convention, configuration, or a shared ' +
|
|
60
|
+
'concern the parser does not see.',
|
|
61
|
+
remediation: 'Read the members and decide whether they belong together. If they do not, co-locate ' +
|
|
62
|
+
'related functionality; if they do, no change is needed.',
|
|
56
63
|
severity: 'info',
|
|
57
64
|
},
|
|
58
65
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/graph/explain.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,oEAAoE;QACjF,SAAS,EAAE,2EAA2E;QACtF,WAAW,EAAE,+EAA+E;QAC5F,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,EAAE,EAAE,kBAAkB;QACtB,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,qEAAqE;QAClF,SAAS,EAAE,oFAAoF;QAC/F,WAAW,EACT,+FAA+F;QACjG,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,kCAAkC;QAC/C,SAAS,EAAE,6EAA6E;QACxF,WAAW,EACT,qFAAqF;QACvF,QAAQ,EAAE,OAAO;KAClB;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,6BAA6B;QACnC,WAAW,EAAE,wEAAwE;QACrF,SAAS,EAAE,4EAA4E;QACvF,WAAW,EAAE,6EAA6E;QAC1F,QAAQ,EAAE,SAAS;KACpB;IACD;QACE,EAAE,EAAE,eAAe;QACnB,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,0CAA0C;QACvD,SAAS,EAAE,+EAA+E;QAC1F,WAAW,EAAE,yDAAyD;QACtE,QAAQ,EAAE,MAAM;KACjB;IACD;QACE,EAAE,EAAE,oBAAoB;QACxB,IAAI,EAAE,yBAAyB;QAC/B,WAAW,EAAE,4DAA4D;QACzE,SAAS,EACP,sFAAsF;QACxF,WAAW,EAAE,2EAA2E;QACxF,QAAQ,EAAE,OAAO;KAClB;IACD;QACE,EAAE,EAAE,cAAc;QAClB,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,oEAAoE;QACjF,SAAS,
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../../src/graph/explain.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,11 @@ export interface PageRankOptions {
|
|
|
8
8
|
tolerance?: number;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Evict cached statements and results for a given DB
|
|
11
|
+
* Evict cached statements and results for a given DB connection (call after writes).
|
|
12
|
+
*
|
|
13
|
+
* Closing a connection needs no explicit call: both caches are keyed by the
|
|
14
|
+
* connection object, so a reopened database gets freshly prepared statements
|
|
15
|
+
* and an empty result cache.
|
|
12
16
|
*/
|
|
13
17
|
export declare function invalidatePageRankCache(db: MonographDb): void;
|
|
14
18
|
/**
|
|
@@ -18,8 +22,10 @@ export declare function invalidatePageRankCache(db: MonographDb): void;
|
|
|
18
22
|
* After convergence the scores still sum to ~1 (standard normalized PageRank).
|
|
19
23
|
* Dangling nodes (out-degree 0) distribute their rank equally to all nodes.
|
|
20
24
|
*
|
|
21
|
-
* Results are cached for 5 seconds when the graph's
|
|
22
|
-
*
|
|
25
|
+
* Results are cached for 5 seconds per connection when both the graph's
|
|
26
|
+
* content revision and the algorithm options are unchanged, making repeated
|
|
27
|
+
* calls (e.g. during context preloading) free. Each call returns its own Map,
|
|
28
|
+
* so a caller mutating the result cannot corrupt another caller's copy.
|
|
23
29
|
*
|
|
24
30
|
* @param db - The MonographDb instance
|
|
25
31
|
* @param options - Optional tuning parameters
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../../src/graph/pagerank.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../../src/graph/pagerank.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiFD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAG7D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,GAAE,eAAoB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuF5F"}
|
|
@@ -1,43 +1,68 @@
|
|
|
1
|
-
const _stmtCache = new
|
|
1
|
+
const _stmtCache = new WeakMap();
|
|
2
2
|
function getStmts(db) {
|
|
3
|
-
|
|
4
|
-
let cache = _stmtCache.get(key);
|
|
3
|
+
let cache = _stmtCache.get(db);
|
|
5
4
|
if (!cache) {
|
|
6
|
-
if (_stmtCache.size >= MAX_STMT_CACHE) {
|
|
7
|
-
const oldest = _stmtCache.keys().next().value;
|
|
8
|
-
_stmtCache.delete(oldest);
|
|
9
|
-
}
|
|
10
5
|
cache = {
|
|
11
6
|
selectNodes: db.prepare('SELECT id FROM nodes'),
|
|
12
7
|
selectEdges: db.prepare('SELECT source_id, target_id FROM edges'),
|
|
13
8
|
};
|
|
14
|
-
_stmtCache.set(
|
|
9
|
+
_stmtCache.set(db, cache);
|
|
15
10
|
}
|
|
16
11
|
return cache;
|
|
17
12
|
}
|
|
18
13
|
// ---------------------------------------------------------------------------
|
|
19
|
-
// Result cache — avoids re-running power iteration when the graph
|
|
20
|
-
//
|
|
14
|
+
// Result cache — avoids re-running power iteration when the graph and the
|
|
15
|
+
// algorithm options are both unchanged. Also keyed per connection, with an
|
|
16
|
+
// inner key of (graph revision, options) and a 5-second TTL.
|
|
21
17
|
// ---------------------------------------------------------------------------
|
|
22
18
|
const PAGERANK_CACHE_TTL_MS = 5_000;
|
|
23
19
|
const MAX_RESULT_CACHE = 50;
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
const _resultCache = new WeakMap();
|
|
21
|
+
const FNV_OFFSET = 0x811c9dc5;
|
|
22
|
+
const FNV_PRIME = 0x01000193;
|
|
23
|
+
/**
|
|
24
|
+
* Cheap content revision for the graph that was just read.
|
|
25
|
+
*
|
|
26
|
+
* There is no persisted graph-generation counter in the schema, and node/edge
|
|
27
|
+
* counts alone are not a topology marker: a graph can be rewired (edges moved
|
|
28
|
+
* between nodes) without either count changing. Both row sets have already
|
|
29
|
+
* been fetched by the time this runs, so hashing them costs O(N+E) — the same
|
|
30
|
+
* order as the fetch itself, and far less than the power iteration it guards.
|
|
31
|
+
*
|
|
32
|
+
* Row order is not guaranteed by SQLite; a reordering only produces a cache
|
|
33
|
+
* miss (a recompute), never a stale hit.
|
|
34
|
+
*/
|
|
35
|
+
function graphRevision(nodeRows, edgeRows) {
|
|
36
|
+
let h1 = FNV_OFFSET;
|
|
37
|
+
let h2 = 0xcbf29ce4;
|
|
38
|
+
const byte = (c) => {
|
|
39
|
+
h1 = Math.imul(h1 ^ c, FNV_PRIME);
|
|
40
|
+
h2 = Math.imul(h2 + c, 0x85ebca6b) ^ (h2 >>> 13);
|
|
41
|
+
};
|
|
42
|
+
const field = (s) => {
|
|
43
|
+
for (let i = 0; i < s.length; i++)
|
|
44
|
+
byte(s.charCodeAt(i));
|
|
45
|
+
byte(0x1f); // field separator — keeps ("ab","c") distinct from ("a","bc")
|
|
46
|
+
};
|
|
47
|
+
for (const r of nodeRows)
|
|
48
|
+
field(r.id);
|
|
49
|
+
for (const e of edgeRows) {
|
|
50
|
+
field(e.source_id);
|
|
51
|
+
field(e.target_id);
|
|
52
|
+
}
|
|
53
|
+
const hex = ((h1 >>> 0).toString(36) + (h2 >>> 0).toString(36)).padStart(2, '0');
|
|
54
|
+
return `${hex}:${nodeRows.length}:${edgeRows.length}`;
|
|
29
55
|
}
|
|
30
56
|
/**
|
|
31
|
-
* Evict cached statements and results for a given DB
|
|
57
|
+
* Evict cached statements and results for a given DB connection (call after writes).
|
|
58
|
+
*
|
|
59
|
+
* Closing a connection needs no explicit call: both caches are keyed by the
|
|
60
|
+
* connection object, so a reopened database gets freshly prepared statements
|
|
61
|
+
* and an empty result cache.
|
|
32
62
|
*/
|
|
33
63
|
export function invalidatePageRankCache(db) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// Purge all result-cache entries for this DB (they have the name as prefix)
|
|
37
|
-
for (const k of _resultCache.keys()) {
|
|
38
|
-
if (k.startsWith(`${key}:`))
|
|
39
|
-
_resultCache.delete(k);
|
|
40
|
-
}
|
|
64
|
+
_stmtCache.delete(db);
|
|
65
|
+
_resultCache.delete(db);
|
|
41
66
|
}
|
|
42
67
|
/**
|
|
43
68
|
* Compute PageRank scores for all nodes using power iteration.
|
|
@@ -46,8 +71,10 @@ export function invalidatePageRankCache(db) {
|
|
|
46
71
|
* After convergence the scores still sum to ~1 (standard normalized PageRank).
|
|
47
72
|
* Dangling nodes (out-degree 0) distribute their rank equally to all nodes.
|
|
48
73
|
*
|
|
49
|
-
* Results are cached for 5 seconds when the graph's
|
|
50
|
-
*
|
|
74
|
+
* Results are cached for 5 seconds per connection when both the graph's
|
|
75
|
+
* content revision and the algorithm options are unchanged, making repeated
|
|
76
|
+
* calls (e.g. during context preloading) free. Each call returns its own Map,
|
|
77
|
+
* so a caller mutating the result cannot corrupt another caller's copy.
|
|
51
78
|
*
|
|
52
79
|
* @param db - The MonographDb instance
|
|
53
80
|
* @param options - Optional tuning parameters
|
|
@@ -60,12 +87,15 @@ export function pageRank(db, options = {}) {
|
|
|
60
87
|
const edgeRows = stmts.selectEdges.all();
|
|
61
88
|
if (nodeRows.length === 0)
|
|
62
89
|
return new Map();
|
|
63
|
-
// Check result cache before running power iteration
|
|
64
|
-
|
|
90
|
+
// Check result cache before running power iteration. The key covers both the
|
|
91
|
+
// graph's content revision and every option that changes the output, so a
|
|
92
|
+
// rewired graph or a different damping factor can never hit a stale entry.
|
|
93
|
+
const cacheKey = `${graphRevision(nodeRows, edgeRows)}|${dampingFactor}|${maxIterations}|${tolerance}`;
|
|
65
94
|
const now = Date.now();
|
|
66
|
-
|
|
95
|
+
let dbCache = _resultCache.get(db);
|
|
96
|
+
const cached = dbCache?.get(cacheKey);
|
|
67
97
|
if (cached && now < cached.expiresAt)
|
|
68
|
-
return cached.result;
|
|
98
|
+
return new Map(cached.result);
|
|
69
99
|
const nodes = nodeRows.map((r) => r.id);
|
|
70
100
|
const n = nodes.length;
|
|
71
101
|
const nodeIndex = new Map();
|
|
@@ -115,11 +145,16 @@ export function pageRank(db, options = {}) {
|
|
|
115
145
|
for (let i = 0; i < n; i++) {
|
|
116
146
|
result.set(nodes[i], scores[i]);
|
|
117
147
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
_resultCache.
|
|
148
|
+
if (!dbCache) {
|
|
149
|
+
dbCache = new Map();
|
|
150
|
+
_resultCache.set(db, dbCache);
|
|
151
|
+
}
|
|
152
|
+
if (dbCache.size >= MAX_RESULT_CACHE) {
|
|
153
|
+
const oldest = dbCache.keys().next().value;
|
|
154
|
+
dbCache.delete(oldest);
|
|
121
155
|
}
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
dbCache.set(cacheKey, { result, expiresAt: now + PAGERANK_CACHE_TTL_MS });
|
|
157
|
+
// Hand out a copy so a caller mutating its result can't corrupt the cache.
|
|
158
|
+
return new Map(result);
|
|
124
159
|
}
|
|
125
160
|
//# sourceMappingURL=pagerank.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagerank.js","sourceRoot":"","sources":["../../../src/graph/pagerank.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pagerank.js","sourceRoot":"","sources":["../../../src/graph/pagerank.ts"],"names":[],"mappings":"AAwBA,MAAM,UAAU,GAAG,IAAI,OAAO,EAA0B,CAAC;AAEzD,SAAS,QAAQ,CAAC,EAAe;IAC/B,IAAI,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG;YACN,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC;YAC/C,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC;SAClE,CAAC;QACF,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,0EAA0E;AAC1E,2EAA2E;AAC3E,6DAA6D;AAC7D,8EAA8E;AAC9E,MAAM,qBAAqB,GAAG,KAAK,CAAC;AACpC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAO5B,MAAM,YAAY,GAAG,IAAI,OAAO,EAAgD,CAAC;AAEjF,MAAM,UAAU,GAAG,UAAU,CAAC;AAC9B,MAAM,SAAS,GAAG,UAAU,CAAC;AAE7B;;;;;;;;;;;GAWG;AACH,SAAS,aAAa,CACpB,QAA0B,EAC1B,QAAoD;IAEpD,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,IAAI,EAAE,GAAG,UAAU,CAAC;IACpB,MAAM,IAAI,GAAG,CAAC,CAAS,EAAQ,EAAE;QAC/B,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;QAClC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,CAAS,EAAQ,EAAE;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,8DAA8D;IAC5E,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnB,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjF,OAAO,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAe;IACrD,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtB,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAe,EAAE,OAAO,GAAoB,EAAE;IACrE,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,aAAa,GAAG,GAAG,EAAE,SAAS,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEhF,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAsB,CAAC;IAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAGnC,CAAC;IAEJ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAE5C,6EAA6E;IAC7E,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,aAAa,IAAI,aAAa,IAAI,SAAS,EAAE,CAAC;IACvG,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,SAAS;QAAE,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpE,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;IACvB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/C,wDAAwD;IACxD,MAAM,QAAQ,GAAe,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,OAAO,GAAe,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAEhD,KAAK,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1D,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS;QAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,SAAS;YAAE,SAAS;QACnD,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtB,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,iEAAiE;IACjE,IAAI,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAE/C,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QAEtC,qCAAqC;QACrC,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,WAAW,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,eAAe,GAAG,CAAC,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3B,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC7C,CAAC;YACD,SAAS,CAAC,CAAC,CAAC,GAAG,cAAc,GAAG,aAAa,GAAG,QAAQ,GAAG,eAAe,CAAC;QAC7E,CAAC;QAED,oBAAoB;QACpB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,GAAG,SAAS,CAAC;QACnB,IAAI,KAAK,GAAG,SAAS;YAAE,MAAM;IAC/B,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,qBAAqB,EAAE,CAAC,CAAC;IAE1E,2EAA2E;IAC3E,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -7,13 +7,39 @@ export interface NeighborEntry {
|
|
|
7
7
|
confidenceScore: number;
|
|
8
8
|
direction: 'outbound' | 'inbound';
|
|
9
9
|
}
|
|
10
|
+
/** A node a name could have referred to — enough to re-query unambiguously. */
|
|
11
|
+
export interface NeighborCandidate {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
label: string;
|
|
15
|
+
filePath: string | null;
|
|
16
|
+
startLine: number | null;
|
|
17
|
+
}
|
|
10
18
|
export interface MonographNeighborsResult {
|
|
11
19
|
node: MonographNode | null;
|
|
12
20
|
neighbors: NeighborEntry[];
|
|
21
|
+
/** True when `name` matched several nodes and nothing narrowed it to one. */
|
|
22
|
+
ambiguous: boolean;
|
|
23
|
+
/** Populated when ambiguous — re-query with `nodeId` or `filePath`. */
|
|
24
|
+
candidates: NeighborCandidate[];
|
|
25
|
+
/** Neighbors matching the query before `limit` was applied. */
|
|
26
|
+
totalNeighbors: number;
|
|
27
|
+
/** True when `totalNeighbors` exceeds the returned `neighbors`. */
|
|
28
|
+
truncated: boolean;
|
|
29
|
+
/** The cap that was applied per direction. */
|
|
30
|
+
limit: number;
|
|
13
31
|
}
|
|
14
|
-
export
|
|
15
|
-
|
|
32
|
+
export interface MonographNeighborsInput {
|
|
33
|
+
/** Canonical node id — the unambiguous way to address a node. */
|
|
34
|
+
nodeId?: string;
|
|
35
|
+
/** Symbol name; may match several nodes. */
|
|
36
|
+
name?: string;
|
|
37
|
+
/** Narrows an ambiguous `name` — exact file path or a trailing fragment of one. */
|
|
38
|
+
filePath?: string;
|
|
16
39
|
relationFilter?: string;
|
|
17
40
|
includeInbound?: boolean;
|
|
18
|
-
|
|
41
|
+
/** Max neighbors per direction (default 50, hard cap 500). */
|
|
42
|
+
limit?: number;
|
|
43
|
+
}
|
|
44
|
+
export declare function getMonographNeighbors(db: Database.Database, input: MonographNeighborsInput): MonographNeighborsResult;
|
|
19
45
|
//# sourceMappingURL=neighbors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neighbors.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/neighbors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,UAAU,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"neighbors.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/neighbors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,UAAU,GAAG,SAAS,CAAC;CACnC;AAED,+EAA+E;AAC/E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuFD,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,uBAAuB,GAC7B,wBAAwB,CAiD1B"}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { rowToNode } from '../storage/node-store.js';
|
|
2
|
+
const DEFAULT_LIMIT = 50;
|
|
3
|
+
const MAX_LIMIT = 500;
|
|
4
|
+
/** Candidate lists exist to be read by a human or an agent; a long one is noise. */
|
|
5
|
+
const CANDIDATE_CAP = 25;
|
|
2
6
|
// ── Shared edge query helper ──────────────────────────────────────────────────
|
|
3
|
-
function
|
|
7
|
+
function edgeColumns(direction) {
|
|
4
8
|
// outbound: source_id = nodeId → join target_id
|
|
5
9
|
// inbound: target_id = nodeId → join source_id
|
|
6
|
-
|
|
10
|
+
return direction === 'outbound' ? ['source_id', 'target_id'] : ['target_id', 'source_id'];
|
|
11
|
+
}
|
|
12
|
+
function countEdges(db, nodeId, direction, relationFilter) {
|
|
13
|
+
const [idCol] = edgeColumns(direction);
|
|
7
14
|
const sql = relationFilter
|
|
8
|
-
? `SELECT
|
|
9
|
-
: `SELECT
|
|
15
|
+
? `SELECT COUNT(*) AS c FROM edges e WHERE e.${idCol} = ? AND e.relation = ?`
|
|
16
|
+
: `SELECT COUNT(*) AS c FROM edges e WHERE e.${idCol} = ?`;
|
|
10
17
|
const params = relationFilter ? [nodeId, relationFilter] : [nodeId];
|
|
18
|
+
return db.prepare(sql).get(...params).c;
|
|
19
|
+
}
|
|
20
|
+
function queryEdges(db, nodeId, direction, relationFilter, limit) {
|
|
21
|
+
const [idCol, joinCol] = edgeColumns(direction);
|
|
22
|
+
const sql = relationFilter
|
|
23
|
+
? `SELECT n.*, e.relation, e.confidence, e.confidence_score FROM nodes n JOIN edges e ON n.id = e.${joinCol} WHERE e.${idCol} = ? AND e.relation = ? LIMIT ?`
|
|
24
|
+
: `SELECT n.*, e.relation, e.confidence, e.confidence_score FROM nodes n JOIN edges e ON n.id = e.${joinCol} WHERE e.${idCol} = ? LIMIT ?`;
|
|
25
|
+
const params = relationFilter ? [nodeId, relationFilter, limit] : [nodeId, limit];
|
|
11
26
|
const rows = db.prepare(sql).all(...params);
|
|
12
27
|
return rows.map((row) => ({
|
|
13
28
|
node: rowToNode(row),
|
|
@@ -17,15 +32,75 @@ function queryEdges(db, nodeId, direction, relationFilter) {
|
|
|
17
32
|
direction,
|
|
18
33
|
}));
|
|
19
34
|
}
|
|
35
|
+
// ── Node resolution ───────────────────────────────────────────────────────────
|
|
36
|
+
function toCandidate(row) {
|
|
37
|
+
return {
|
|
38
|
+
id: row.id,
|
|
39
|
+
name: row.name,
|
|
40
|
+
label: row.label,
|
|
41
|
+
filePath: row.file_path ?? null,
|
|
42
|
+
startLine: row.start_line ?? null,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Exact path match, else a trailing-fragment match so `user.ts` narrows `/app/user.ts`. */
|
|
46
|
+
function matchesFilePath(row, filePath) {
|
|
47
|
+
const rowPath = row.file_path ?? '';
|
|
48
|
+
return rowPath === filePath || rowPath.endsWith(filePath);
|
|
49
|
+
}
|
|
50
|
+
function emptyResult(limit, candidates = []) {
|
|
51
|
+
return {
|
|
52
|
+
node: null,
|
|
53
|
+
neighbors: [],
|
|
54
|
+
ambiguous: candidates.length > 1,
|
|
55
|
+
candidates,
|
|
56
|
+
totalNeighbors: 0,
|
|
57
|
+
truncated: false,
|
|
58
|
+
limit,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
20
61
|
export function getMonographNeighbors(db, input) {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
62
|
+
const limit = Math.min(Math.max(input.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);
|
|
63
|
+
let nodeRow;
|
|
64
|
+
if (input.nodeId) {
|
|
65
|
+
nodeRow = db.prepare('SELECT * FROM nodes WHERE id = ?').get(input.nodeId);
|
|
66
|
+
if (!nodeRow)
|
|
67
|
+
return emptyResult(limit);
|
|
68
|
+
}
|
|
69
|
+
else if (input.name) {
|
|
70
|
+
const rows = db
|
|
71
|
+
.prepare('SELECT * FROM nodes WHERE name = ? LIMIT ?')
|
|
72
|
+
.all(input.name, CANDIDATE_CAP + 1);
|
|
73
|
+
const matches = input.filePath
|
|
74
|
+
? rows.filter((r) => matchesFilePath(r, input.filePath))
|
|
75
|
+
: rows;
|
|
76
|
+
if (matches.length === 0)
|
|
77
|
+
return emptyResult(limit);
|
|
78
|
+
if (matches.length > 1) {
|
|
79
|
+
// A confident answer about the wrong node is worse than asking which one.
|
|
80
|
+
return emptyResult(limit, matches.slice(0, CANDIDATE_CAP).map(toCandidate));
|
|
81
|
+
}
|
|
82
|
+
nodeRow = matches[0];
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return emptyResult(limit);
|
|
86
|
+
}
|
|
24
87
|
const node = rowToNode(nodeRow);
|
|
25
88
|
const neighbors = [
|
|
26
|
-
...queryEdges(db, node.id, 'outbound', input.relationFilter),
|
|
27
|
-
...(input.includeInbound
|
|
89
|
+
...queryEdges(db, node.id, 'outbound', input.relationFilter, limit),
|
|
90
|
+
...(input.includeInbound
|
|
91
|
+
? queryEdges(db, node.id, 'inbound', input.relationFilter, limit)
|
|
92
|
+
: []),
|
|
28
93
|
];
|
|
29
|
-
|
|
94
|
+
const totalNeighbors = countEdges(db, node.id, 'outbound', input.relationFilter) +
|
|
95
|
+
(input.includeInbound ? countEdges(db, node.id, 'inbound', input.relationFilter) : 0);
|
|
96
|
+
return {
|
|
97
|
+
node,
|
|
98
|
+
neighbors,
|
|
99
|
+
ambiguous: false,
|
|
100
|
+
candidates: [],
|
|
101
|
+
totalNeighbors,
|
|
102
|
+
truncated: totalNeighbors > neighbors.length,
|
|
103
|
+
limit,
|
|
104
|
+
};
|
|
30
105
|
}
|
|
31
106
|
//# sourceMappingURL=neighbors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neighbors.js","sourceRoot":"","sources":["../../../src/mcp-tools/neighbors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"neighbors.js","sourceRoot":"","sources":["../../../src/mcp-tools/neighbors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RetrievalMode } from '../search/hybrid-query.js';
|
|
1
2
|
import type { MonographDb } from '../storage/db.js';
|
|
2
3
|
export interface QueryResult {
|
|
3
4
|
id: string;
|
|
@@ -6,6 +7,7 @@ export interface QueryResult {
|
|
|
6
7
|
filePath?: string;
|
|
7
8
|
/** Line number where the symbol is defined — enables direct file:line navigation. */
|
|
8
9
|
startLine?: number | null;
|
|
10
|
+
/** Higher is better, always ≥ 0 (monograph's single score convention). */
|
|
9
11
|
score: number;
|
|
10
12
|
isProcess: boolean;
|
|
11
13
|
}
|
|
@@ -37,6 +39,11 @@ export declare const monographQueryTool: {
|
|
|
37
39
|
type: string;
|
|
38
40
|
description: string;
|
|
39
41
|
};
|
|
42
|
+
mode: {
|
|
43
|
+
type: string;
|
|
44
|
+
enum: string[];
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
40
47
|
};
|
|
41
48
|
required: string[];
|
|
42
49
|
};
|
|
@@ -45,6 +52,7 @@ export declare const monographQueryTool: {
|
|
|
45
52
|
repoPath?: string;
|
|
46
53
|
topK?: number;
|
|
47
54
|
includeProcesses?: boolean;
|
|
55
|
+
mode?: RetrievalMode;
|
|
48
56
|
db?: MonographDb;
|
|
49
57
|
}): Promise<MonographQueryOutput>;
|
|
50
58
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,kBAAkB;IAC7B,IAAI;IACJ,WAAW;IAIX,WAAW;QACT,IAAI,EAAE,QAAQ;QACd,UAAU;YACR,KAAK;gBAAI,IAAI;gBAAY,WAAW;;YACpC,QAAQ;gBAAI,IAAI;gBAAY,WAAW;;YACvC,IAAI;gBAAI,IAAI;gBAAY,WAAW;;YACnC,gBAAgB;gBACd,IAAI;gBACJ,WAAW;;YAEb,IAAI;gBACF,IAAI;gBACJ,IAAI;gBACJ,WAAW;;;QAGf,QAAQ;;IAEJ,OAAO,OAAO;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,IAAI,CAAC,EAAE,aAAa,CAAC;QACrB,EAAE,CAAC,EAAE,WAAW,CAAC;KAClB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA2ClC,CAAC"}
|