@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.
- package/DISCLOSURE +43 -0
- package/LICENSE +21 -0
- package/README.md +545 -0
- package/dist/agent-context.js +35 -0
- package/dist/agent-guide-audit.js +18 -0
- package/dist/attachments.js +19 -0
- package/dist/authoring.js +33 -0
- package/dist/benchmark.js +19 -0
- package/dist/capture.js +49 -0
- package/dist/cli.js +3646 -0
- package/dist/clip/acquire.js +57 -0
- package/dist/clip/args.js +21 -0
- package/dist/clip/bounded-byte-buffer.js +9 -0
- package/dist/clip/browser-profiles.js +17 -0
- package/dist/clip/bundle-reader.js +11 -0
- package/dist/clip/cli.js +27 -0
- package/dist/clip/cookies.js +21 -0
- package/dist/clip/defuddle-worker.js +84 -0
- package/dist/clip/doctor.js +32 -0
- package/dist/clip/jobs.js +784 -0
- package/dist/clip/network-proxy.js +9 -0
- package/dist/clip/network.js +28 -0
- package/dist/clip/persist.js +30 -0
- package/dist/clip/refresh.js +11 -0
- package/dist/clip/terminal.js +11 -0
- package/dist/evaluation-builder.js +12238 -0
- package/dist/evaluation-kb.js +26 -0
- package/dist/evaluation.js +35 -0
- package/dist/git.js +39 -0
- package/dist/graph.js +39 -0
- package/dist/index-01jj6rbv.js +1103 -0
- package/dist/index-06c9ctr6.js +738 -0
- package/dist/index-0kavxzqj.js +2480 -0
- package/dist/index-1gwbassd.js +743 -0
- package/dist/index-1n418kb9.js +827 -0
- package/dist/index-1vrd1rmn.js +56 -0
- package/dist/index-1xxnjn0d.js +171 -0
- package/dist/index-3rm7cz6h.js +373 -0
- package/dist/index-3v2z4f0q.js +328 -0
- package/dist/index-48pz4jpc.js +392 -0
- package/dist/index-4j3tt0c3.js +234 -0
- package/dist/index-5n05se68.js +307 -0
- package/dist/index-5vwpzb5a.js +764 -0
- package/dist/index-6g2pv9d2.js +370 -0
- package/dist/index-7fzc32gf.js +712 -0
- package/dist/index-84x0vjjp.js +432 -0
- package/dist/index-adx6khj5.js +488 -0
- package/dist/index-b88v3vtm.js +805 -0
- package/dist/index-cv6fh7z5.js +462 -0
- package/dist/index-cxfrakt7.js +1067 -0
- package/dist/index-d13v9ckt.js +150 -0
- package/dist/index-dycjbhw2.js +1943 -0
- package/dist/index-dyqwejk5.js +531 -0
- package/dist/index-e5fbsywq.js +658 -0
- package/dist/index-f984hw45.js +927 -0
- package/dist/index-gh719d91.js +63 -0
- package/dist/index-hgve9rh2.js +2046 -0
- package/dist/index-hya40gb2.js +474 -0
- package/dist/index-j4zgmzjr.js +152 -0
- package/dist/index-jsmvyyvf.js +1166 -0
- package/dist/index-kh0pwvdd.js +1974 -0
- package/dist/index-mqx4nd6v.js +119 -0
- package/dist/index-mxxxytys.js +1254 -0
- package/dist/index-n5dd7r0v.js +711 -0
- package/dist/index-npg9z1a4.js +431 -0
- package/dist/index-pj501bh1.js +140 -0
- package/dist/index-qry4vhxk.js +1041 -0
- package/dist/index-s2gw5aw9.js +199 -0
- package/dist/index-vvdj6kca.js +70 -0
- package/dist/index-w2zc0vwa.js +571 -0
- package/dist/index-x3fthpsc.js +585 -0
- package/dist/index-zr53sf63.js +44 -0
- package/dist/index-zxdy5pby.js +2728 -0
- package/dist/index-zzhgcwyt.js +966 -0
- package/dist/index.js +453 -0
- package/dist/navigation.js +13 -0
- package/dist/pdf.js +85 -0
- package/dist/percolate.js +24 -0
- package/dist/portfolio.js +77 -0
- package/dist/query.js +29 -0
- package/dist/repository-memory.js +60 -0
- package/dist/sdk.js +36 -0
- package/dist/search-rules.js +34 -0
- package/dist/search.js +22 -0
- package/dist/semantic.js +39 -0
- package/dist/source-inbox.js +17 -0
- package/dist/untrusted-content.js +32 -0
- package/dist/url-intelligence.js +74 -0
- package/dist/workflow.js +23 -0
- package/dist/workflows/decision-context.js +20 -0
- package/dist/workflows/explain-change.js +8 -0
- package/dist/workflows/index.js +28 -0
- package/dist/workflows/plan-radar.js +10 -0
- package/package.json +409 -0
- package/skills/kb/AGENTS.md +19 -0
- package/skills/kb/SKILL.md +82 -0
- package/skills/kb/agents/openai.yaml +4 -0
- package/skills/kb/references/pdf-review.md +51 -0
- package/skills/kb/references/percolate.md +144 -0
- package/skills/kb/references/plan-structure.md +105 -0
- package/skills/kb/references/plan.md +115 -0
- package/skills/kb/references/query.md +231 -0
- package/skills/kb/references/refresh.md +133 -0
- package/skills/kb/references/save-pdf.md +125 -0
- package/skills/kb/references/save-url.md +178 -0
- package/skills/kb/references/url-authentication.md +75 -0
- package/skills/kb/references/url-platforms.md +25 -0
- package/src/agent-context.ts +1241 -0
- package/src/agent-guide-audit.ts +750 -0
- package/src/attachments.ts +723 -0
- package/src/authoring.ts +1725 -0
- package/src/benchmark.ts +362 -0
- package/src/capture.ts +68 -0
- package/src/cli.ts +3660 -0
- package/src/clip/acquire.ts +1273 -0
- package/src/clip/archive-today.ts +402 -0
- package/src/clip/args.ts +423 -0
- package/src/clip/assets.ts +262 -0
- package/src/clip/bounded-byte-buffer.ts +75 -0
- package/src/clip/browser-profiles.ts +372 -0
- package/src/clip/bundle-reader.ts +608 -0
- package/src/clip/capture.ts +1054 -0
- package/src/clip/cli.ts +181 -0
- package/src/clip/cookies.ts +512 -0
- package/src/clip/doctor.ts +1110 -0
- package/src/clip/extract.ts +868 -0
- package/src/clip/jobs.ts +959 -0
- package/src/clip/lib.ts +861 -0
- package/src/clip/media.ts +1474 -0
- package/src/clip/metadata-search-tool/Cargo.lock +2498 -0
- package/src/clip/metadata-search-tool/Cargo.toml +18 -0
- package/src/clip/metadata-search-tool/runner.ts +685 -0
- package/src/clip/metadata-search-tool/src/main.rs +389 -0
- package/src/clip/metadata-search.ts +687 -0
- package/src/clip/network-proxy.ts +627 -0
- package/src/clip/network.ts +950 -0
- package/src/clip/package-root.ts +54 -0
- package/src/clip/persist.ts +1472 -0
- package/src/clip/platforms.ts +1824 -0
- package/src/clip/refresh.ts +197 -0
- package/src/clip/structured.ts +432 -0
- package/src/clip/terminal.ts +197 -0
- package/src/clip/url-intelligence.ts +581 -0
- package/src/clip/url-metadata-backfill.ts +616 -0
- package/src/clip/url-metadata-cli.ts +251 -0
- package/src/clip/url-metadata.ts +1397 -0
- package/src/evaluation-analysis-v2.ts +1440 -0
- package/src/evaluation-builder.ts +2539 -0
- package/src/evaluation-corpus-authoring.ts +2052 -0
- package/src/evaluation-evidence.ts +1147 -0
- package/src/evaluation-execution-v2.ts +426 -0
- package/src/evaluation-implementation.ts +131 -0
- package/src/evaluation-kb-closure.ts +1430 -0
- package/src/evaluation-kb-runner-v2.ts +735 -0
- package/src/evaluation-kb-v2.ts +2567 -0
- package/src/evaluation-kb.ts +1018 -0
- package/src/evaluation-measurement-v2.ts +1462 -0
- package/src/evaluation-packing-v2.ts +452 -0
- package/src/evaluation-redaction.ts +28 -0
- package/src/evaluation-v2.ts +3857 -0
- package/src/evaluation.ts +1220 -0
- package/src/git.ts +1276 -0
- package/src/graph.ts +1487 -0
- package/src/index.ts +20 -0
- package/src/init.ts +123 -0
- package/src/navigation.ts +277 -0
- package/src/note-lock.ts +529 -0
- package/src/pdf/args.ts +202 -0
- package/src/pdf/capture.ts +298 -0
- package/src/pdf/cli.ts +159 -0
- package/src/pdf/extract.ts +303 -0
- package/src/pdf/layout.ts +618 -0
- package/src/pdf/markdown.ts +154 -0
- package/src/pdf/model.ts +234 -0
- package/src/pdf/ocr.ts +190 -0
- package/src/pdf/persist.ts +314 -0
- package/src/pdf/source.ts +135 -0
- package/src/pdf/tools.ts +146 -0
- package/src/pdf.ts +92 -0
- package/src/percolate.ts +877 -0
- package/src/portfolio-audit.ts +574 -0
- package/src/portfolio-identity.ts +162 -0
- package/src/portfolio-registry.ts +473 -0
- package/src/portfolio.ts +765 -0
- package/src/query.ts +646 -0
- package/src/repository-memory.ts +1150 -0
- package/src/sdk.ts +1452 -0
- package/src/search-rules.ts +712 -0
- package/src/search.ts +710 -0
- package/src/semantic-runtime.ts +1139 -0
- package/src/semantic.ts +2480 -0
- package/src/source-inbox.ts +232 -0
- package/src/untrusted-content.ts +401 -0
- package/src/url-intelligence.ts +104 -0
- package/src/vault.ts +636 -0
- package/src/workflow.ts +653 -0
- package/src/workflows/decision-context.ts +81 -0
- package/src/workflows/explain-change.ts +73 -0
- package/src/workflows/index.ts +3 -0
- package/src/workflows/plan-radar.ts +101 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
fuseRankedCandidates
|
|
4
|
+
} from "./index-cv6fh7z5.js";
|
|
5
|
+
|
|
6
|
+
// src/benchmark.ts
|
|
7
|
+
var MAX_BENCHMARK_CASES = 500;
|
|
8
|
+
var MAX_BENCHMARK_SYSTEMS = 16;
|
|
9
|
+
var MAX_JUDGMENTS_PER_CASE = 1000;
|
|
10
|
+
var MAX_RESULTS_PER_RANKING = 1000;
|
|
11
|
+
var MAX_CUTOFF = 100;
|
|
12
|
+
var MAX_RELEVANCE = 10;
|
|
13
|
+
function checkedCutoff(value) {
|
|
14
|
+
const cutoff = value ?? 10;
|
|
15
|
+
if (!Number.isSafeInteger(cutoff) || cutoff < 1 || cutoff > MAX_CUTOFF) {
|
|
16
|
+
throw new RangeError(`Benchmark cutoff must be an integer from 1 through ${MAX_CUTOFF}.`);
|
|
17
|
+
}
|
|
18
|
+
return cutoff;
|
|
19
|
+
}
|
|
20
|
+
function checkedLabel(value, label) {
|
|
21
|
+
if (value.trim() === "" || value !== value.trim()) {
|
|
22
|
+
throw new Error(`${label} must be non-empty and have no outer whitespace.`);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function validatedJudgments(judgments) {
|
|
27
|
+
if (judgments.length === 0 || judgments.length > MAX_JUDGMENTS_PER_CASE) {
|
|
28
|
+
throw new RangeError(`A benchmark case requires from 1 through ${MAX_JUDGMENTS_PER_CASE} judgments.`);
|
|
29
|
+
}
|
|
30
|
+
const result = new Map;
|
|
31
|
+
for (const judgment of judgments) {
|
|
32
|
+
const id = checkedLabel(judgment.id, "Judgment id");
|
|
33
|
+
if (result.has(id))
|
|
34
|
+
throw new Error(`Duplicate judgment id: ${id}`);
|
|
35
|
+
if (!Number.isSafeInteger(judgment.relevance) || judgment.relevance < 1 || judgment.relevance > MAX_RELEVANCE) {
|
|
36
|
+
throw new RangeError(`Judgment relevance must be an integer from 1 through ${MAX_RELEVANCE}.`);
|
|
37
|
+
}
|
|
38
|
+
result.set(id, judgment.relevance);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function validatedRanking(ids) {
|
|
43
|
+
if (ids.length > MAX_RESULTS_PER_RANKING) {
|
|
44
|
+
throw new RangeError(`A benchmark ranking may contain at most ${MAX_RESULTS_PER_RANKING} results.`);
|
|
45
|
+
}
|
|
46
|
+
const seen = new Set;
|
|
47
|
+
return ids.map((rawId) => {
|
|
48
|
+
const id = checkedLabel(rawId, "Ranking result id");
|
|
49
|
+
if (seen.has(id))
|
|
50
|
+
throw new Error(`Duplicate ranking result id: ${id}`);
|
|
51
|
+
seen.add(id);
|
|
52
|
+
return id;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function discount(rank) {
|
|
56
|
+
return Math.log2(rank + 1);
|
|
57
|
+
}
|
|
58
|
+
function gain(relevance) {
|
|
59
|
+
return 2 ** relevance - 1;
|
|
60
|
+
}
|
|
61
|
+
function metricsForValidatedRanking(ranking, judgments, cutoff) {
|
|
62
|
+
const top = ranking.slice(0, cutoff);
|
|
63
|
+
let relevantRetrieved = 0;
|
|
64
|
+
let firstRelevantRank = null;
|
|
65
|
+
let dcg = 0;
|
|
66
|
+
for (const [index, id] of top.entries()) {
|
|
67
|
+
const relevance = judgments.get(id) ?? 0;
|
|
68
|
+
if (relevance === 0)
|
|
69
|
+
continue;
|
|
70
|
+
relevantRetrieved += 1;
|
|
71
|
+
firstRelevantRank ??= index + 1;
|
|
72
|
+
dcg += gain(relevance) / discount(index + 1);
|
|
73
|
+
}
|
|
74
|
+
const idealDcg = [...judgments.values()].toSorted((left, right) => right - left).slice(0, cutoff).reduce((sum, relevance, index) => sum + gain(relevance) / discount(index + 1), 0);
|
|
75
|
+
return {
|
|
76
|
+
recallAtK: relevantRetrieved / judgments.size,
|
|
77
|
+
mrrAtK: firstRelevantRank === null ? 0 : 1 / firstRelevantRank,
|
|
78
|
+
ndcgAtK: Math.min(1, dcg / idealDcg)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function evaluateRanking(ranking, judgments, cutoff = 10) {
|
|
82
|
+
return metricsForValidatedRanking(validatedRanking(ranking), validatedJudgments(judgments), checkedCutoff(cutoff));
|
|
83
|
+
}
|
|
84
|
+
function averageMetrics(evaluations) {
|
|
85
|
+
if (evaluations.length === 0) {
|
|
86
|
+
return { recallAtK: 0, mrrAtK: 0, ndcgAtK: 0 };
|
|
87
|
+
}
|
|
88
|
+
const totals = evaluations.reduce((sum, evaluation) => ({
|
|
89
|
+
recallAtK: sum.recallAtK + evaluation.metrics.recallAtK,
|
|
90
|
+
mrrAtK: sum.mrrAtK + evaluation.metrics.mrrAtK,
|
|
91
|
+
ndcgAtK: sum.ndcgAtK + evaluation.metrics.ndcgAtK
|
|
92
|
+
}), { recallAtK: 0, mrrAtK: 0, ndcgAtK: 0 });
|
|
93
|
+
return {
|
|
94
|
+
recallAtK: totals.recallAtK / evaluations.length,
|
|
95
|
+
mrrAtK: totals.mrrAtK / evaluations.length,
|
|
96
|
+
ndcgAtK: totals.ndcgAtK / evaluations.length
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function aggregateSystems(cases, systems) {
|
|
100
|
+
return systems.map((system) => {
|
|
101
|
+
const evaluations = cases.map((benchmarkCase) => {
|
|
102
|
+
const evaluation = benchmarkCase.systems.find((item) => item.system === system);
|
|
103
|
+
if (evaluation === undefined) {
|
|
104
|
+
throw new Error(`Missing system ${system} in evaluated case ${benchmarkCase.id}.`);
|
|
105
|
+
}
|
|
106
|
+
return evaluation;
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
system,
|
|
110
|
+
caseCount: evaluations.length,
|
|
111
|
+
metrics: averageMetrics(evaluations)
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function evaluateRetrievalBenchmark(benchmarkCases, options = {}) {
|
|
116
|
+
const cutoff = checkedCutoff(options.cutoff);
|
|
117
|
+
if (benchmarkCases.length === 0 || benchmarkCases.length > MAX_BENCHMARK_CASES) {
|
|
118
|
+
throw new RangeError(`A retrieval benchmark requires from 1 through ${MAX_BENCHMARK_CASES} cases.`);
|
|
119
|
+
}
|
|
120
|
+
const caseIds = new Set;
|
|
121
|
+
let expectedSystems = null;
|
|
122
|
+
const evaluated = benchmarkCases.map((benchmarkCase) => {
|
|
123
|
+
const id = checkedLabel(benchmarkCase.id, "Benchmark case id");
|
|
124
|
+
const queryClass = checkedLabel(benchmarkCase.queryClass, "Query class");
|
|
125
|
+
if (caseIds.has(id))
|
|
126
|
+
throw new Error(`Duplicate benchmark case id: ${id}`);
|
|
127
|
+
caseIds.add(id);
|
|
128
|
+
const judgments = validatedJudgments(benchmarkCase.judgments);
|
|
129
|
+
if (benchmarkCase.rankings.length === 0 || benchmarkCase.rankings.length > MAX_BENCHMARK_SYSTEMS) {
|
|
130
|
+
throw new RangeError(`A benchmark case requires from 1 through ${MAX_BENCHMARK_SYSTEMS} systems.`);
|
|
131
|
+
}
|
|
132
|
+
const systemNames = new Set;
|
|
133
|
+
const systems2 = benchmarkCase.rankings.map((ranking) => {
|
|
134
|
+
const system = checkedLabel(ranking.system, "Benchmark system");
|
|
135
|
+
if (systemNames.has(system))
|
|
136
|
+
throw new Error(`Duplicate benchmark system: ${system}`);
|
|
137
|
+
systemNames.add(system);
|
|
138
|
+
return {
|
|
139
|
+
system,
|
|
140
|
+
metrics: metricsForValidatedRanking(validatedRanking(ranking.ids), judgments, cutoff)
|
|
141
|
+
};
|
|
142
|
+
}).toSorted((left, right) => left.system.localeCompare(right.system));
|
|
143
|
+
const names = systems2.map(({ system }) => system);
|
|
144
|
+
if (expectedSystems === null) {
|
|
145
|
+
expectedSystems = names;
|
|
146
|
+
} else if (names.length !== expectedSystems.length || names.some((name, index) => name !== expectedSystems?.[index])) {
|
|
147
|
+
throw new Error("Every benchmark case must contain the same systems.");
|
|
148
|
+
}
|
|
149
|
+
return { id, queryClass, systems: systems2 };
|
|
150
|
+
}).toSorted((left, right) => left.id.localeCompare(right.id));
|
|
151
|
+
const systems = expectedSystems ?? [];
|
|
152
|
+
const queryClasses = [...new Set(evaluated.map(({ queryClass }) => queryClass))].toSorted((left, right) => left.localeCompare(right));
|
|
153
|
+
return {
|
|
154
|
+
cutoff,
|
|
155
|
+
cases: evaluated,
|
|
156
|
+
overall: aggregateSystems(evaluated, systems),
|
|
157
|
+
byClass: queryClasses.map((queryClass) => {
|
|
158
|
+
const matching = evaluated.filter((item) => item.queryClass === queryClass);
|
|
159
|
+
return {
|
|
160
|
+
queryClass,
|
|
161
|
+
caseCount: matching.length,
|
|
162
|
+
systems: aggregateSystems(matching, systems)
|
|
163
|
+
};
|
|
164
|
+
})
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function fixtureCase(id, queryClass, judgments, exact, semanticLike) {
|
|
168
|
+
const hybrid = fuseRankedCandidates([
|
|
169
|
+
{ name: "exact", weight: 1, ids: exact },
|
|
170
|
+
{ name: "semantic-like", weight: 1, ids: semanticLike }
|
|
171
|
+
]).map(({ id: resultId }) => resultId);
|
|
172
|
+
return {
|
|
173
|
+
id,
|
|
174
|
+
queryClass,
|
|
175
|
+
judgments,
|
|
176
|
+
rankings: [
|
|
177
|
+
{ system: "exact", ids: exact },
|
|
178
|
+
{ system: "hybrid-rrf", ids: hybrid },
|
|
179
|
+
{ system: "semantic-like", ids: semanticLike }
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function createSyntheticRankFusionFixture() {
|
|
184
|
+
return [
|
|
185
|
+
fixtureCase("alias-identity", "identity", [{ id: "write-path", relevance: 3 }, { id: "agent-memory", relevance: 1 }], ["write-path", "agent-memory", "durable-notes"], ["durable-notes", "context-window", "write-path", "agent-memory"]),
|
|
186
|
+
fixtureCase("literal-title", "identity", [{ id: "repository-context", relevance: 3 }], ["repository-context", "repository-map"], ["repository-map", "repository-context", "shared-context"]),
|
|
187
|
+
fixtureCase("paraphrased-memory", "conceptual", [{ id: "durable-memory", relevance: 3 }, { id: "write-path", relevance: 1 }], ["chat-history", "context-window", "durable-memory", "write-path"], ["durable-memory", "write-path", "chat-history"]),
|
|
188
|
+
fixtureCase("meaning-without-keywords", "conceptual", [{ id: "retrieval-fusion", relevance: 3 }, { id: "local-search", relevance: 2 }], ["retrieval-fusion", "ranking-noise", "local-search"], ["embedding-noise", "retrieval-fusion", "local-search"]),
|
|
189
|
+
fixtureCase("implementation-decision", "mixed", [
|
|
190
|
+
{ id: "decision", relevance: 3 },
|
|
191
|
+
{ id: "evidence", relevance: 2 },
|
|
192
|
+
{ id: "history", relevance: 1 }
|
|
193
|
+
], ["decision", "filename-noise", "evidence", "tag-noise", "history"], ["semantic-noise", "evidence", "decision", "history"]),
|
|
194
|
+
fixtureCase("plan-context", "mixed", [{ id: "active-plan", relevance: 3 }, { id: "prior-rationale", relevance: 2 }], ["active-plan", "status-noise", "prior-rationale"], ["concept-noise", "prior-rationale", "active-plan"])
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
var createRepresentativeRetrievalFixture = createSyntheticRankFusionFixture;
|
|
198
|
+
|
|
199
|
+
export { evaluateRanking, evaluateRetrievalBenchmark, createSyntheticRankFusionFixture, createRepresentativeRetrievalFixture };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
defineWorkflow
|
|
4
|
+
} from "./index-3v2z4f0q.js";
|
|
5
|
+
import {
|
|
6
|
+
activePlanStatuses
|
|
7
|
+
} from "./index-06c9ctr6.js";
|
|
8
|
+
|
|
9
|
+
// src/workflows/plan-radar.ts
|
|
10
|
+
function planFilters(status) {
|
|
11
|
+
return [
|
|
12
|
+
{ kind: "equals", path: "type", value: "plan" },
|
|
13
|
+
status === undefined ? { kind: "one-of", path: "status", values: activePlanStatuses } : { kind: "equals", path: "status", value: status }
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
var planRadarWorkflow = defineWorkflow({
|
|
17
|
+
id: "plan-radar",
|
|
18
|
+
nodes: [
|
|
19
|
+
{
|
|
20
|
+
id: "plans",
|
|
21
|
+
run: ({ input, kb }) => kb.list({
|
|
22
|
+
filters: planFilters(input.status),
|
|
23
|
+
repositoryScopes: input.repositoryScopes ?? [],
|
|
24
|
+
sort: { kind: "builtin", field: "inbound" },
|
|
25
|
+
direction: "desc",
|
|
26
|
+
limit: 100
|
|
27
|
+
})
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "matches",
|
|
31
|
+
resource: "qmd",
|
|
32
|
+
run: ({ input, kb }) => kb.search({
|
|
33
|
+
query: input.query,
|
|
34
|
+
filters: planFilters(input.status),
|
|
35
|
+
repositoryScopes: input.repositoryScopes ?? [],
|
|
36
|
+
history: false,
|
|
37
|
+
...input.resultLimit === undefined ? {} : { limit: input.resultLimit }
|
|
38
|
+
})
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "history",
|
|
42
|
+
resource: "git",
|
|
43
|
+
needs: ["plans", "matches"],
|
|
44
|
+
run: async ({ kb, result }) => {
|
|
45
|
+
const plans = result("plans");
|
|
46
|
+
const matches = result("matches");
|
|
47
|
+
const noteIds = [...new Set([
|
|
48
|
+
...matches.results.map(({ id }) => id),
|
|
49
|
+
...plans.slice(0, 10).map(({ id }) => id)
|
|
50
|
+
])].slice(0, 15);
|
|
51
|
+
return await kb.history(noteIds, {
|
|
52
|
+
commitsPerNote: 2,
|
|
53
|
+
cochangedPathsPerCommit: 5
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "assemble",
|
|
59
|
+
needs: ["plans", "matches", "history"],
|
|
60
|
+
run: ({ result }) => ({
|
|
61
|
+
plans: result("plans"),
|
|
62
|
+
matches: result("matches"),
|
|
63
|
+
history: result("history")
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
output: "assemble"
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export { planRadarWorkflow };
|