@untangle-code/search 0.0.0-stage → 0.1.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.
Files changed (140) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +433 -2
  4. package/THIRD_PARTY_LICENSES.md +29 -0
  5. package/dist/benchmark-integrity.d.ts +12 -0
  6. package/dist/benchmark-integrity.d.ts.map +1 -0
  7. package/dist/benchmark-integrity.js +10 -0
  8. package/dist/benchmark-integrity.js.map +1 -0
  9. package/dist/bm25.d.ts +46 -0
  10. package/dist/bm25.d.ts.map +1 -0
  11. package/dist/bm25.js +105 -0
  12. package/dist/bm25.js.map +1 -0
  13. package/dist/deadline.d.ts +4 -0
  14. package/dist/deadline.d.ts.map +1 -0
  15. package/dist/deadline.js +54 -0
  16. package/dist/deadline.js.map +1 -0
  17. package/dist/dedupe.d.ts +48 -0
  18. package/dist/dedupe.d.ts.map +1 -0
  19. package/dist/dedupe.js +58 -0
  20. package/dist/dedupe.js.map +1 -0
  21. package/dist/diversify.d.ts +45 -0
  22. package/dist/diversify.d.ts.map +1 -0
  23. package/dist/diversify.js +30 -0
  24. package/dist/diversify.js.map +1 -0
  25. package/dist/engine.d.ts +157 -0
  26. package/dist/engine.d.ts.map +1 -0
  27. package/dist/engine.js +1498 -0
  28. package/dist/engine.js.map +1 -0
  29. package/dist/enrichment.d.ts +16 -0
  30. package/dist/enrichment.d.ts.map +1 -0
  31. package/dist/enrichment.js +92 -0
  32. package/dist/enrichment.js.map +1 -0
  33. package/dist/filter.d.ts +86 -0
  34. package/dist/filter.d.ts.map +1 -0
  35. package/dist/filter.js +166 -0
  36. package/dist/filter.js.map +1 -0
  37. package/dist/findability.d.ts +144 -0
  38. package/dist/findability.d.ts.map +1 -0
  39. package/dist/findability.js +393 -0
  40. package/dist/findability.js.map +1 -0
  41. package/dist/format.d.ts +28 -0
  42. package/dist/format.d.ts.map +1 -0
  43. package/dist/format.js +172 -0
  44. package/dist/format.js.map +1 -0
  45. package/dist/fusion.d.ts +47 -0
  46. package/dist/fusion.d.ts.map +1 -0
  47. package/dist/fusion.js +84 -0
  48. package/dist/fusion.js.map +1 -0
  49. package/dist/glob.d.ts +50 -0
  50. package/dist/glob.d.ts.map +1 -0
  51. package/dist/glob.js +144 -0
  52. package/dist/glob.js.map +1 -0
  53. package/dist/grep.d.ts +76 -0
  54. package/dist/grep.d.ts.map +1 -0
  55. package/dist/grep.js +475 -0
  56. package/dist/grep.js.map +1 -0
  57. package/dist/index.d.ts +42 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +63 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/ledger.d.ts +45 -0
  62. package/dist/ledger.d.ts.map +1 -0
  63. package/dist/ledger.js +39 -0
  64. package/dist/ledger.js.map +1 -0
  65. package/dist/payload.d.ts +108 -0
  66. package/dist/payload.d.ts.map +1 -0
  67. package/dist/payload.js +263 -0
  68. package/dist/payload.js.map +1 -0
  69. package/dist/port.d.ts +112 -0
  70. package/dist/port.d.ts.map +1 -0
  71. package/dist/port.js +2 -0
  72. package/dist/port.js.map +1 -0
  73. package/dist/product-complexity.d.ts +89 -0
  74. package/dist/product-complexity.d.ts.map +1 -0
  75. package/dist/product-complexity.js +1367 -0
  76. package/dist/product-complexity.js.map +1 -0
  77. package/dist/regex-safety.d.ts +75 -0
  78. package/dist/regex-safety.d.ts.map +1 -0
  79. package/dist/regex-safety.js +902 -0
  80. package/dist/regex-safety.js.map +1 -0
  81. package/dist/relevance-prerequisites.d.ts +21 -0
  82. package/dist/relevance-prerequisites.d.ts.map +1 -0
  83. package/dist/relevance-prerequisites.js +47 -0
  84. package/dist/relevance-prerequisites.js.map +1 -0
  85. package/dist/relevance.d.ts +107 -0
  86. package/dist/relevance.d.ts.map +1 -0
  87. package/dist/relevance.js +199 -0
  88. package/dist/relevance.js.map +1 -0
  89. package/dist/retrieval.d.ts +46 -0
  90. package/dist/retrieval.d.ts.map +1 -0
  91. package/dist/retrieval.js +182 -0
  92. package/dist/retrieval.js.map +1 -0
  93. package/dist/scoring.d.ts +102 -0
  94. package/dist/scoring.d.ts.map +1 -0
  95. package/dist/scoring.js +175 -0
  96. package/dist/scoring.js.map +1 -0
  97. package/dist/sort.d.ts +21 -0
  98. package/dist/sort.d.ts.map +1 -0
  99. package/dist/sort.js +53 -0
  100. package/dist/sort.js.map +1 -0
  101. package/dist/symbol-match.d.ts +21 -0
  102. package/dist/symbol-match.d.ts.map +1 -0
  103. package/dist/symbol-match.js +72 -0
  104. package/dist/symbol-match.js.map +1 -0
  105. package/dist/tokenize.d.ts +41 -0
  106. package/dist/tokenize.d.ts.map +1 -0
  107. package/dist/tokenize.js +202 -0
  108. package/dist/tokenize.js.map +1 -0
  109. package/dist/types.d.ts +173 -0
  110. package/dist/types.d.ts.map +1 -0
  111. package/dist/types.js +42 -0
  112. package/dist/types.js.map +1 -0
  113. package/package.json +61 -3
  114. package/src/benchmark-integrity.ts +25 -0
  115. package/src/bm25.ts +135 -0
  116. package/src/deadline.ts +59 -0
  117. package/src/dedupe.ts +99 -0
  118. package/src/diversify.ts +71 -0
  119. package/src/engine.ts +1957 -0
  120. package/src/enrichment.ts +115 -0
  121. package/src/filter.ts +267 -0
  122. package/src/findability.ts +580 -0
  123. package/src/format.ts +228 -0
  124. package/src/fusion.ts +121 -0
  125. package/src/glob.ts +151 -0
  126. package/src/grep.ts +618 -0
  127. package/src/index.ts +83 -0
  128. package/src/ledger.ts +72 -0
  129. package/src/payload.ts +382 -0
  130. package/src/port.ts +133 -0
  131. package/src/product-complexity.ts +2168 -0
  132. package/src/regex-safety.ts +1002 -0
  133. package/src/relevance-prerequisites.ts +83 -0
  134. package/src/relevance.ts +328 -0
  135. package/src/retrieval.ts +299 -0
  136. package/src/scoring.ts +321 -0
  137. package/src/sort.ts +86 -0
  138. package/src/symbol-match.ts +87 -0
  139. package/src/tokenize.ts +213 -0
  140. package/src/types.ts +206 -0
