bantamkit-mcp 0.29.1 → 0.30.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.
@@ -0,0 +1,81 @@
1
+ /**
2
+ * CPython string semantics this runtime needs in more than one place, written ONCE.
3
+ *
4
+ * `docs/roadmap-toolbox.md` row 8, entry (n): `pyStrip`, `cmpCodepoint` and `pyRepr` had each
5
+ * been ported twice — once in `docread.ts` and once under `memory/` — as independent
6
+ * re-derivations of the same three CPython behaviours. Two implementations of one semantic are
7
+ * two chances to be right and one certainty of drifting, and neither copy had a test that
8
+ * compared it to the other.
9
+ *
10
+ * **The pairs were diffed before they were merged**, because unifying two functions that are
11
+ * not the same function is a behaviour change wearing a refactor's clothes:
12
+ *
13
+ * * `pyStrip` — the two agreed on the set of characters `str.isspace()` is true for (29 each,
14
+ * with an empty symmetric difference over all 1,114,112 codepoints) and on 200,000 random
15
+ * strings built from that alphabet. Kept: the REGEX spelling, because the set-based one
16
+ * spreads the whole string into an array of characters first, and this is called once per
17
+ * rendered row.
18
+ * * `pyRepr` — byte-identical output on every one of the 1,114,112 codepoints and on a pool of
19
+ * quoting edge cases. `docread`'s explicit `Cc|Cf|Cs|Co|Cn|Zl|Zp|Zs` class and `memory`'s
20
+ * `\p{C}|\p{Z}` are the same set spelled two ways. Kept: the precompiled class.
21
+ * * `cmpCodepoint` — the same ORDER on every pair (0 sign disagreements), and different
22
+ * NUMBERS: `docread`'s returned the codepoint difference and the `memory` copy returns
23
+ * -1/0/1, so `cmp('', 'ab')` was -1 there and -2 here. Kept: the `memory` spelling to the
24
+ * digit, because every importer outside `docread.ts` already sees those numbers, while
25
+ * `docread`'s copy had no importer at all and one use — `Array.prototype.sort`, which reads
26
+ * the sign and nothing else.
27
+ *
28
+ * **A THIRD COPY SURVIVED THAT CLOSURE AND WAS FOLDED IN ON 2026-09-06 (job44, unit F4).**
29
+ * "written ONCE" was not true when it was written: entry (n) named `docread.ts` and `memory/`
30
+ * and nothing else, so `skillaudit.ts` — product surface, the eleventh MCP tool — kept its own
31
+ * `pyStrip` on a 29-codepoint Set and its own `cmpCodepoint` in the `cx - cy` spelling, the two
32
+ * this module had just rejected. Both now import from here, gated first by the same method:
33
+ * an empty symmetric difference between the two whitespace sets over every codepoint, 0
34
+ * disagreements on `pyStrip` over 200,000 random strings, 0 disagreements on a
35
+ * `` `^${PY_WS_CLASS}` `` regex against that module's Set-membership `startsWithSpace` over
36
+ * every codepoint, and — the reason the gate is not optional — `cmpCodepoint` agreeing on SIGN
37
+ * in all of 324 exhaustive plus 200,000 random pairs while disagreeing on the NUMBER in
38
+ * 167,851 of them. `skillaudit.ts`'s six uses read the sign alone, which is what made the
39
+ * substitution safe; its header carries the reading and the caveat.
40
+ *
41
+ * Nothing here is re-exported from `index.ts`: the names stay exported from the modules that
42
+ * always exported them, so this is a delegation and not a surface change.
43
+ */
44
+ /**
45
+ * The characters `str.isspace()` is true for — what `strip()` and `split()` consume.
46
+ *
47
+ * NOT `String.prototype.trim()`'s set. Measured over all 0x110000 codepoints: Python strips 29,
48
+ * JS strips 25, and the two disagree on six — Python also strips U+001C..U+001F and U+0085, JS
49
+ * also strips U+FEFF. `_write_fact` ends with `fact.body.strip() + "\n"`, so each of those six
50
+ * is a byte of difference in a file the memory store then compares, hashes and diffs; in
51
+ * `docread` the same six decide whether a row is blank.
52
+ */
53
+ export declare const PY_WS = "\t\n\v\f\r\u001C\u001D\u001E\u001F \u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000";
54
+ /** `PY_WS` as a character class, with the four characters a class gives meaning escaped. */
55
+ export declare const PY_WS_CLASS: string;
56
+ /** `str.strip()` with no argument. */
57
+ export declare function pyStrip(s: string): string;
58
+ /**
59
+ * Python's `<` on `str`, which is CODEPOINT order. JS compares UTF-16 code units.
60
+ *
61
+ * They disagree for every astral character: `['\u{1F414}.md', '!.md'].sort()` puts the chicken
62
+ * first because its lead surrogate is 0xD83D, and Python puts it last because 0x1F414 > 0xFF01.
63
+ * `_fact_paths` sorts, `recall` breaks score ties on the name, and the index is written in that
64
+ * order — so a single astral fact name is enough to make two `index.md` files that differ. In
65
+ * `docread` the same order decides which omission reason is rendered first.
66
+ */
67
+ export declare function cmpCodepoint(a: string, b: string): number;
68
+ /**
69
+ * `repr(str)` — the refusal sentences' quoting, and `_pinned_store`'s `{raw!r}`.
70
+ *
71
+ * Python quotes with `'` unless the value contains a `'` and no `"`; it escapes `\\`, the
72
+ * quote, `\t`, `\n`, `\r`, and every codepoint that is not `str.isprintable()` — that is,
73
+ * everything in a `C*` category and every separator except the space itself. The escapes are
74
+ * `\xNN` below U+0100, `\uNNNN` below U+10000, `\UNNNNNNNN` above.
75
+ *
76
+ * The one place it can drift is a codepoint whose category changed between CPython 3.12's
77
+ * Unicode 15.0 and the ICU this Node was built against: a newly assigned character is `Cn`
78
+ * (not printable, escaped) for Python and assigned (printable, raw) here. A path made of
79
+ * brand-new codepoints is the only input that reaches it.
80
+ */
81
+ export declare function pyRepr(s: string): string;
package/dist/pysem.js ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * CPython string semantics this runtime needs in more than one place, written ONCE.
3
+ *
4
+ * `docs/roadmap-toolbox.md` row 8, entry (n): `pyStrip`, `cmpCodepoint` and `pyRepr` had each
5
+ * been ported twice — once in `docread.ts` and once under `memory/` — as independent
6
+ * re-derivations of the same three CPython behaviours. Two implementations of one semantic are
7
+ * two chances to be right and one certainty of drifting, and neither copy had a test that
8
+ * compared it to the other.
9
+ *
10
+ * **The pairs were diffed before they were merged**, because unifying two functions that are
11
+ * not the same function is a behaviour change wearing a refactor's clothes:
12
+ *
13
+ * * `pyStrip` — the two agreed on the set of characters `str.isspace()` is true for (29 each,
14
+ * with an empty symmetric difference over all 1,114,112 codepoints) and on 200,000 random
15
+ * strings built from that alphabet. Kept: the REGEX spelling, because the set-based one
16
+ * spreads the whole string into an array of characters first, and this is called once per
17
+ * rendered row.
18
+ * * `pyRepr` — byte-identical output on every one of the 1,114,112 codepoints and on a pool of
19
+ * quoting edge cases. `docread`'s explicit `Cc|Cf|Cs|Co|Cn|Zl|Zp|Zs` class and `memory`'s
20
+ * `\p{C}|\p{Z}` are the same set spelled two ways. Kept: the precompiled class.
21
+ * * `cmpCodepoint` — the same ORDER on every pair (0 sign disagreements), and different
22
+ * NUMBERS: `docread`'s returned the codepoint difference and the `memory` copy returns
23
+ * -1/0/1, so `cmp('', 'ab')` was -1 there and -2 here. Kept: the `memory` spelling to the
24
+ * digit, because every importer outside `docread.ts` already sees those numbers, while
25
+ * `docread`'s copy had no importer at all and one use — `Array.prototype.sort`, which reads
26
+ * the sign and nothing else.
27
+ *
28
+ * **A THIRD COPY SURVIVED THAT CLOSURE AND WAS FOLDED IN ON 2026-09-06 (job44, unit F4).**
29
+ * "written ONCE" was not true when it was written: entry (n) named `docread.ts` and `memory/`
30
+ * and nothing else, so `skillaudit.ts` — product surface, the eleventh MCP tool — kept its own
31
+ * `pyStrip` on a 29-codepoint Set and its own `cmpCodepoint` in the `cx - cy` spelling, the two
32
+ * this module had just rejected. Both now import from here, gated first by the same method:
33
+ * an empty symmetric difference between the two whitespace sets over every codepoint, 0
34
+ * disagreements on `pyStrip` over 200,000 random strings, 0 disagreements on a
35
+ * `` `^${PY_WS_CLASS}` `` regex against that module's Set-membership `startsWithSpace` over
36
+ * every codepoint, and — the reason the gate is not optional — `cmpCodepoint` agreeing on SIGN
37
+ * in all of 324 exhaustive plus 200,000 random pairs while disagreeing on the NUMBER in
38
+ * 167,851 of them. `skillaudit.ts`'s six uses read the sign alone, which is what made the
39
+ * substitution safe; its header carries the reading and the caveat.
40
+ *
41
+ * Nothing here is re-exported from `index.ts`: the names stay exported from the modules that
42
+ * always exported them, so this is a delegation and not a surface change.
43
+ */
44
+ // ------------------------------------------------------------------------- str.strip()
45
+ /**
46
+ * The characters `str.isspace()` is true for — what `strip()` and `split()` consume.
47
+ *
48
+ * NOT `String.prototype.trim()`'s set. Measured over all 0x110000 codepoints: Python strips 29,
49
+ * JS strips 25, and the two disagree on six — Python also strips U+001C..U+001F and U+0085, JS
50
+ * also strips U+FEFF. `_write_fact` ends with `fact.body.strip() + "\n"`, so each of those six
51
+ * is a byte of difference in a file the memory store then compares, hashes and diffs; in
52
+ * `docread` the same six decide whether a row is blank.
53
+ */
54
+ export const PY_WS = '\t\n\x0b\x0c\r\x1c\x1d\x1e\x1f \x85\xa0            

   ';
