@hraness/kb 0.17.1

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 (200) hide show
  1. package/DISCLOSURE +43 -0
  2. package/LICENSE +21 -0
  3. package/README.md +545 -0
  4. package/dist/agent-context.js +35 -0
  5. package/dist/agent-guide-audit.js +18 -0
  6. package/dist/attachments.js +19 -0
  7. package/dist/authoring.js +33 -0
  8. package/dist/benchmark.js +19 -0
  9. package/dist/capture.js +49 -0
  10. package/dist/cli.js +3646 -0
  11. package/dist/clip/acquire.js +57 -0
  12. package/dist/clip/args.js +21 -0
  13. package/dist/clip/bounded-byte-buffer.js +9 -0
  14. package/dist/clip/browser-profiles.js +17 -0
  15. package/dist/clip/bundle-reader.js +11 -0
  16. package/dist/clip/cli.js +27 -0
  17. package/dist/clip/cookies.js +21 -0
  18. package/dist/clip/defuddle-worker.js +84 -0
  19. package/dist/clip/doctor.js +32 -0
  20. package/dist/clip/jobs.js +784 -0
  21. package/dist/clip/network-proxy.js +9 -0
  22. package/dist/clip/network.js +28 -0
  23. package/dist/clip/persist.js +30 -0
  24. package/dist/clip/refresh.js +11 -0
  25. package/dist/clip/terminal.js +11 -0
  26. package/dist/evaluation-builder.js +12238 -0
  27. package/dist/evaluation-kb.js +26 -0
  28. package/dist/evaluation.js +35 -0
  29. package/dist/git.js +39 -0
  30. package/dist/graph.js +39 -0
  31. package/dist/index-01jj6rbv.js +1103 -0
  32. package/dist/index-06c9ctr6.js +738 -0
  33. package/dist/index-0kavxzqj.js +2480 -0
  34. package/dist/index-1gwbassd.js +743 -0
  35. package/dist/index-1n418kb9.js +827 -0
  36. package/dist/index-1vrd1rmn.js +56 -0
  37. package/dist/index-1xxnjn0d.js +171 -0
  38. package/dist/index-3rm7cz6h.js +373 -0
  39. package/dist/index-3v2z4f0q.js +328 -0
  40. package/dist/index-48pz4jpc.js +392 -0
  41. package/dist/index-4j3tt0c3.js +234 -0
  42. package/dist/index-5n05se68.js +307 -0
  43. package/dist/index-5vwpzb5a.js +764 -0
  44. package/dist/index-6g2pv9d2.js +370 -0
  45. package/dist/index-7fzc32gf.js +712 -0
  46. package/dist/index-84x0vjjp.js +432 -0
  47. package/dist/index-adx6khj5.js +488 -0
  48. package/dist/index-b88v3vtm.js +805 -0
  49. package/dist/index-cv6fh7z5.js +462 -0
  50. package/dist/index-cxfrakt7.js +1067 -0
  51. package/dist/index-d13v9ckt.js +150 -0
  52. package/dist/index-dycjbhw2.js +1943 -0
  53. package/dist/index-dyqwejk5.js +531 -0
  54. package/dist/index-e5fbsywq.js +658 -0
  55. package/dist/index-f984hw45.js +927 -0
  56. package/dist/index-gh719d91.js +63 -0
  57. package/dist/index-hgve9rh2.js +2046 -0
  58. package/dist/index-hya40gb2.js +474 -0
  59. package/dist/index-j4zgmzjr.js +152 -0
  60. package/dist/index-jsmvyyvf.js +1166 -0
  61. package/dist/index-kh0pwvdd.js +1974 -0
  62. package/dist/index-mqx4nd6v.js +119 -0
  63. package/dist/index-mxxxytys.js +1254 -0
  64. package/dist/index-n5dd7r0v.js +711 -0
  65. package/dist/index-npg9z1a4.js +431 -0
  66. package/dist/index-pj501bh1.js +140 -0
  67. package/dist/index-qry4vhxk.js +1041 -0
  68. package/dist/index-s2gw5aw9.js +199 -0
  69. package/dist/index-vvdj6kca.js +70 -0
  70. package/dist/index-w2zc0vwa.js +571 -0
  71. package/dist/index-x3fthpsc.js +585 -0
  72. package/dist/index-zr53sf63.js +44 -0
  73. package/dist/index-zxdy5pby.js +2728 -0
  74. package/dist/index-zzhgcwyt.js +966 -0
  75. package/dist/index.js +453 -0
  76. package/dist/navigation.js +13 -0
  77. package/dist/pdf.js +85 -0
  78. package/dist/percolate.js +24 -0
  79. package/dist/portfolio.js +77 -0
  80. package/dist/query.js +29 -0
  81. package/dist/repository-memory.js +60 -0
  82. package/dist/sdk.js +36 -0
  83. package/dist/search-rules.js +34 -0
  84. package/dist/search.js +22 -0
  85. package/dist/semantic.js +39 -0
  86. package/dist/source-inbox.js +17 -0
  87. package/dist/untrusted-content.js +32 -0
  88. package/dist/url-intelligence.js +74 -0
  89. package/dist/workflow.js +23 -0
  90. package/dist/workflows/decision-context.js +20 -0
  91. package/dist/workflows/explain-change.js +8 -0
  92. package/dist/workflows/index.js +28 -0
  93. package/dist/workflows/plan-radar.js +10 -0
  94. package/package.json +409 -0
  95. package/skills/kb/AGENTS.md +19 -0
  96. package/skills/kb/SKILL.md +82 -0
  97. package/skills/kb/agents/openai.yaml +4 -0
  98. package/skills/kb/references/pdf-review.md +51 -0
  99. package/skills/kb/references/percolate.md +144 -0
  100. package/skills/kb/references/plan-structure.md +105 -0
  101. package/skills/kb/references/plan.md +115 -0
  102. package/skills/kb/references/query.md +231 -0
  103. package/skills/kb/references/refresh.md +133 -0
  104. package/skills/kb/references/save-pdf.md +125 -0
  105. package/skills/kb/references/save-url.md +178 -0
  106. package/skills/kb/references/url-authentication.md +75 -0
  107. package/skills/kb/references/url-platforms.md +25 -0
  108. package/src/agent-context.ts +1241 -0
  109. package/src/agent-guide-audit.ts +750 -0
  110. package/src/attachments.ts +723 -0
  111. package/src/authoring.ts +1725 -0
  112. package/src/benchmark.ts +362 -0
  113. package/src/capture.ts +68 -0
  114. package/src/cli.ts +3660 -0
  115. package/src/clip/acquire.ts +1273 -0
  116. package/src/clip/archive-today.ts +402 -0
  117. package/src/clip/args.ts +423 -0
  118. package/src/clip/assets.ts +262 -0
  119. package/src/clip/bounded-byte-buffer.ts +75 -0
  120. package/src/clip/browser-profiles.ts +372 -0
  121. package/src/clip/bundle-reader.ts +608 -0
  122. package/src/clip/capture.ts +1054 -0
  123. package/src/clip/cli.ts +181 -0
  124. package/src/clip/cookies.ts +512 -0
  125. package/src/clip/doctor.ts +1110 -0
  126. package/src/clip/extract.ts +868 -0
  127. package/src/clip/jobs.ts +959 -0
  128. package/src/clip/lib.ts +861 -0
  129. package/src/clip/media.ts +1474 -0
  130. package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
  131. package/src/clip/metadata-search-tool/Cargo.toml +18 -0
  132. package/src/clip/metadata-search-tool/runner.ts +685 -0
  133. package/src/clip/metadata-search-tool/src/main.rs +389 -0
  134. package/src/clip/metadata-search.ts +687 -0
  135. package/src/clip/network-proxy.ts +627 -0
  136. package/src/clip/network.ts +950 -0
  137. package/src/clip/package-root.ts +54 -0
  138. package/src/clip/persist.ts +1472 -0
  139. package/src/clip/platforms.ts +1824 -0
  140. package/src/clip/refresh.ts +197 -0
  141. package/src/clip/structured.ts +432 -0
  142. package/src/clip/terminal.ts +197 -0
  143. package/src/clip/url-intelligence.ts +581 -0
  144. package/src/clip/url-metadata-backfill.ts +616 -0
  145. package/src/clip/url-metadata-cli.ts +251 -0
  146. package/src/clip/url-metadata.ts +1397 -0
  147. package/src/evaluation-analysis-v2.ts +1440 -0
  148. package/src/evaluation-builder.ts +2539 -0
  149. package/src/evaluation-corpus-authoring.ts +2052 -0
  150. package/src/evaluation-evidence.ts +1147 -0
  151. package/src/evaluation-execution-v2.ts +426 -0
  152. package/src/evaluation-implementation.ts +131 -0
  153. package/src/evaluation-kb-closure.ts +1430 -0
  154. package/src/evaluation-kb-runner-v2.ts +735 -0
  155. package/src/evaluation-kb-v2.ts +2567 -0
  156. package/src/evaluation-kb.ts +1018 -0
  157. package/src/evaluation-measurement-v2.ts +1462 -0
  158. package/src/evaluation-packing-v2.ts +452 -0
  159. package/src/evaluation-redaction.ts +28 -0
  160. package/src/evaluation-v2.ts +3857 -0
  161. package/src/evaluation.ts +1220 -0
  162. package/src/git.ts +1276 -0
  163. package/src/graph.ts +1487 -0
  164. package/src/index.ts +20 -0
  165. package/src/init.ts +123 -0
  166. package/src/navigation.ts +277 -0
  167. package/src/note-lock.ts +529 -0
  168. package/src/pdf/args.ts +202 -0
  169. package/src/pdf/capture.ts +298 -0
  170. package/src/pdf/cli.ts +159 -0
  171. package/src/pdf/extract.ts +303 -0
  172. package/src/pdf/layout.ts +618 -0
  173. package/src/pdf/markdown.ts +154 -0
  174. package/src/pdf/model.ts +234 -0
  175. package/src/pdf/ocr.ts +190 -0
  176. package/src/pdf/persist.ts +314 -0
  177. package/src/pdf/source.ts +135 -0
  178. package/src/pdf/tools.ts +146 -0
  179. package/src/pdf.ts +92 -0
  180. package/src/percolate.ts +877 -0
  181. package/src/portfolio-audit.ts +574 -0
  182. package/src/portfolio-identity.ts +162 -0
  183. package/src/portfolio-registry.ts +473 -0
  184. package/src/portfolio.ts +765 -0
  185. package/src/query.ts +646 -0
  186. package/src/repository-memory.ts +1150 -0
  187. package/src/sdk.ts +1452 -0
  188. package/src/search-rules.ts +712 -0
  189. package/src/search.ts +710 -0
  190. package/src/semantic-runtime.ts +1139 -0
  191. package/src/semantic.ts +2480 -0
  192. package/src/source-inbox.ts +232 -0
  193. package/src/untrusted-content.ts +401 -0
  194. package/src/url-intelligence.ts +104 -0
  195. package/src/vault.ts +636 -0
  196. package/src/workflow.ts +653 -0
  197. package/src/workflows/decision-context.ts +81 -0
  198. package/src/workflows/explain-change.ts +73 -0
  199. package/src/workflows/index.ts +3 -0
  200. package/src/workflows/plan-radar.ts +101 -0