package/dist/format.js ADDED
@@ -0,0 +1,172 @@
1
+ /** Formatiert eine Zahl mit fester Stellenzahl — stabil ueber Plattformen. */
2
+ function fixed(value, digits = 4) {
3
+ return value.toFixed(digits);
4
+ }
5
+ function formatComponent(component) {
6
+ const sign = component.contribution < 0 ? "-" : "+";
7
+ const evidence = component.evidence === undefined ? "" : ` [${component.evidence}]`;
8
+ return ` ${sign} ${component.kind} = ${fixed(Math.abs(component.contribution))} (raw ${fixed(component.rawValue)} x weight ${fixed(component.weight)})${evidence}`;
9
+ }
10
+ /** Kompakte, aber vollstaendige Textdarstellung einer begrenzten Graphfacette. */
11
+ export function formatSearchGraphRelationsAsText(label, value) {
12
+ const lines = value.relations.map((relation) => {
13
+ const arrow = relation.direction === "incoming" ? "<-" : "->";
14
+ const symbol = relation.symbol === undefined ? "" : ` symbol=${relation.symbol.id}`;
15
+ return (` ${label} ${arrow} ${relation.repoId}@${relation.refId} ` +
16
+ `${relation.path} file=${relation.fileId}${symbol} ` +
17
+ `edge=${relation.edgeId} kind=${relation.edgeKind} crossRepository=${String(relation.crossRepository)}`);
18
+ });
19
+ for (const omission of value.omissions) {
20
+ lines.push(` ${label} omitted ${omission.reason} x${String(omission.count)}: ${omission.detail}`);
21
+ }
22
+ return lines;
23
+ }
24
+ /** Eine Trefferzeile plus Score-Zerlegung im Textformat. */
25
+ export function formatHitAsText(hit) {
26
+ const lines = [];
27
+ const symbol = hit.symbolName === undefined ? "" : ` ${hit.symbolKind ?? "symbol"} ${hit.symbolName}`;
28
+ lines.push(`${String(hit.rank).padStart(3, " ")}. ${fixed(hit.score.final)} ${hit.repoLabel}@${hit.refName} ${hit.filePath}:${hit.range.startLine}-${hit.range.endLine}${symbol}`);
29
+ if (hit.complexity?.cognitive !== undefined) {
30
+ lines.push(` complexity: cognitive ${hit.complexity.cognitive}`);
31
+ }
32
+ if (hit.findability !== undefined) {
33
+ lines.push(` findability: ${fixed(hit.findability.score, 2)} (heuristic${hit.findability.primaryCause === undefined ? "" : `, ${hit.findability.primaryCause}`})`);
34
+ }
35
+ lines.push(" why:");
36
+ for (const component of hit.score.components) {
37
+ lines.push(formatComponent(component));
38
+ }
39
+ if (hit.score.clamped) {
40
+ lines.push(` clamped: ${hit.score.clampReason ?? ""}`);
41
+ }
42
+ if (hit.relatedFragments.length > 0) {
43
+ lines.push(` related fragments: ${hit.relatedFragments.map((fragment) => `${fragment.chunkKind}@${fragment.startLine}`).join(", ")}`);
44
+ }
45
+ if (hit.graphContext !== undefined) {
46
+ lines.push(...formatSearchGraphRelationsAsText("context", hit.graphContext));
47
+ }
48
+ if (hit.linkedSymbols !== undefined) {
49
+ lines.push(...formatSearchGraphRelationsAsText("linked", hit.linkedSymbols));
50
+ }
51
+ if (hit.contentOmittedReason !== undefined) {
52
+ lines.push(` content omitted: ${hit.contentOmittedReason}`);
53
+ }
54
+ if (hit.content !== undefined) {
55
+ for (const line of hit.content.split("\n")) {
56
+ lines.push(` | ${line}`);
57
+ }
58
+ }
59
+ return lines.join("\n");
60
+ }
61
+ /** Formatiert eine ganze Ergebnismenge. */
62
+ export function formatSearchResultSet(set, format) {
63
+ if (format === "json") {
64
+ return JSON.stringify(set, null, 2);
65
+ }
66
+ if (format === "jsonl") {
67
+ const header = {
68
+ kind: "header",
69
+ queryFingerprint: set.queryFingerprint,
70
+ ...(set.indexFreshness === undefined ? {} : { indexFreshness: set.indexFreshness }),
71
+ query: set.query,
72
+ profileSeparation: set.profileSeparation,
73
+ totalHits: set.totalHits,
74
+ warnings: set.warnings,
75
+ skipped: set.skipped,
76
+ };
77
+ const lines = [JSON.stringify(header)];
78
+ for (const group of set.groups) {
79
+ for (const hit of group.hits) {
80
+ lines.push(JSON.stringify({ kind: "hit", embeddingProfileId: group.embeddingProfileId, hit }));
81
+ }
82
+ }
83
+ return lines.join("\n");
84
+ }
85
+ const lines = [];
86
+ lines.push(`query: ${set.query.text}`);
87
+ lines.push(`fingerprint: ${set.queryFingerprint}`);
88
+ if (set.profileSeparation) {
89
+ lines.push(`NOTE: ${set.groups.length} embedding profiles — scores are comparable only within a group (spec.md §13.4)`);
90
+ }
91
+ for (const group of set.groups) {
92
+ lines.push("");
93
+ lines.push(`profile ${group.embeddingProfileId} (repos: ${group.repoIds.join(", ")})`);
94
+ for (const caveat of group.caveats) {
95
+ lines.push(` caveat: ${caveat}`);
96
+ }
97
+ // Das Verdikt kommt aus der Entscheidung, nie aus der Listenlaenge. Ein
98
+ // blosses „(no hits)" waere bei einer Ablehnung eine Tatsachenbehauptung
99
+ // ueber den Code: es GAB Kandidaten, die Policy hat sie verworfen.
100
+ const verdict = group.relevanceDecision;
101
+ if (verdict?.status === "rejected") {
102
+ lines.push(` (relevance policy ${verdict.calibrationId ?? "unknown"} judged the evidence ` +
103
+ `insufficient: ${verdict.basis}; abstention=${verdict.abstention})`);
104
+ }
105
+ if (group.hits.length === 0 && verdict?.status !== "rejected") {
106
+ lines.push(" (no hits)");
107
+ }
108
+ for (const hit of group.hits) {
109
+ lines.push(formatHitAsText(hit));
110
+ }
111
+ }
112
+ if (set.warnings.length > 0) {
113
+ lines.push("");
114
+ lines.push("warnings:");
115
+ for (const warning of set.warnings) {
116
+ lines.push(` ${warning.code}: ${warning.message}`);
117
+ }
118
+ }
119
+ if (set.skipped.length > 0) {
120
+ lines.push("");
121
+ lines.push(`skipped (${set.skipped.length}) — nothing is dropped silently:`);
122
+ for (const entry of set.skipped) {
123
+ lines.push(` ${entry.reason} ${entry.subjectKind} ${entry.subjectId ?? entry.path ?? ""}: ${entry.detail}`);
124
+ }
125
+ }
126
+ return lines.join("\n");
127
+ }
128
+ /** Formatiert grep-Treffer. */
129
+ export function formatGrepResultSet(set, format) {
130
+ if (format === "json") {
131
+ return JSON.stringify(set, null, 2);
132
+ }
133
+ if (format === "jsonl") {
134
+ const header = {
135
+ kind: "header",
136
+ pattern: set.pattern,
137
+ ...(set.indexFreshness === undefined ? {} : { indexFreshness: set.indexFreshness }),
138
+ isRegex: set.isRegex,
139
+ totalMatches: set.totalMatches,
140
+ truncated: set.truncated,
141
+ ...(set.truncationReason === undefined ? {} : { truncationReason: set.truncationReason }),
142
+ scannedChunks: set.scannedChunks,
143
+ warnings: set.warnings,
144
+ skipped: set.skipped,
145
+ };
146
+ return [header, ...set.matches.map((match) => ({ kind: "match", match }))]
147
+ .map((entry) => JSON.stringify(entry))
148
+ .join("\n");
149
+ }
150
+ const lines = [];
151
+ for (const match of set.matches) {
152
+ for (const context of match.before) {
153
+ lines.push(`${match.filePath}-${context.line}- ${context.text}`);
154
+ }
155
+ lines.push(`${match.filePath}:${match.line}:${match.column}: ${match.lineText}`);
156
+ for (const context of match.after) {
157
+ lines.push(`${match.filePath}-${context.line}- ${context.text}`);
158
+ }
159
+ if (match.before.length > 0 || match.after.length > 0) {
160
+ lines.push("--");
161
+ }
162
+ }
163
+ lines.push(`${set.totalMatches} match(es) in ${set.scannedChunks} scanned chunk(s)${set.truncated ? ` — TRUNCATED (${set.truncationReason ?? "unknown"})` : ""}`);
164
+ if (set.skipped.length > 0) {
165
+ lines.push(`skipped (${set.skipped.length}):`);
166
+ for (const entry of set.skipped) {
167
+ lines.push(` ${entry.reason} ${entry.subjectId ?? entry.path ?? ""}: ${entry.detail}`);
168
+ }
169
+ }
170
+ return lines.join("\n");
171
+ }
172
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /** Glaettungskonstante der RRF-Formel (siehe Modulkommentar). */
2
+ export declare const RRF_K = 60;
3
+ /** Voreingestellte Zweiggewichte (siehe Modulkommentar). */
4
+ export declare const DEFAULT_BRANCH_WEIGHTS: {
5
+ readonly dense: 1;
6
+ readonly lexical: 1;
7
+ readonly symbol: 0.5;
8
+ };
9
+ export type FusionBranch = keyof typeof DEFAULT_BRANCH_WEIGHTS;
10
+ /** Eine Rangliste eines Zweigs: IDs, bester zuerst. */
11
+ export interface FusionInput {
12
+ branch: FusionBranch;
13
+ /** IDs in Rangfolge; Position 0 ist Rang 1. */
14
+ rankedIds: readonly string[];
15
+ }
16
+ export interface FusionResult {
17
+ id: string;
18
+ /** Roher RRF-Wert. */
19
+ rrf: number;
20
+ /** Auf [0, 1] normalisierter RRF-Wert (siehe {@link maximumRrf}). */
21
+ normalized: number;
22
+ /** Beitragende Zweige mit ihrem 1-basierten Rang. */
23
+ ranks: Partial<Record<FusionBranch, number>>;
24
+ /** Wirksame Gewichte der beteiligten Zweige (fuer die Score-Evidenz). */
25
+ weights?: Partial<Record<FusionBranch, number>>;
26
+ }
27
+ export type BranchWeights = Record<FusionBranch, number>;
28
+ /**
29
+ * Der groesstmoegliche RRF-Wert: jeder beteiligte Zweig auf Rang 1.
30
+ *
31
+ * Damit wird auf [0, 1] normalisiert, OHNE durch den Maximalwert der aktuellen
32
+ * Trefferliste zu teilen. Das ist der Unterschied zwischen „dieser Treffer ist
33
+ * gut" und „dieser Treffer war der beste, den wir hatten": eine Normalisierung
34
+ * am Listenmaximum gaebe dem besten Treffer immer 1.0, auch wenn er schlecht
35
+ * ist — und die Findability-Diagnose (vision.md §1d) braucht genau diesen
36
+ * Unterschied.
37
+ */
38
+ export declare function maximumRrf(branches: readonly FusionBranch[], weights: BranchWeights): number;
39
+ /**
40
+ * Fusioniert die Ranglisten. Ein Kandidat, der in einem Zweig nicht vorkommt,
41
+ * bekommt von diesem Zweig schlicht keinen Beitrag — er wird nicht bestraft.
42
+ *
43
+ * Die Ausgabe ist absteigend nach RRF sortiert, bei Gleichstand nach
44
+ * Codepoints der ID (deterministisch).
45
+ */
46
+ export declare function fuseRankings(inputs: readonly FusionInput[], weights?: BranchWeights): FusionResult[];
47
+ //# sourceMappingURL=fusion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fusion.d.ts","sourceRoot":"","sources":["../src/fusion.ts"],"names":[],"mappings":"AAgCA,iEAAiE;AACjE,eAAO,MAAM,KAAK,KAAK,CAAC;AAExB,4DAA4D;AAC5D,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,sBAAsB,CAAC;AAE/D,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAEzD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAG5F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,WAAW,EAAE,EAC9B,OAAO,GAAE,aAA6C,GACrD,YAAY,EAAE,CA8BhB"}
package/dist/fusion.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Fusion der drei Ranglisten (spec.md §13.2 Schritt 6, §13.4).
3
+ *
4
+ * Verfahren: gewichtete Reciprocal Rank Fusion.
5
+ *
6
+ * rrf(d) = Σ_zweig w_zweig / (k + rang_zweig(d))
7
+ *
8
+ * WARUM RRF UND NICHT EINE SCORE-SUMME: Cosine-Aehnlichkeit, BM25 und eine
9
+ * Namensuebereinstimmung leben in drei verschiedenen Wertebereichen. Sie zu
10
+ * addieren hiesse, sie stillschweigend gleich zu skalieren. RRF benutzt nur
11
+ * die RANGFOLGE jedes Zweigs und ist damit gegen die Skala jedes einzelnen
12
+ * Zweigs unempfindlich — dieselbe Eigenschaft, wegen der spec.md §13.4 RRF
13
+ * als einziges Fusionsverfahren fuer v1 festlegt.
14
+ *
15
+ * WARUM k = 60: der Wert aus der RRF-Originalarbeit (Cormack, Clarke,
16
+ * Buettcher 2009), seither die uebliche Voreinstellung — unter anderem in
17
+ * Qdrants eigener RRF-Implementierung, gegen die dieser Abrufkern austauschbar
18
+ * bleiben soll. Grosses k daempft den Vorsprung der ersten Plaetze, kleines k
19
+ * ueberhoeht ihn; 60 ist der dokumentierte Mittelweg, nicht ein geratener.
20
+ *
21
+ * WARUM DIE ZWEIGGEWICHTE SO GEWAEHLT SIND:
22
+ * - dicht 1.0 und lexikalisch 1.0 — die beiden Abrufzweige sind gleichwertig;
23
+ * welcher besser ist, haengt an der Anfrage (Absichtsfrage vs. Bezeichner),
24
+ * und genau deshalb werden beide gefragt;
25
+ * - Symbolname 0.5 — der Zweig ist eine PRAEZISIONS-, keine Abrufquelle. Ein
26
+ * exakter Namenstreffer wird zusaetzlich als `exact_symbol_boost` belohnt
27
+ * (spec.md §13.3). Mit vollem Gewicht in der Fusion UND vollem Boost
28
+ * wuerde derselbe Beleg doppelt zaehlen; das halbe Gewicht ist der
29
+ * ausdrueckliche Abschlag dafuer.
30
+ */
31
+ import { compareCodepoints } from "@untangle-code/domain";
32
+ /** Glaettungskonstante der RRF-Formel (siehe Modulkommentar). */
33
+ export const RRF_K = 60;
34
+ /** Voreingestellte Zweiggewichte (siehe Modulkommentar). */
35
+ export const DEFAULT_BRANCH_WEIGHTS = {
36
+ dense: 1,
37
+ lexical: 1,
38
+ symbol: 0.5,
39
+ };
40
+ /**
41
+ * Der groesstmoegliche RRF-Wert: jeder beteiligte Zweig auf Rang 1.
42
+ *
43
+ * Damit wird auf [0, 1] normalisiert, OHNE durch den Maximalwert der aktuellen
44
+ * Trefferliste zu teilen. Das ist der Unterschied zwischen „dieser Treffer ist
45
+ * gut" und „dieser Treffer war der beste, den wir hatten": eine Normalisierung
46
+ * am Listenmaximum gaebe dem besten Treffer immer 1.0, auch wenn er schlecht
47
+ * ist — und die Findability-Diagnose (vision.md §1d) braucht genau diesen
48
+ * Unterschied.
49
+ */
50
+ export function maximumRrf(branches, weights) {
51
+ const uniqueBranches = [...new Set(branches)];
52
+ return uniqueBranches.reduce((sum, branch) => sum + weights[branch] / (RRF_K + 1), 0);
53
+ }
54
+ /**
55
+ * Fusioniert die Ranglisten. Ein Kandidat, der in einem Zweig nicht vorkommt,
56
+ * bekommt von diesem Zweig schlicht keinen Beitrag — er wird nicht bestraft.
57
+ *
58
+ * Die Ausgabe ist absteigend nach RRF sortiert, bei Gleichstand nach
59
+ * Codepoints der ID (deterministisch).
60
+ */
61
+ export function fuseRankings(inputs, weights = { ...DEFAULT_BRANCH_WEIGHTS }) {
62
+ const accumulator = new Map();
63
+ for (const input of inputs) {
64
+ const weight = weights[input.branch];
65
+ input.rankedIds.forEach((id, index) => {
66
+ const rank = index + 1;
67
+ const entry = accumulator.get(id) ?? { rrf: 0, ranks: {} };
68
+ entry.rrf += weight / (RRF_K + rank);
69
+ entry.ranks[input.branch] = rank;
70
+ accumulator.set(id, entry);
71
+ });
72
+ }
73
+ const maximum = maximumRrf(inputs.map((input) => input.branch), weights);
74
+ const results = [...accumulator.entries()].map(([id, entry]) => ({
75
+ id,
76
+ rrf: entry.rrf,
77
+ normalized: maximum === 0 ? 0 : entry.rrf / maximum,
78
+ ranks: entry.ranks,
79
+ weights: Object.fromEntries([...new Set(inputs.map((input) => input.branch))].map((branch) => [branch, weights[branch]])),
80
+ }));
81
+ results.sort((a, b) => (a.rrf === b.rrf ? compareCodepoints(a.id, b.id) : b.rrf - a.rrf));
82
+ return results;
83
+ }
84
+ //# sourceMappingURL=fusion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fusion.js","sourceRoot":"","sources":["../src/fusion.ts"],"names":[],"mappings":"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"}
package/dist/glob.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Deterministischer Glob-Abgleich fuer Pfad-Ein- und -Ausschluss
3
+ * (Nutzerwunsch A4: „Pfad-Ein-/Ausschluss" wie ein grep-Werkzeug).
4
+ *
5
+ * Warum eine eigene, kleine Implementierung statt einer Bibliothek: der
6
+ * Abgleich muss auf „/"-normalisierten, repo-relativen Pfaden arbeiten
7
+ * (spec.md §5.2), darf keine Dateisystemzugriffe machen (wir globben ueber
8
+ * INDIZIERTE Pfade, nicht ueber die Platte) und muss auf jeder Maschine
9
+ * dieselbe Antwort geben. Die unterstuetzte Teilmenge ist bewusst klein und
10
+ * hier vollstaendig dokumentiert:
11
+ *
12
+ * | Muster | Bedeutung |
13
+ * |---|---|
14
+ * | `?` | genau ein Zeichen, aber nie `/` |
15
+ * | `*` | beliebig viele Zeichen, aber nie `/` |
16
+ * | `**` | beliebig viele Zeichen inklusive `/` |
17
+ * | `[abc]` | eine Zeichenklasse, `[!abc]`/`[^abc]` negiert |
18
+ * | sonst | Literal |
19
+ *
20
+ * Ein Muster ohne `/` wird zusaetzlich gegen den BASENAMEN geprueft, damit
21
+ * `*.ts` das tut, was jeder erwartet, ohne dass der Nutzer `**\/*.ts`
22
+ * schreiben muss. Diese Bequemlichkeit ist eine bewusste Entscheidung und in
23
+ * der README als solche vermerkt.
24
+ */
25
+ /** Wandelt ein Glob-Muster in einen verankerten regulaeren Ausdruck. */
26
+ export declare function globToRegExp(pattern: string): RegExp;
27
+ /**
28
+ * Prueft eine Musterliste, BEVOR sie benutzt wird.
29
+ *
30
+ * Warum vorab und nicht erst beim Abgleich: der Abgleich laeuft je Kandidat,
31
+ * tief in der Auswertung. Ein Fehler dort trifft eine Stelle, die ihn nur noch
32
+ * als „dieses Ziel hat nicht geantwortet" deuten kann. Vorab geprueft, ist er
33
+ * das, was er ist: eine abgelehnte Anfrage mit benanntem Muster.
34
+ */
35
+ export declare function assertValidGlobPatterns(patterns: readonly string[], label: string): void;
36
+ /** Kanonisiert einen Pfad fuer den Abgleich: Backslashes zu `/`, kein `./`. */
37
+ export declare function normalizeGlobPath(path: string): string;
38
+ /** True, wenn `path` auf `pattern` passt (siehe Modulkommentar). */
39
+ export declare function matchesGlob(path: string, pattern: string): boolean;
40
+ /** True, wenn `path` auf mindestens eines der Muster passt. */
41
+ export declare function matchesAnyGlob(path: string, patterns: readonly string[]): boolean;
42
+ /**
43
+ * Entscheidet ueber Ein-/Ausschluss eines Pfades.
44
+ *
45
+ * - leere Einschlussliste heisst „alles einschliessen" (wie in SearchFiltersV1
46
+ * dokumentiert: eine leere Liste ist kein Filter);
47
+ * - Ausschluss gewinnt immer gegen Einschluss.
48
+ */
49
+ export declare function isPathSelected(path: string, include: readonly string[], exclude: readonly string[]): boolean;
50
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0DpD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CASxF;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAYlE;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEjF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,OAAO,CAQT"}
package/dist/glob.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Deterministischer Glob-Abgleich fuer Pfad-Ein- und -Ausschluss
3
+ * (Nutzerwunsch A4: „Pfad-Ein-/Ausschluss" wie ein grep-Werkzeug).
4
+ *
5
+ * Warum eine eigene, kleine Implementierung statt einer Bibliothek: der
6
+ * Abgleich muss auf „/"-normalisierten, repo-relativen Pfaden arbeiten
7
+ * (spec.md §5.2), darf keine Dateisystemzugriffe machen (wir globben ueber
8
+ * INDIZIERTE Pfade, nicht ueber die Platte) und muss auf jeder Maschine
9
+ * dieselbe Antwort geben. Die unterstuetzte Teilmenge ist bewusst klein und
10
+ * hier vollstaendig dokumentiert:
11
+ *
12
+ * | Muster | Bedeutung |
13
+ * |---|---|
14
+ * | `?` | genau ein Zeichen, aber nie `/` |
15
+ * | `*` | beliebig viele Zeichen, aber nie `/` |
16
+ * | `**` | beliebig viele Zeichen inklusive `/` |
17
+ * | `[abc]` | eine Zeichenklasse, `[!abc]`/`[^abc]` negiert |
18
+ * | sonst | Literal |
19
+ *
20
+ * Ein Muster ohne `/` wird zusaetzlich gegen den BASENAMEN geprueft, damit
21
+ * `*.ts` das tut, was jeder erwartet, ohne dass der Nutzer `**\/*.ts`
22
+ * schreiben muss. Diese Bequemlichkeit ist eine bewusste Entscheidung und in
23
+ * der README als solche vermerkt.
24
+ */
25
+ /** Wandelt ein Glob-Muster in einen verankerten regulaeren Ausdruck. */
26
+ export function globToRegExp(pattern) {
27
+ let source = "^";
28
+ let index = 0;
29
+ while (index < pattern.length) {
30
+ const char = pattern[index];
31
+ if (char === "*") {
32
+ const isDouble = pattern[index + 1] === "*";
33
+ if (isDouble) {
34
+ // `a/**/b` soll auch `a/b` treffen: der Schraegstrich hinter `**`
35
+ // wird optional mitgeschluckt.
36
+ if (pattern[index + 2] === "/") {
37
+ source += "(?:.*/)?";
38
+ index += 3;
39
+ continue;
40
+ }
41
+ source += ".*";
42
+ index += 2;
43
+ continue;
44
+ }
45
+ source += "[^/]*";
46
+ index += 1;
47
+ continue;
48
+ }
49
+ if (char === "?") {
50
+ source += "[^/]";
51
+ index += 1;
52
+ continue;
53
+ }
54
+ if (char === "[") {
55
+ const close = pattern.indexOf("]", index + 1);
56
+ if (close === -1) {
57
+ // Unpaarige Klammer ist ein Literal, kein Fehler — ein Suchmuster
58
+ // darf nicht daran scheitern, dass jemand `[` im Pfad meint.
59
+ source += "\\[";
60
+ index += 1;
61
+ continue;
62
+ }
63
+ const body = pattern.slice(index + 1, close);
64
+ const negated = body.startsWith("!") || body.startsWith("^");
65
+ const content = negated ? body.slice(1) : body;
66
+ source += `[${negated ? "^" : ""}${content.replace(/[\\\]]/g, "\\$&")}]`;
67
+ index = close + 1;
68
+ continue;
69
+ }
70
+ source += char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
71
+ index += 1;
72
+ }
73
+ source += "$";
74
+ try {
75
+ return new RegExp(source, "u");
76
+ }
77
+ catch (error) {
78
+ // Ein fehlerhaftes Muster ist ein EINGABEFEHLER des Nutzers. Ohne diesen
79
+ // Rahmen wandert der rohe `SyntaxError` durch den Abgleich bis in ein
80
+ // catch, das ihn als Speicherausfall verbucht — der Nutzer bekaeme dann
81
+ // „Provider nicht verfuegbar" fuer sein eigenes Zeichenklassenmuster.
82
+ const message = error instanceof Error ? error.message : String(error);
83
+ throw new Error(`glob pattern "${pattern}" is not a valid pattern: ${message}`);
84
+ }
85
+ }
86
+ /**
87
+ * Prueft eine Musterliste, BEVOR sie benutzt wird.
88
+ *
89
+ * Warum vorab und nicht erst beim Abgleich: der Abgleich laeuft je Kandidat,
90
+ * tief in der Auswertung. Ein Fehler dort trifft eine Stelle, die ihn nur noch
91
+ * als „dieses Ziel hat nicht geantwortet" deuten kann. Vorab geprueft, ist er
92
+ * das, was er ist: eine abgelehnte Anfrage mit benanntem Muster.
93
+ */
94
+ export function assertValidGlobPatterns(patterns, label) {
95
+ for (const pattern of patterns) {
96
+ try {
97
+ globToRegExp(normalizeGlobPath(pattern));
98
+ }
99
+ catch (error) {
100
+ const message = error instanceof Error ? error.message : String(error);
101
+ throw new Error(`search query field "${label}" contains an invalid pattern: ${message}`);
102
+ }
103
+ }
104
+ }
105
+ /** Kanonisiert einen Pfad fuer den Abgleich: Backslashes zu `/`, kein `./`. */
106
+ export function normalizeGlobPath(path) {
107
+ const slashed = path.replace(/\\/g, "/");
108
+ return slashed.startsWith("./") ? slashed.slice(2) : slashed;
109
+ }
110
+ /** True, wenn `path` auf `pattern` passt (siehe Modulkommentar). */
111
+ export function matchesGlob(path, pattern) {
112
+ const normalizedPath = normalizeGlobPath(path);
113
+ const normalizedPattern = normalizeGlobPath(pattern);
114
+ const expression = globToRegExp(normalizedPattern);
115
+ if (expression.test(normalizedPath)) {
116
+ return true;
117
+ }
118
+ if (!normalizedPattern.includes("/")) {
119
+ const basename = normalizedPath.slice(normalizedPath.lastIndexOf("/") + 1);
120
+ return expression.test(basename);
121
+ }
122
+ return false;
123
+ }
124
+ /** True, wenn `path` auf mindestens eines der Muster passt. */
125
+ export function matchesAnyGlob(path, patterns) {
126
+ return patterns.some((pattern) => matchesGlob(path, pattern));
127
+ }
128
+ /**
129
+ * Entscheidet ueber Ein-/Ausschluss eines Pfades.
130
+ *
131
+ * - leere Einschlussliste heisst „alles einschliessen" (wie in SearchFiltersV1
132
+ * dokumentiert: eine leere Liste ist kein Filter);
133
+ * - Ausschluss gewinnt immer gegen Einschluss.
134
+ */
135
+ export function isPathSelected(path, include, exclude) {
136
+ if (exclude.length > 0 && matchesAnyGlob(path, exclude)) {
137
+ return false;
138
+ }
139
+ if (include.length === 0) {
140
+ return true;
141
+ }
142
+ return matchesAnyGlob(path, include);
143
+ }
144
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../src/glob.ts"],"names":[],"mappings":"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"}
package/dist/grep.d.ts ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * grep-artige Suche ueber den indexierten Inhalt (Nutzerwunsch A4).
3
+ *
4
+ * „Beides — semantisch UND grep-artig — unter einer Oberflaeche" heisst hier
5
+ * woertlich: derselbe Port, dieselben Filter, dieselbe Provenienz je Treffer,
6
+ * derselbe Skip-Ledger. Der Unterschied ist nur, WAS gefragt wird — ein
7
+ * Zeichenmuster statt einer Bedeutung.
8
+ *
9
+ * WICHTIG FUER DIE INTERPRETATION DER ERGEBNISSE: Gesucht wird im INDEX, nicht
10
+ * auf der Platte. Was nicht indexiert ist (uebersprungene Datei, Chunk ohne
11
+ * gespeicherten Inhalt), kann hier nicht gefunden werden. Genau deshalb traegt
12
+ * `GrepResultSetV1` den Skip-Ledger und die Zahl der durchsuchten Chunks mit —
13
+ * „keine Treffer" und „nichts durchsucht" duerfen nicht gleich aussehen (E4).
14
+ *
15
+ * Zeilennummern sind ECHTE Dateizeilen: der Chunk kennt seine `start_line`,
16
+ * und die Zeilenzaehlung setzt darauf auf. Kontextzeilen kommen aus demselben
17
+ * Chunk; reicht der Kontext ueber die Chunkgrenze hinaus, endet er dort. Das
18
+ * ist eine bewusste Grenze (siehe README „Bekannte Grenzen") — die
19
+ * Nachbarzeilen liegen in einem anderen Punkt und muessten einzeln nachgeladen
20
+ * werden.
21
+ */
22
+ import type { PortCallOptions, VectorStore } from "@untangle-code/domain";
23
+ import type { GrepMatchV1, GrepRequestV1, GrepResultSetV1 } from "./types.js";
24
+ /** Voreinstellungen der Budgets — jede Ueberschreitung ist ein benannter Abbruchgrund. */
25
+ export declare const GREP_DEFAULTS: {
26
+ readonly maxMatches: 200;
27
+ readonly maxMatchesPerFile: 50;
28
+ readonly maxScannedChunks: 5000;
29
+ /** Seitengroesse des Scroll-Laufs ueber die Collection. */
30
+ readonly scrollPageSize: 256;
31
+ };
32
+ /**
33
+ * Wie viele glob-ausgeschlossene Chunks EINZELN im Ledger stehen.
34
+ *
35
+ * Jeder ausgeschlossene Chunk gehoert in den Ledger (E4) — bei einem Budget
36
+ * von 5000 gescannten Chunks waere eine Liste mit 5000 Eintraegen aber selbst
37
+ * ein Problem fuer den Leser. Also: die ersten `GREP_GLOB_LEDGER_DETAIL_LIMIT`
38
+ * einzeln, danach EIN Sammeleintrag mit der vollstaendigen Zahl. Verschwiegen
39
+ * wird nichts; die Zahl stimmt in jedem Fall.
40
+ */
41
+ export declare const GREP_GLOB_LEDGER_DETAIL_LIMIT = 50;
42
+ /**
43
+ * Der Geltungsbereich, in dem grep ueberhaupt suchen darf.
44
+ *
45
+ * Dieselbe Begruendung wie bei `SearchScopeV1` in `filter.ts`: ohne Workspace
46
+ * laeuft eine Mustersuche ueber die Chunks JEDES Workspaces, der zufaellig in
47
+ * derselben Collection liegt, und meldet fremden Code als eigenen.
48
+ */
49
+ export interface GrepScopeV1 {
50
+ /** Workspace, falls die Anfrage selbst keinen nennt. */
51
+ workspaceId?: string;
52
+ /** Repositories der durchsuchten Collections; leer heisst „nicht deklariert". */
53
+ repoIds?: readonly string[];
54
+ }
55
+ /** Maskiert einen Literaltext, damit er als regulaerer Ausdruck sich selbst bedeutet. */
56
+ export declare function escapeRegExpLiteral(text: string): string;
57
+ /**
58
+ * Baut den Suchausdruck.
59
+ *
60
+ * `wholeWord` verwendet bewusst Lookarounds ueber Bezeichnerzeichen statt
61
+ * `\b`: `\b` kennt nur ASCII-Wortzeichen, und ein Bezeichner mit Umlaut oder
62
+ * `$` waere damit an der falschen Stelle „ganzes Wort".
63
+ */
64
+ export declare function buildGrepRegExp(request: GrepRequestV1): RegExp;
65
+ /**
66
+ * Durchsucht die angegebenen Collections mit einem Muster.
67
+ *
68
+ * Der Ablauf ist bewusst ein Scroll und kein `hybridQuery`: eine Regex-Suche
69
+ * hat kein Ranking-Signal, sie hat einen VOLLSTAENDIGKEITSANSPRUCH. Also wird
70
+ * gefiltert und durchlaufen, bis das Budget greift — und wenn es greift, steht
71
+ * das im Ergebnis.
72
+ */
73
+ export declare function grepIndexedChunks(store: VectorStore, collections: readonly string[], request: GrepRequestV1, options?: PortCallOptions, scope?: GrepScopeV1): Promise<GrepResultSetV1>;
74
+ /** Sortiert grep-Treffer deterministisch. */
75
+ export declare function sortGrepMatches<T extends GrepMatchV1>(matches: readonly T[], sort: "path" | "matches-desc"): T[];
76
+ //# sourceMappingURL=grep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../src/grep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAGV,eAAe,EAGf,WAAW,EACZ,MAAM,uBAAuB,CAAC;AAO/B,OAAO,KAAK,EAAqB,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjG,0FAA0F;AAC1F,eAAO,MAAM,aAAa;;;;IAIxB,2DAA2D;;CAEnD,CAAC;AAEX;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iFAAiF;IACjF,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAqB9D;AAiLD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,eAAe,EACzB,KAAK,GAAE,WAAgB,GACtB,OAAO,CAAC,eAAe,CAAC,CA4R1B;AAED,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,EACnD,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,IAAI,EAAE,MAAM,GAAG,cAAc,GAC5B,CAAC,EAAE,CAgCL"}