55
+ /** `PY_WS` as a character class, with the four characters a class gives meaning escaped. */
56
+ export const PY_WS_CLASS = `[${PY_WS.replace(/[\]\\^-]/g, '\\$&')}]`;
57
+ const PY_STRIP = new RegExp(`^${PY_WS_CLASS}+|${PY_WS_CLASS}+$`, 'g');
58
+ /** `str.strip()` with no argument. */
59
+ export function pyStrip(s) {
60
+ return s.replace(PY_STRIP, '');
61
+ }
62
+ // ------------------------------------------------------------------------ sorted() on str
63
+ /**
64
+ * Python's `<` on `str`, which is CODEPOINT order. JS compares UTF-16 code units.
65
+ *
66
+ * They disagree for every astral character: `['\u{1F414}.md', '!.md'].sort()` puts the chicken
67
+ * first because its lead surrogate is 0xD83D, and Python puts it last because 0x1F414 > 0xFF01.
68
+ * `_fact_paths` sorts, `recall` breaks score ties on the name, and the index is written in that
69
+ * order — so a single astral fact name is enough to make two `index.md` files that differ. In
70
+ * `docread` the same order decides which omission reason is rendered first.
71
+ */
72
+ export function cmpCodepoint(a, b) {
73
+ const x = [...a];
74
+ const y = [...b];
75
+ const n = Math.min(x.length, y.length);
76
+ for (let i = 0; i < n; i += 1) {
77
+ const p = x[i].codePointAt(0);
78
+ const q = y[i].codePointAt(0);
79
+ if (p !== q)
80
+ return p < q ? -1 : 1;
81
+ }
82
+ return x.length - y.length;
83
+ }
84
+ // ---------------------------------------------------------------------------- repr(str)
85
+ // `str.isprintable()` is false for these categories (space itself excepted). Precompiled: the
86
+ // refusal sentences build one of these per character of a path.
87
+ const NONPRINTABLE = /[\p{Cc}\p{Cf}\p{Cs}\p{Co}\p{Cn}\p{Zl}\p{Zp}\p{Zs}]/u;
88
+ /**
89
+ * `repr(str)` — the refusal sentences' quoting, and `_pinned_store`'s `{raw!r}`.
90
+ *
91
+ * Python quotes with `'` unless the value contains a `'` and no `"`; it escapes `\\`, the
92
+ * quote, `\t`, `\n`, `\r`, and every codepoint that is not `str.isprintable()` — that is,
93
+ * everything in a `C*` category and every separator except the space itself. The escapes are
94
+ * `\xNN` below U+0100, `\uNNNN` below U+10000, `\UNNNNNNNN` above.
95
+ *
96
+ * The one place it can drift is a codepoint whose category changed between CPython 3.12's
97
+ * Unicode 15.0 and the ICU this Node was built against: a newly assigned character is `Cn`
98
+ * (not printable, escaped) for Python and assigned (printable, raw) here. A path made of
99
+ * brand-new codepoints is the only input that reaches it.
100
+ */
101
+ export function pyRepr(s) {
102
+ const quote = s.includes("'") && !s.includes('"') ? '"' : "'";
103
+ let out = quote;
104
+ for (const ch of s) {
105
+ const code = ch.codePointAt(0);
106
+ if (ch === quote || ch === '\\')
107
+ out += '\\' + ch;
108
+ else if (ch === '\t')
109
+ out += '\\t';
110
+ else if (ch === '\n')
111
+ out += '\\n';
112
+ else if (ch === '\r')
113
+ out += '\\r';
114
+ else if (ch !== ' ' && NONPRINTABLE.test(ch)) {
115
+ if (code < 0x100)
116
+ out += '\\x' + code.toString(16).padStart(2, '0');
117
+ else if (code < 0x10000)
118
+ out += '\\u' + code.toString(16).padStart(4, '0');
119
+ else
120
+ out += '\\U' + code.toString(16).padStart(8, '0');
121
+ }
122
+ else
123
+ out += ch;
124
+ }
125
+ return out + quote;
126
+ }
@@ -0,0 +1,247 @@
1
+ export declare const DAMPING = 0.2;
2
+ export declare const ITERATIONS = 30;
3
+ export declare const MIN_REFERENCE_LENGTH = 3;
4
+ export declare const REFERENCE_DF_MAX_NUM = 1;
5
+ export declare const REFERENCE_DF_MAX_DEN = 8;
6
+ export declare const MAX_DEFINITIONS_PER_FILE = 4;
7
+ export declare const DEFAULT_BUDGET = 4000;
8
+ export declare const SCORE_SCALE = 1000000000;
9
+ export declare const MAX_FILE_BYTES = 1048576;
10
+ export declare const SKIP_DIRS: readonly string[];
11
+ /**
12
+ * Suffix -> dialect. Two dialects only: `python` and `ecma`. TypeScript and JavaScript
13
+ * share a scanner because their DECLARATION forms are the same set; the extra TypeScript
14
+ * keywords (`interface`, `type`, `enum`) are simply absent from a `.js` file.
15
+ */
16
+ export declare const LANGUAGES: Readonly<Record<string, string>>;
17
+ export declare const OMIT_UNKNOWN_LANGUAGE = "unknown-language";
18
+ export declare const OMIT_UNREADABLE = "unreadable-bytes";
19
+ export declare const OMIT_SIZE_CAP = "size-cap";
20
+ export declare const OMIT_NO_DEFINITIONS = "no-definitions";
21
+ export declare const OMIT_UNREACHABLE = "unreachable";
22
+ export declare const OMIT_PER_FILE_CAP = "per-file-cap";
23
+ export declare const OMIT_BUDGET = "budget";
24
+ /**
25
+ * Fixed render order for the footer, so two runs of the same map cannot disagree about the
26
+ * order of their disclosures.
27
+ */
28
+ export declare const OMISSION_ORDER: readonly string[];
29
+ /**
30
+ * One definition, at the line it was declared on. `line` is 1-based and counts lines of the
31
+ * ORIGINAL file, not of the comment-stripped view: a caller that jumps to it must land
32
+ * where the reader would.
33
+ */
34
+ export interface Definition {
35
+ readonly path: string;
36
+ readonly line: number;
37
+ readonly kind: string;
38
+ readonly name: string;
39
+ }
40
+ /**
41
+ * Something the tree holds that the map does not carry, as a COUNT and the fact behind it —
42
+ * `docread`'s `Omission` discipline, deliberately re-stated here rather than imported,
43
+ * because these subjects are this module's and a shared vocabulary would make a change to
44
+ * one reader a change to the other.
45
+ *
46
+ * Never an adjective. `subject` is one of the `OMIT_*` tokens; a renderer that meets a token
47
+ * it does not know must still print the count. A silent skip is how a reader lies about its
48
+ * coverage.
49
+ */
50
+ export interface Omission {
51
+ readonly subject: string;
52
+ readonly count: number;
53
+ readonly size: number;
54
+ readonly facts: readonly (readonly [string, number])[];
55
+ }
56
+ export interface RankedFile {
57
+ readonly path: string;
58
+ readonly rankUnits: number;
59
+ readonly definitions: readonly Definition[];
60
+ /**
61
+ * The raw double. Reported for a caller that wants it; NEVER rendered, and never the sort
62
+ * key — see trap (8).
63
+ */
64
+ readonly score: number;
65
+ }
66
+ export interface RepoMap {
67
+ readonly text: string;
68
+ readonly ranked: readonly RankedFile[];
69
+ readonly omissions: readonly Omission[];
70
+ readonly focus: readonly string[];
71
+ readonly nodes: number;
72
+ readonly edges: number;
73
+ readonly definitions: number;
74
+ readonly damping: number;
75
+ readonly iterations: number;
76
+ readonly budget: number;
77
+ readonly perFile: number;
78
+ readonly listingBytes: number;
79
+ readonly filesRendered: number;
80
+ readonly definitionsRendered: number;
81
+ }
82
+ export interface RepoMapOptions {
83
+ readonly focus?: readonly string[];
84
+ readonly budget?: number;
85
+ readonly files?: readonly string[] | null;
86
+ readonly damping?: number;
87
+ readonly iterations?: number;
88
+ readonly perFile?: number;
89
+ }
90
+ /**
91
+ * The dialect for a path, or `null` when this scanner has no reader for it.
92
+ *
93
+ * Dispatch is on SUFFIX, and that is a deliberate departure from `docread`, which sniffs
94
+ * because a suffix is measurably a lie about a document's container. A source file is
95
+ * different: `.py` and `.ts` name a GRAMMAR, and there is no magic number for a grammar. A
96
+ * file whose suffix is unknown is reported, never guessed at.
97
+ */
98
+ export declare function languageOf(path: string): string | null;
99
+ /**
100
+ * The file's lines with comments and docstrings blanked, one output line per input line so
101
+ * line numbers survive.
102
+ *
103
+ * Line-oriented and stateful across lines, because both traps that matter span lines: a
104
+ * Python triple-quoted docstring and an ECMAScript block comment. What is removed:
105
+ *
106
+ * - `python` — `'''`/`"""` blocks (the delimiter that opens is the only one that can close),
107
+ * and everything from an unquoted `#` to end of line.
108
+ * - `ecma` — block comments, and everything from `//` to end of line.
109
+ *
110
+ * What is NOT removed, and is declared rather than hidden: the contents of a SINGLE-line
111
+ * string literal. Stripping those would lose the real references inside an f-string, and
112
+ * keeping them costs a definition-shaped line inside a one-line string being read as a
113
+ * definition. Backslash escapes are NOT honoured: a `"""` inside a string toggles the state
114
+ * machine. Both runtimes get that wrong identically, which is the requirement.
115
+ */
116
+ export declare function stripNoncode(text: string, language: string): string[];
117
+ /**
118
+ * Every definition in `text`, in source order.
119
+ *
120
+ * `python` — `def` and `class` at ANY indentation, so a method counts. Methods are the
121
+ * signal that made the difference in measurement: a focus on `memory/dream.py` reaches
122
+ * `memory/store.py` through `_write_fact`, `_fact_path` and `_check_index_budget`, none of
123
+ * which is top-level. Plus a bare `NAME =` or `NAME: T =` at column 0, which is how this
124
+ * repository declares its constants.
125
+ *
126
+ * `ecma` — `function class interface type const let var enum` at COLUMN 0 only, optionally
127
+ * behind `export` and `default` and `async`. Restricting to column 0 was the second-largest
128
+ * measured improvement in this module (recall@10 0.361 -> 0.410 on its own): an indented
129
+ * `const` is a local, and `runtime-ts/src/docread.ts` was contributing 452 of them.
130
+ *
131
+ * The asymmetry is real and is not an oversight: an ECMAScript class member cannot be told
132
+ * from a call at the same indentation without tracking braces, and a scanner that guessed
133
+ * would invent definitions. Python's `def` keyword makes the same question free.
134
+ */
135
+ export declare function scanDefinitions(text: string, language: string, path?: string): Definition[];
136
+ /**
137
+ * Every identifier of at least `MIN_REFERENCE_LENGTH` characters outside a comment.
138
+ *
139
+ * A SET, not a count. The edge weight below is "how many DISTINCT names of B does A
140
+ * mention", so a file that repeats one name a hundred times does not out-weigh a file that
141
+ * mentions ten. That is the choice the ambiguity filter and `MIN_REFERENCE_LENGTH` were
142
+ * tuned against and it keeps every weight an exact integer.
143
+ */
144
+ export declare function referenceNames(text: string, language: string): Set<string>;
145
+ /**
146
+ * Every path under `root`, relative, POSIX, code-point sorted.
147
+ *
148
+ * DIRECTORY SYMLINKS ARE NOT FOLLOWED, AND ON THIS SIDE THAT IS REAL LOGIC RATHER THAN A
149
+ * FLAG. `os.walk(followlinks=False)` gives CPython the whole rule for free, and J45-9's
150
+ * mutation 24 — delete the explicit `islink` filter — SURVIVED there for exactly that
151
+ * reason. Node has no equivalent, and the Dirent that looks like the answer is the wrong
152
+ * one: `readdirSync(..., {withFileTypes: true})` reports from **lstat**, so a symlink to a
153
+ * directory answers `isDirectory() === false` and a naive port hands it to the scanner as a
154
+ * source FILE. CPython does the opposite — `os.scandir`'s `entry.is_dir()` FOLLOWS, so the
155
+ * link lands in `dirs`, and `followlinks=False` then declines to descend, so it appears in
156
+ * the output neither as a file nor as a directory.
157
+ *
158
+ * Measured on node v25.2.1 and CPython 3.12.13 over one tree holding `real/`,
159
+ * `linkdir -> real`, `linkfile.py -> plain.py` and a dangling `dangling.py`: CPython's walk
160
+ * yields `dirs=['linkdir', 'real'] files=['dangling.py', 'linkfile.py', 'plain.py']` and
161
+ * `walk_sources` returns `['dangling.py', 'linkfile.py', 'plain.py', 'real/a.py']`. So the
162
+ * three cases are separated by a FOLLOW-`stat`, not by the Dirent:
163
+ *
164
+ * - symlink whose target is a directory -> a directory, and not descended into: gone.
165
+ * - symlink whose target is a file -> a file: kept.
166
+ * - dangling symlink -> `stat` throws, CPython's `is_dir()` raises and
167
+ * is caught as False: a file, kept, and it will
168
+ * be counted as `unreadable-bytes` downstream.
169
+ *
170
+ * Two reasons the rule exists and both are measured elsewhere in this repository: a symlink
171
+ * cycle makes the walk non-terminating, and a dangling directory symlink is one error shape
172
+ * on POSIX and two on Windows (`reference-windows-dangling-symlink-two-shapes`).
173
+ *
174
+ * A directory whose listing throws is skipped whole, silently, because that is what
175
+ * `os.walk`'s default `onerror=None` does.
176
+ */
177
+ export declare function walkSources(root: string): string[];
178
+ /**
179
+ * `source -> {target: weight}`, weight being the number of surviving names the source
180
+ * mentions that ONLY the target defines.
181
+ *
182
+ * Weights are exact integers, so `out[i]` in `pagerank` is an exact integer too and the only
183
+ * inexact step in the whole pass is the one division.
184
+ */
185
+ export declare function buildGraph(definitions: Map<string, readonly Definition[]>, references: Map<string, ReadonlySet<string>>): Map<string, Map<string, number>>;
186
+ /**
187
+ * At most `limit` of a file's definitions, chosen by kind then reach, returned in SOURCE
188
+ * order.
189
+ *
190
+ * The key is `(kind rank, -reference count, line, name)`, and every part of it is an integer
191
+ * or a code-point comparison, so the choice is TOTAL — which is why this port does not lean
192
+ * on `Array.prototype.sort` being stable. `references` is the RAW count from `nameIndex`;
193
+ * see there for why it is not the filtered one.
194
+ *
195
+ * **This ordering is argued, not measured, and the difference matters.** Every other
196
+ * constant in this module beat a named alternative on a yardstick. This one cannot: the
197
+ * yardstick is "does the focus file's own import appear in the rendered map", which is a
198
+ * question about which FILES are listed, and selection only decides which lines appear UNDER
199
+ * a file already listed. Measured, it moves that number by zero. So it rests on a stated
200
+ * principle instead — name the file's subject before its details — and a later unit with a
201
+ * definition-level yardstick is entitled to overturn it. What it is NOT is source order,
202
+ * which put `VALID_TYPES`, `DURABLE_TYPES`, `NAME_RE` and `DUPLICATE_JACCARD` at the head of
203
+ * `memory/store.py`'s block.
204
+ *
205
+ * The selected definitions are re-sorted into SOURCE order for rendering: a block whose line
206
+ * numbers ran backwards would be harder to read for no gain, and the order a block is chosen
207
+ * in is not the order it is read in.
208
+ */
209
+ export declare function selectDefinitions(definitions: readonly Definition[], references: Map<string, number>, limit: number): readonly Definition[];
210
+ /**
211
+ * Personalised PageRank, bit-identical to `repomap.py` by construction.
212
+ *
213
+ * The port contract, in the order the loop performs it:
214
+ *
215
+ * 1. `nodes` is already sorted; index by position in it.
216
+ * 2. `out[i]` is the exact integer sum of node i's out-weights.
217
+ * 3. Each node's out-edges are visited in sorted TARGET order.
218
+ * 4. The personalisation vector is `1/len(personal)` on each focus node and 0 elsewhere;
219
+ * with no focus it is `1/n` on every node. The INITIAL vector is that same vector.
220
+ * 5. Per round: zero `next`; walk sources in node order; a node with no out-edges adds its
221
+ * whole score to `dangling`; otherwise each out-edge adds `score[i] * weight / out[i]`,
222
+ * evaluated strictly left to right.
223
+ * 6. `tele = damping * dangling + (1.0 - damping)`, then
224
+ * `next[i] = next[i] * damping + tele * personal[i]`.
225
+ * 7. Exactly `iterations` rounds. No early stop, no convergence test — a branch on a float
226
+ * is one more thing for a port to get wrong, and the contraction bound (the linear part
227
+ * is `damping * column-stochastic`, so the residual after 30 rounds is under
228
+ * `2 * 0.2 ** 30` = 2.1e-21) makes the test unnecessary.
229
+ *
230
+ * THERE IS NO `reduce` HERE AND THERE MUST NOT BE ONE: every accumulation is a written-out
231
+ * loop in the same order as CPython's, because CPython's `sum()` is Neumaier-compensated and
232
+ * nothing in JavaScript is (trap 7). The Python side is held to the same rule by
233
+ * `test_no_float_summation_or_rounding_in_the_source`, which reads that function's body.
234
+ */
235
+ export declare function pagerank(nodes: readonly string[], edges: Map<string, Map<string, number>>, personal: readonly string[], damping?: number, iterations?: number): number[];
236
+ /**
237
+ * Scan `root`, rank its files against `focus`, and render a listing within `budget`.
238
+ *
239
+ * `focus` is the current unit's files, relative to `root` and POSIX-separated; a focus entry
240
+ * that is not a scanned source is ignored for the personalisation vector but is still
241
+ * excluded from the listing, because a caller naming a file has it open already. An empty
242
+ * focus gives the uniform vector — plain centrality over the whole tree.
243
+ *
244
+ * `budget` is UTF-8 BYTES of the listing. See the header: this runtime has no model
245
+ * tokenizer and will not pretend to one.
246
+ */
247
+ export declare function repoMap(root: string, options?: RepoMapOptions): RepoMap;