@@ -0,0 +1,362 @@
1
+ import { fuseRankedCandidates } from "./search.js";
2
+
3
+ const MAX_BENCHMARK_CASES = 500;
4
+ const MAX_BENCHMARK_SYSTEMS = 16;
5
+ const MAX_JUDGMENTS_PER_CASE = 1_000;
6
+ const MAX_RESULTS_PER_RANKING = 1_000;
7
+ const MAX_CUTOFF = 100;
8
+ const MAX_RELEVANCE = 10;
9
+
10
+ export type RelevanceJudgment = {
11
+ readonly id: string;
12
+ /** A positive integer. Larger values mean that a result is more useful. */
13
+ readonly relevance: number;
14
+ };
15
+
16
+ export type BenchmarkRanking = {
17
+ readonly system: string;
18
+ readonly ids: readonly string[];
19
+ };
20
+
21
+ export type RetrievalBenchmarkCase = {
22
+ readonly id: string;
23
+ readonly queryClass: string;
24
+ readonly judgments: readonly RelevanceJudgment[];
25
+ readonly rankings: readonly BenchmarkRanking[];
26
+ };
27
+
28
+ export type RetrievalMetrics = {
29
+ readonly recallAtK: number;
30
+ readonly mrrAtK: number;
31
+ readonly ndcgAtK: number;
32
+ };
33
+
34
+ export type EvaluatedRanking = {
35
+ readonly system: string;
36
+ readonly metrics: RetrievalMetrics;
37
+ };
38
+
39
+ export type EvaluatedBenchmarkCase = {
40
+ readonly id: string;
41
+ readonly queryClass: string;
42
+ readonly systems: readonly EvaluatedRanking[];
43
+ };
44
+
45
+ export type BenchmarkAggregate = {
46
+ readonly system: string;
47
+ readonly caseCount: number;
48
+ readonly metrics: RetrievalMetrics;
49
+ };
50
+
51
+ export type BenchmarkClassAggregate = {
52
+ readonly queryClass: string;
53
+ readonly caseCount: number;
54
+ readonly systems: readonly BenchmarkAggregate[];
55
+ };
56
+
57
+ export type RetrievalBenchmarkReport = {
58
+ readonly cutoff: number;
59
+ readonly cases: readonly EvaluatedBenchmarkCase[];
60
+ readonly overall: readonly BenchmarkAggregate[];
61
+ readonly byClass: readonly BenchmarkClassAggregate[];
62
+ };
63
+
64
+ export type RetrievalBenchmarkOptions = {
65
+ readonly cutoff?: number;
66
+ };
67
+
68
+ function checkedCutoff(value: number | undefined): number {
69
+ const cutoff = value ?? 10;
70
+ if (!Number.isSafeInteger(cutoff) || cutoff < 1 || cutoff > MAX_CUTOFF) {
71
+ throw new RangeError(
72
+ `Benchmark cutoff must be an integer from 1 through ${MAX_CUTOFF}.`,
73
+ );
74
+ }
75
+ return cutoff;
76
+ }
77
+
78
+ function checkedLabel(value: string, label: string): string {
79
+ if (value.trim() === "" || value !== value.trim()) {
80
+ throw new Error(`${label} must be non-empty and have no outer whitespace.`);
81
+ }
82
+ return value;
83
+ }
84
+
85
+ function validatedJudgments(
86
+ judgments: readonly RelevanceJudgment[],
87
+ ): ReadonlyMap<string, number> {
88
+ if (judgments.length === 0 || judgments.length > MAX_JUDGMENTS_PER_CASE) {
89
+ throw new RangeError(
90
+ `A benchmark case requires from 1 through ${MAX_JUDGMENTS_PER_CASE} judgments.`,
91
+ );
92
+ }
93
+ const result = new Map<string, number>();
94
+ for (const judgment of judgments) {
95
+ const id = checkedLabel(judgment.id, "Judgment id");
96
+ if (result.has(id)) throw new Error(`Duplicate judgment id: ${id}`);
97
+ if (!Number.isSafeInteger(judgment.relevance)
98
+ || judgment.relevance < 1
99
+ || judgment.relevance > MAX_RELEVANCE) {
100
+ throw new RangeError(
101
+ `Judgment relevance must be an integer from 1 through ${MAX_RELEVANCE}.`,
102
+ );
103
+ }
104
+ result.set(id, judgment.relevance);
105
+ }
106
+ return result;
107
+ }
108
+
109
+ function validatedRanking(ids: readonly string[]): readonly string[] {
110
+ if (ids.length > MAX_RESULTS_PER_RANKING) {
111
+ throw new RangeError(
112
+ `A benchmark ranking may contain at most ${MAX_RESULTS_PER_RANKING} results.`,
113
+ );
114
+ }
115
+ const seen = new Set<string>();
116
+ return ids.map((rawId) => {
117
+ const id = checkedLabel(rawId, "Ranking result id");
118
+ if (seen.has(id)) throw new Error(`Duplicate ranking result id: ${id}`);
119
+ seen.add(id);
120
+ return id;
121
+ });
122
+ }
123
+
124
+ function discount(rank: number): number {
125
+ return Math.log2(rank + 1);
126
+ }
127
+
128
+ function gain(relevance: number): number {
129
+ return (2 ** relevance) - 1;
130
+ }
131
+
132
+ function metricsForValidatedRanking(
133
+ ranking: readonly string[],
134
+ judgments: ReadonlyMap<string, number>,
135
+ cutoff: number,
136
+ ): RetrievalMetrics {
137
+ const top = ranking.slice(0, cutoff);
138
+ let relevantRetrieved = 0;
139
+ let firstRelevantRank: number | null = null;
140
+ let dcg = 0;
141
+ for (const [index, id] of top.entries()) {
142
+ const relevance = judgments.get(id) ?? 0;
143
+ if (relevance === 0) continue;
144
+ relevantRetrieved += 1;
145
+ firstRelevantRank ??= index + 1;
146
+ dcg += gain(relevance) / discount(index + 1);
147
+ }
148
+ const idealDcg = [...judgments.values()]
149
+ .toSorted((left, right) => right - left)
150
+ .slice(0, cutoff)
151
+ .reduce((sum, relevance, index) =>
152
+ sum + (gain(relevance) / discount(index + 1)), 0);
153
+ return {
154
+ recallAtK: relevantRetrieved / judgments.size,
155
+ mrrAtK: firstRelevantRank === null ? 0 : 1 / firstRelevantRank,
156
+ ndcgAtK: Math.min(1, dcg / idealDcg),
157
+ };
158
+ }
159
+
160
+ /** Evaluate one unique ranked list against positive graded judgments. */
161
+ export function evaluateRanking(
162
+ ranking: readonly string[],
163
+ judgments: readonly RelevanceJudgment[],
164
+ cutoff = 10,
165
+ ): RetrievalMetrics {
166
+ return metricsForValidatedRanking(
167
+ validatedRanking(ranking),
168
+ validatedJudgments(judgments),
169
+ checkedCutoff(cutoff),
170
+ );
171
+ }
172
+
173
+ function averageMetrics(
174
+ evaluations: readonly EvaluatedRanking[],
175
+ ): RetrievalMetrics {
176
+ if (evaluations.length === 0) {
177
+ return { recallAtK: 0, mrrAtK: 0, ndcgAtK: 0 };
178
+ }
179
+ const totals = evaluations.reduce((sum, evaluation) => ({
180
+ recallAtK: sum.recallAtK + evaluation.metrics.recallAtK,
181
+ mrrAtK: sum.mrrAtK + evaluation.metrics.mrrAtK,
182
+ ndcgAtK: sum.ndcgAtK + evaluation.metrics.ndcgAtK,
183
+ }), { recallAtK: 0, mrrAtK: 0, ndcgAtK: 0 });
184
+ return {
185
+ recallAtK: totals.recallAtK / evaluations.length,
186
+ mrrAtK: totals.mrrAtK / evaluations.length,
187
+ ndcgAtK: totals.ndcgAtK / evaluations.length,
188
+ };
189
+ }
190
+
191
+ function aggregateSystems(
192
+ cases: readonly EvaluatedBenchmarkCase[],
193
+ systems: readonly string[],
194
+ ): readonly BenchmarkAggregate[] {
195
+ return systems.map((system) => {
196
+ const evaluations = cases.map((benchmarkCase) => {
197
+ const evaluation = benchmarkCase.systems.find((item) => item.system === system);
198
+ if (evaluation === undefined) {
199
+ throw new Error(`Missing system ${system} in evaluated case ${benchmarkCase.id}.`);
200
+ }
201
+ return evaluation;
202
+ });
203
+ return {
204
+ system,
205
+ caseCount: evaluations.length,
206
+ metrics: averageMetrics(evaluations),
207
+ };
208
+ });
209
+ }
210
+
211
+ /**
212
+ * Evaluate comparable system rankings over a bounded labeled query set.
213
+ * Output is sorted by stable identifiers, so reordering the input does not
214
+ * change the report.
215
+ */
216
+ export function evaluateRetrievalBenchmark(
217
+ benchmarkCases: readonly RetrievalBenchmarkCase[],
218
+ options: RetrievalBenchmarkOptions = {},
219
+ ): RetrievalBenchmarkReport {
220
+ const cutoff = checkedCutoff(options.cutoff);
221
+ if (benchmarkCases.length === 0 || benchmarkCases.length > MAX_BENCHMARK_CASES) {
222
+ throw new RangeError(
223
+ `A retrieval benchmark requires from 1 through ${MAX_BENCHMARK_CASES} cases.`,
224
+ );
225
+ }
226
+ const caseIds = new Set<string>();
227
+ let expectedSystems: readonly string[] | null = null;
228
+ const evaluated = benchmarkCases.map((benchmarkCase) => {
229
+ const id = checkedLabel(benchmarkCase.id, "Benchmark case id");
230
+ const queryClass = checkedLabel(benchmarkCase.queryClass, "Query class");
231
+ if (caseIds.has(id)) throw new Error(`Duplicate benchmark case id: ${id}`);
232
+ caseIds.add(id);
233
+ const judgments = validatedJudgments(benchmarkCase.judgments);
234
+ if (benchmarkCase.rankings.length === 0
235
+ || benchmarkCase.rankings.length > MAX_BENCHMARK_SYSTEMS) {
236
+ throw new RangeError(
237
+ `A benchmark case requires from 1 through ${MAX_BENCHMARK_SYSTEMS} systems.`,
238
+ );
239
+ }
240
+ const systemNames = new Set<string>();
241
+ const systems = benchmarkCase.rankings.map((ranking) => {
242
+ const system = checkedLabel(ranking.system, "Benchmark system");
243
+ if (systemNames.has(system)) throw new Error(`Duplicate benchmark system: ${system}`);
244
+ systemNames.add(system);
245
+ return {
246
+ system,
247
+ metrics: metricsForValidatedRanking(
248
+ validatedRanking(ranking.ids),
249
+ judgments,
250
+ cutoff,
251
+ ),
252
+ };
253
+ }).toSorted((left, right) => left.system.localeCompare(right.system));
254
+ const names = systems.map(({ system }) => system);
255
+ if (expectedSystems === null) {
256
+ expectedSystems = names;
257
+ } else if (names.length !== expectedSystems.length
258
+ || names.some((name, index) => name !== expectedSystems?.[index])) {
259
+ throw new Error("Every benchmark case must contain the same systems.");
260
+ }
261
+ return { id, queryClass, systems };
262
+ }).toSorted((left, right) => left.id.localeCompare(right.id));
263
+
264
+ const systems: readonly string[] = expectedSystems ?? [];
265
+ const queryClasses = [...new Set(evaluated.map(({ queryClass }) => queryClass))]
266
+ .toSorted((left, right) => left.localeCompare(right));
267
+ return {
268
+ cutoff,
269
+ cases: evaluated,
270
+ overall: aggregateSystems(evaluated, systems),
271
+ byClass: queryClasses.map((queryClass) => {
272
+ const matching = evaluated.filter((item) => item.queryClass === queryClass);
273
+ return {
274
+ queryClass,
275
+ caseCount: matching.length,
276
+ systems: aggregateSystems(matching, systems),
277
+ };
278
+ }),
279
+ };
280
+ }
281
+
282
+ function fixtureCase(
283
+ id: string,
284
+ queryClass: string,
285
+ judgments: readonly RelevanceJudgment[],
286
+ exact: readonly string[],
287
+ semanticLike: readonly string[],
288
+ ): RetrievalBenchmarkCase {
289
+ const hybrid = fuseRankedCandidates([
290
+ { name: "exact", weight: 1, ids: exact },
291
+ { name: "semantic-like", weight: 1, ids: semanticLike },
292
+ ]).map(({ id: resultId }) => resultId);
293
+ return {
294
+ id,
295
+ queryClass,
296
+ judgments,
297
+ rankings: [
298
+ { system: "exact", ids: exact },
299
+ { system: "hybrid-rrf", ids: hybrid },
300
+ { system: "semantic-like", ids: semanticLike },
301
+ ],
302
+ };
303
+ }
304
+
305
+ /**
306
+ * A deterministic regression fixture spanning identity, conceptual, and mixed
307
+ * query shapes. Its synthetic semantic-like rankings exercise complementarity;
308
+ * the fixture does not establish universal superiority over either input lane.
309
+ */
310
+ export function createSyntheticRankFusionFixture(): readonly RetrievalBenchmarkCase[] {
311
+ return [
312
+ fixtureCase(
313
+ "alias-identity",
314
+ "identity",
315
+ [{ id: "write-path", relevance: 3 }, { id: "agent-memory", relevance: 1 }],
316
+ ["write-path", "agent-memory", "durable-notes"],
317
+ ["durable-notes", "context-window", "write-path", "agent-memory"],
318
+ ),
319
+ fixtureCase(
320
+ "literal-title",
321
+ "identity",
322
+ [{ id: "repository-context", relevance: 3 }],
323
+ ["repository-context", "repository-map"],
324
+ ["repository-map", "repository-context", "shared-context"],
325
+ ),
326
+ fixtureCase(
327
+ "paraphrased-memory",
328
+ "conceptual",
329
+ [{ id: "durable-memory", relevance: 3 }, { id: "write-path", relevance: 1 }],
330
+ ["chat-history", "context-window", "durable-memory", "write-path"],
331
+ ["durable-memory", "write-path", "chat-history"],
332
+ ),
333
+ fixtureCase(
334
+ "meaning-without-keywords",
335
+ "conceptual",
336
+ [{ id: "retrieval-fusion", relevance: 3 }, { id: "local-search", relevance: 2 }],
337
+ ["retrieval-fusion", "ranking-noise", "local-search"],
338
+ ["embedding-noise", "retrieval-fusion", "local-search"],
339
+ ),
340
+ fixtureCase(
341
+ "implementation-decision",
342
+ "mixed",
343
+ [
344
+ { id: "decision", relevance: 3 },
345
+ { id: "evidence", relevance: 2 },
346
+ { id: "history", relevance: 1 },
347
+ ],
348
+ ["decision", "filename-noise", "evidence", "tag-noise", "history"],
349
+ ["semantic-noise", "evidence", "decision", "history"],
350
+ ),
351
+ fixtureCase(
352
+ "plan-context",
353
+ "mixed",
354
+ [{ id: "active-plan", relevance: 3 }, { id: "prior-rationale", relevance: 2 }],
355
+ ["active-plan", "status-noise", "prior-rationale"],
356
+ ["concept-noise", "prior-rationale", "active-plan"],
357
+ ),
358
+ ];
359
+ }
360
+
361
+ /** @deprecated Use createSyntheticRankFusionFixture. */
362
+ export const createRepresentativeRetrievalFixture = createSyntheticRankFusionFixture;
package/src/capture.ts ADDED
@@ -0,0 +1,68 @@
1
+ import {
2
+ parseArguments as parseCaptureArgumentsImplementation,
3
+ type CaptureArguments,
4
+ type CaptureMode,
5
+ type CaptureScope,
6
+ type CliArguments,
7
+ type CookieSource,
8
+ type EvidenceMode,
9
+ type MediaMode,
10
+ type ParseArgumentsResult,
11
+ } from "./clip/args.js";
12
+ import {
13
+ captureExitCode as captureExitCodeImplementation,
14
+ captureSucceeded as captureSucceededImplementation,
15
+ captureSummary as captureSummaryImplementation,
16
+ main as clipMainImplementation,
17
+ type ClipRuntimeOptions,
18
+ } from "./clip/cli.js";
19
+ import {
20
+ runCapture as runCaptureImplementation,
21
+ type CaptureAttempt,
22
+ type CaptureDependencies,
23
+ type CaptureOutcome,
24
+ } from "./clip/capture.js";
25
+ import {
26
+ adapterCapabilities as installedAdapterCapabilities,
27
+ inspectClipEnvironment as inspectClipEnvironmentImplementation,
28
+ renderDoctorReport as renderDoctorReportImplementation,
29
+ type DoctorOptions,
30
+ type DoctorReport,
31
+ } from "./clip/doctor.js";
32
+
33
+ // Explicit value assignments avoid a Bun bundler bug that can drop bindings
34
+ // used only by a re-exporting entrypoint.
35
+ export const adapterCapabilities = installedAdapterCapabilities;
36
+ export const captureExitCode: typeof captureExitCodeImplementation = (...arguments_) =>
37
+ captureExitCodeImplementation(...arguments_);
38
+ export const captureSucceeded: typeof captureSucceededImplementation = (...arguments_) =>
39
+ captureSucceededImplementation(...arguments_);
40
+ export const captureSummary: typeof captureSummaryImplementation = (...arguments_) =>
41
+ captureSummaryImplementation(...arguments_);
42
+ export const clipMain: typeof clipMainImplementation = (...arguments_) =>
43
+ clipMainImplementation(...arguments_);
44
+ export const inspectClipEnvironment: typeof inspectClipEnvironmentImplementation = (...arguments_) =>
45
+ inspectClipEnvironmentImplementation(...arguments_);
46
+ export const parseCaptureArguments: typeof parseCaptureArgumentsImplementation = (...arguments_) =>
47
+ parseCaptureArgumentsImplementation(...arguments_);
48
+ export const renderDoctorReport: typeof renderDoctorReportImplementation = (...arguments_) =>
49
+ renderDoctorReportImplementation(...arguments_);
50
+ export const runCapture: typeof runCaptureImplementation = (...arguments_) =>
51
+ runCaptureImplementation(...arguments_);
52
+
53
+ export type {
54
+ CaptureArguments,
55
+ CaptureAttempt,
56
+ CaptureDependencies,
57
+ CaptureMode,
58
+ CaptureOutcome,
59
+ CaptureScope,
60
+ CliArguments,
61
+ ClipRuntimeOptions,
62
+ CookieSource,
63
+ DoctorOptions,
64
+ DoctorReport,
65
+ EvidenceMode,
66
+ MediaMode,
67
+ ParseArgumentsResult,
68
+ };