@vpxa/kb 0.1.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/LICENSE +21 -0
- package/README.md +1140 -0
- package/bin/kb.mjs +10 -0
- package/package.json +67 -0
- package/packages/analyzers/dist/blast-radius-analyzer.d.ts +23 -0
- package/packages/analyzers/dist/blast-radius-analyzer.js +114 -0
- package/packages/analyzers/dist/dependency-analyzer.d.ts +29 -0
- package/packages/analyzers/dist/dependency-analyzer.js +425 -0
- package/packages/analyzers/dist/diagram-generator.d.ts +13 -0
- package/packages/analyzers/dist/diagram-generator.js +86 -0
- package/packages/analyzers/dist/entry-point-analyzer.d.ts +19 -0
- package/packages/analyzers/dist/entry-point-analyzer.js +239 -0
- package/packages/analyzers/dist/index.d.ts +14 -0
- package/packages/analyzers/dist/index.js +23 -0
- package/packages/analyzers/dist/knowledge-producer.d.ts +32 -0
- package/packages/analyzers/dist/knowledge-producer.js +113 -0
- package/packages/analyzers/dist/pattern-analyzer.d.ts +12 -0
- package/packages/analyzers/dist/pattern-analyzer.js +359 -0
- package/packages/analyzers/dist/regex-call-graph.d.ts +17 -0
- package/packages/analyzers/dist/regex-call-graph.js +428 -0
- package/packages/analyzers/dist/structure-analyzer.d.ts +11 -0
- package/packages/analyzers/dist/structure-analyzer.js +258 -0
- package/packages/analyzers/dist/symbol-analyzer.d.ts +10 -0
- package/packages/analyzers/dist/symbol-analyzer.js +442 -0
- package/packages/analyzers/dist/ts-call-graph.d.ts +27 -0
- package/packages/analyzers/dist/ts-call-graph.js +160 -0
- package/packages/analyzers/dist/types.d.ts +98 -0
- package/packages/analyzers/dist/types.js +1 -0
- package/packages/chunker/dist/call-graph-extractor.d.ts +22 -0
- package/packages/chunker/dist/call-graph-extractor.js +90 -0
- package/packages/chunker/dist/chunker-factory.d.ts +7 -0
- package/packages/chunker/dist/chunker-factory.js +36 -0
- package/packages/chunker/dist/chunker.interface.d.ts +10 -0
- package/packages/chunker/dist/chunker.interface.js +1 -0
- package/packages/chunker/dist/code-chunker.d.ts +14 -0
- package/packages/chunker/dist/code-chunker.js +134 -0
- package/packages/chunker/dist/generic-chunker.d.ts +12 -0
- package/packages/chunker/dist/generic-chunker.js +72 -0
- package/packages/chunker/dist/index.d.ts +8 -0
- package/packages/chunker/dist/index.js +21 -0
- package/packages/chunker/dist/markdown-chunker.d.ts +14 -0
- package/packages/chunker/dist/markdown-chunker.js +122 -0
- package/packages/chunker/dist/treesitter-chunker.d.ts +47 -0
- package/packages/chunker/dist/treesitter-chunker.js +234 -0
- package/packages/cli/dist/commands/analyze.d.ts +3 -0
- package/packages/cli/dist/commands/analyze.js +112 -0
- package/packages/cli/dist/commands/context-cmds.d.ts +3 -0
- package/packages/cli/dist/commands/context-cmds.js +155 -0
- package/packages/cli/dist/commands/environment.d.ts +3 -0
- package/packages/cli/dist/commands/environment.js +204 -0
- package/packages/cli/dist/commands/execution.d.ts +3 -0
- package/packages/cli/dist/commands/execution.js +137 -0
- package/packages/cli/dist/commands/graph.d.ts +3 -0
- package/packages/cli/dist/commands/graph.js +81 -0
- package/packages/cli/dist/commands/init.d.ts +8 -0
- package/packages/cli/dist/commands/init.js +87 -0
- package/packages/cli/dist/commands/knowledge.d.ts +3 -0
- package/packages/cli/dist/commands/knowledge.js +139 -0
- package/packages/cli/dist/commands/search.d.ts +3 -0
- package/packages/cli/dist/commands/search.js +267 -0
- package/packages/cli/dist/commands/system.d.ts +3 -0
- package/packages/cli/dist/commands/system.js +241 -0
- package/packages/cli/dist/commands/workspace.d.ts +3 -0
- package/packages/cli/dist/commands/workspace.js +388 -0
- package/packages/cli/dist/context.d.ts +5 -0
- package/packages/cli/dist/context.js +14 -0
- package/packages/cli/dist/helpers.d.ts +52 -0
- package/packages/cli/dist/helpers.js +458 -0
- package/packages/cli/dist/index.d.ts +8 -0
- package/packages/cli/dist/index.js +69 -0
- package/packages/cli/dist/kb-init.d.ts +57 -0
- package/packages/cli/dist/kb-init.js +82 -0
- package/packages/cli/dist/types.d.ts +7 -0
- package/packages/cli/dist/types.js +1 -0
- package/packages/core/dist/constants.d.ts +49 -0
- package/packages/core/dist/constants.js +43 -0
- package/packages/core/dist/content-detector.d.ts +9 -0
- package/packages/core/dist/content-detector.js +79 -0
- package/packages/core/dist/errors.d.ts +18 -0
- package/packages/core/dist/errors.js +40 -0
- package/packages/core/dist/index.d.ts +6 -0
- package/packages/core/dist/index.js +9 -0
- package/packages/core/dist/logger.d.ts +9 -0
- package/packages/core/dist/logger.js +34 -0
- package/packages/core/dist/types.d.ts +108 -0
- package/packages/core/dist/types.js +1 -0
- package/packages/embeddings/dist/embedder.interface.d.ts +24 -0
- package/packages/embeddings/dist/embedder.interface.js +1 -0
- package/packages/embeddings/dist/index.d.ts +3 -0
- package/packages/embeddings/dist/index.js +5 -0
- package/packages/embeddings/dist/onnx-embedder.d.ts +24 -0
- package/packages/embeddings/dist/onnx-embedder.js +82 -0
- package/packages/indexer/dist/file-hasher.d.ts +11 -0
- package/packages/indexer/dist/file-hasher.js +13 -0
- package/packages/indexer/dist/filesystem-crawler.d.ts +27 -0
- package/packages/indexer/dist/filesystem-crawler.js +125 -0
- package/packages/indexer/dist/graph-extractor.d.ts +22 -0
- package/packages/indexer/dist/graph-extractor.js +111 -0
- package/packages/indexer/dist/incremental-indexer.d.ts +47 -0
- package/packages/indexer/dist/incremental-indexer.js +278 -0
- package/packages/indexer/dist/index.d.ts +5 -0
- package/packages/indexer/dist/index.js +14 -0
- package/packages/server/dist/api.d.ts +8 -0
- package/packages/server/dist/api.js +9 -0
- package/packages/server/dist/config.d.ts +3 -0
- package/packages/server/dist/config.js +75 -0
- package/packages/server/dist/curated-manager.d.ts +86 -0
- package/packages/server/dist/curated-manager.js +357 -0
- package/packages/server/dist/index.d.ts +2 -0
- package/packages/server/dist/index.js +134 -0
- package/packages/server/dist/replay-interceptor.d.ts +11 -0
- package/packages/server/dist/replay-interceptor.js +38 -0
- package/packages/server/dist/resources/resources.d.ts +4 -0
- package/packages/server/dist/resources/resources.js +40 -0
- package/packages/server/dist/server.d.ts +21 -0
- package/packages/server/dist/server.js +247 -0
- package/packages/server/dist/tools/analyze.tools.d.ts +11 -0
- package/packages/server/dist/tools/analyze.tools.js +288 -0
- package/packages/server/dist/tools/forge.tools.d.ts +12 -0
- package/packages/server/dist/tools/forge.tools.js +501 -0
- package/packages/server/dist/tools/forget.tool.d.ts +4 -0
- package/packages/server/dist/tools/forget.tool.js +43 -0
- package/packages/server/dist/tools/graph.tool.d.ts +4 -0
- package/packages/server/dist/tools/graph.tool.js +110 -0
- package/packages/server/dist/tools/list.tool.d.ts +4 -0
- package/packages/server/dist/tools/list.tool.js +56 -0
- package/packages/server/dist/tools/lookup.tool.d.ts +4 -0
- package/packages/server/dist/tools/lookup.tool.js +53 -0
- package/packages/server/dist/tools/onboard.tool.d.ts +5 -0
- package/packages/server/dist/tools/onboard.tool.js +112 -0
- package/packages/server/dist/tools/produce.tool.d.ts +3 -0
- package/packages/server/dist/tools/produce.tool.js +74 -0
- package/packages/server/dist/tools/read.tool.d.ts +4 -0
- package/packages/server/dist/tools/read.tool.js +49 -0
- package/packages/server/dist/tools/reindex.tool.d.ts +7 -0
- package/packages/server/dist/tools/reindex.tool.js +70 -0
- package/packages/server/dist/tools/remember.tool.d.ts +4 -0
- package/packages/server/dist/tools/remember.tool.js +45 -0
- package/packages/server/dist/tools/replay.tool.d.ts +3 -0
- package/packages/server/dist/tools/replay.tool.js +89 -0
- package/packages/server/dist/tools/search.tool.d.ts +5 -0
- package/packages/server/dist/tools/search.tool.js +331 -0
- package/packages/server/dist/tools/status.tool.d.ts +4 -0
- package/packages/server/dist/tools/status.tool.js +68 -0
- package/packages/server/dist/tools/toolkit.tools.d.ts +35 -0
- package/packages/server/dist/tools/toolkit.tools.js +1674 -0
- package/packages/server/dist/tools/update.tool.d.ts +4 -0
- package/packages/server/dist/tools/update.tool.js +42 -0
- package/packages/server/dist/tools/utility.tools.d.ts +15 -0
- package/packages/server/dist/tools/utility.tools.js +461 -0
- package/packages/store/dist/graph-store.interface.d.ts +104 -0
- package/packages/store/dist/graph-store.interface.js +1 -0
- package/packages/store/dist/index.d.ts +6 -0
- package/packages/store/dist/index.js +9 -0
- package/packages/store/dist/lance-store.d.ts +32 -0
- package/packages/store/dist/lance-store.js +258 -0
- package/packages/store/dist/sqlite-graph-store.d.ts +43 -0
- package/packages/store/dist/sqlite-graph-store.js +374 -0
- package/packages/store/dist/store-factory.d.ts +9 -0
- package/packages/store/dist/store-factory.js +14 -0
- package/packages/store/dist/store.interface.d.ts +48 -0
- package/packages/store/dist/store.interface.js +1 -0
- package/packages/tools/dist/batch.d.ts +21 -0
- package/packages/tools/dist/batch.js +45 -0
- package/packages/tools/dist/changelog.d.ts +34 -0
- package/packages/tools/dist/changelog.js +112 -0
- package/packages/tools/dist/check.d.ts +26 -0
- package/packages/tools/dist/check.js +59 -0
- package/packages/tools/dist/checkpoint.d.ts +17 -0
- package/packages/tools/dist/checkpoint.js +43 -0
- package/packages/tools/dist/codemod.d.ts +37 -0
- package/packages/tools/dist/codemod.js +69 -0
- package/packages/tools/dist/compact.d.ts +41 -0
- package/packages/tools/dist/compact.js +60 -0
- package/packages/tools/dist/data-transform.d.ts +10 -0
- package/packages/tools/dist/data-transform.js +124 -0
- package/packages/tools/dist/dead-symbols.d.ts +21 -0
- package/packages/tools/dist/dead-symbols.js +71 -0
- package/packages/tools/dist/delegate.d.ts +34 -0
- package/packages/tools/dist/delegate.js +130 -0
- package/packages/tools/dist/diff-parse.d.ts +26 -0
- package/packages/tools/dist/diff-parse.js +153 -0
- package/packages/tools/dist/digest.d.ts +53 -0
- package/packages/tools/dist/digest.js +242 -0
- package/packages/tools/dist/encode.d.ts +14 -0
- package/packages/tools/dist/encode.js +46 -0
- package/packages/tools/dist/env-info.d.ts +28 -0
- package/packages/tools/dist/env-info.js +58 -0
- package/packages/tools/dist/eval.d.ts +13 -0
- package/packages/tools/dist/eval.js +79 -0
- package/packages/tools/dist/evidence-map.d.ts +79 -0
- package/packages/tools/dist/evidence-map.js +203 -0
- package/packages/tools/dist/file-summary.d.ts +32 -0
- package/packages/tools/dist/file-summary.js +106 -0
- package/packages/tools/dist/file-walk.d.ts +4 -0
- package/packages/tools/dist/file-walk.js +75 -0
- package/packages/tools/dist/find-examples.d.ts +25 -0
- package/packages/tools/dist/find-examples.js +48 -0
- package/packages/tools/dist/find.d.ts +47 -0
- package/packages/tools/dist/find.js +120 -0
- package/packages/tools/dist/forge-classify.d.ts +44 -0
- package/packages/tools/dist/forge-classify.js +319 -0
- package/packages/tools/dist/forge-ground.d.ts +64 -0
- package/packages/tools/dist/forge-ground.js +184 -0
- package/packages/tools/dist/git-context.d.ts +22 -0
- package/packages/tools/dist/git-context.js +46 -0
- package/packages/tools/dist/graph-query.d.ts +89 -0
- package/packages/tools/dist/graph-query.js +194 -0
- package/packages/tools/dist/health.d.ts +14 -0
- package/packages/tools/dist/health.js +118 -0
- package/packages/tools/dist/http-request.d.ts +23 -0
- package/packages/tools/dist/http-request.js +58 -0
- package/packages/tools/dist/index.d.ts +49 -0
- package/packages/tools/dist/index.js +273 -0
- package/packages/tools/dist/lane.d.ts +39 -0
- package/packages/tools/dist/lane.js +227 -0
- package/packages/tools/dist/measure.d.ts +38 -0
- package/packages/tools/dist/measure.js +119 -0
- package/packages/tools/dist/onboard.d.ts +41 -0
- package/packages/tools/dist/onboard.js +1139 -0
- package/packages/tools/dist/parse-output.d.ts +80 -0
- package/packages/tools/dist/parse-output.js +158 -0
- package/packages/tools/dist/process-manager.d.ts +18 -0
- package/packages/tools/dist/process-manager.js +69 -0
- package/packages/tools/dist/queue.d.ts +38 -0
- package/packages/tools/dist/queue.js +126 -0
- package/packages/tools/dist/regex-test.d.ts +31 -0
- package/packages/tools/dist/regex-test.js +39 -0
- package/packages/tools/dist/rename.d.ts +29 -0
- package/packages/tools/dist/rename.js +70 -0
- package/packages/tools/dist/replay.d.ts +56 -0
- package/packages/tools/dist/replay.js +108 -0
- package/packages/tools/dist/schema-validate.d.ts +23 -0
- package/packages/tools/dist/schema-validate.js +141 -0
- package/packages/tools/dist/scope-map.d.ts +52 -0
- package/packages/tools/dist/scope-map.js +72 -0
- package/packages/tools/dist/snippet.d.ts +34 -0
- package/packages/tools/dist/snippet.js +80 -0
- package/packages/tools/dist/stash.d.ts +12 -0
- package/packages/tools/dist/stash.js +60 -0
- package/packages/tools/dist/stratum-card.d.ts +31 -0
- package/packages/tools/dist/stratum-card.js +239 -0
- package/packages/tools/dist/symbol.d.ts +28 -0
- package/packages/tools/dist/symbol.js +87 -0
- package/packages/tools/dist/test-run.d.ts +23 -0
- package/packages/tools/dist/test-run.js +55 -0
- package/packages/tools/dist/text-utils.d.ts +16 -0
- package/packages/tools/dist/text-utils.js +31 -0
- package/packages/tools/dist/time-utils.d.ts +18 -0
- package/packages/tools/dist/time-utils.js +135 -0
- package/packages/tools/dist/trace.d.ts +24 -0
- package/packages/tools/dist/trace.js +114 -0
- package/packages/tools/dist/truncation.d.ts +22 -0
- package/packages/tools/dist/truncation.js +45 -0
- package/packages/tools/dist/watch.d.ts +30 -0
- package/packages/tools/dist/watch.js +61 -0
- package/packages/tools/dist/web-fetch.d.ts +45 -0
- package/packages/tools/dist/web-fetch.js +249 -0
- package/packages/tools/dist/web-search.d.ts +23 -0
- package/packages/tools/dist/web-search.js +46 -0
- package/packages/tools/dist/workset.d.ts +45 -0
- package/packages/tools/dist/workset.js +77 -0
- package/packages/tui/dist/App.d.ts +8 -0
- package/packages/tui/dist/App.js +52659 -0
- package/packages/tui/dist/index.d.ts +19 -0
- package/packages/tui/dist/index.js +54742 -0
- package/packages/tui/dist/panels/CuratedPanel.d.ts +8 -0
- package/packages/tui/dist/panels/CuratedPanel.js +34452 -0
- package/packages/tui/dist/panels/LogPanel.d.ts +3 -0
- package/packages/tui/dist/panels/LogPanel.js +51894 -0
- package/packages/tui/dist/panels/SearchPanel.d.ts +10 -0
- package/packages/tui/dist/panels/SearchPanel.js +34985 -0
- package/packages/tui/dist/panels/StatusPanel.d.ts +8 -0
- package/packages/tui/dist/panels/StatusPanel.js +34465 -0
- package/skills/knowledge-base/SKILL.md +316 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
const MAPS_DIR = ".kb-state";
|
|
4
|
+
const MAPS_FILE = "evidence-maps.json";
|
|
5
|
+
function mapsPath(cwd) {
|
|
6
|
+
const root = cwd ?? process.cwd();
|
|
7
|
+
return resolve(root, MAPS_DIR, MAPS_FILE);
|
|
8
|
+
}
|
|
9
|
+
function loadMaps(cwd) {
|
|
10
|
+
const path = mapsPath(cwd);
|
|
11
|
+
if (!existsSync(path)) return {};
|
|
12
|
+
const raw = readFileSync(path, "utf-8");
|
|
13
|
+
return JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
function saveMaps(data, cwd) {
|
|
16
|
+
const path = mapsPath(cwd);
|
|
17
|
+
const dir = dirname(path);
|
|
18
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
19
|
+
writeFileSync(path, `${JSON.stringify(data, null, 2)}
|
|
20
|
+
`, "utf-8");
|
|
21
|
+
}
|
|
22
|
+
function requireMap(taskId, cwd) {
|
|
23
|
+
const maps = loadMaps(cwd);
|
|
24
|
+
const state = maps[taskId];
|
|
25
|
+
if (!state) {
|
|
26
|
+
throw new Error(`Evidence map not found: ${taskId}`);
|
|
27
|
+
}
|
|
28
|
+
return { maps, state };
|
|
29
|
+
}
|
|
30
|
+
function nextEntryId(entries) {
|
|
31
|
+
return entries.reduce((maxId, entry) => Math.max(maxId, entry.id), 0) + 1;
|
|
32
|
+
}
|
|
33
|
+
function validateClaim(claim) {
|
|
34
|
+
const trimmed = claim.trim();
|
|
35
|
+
if (!trimmed) {
|
|
36
|
+
throw new Error("Claim is required");
|
|
37
|
+
}
|
|
38
|
+
if (/\r?\n/.test(trimmed)) {
|
|
39
|
+
throw new Error("Claim must be a single line");
|
|
40
|
+
}
|
|
41
|
+
return trimmed;
|
|
42
|
+
}
|
|
43
|
+
function escapeTableCell(value) {
|
|
44
|
+
return (value ?? "").replace(/\r?\n/g, " ").replace(/\|/g, "\\|");
|
|
45
|
+
}
|
|
46
|
+
function formatEvidenceMap(state) {
|
|
47
|
+
const lines = [
|
|
48
|
+
"| # | Claim | Status | Receipt | Critical | Type |",
|
|
49
|
+
"|---|-------|--------|---------|----------|------|"
|
|
50
|
+
];
|
|
51
|
+
for (const entry of state.entries) {
|
|
52
|
+
lines.push(
|
|
53
|
+
`| ${entry.id} | ${escapeTableCell(entry.claim)} | ${entry.status} | ${escapeTableCell(entry.receipt)} | ${entry.criticalPath ? "yes" : "no"} | ${escapeTableCell(entry.unknownType)} |`
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
58
|
+
function buildStats(entries) {
|
|
59
|
+
return {
|
|
60
|
+
total: entries.length,
|
|
61
|
+
verified: entries.filter((entry) => entry.status === "V").length,
|
|
62
|
+
assumed: entries.filter((entry) => entry.status === "A").length,
|
|
63
|
+
unresolved: entries.filter((entry) => entry.status === "U").length
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function buildWarnings(state) {
|
|
67
|
+
const warnings = [];
|
|
68
|
+
for (const entry of state.entries) {
|
|
69
|
+
if (entry.status === "V" && entry.receipt.trim() === "") {
|
|
70
|
+
warnings.push("V entry without receipt");
|
|
71
|
+
}
|
|
72
|
+
if (entry.status === "A" && state.tier === "critical" && entry.unknownType === "contract") {
|
|
73
|
+
warnings.push("Assumed contract at Critical tier \u2014 should be Verified");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return warnings;
|
|
77
|
+
}
|
|
78
|
+
function buildForcedDeliveryAnnotation(entries) {
|
|
79
|
+
const unresolved = entries.filter((entry) => entry.status === "U");
|
|
80
|
+
const summary = unresolved.map((entry) => `#${entry.id} ${entry.claim}`).join("; ");
|
|
81
|
+
return `FORCED DELIVERY annotation: unresolved entries remain -> ${summary}`;
|
|
82
|
+
}
|
|
83
|
+
function evaluateGate(state, retryCount = 0) {
|
|
84
|
+
const unresolvedCritical = state.entries.filter(
|
|
85
|
+
(entry) => entry.criticalPath && entry.status === "U"
|
|
86
|
+
);
|
|
87
|
+
const warnings = buildWarnings(state);
|
|
88
|
+
const stats = buildStats(state.entries);
|
|
89
|
+
const unresolvedContract = unresolvedCritical.find((entry) => entry.unknownType === "contract");
|
|
90
|
+
if (unresolvedContract) {
|
|
91
|
+
return {
|
|
92
|
+
decision: "HARD_BLOCK",
|
|
93
|
+
reason: "Unresolved contract unknown on critical path",
|
|
94
|
+
unresolvedCritical,
|
|
95
|
+
warnings,
|
|
96
|
+
stats
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (unresolvedCritical.length > 0 && retryCount === 0) {
|
|
100
|
+
return {
|
|
101
|
+
decision: "HOLD",
|
|
102
|
+
reason: "Unresolved critical-path unknown \u2014 retry available",
|
|
103
|
+
unresolvedCritical,
|
|
104
|
+
warnings,
|
|
105
|
+
stats
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (unresolvedCritical.length > 0 && retryCount >= 1) {
|
|
109
|
+
return {
|
|
110
|
+
decision: "FORCED_DELIVERY",
|
|
111
|
+
reason: "Unresolved critical-path unknown after retry",
|
|
112
|
+
unresolvedCritical,
|
|
113
|
+
warnings,
|
|
114
|
+
stats,
|
|
115
|
+
annotation: buildForcedDeliveryAnnotation(state.entries)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
decision: "YIELD",
|
|
120
|
+
reason: "All critical-path claims satisfy gate rules",
|
|
121
|
+
unresolvedCritical: [],
|
|
122
|
+
warnings,
|
|
123
|
+
stats
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function evidenceMap(action, cwd) {
|
|
127
|
+
switch (action.action) {
|
|
128
|
+
case "create": {
|
|
129
|
+
const maps = loadMaps(cwd);
|
|
130
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
131
|
+
const state = {
|
|
132
|
+
taskId: action.taskId,
|
|
133
|
+
tier: action.tier,
|
|
134
|
+
entries: [],
|
|
135
|
+
createdAt: now,
|
|
136
|
+
updatedAt: now
|
|
137
|
+
};
|
|
138
|
+
maps[action.taskId] = state;
|
|
139
|
+
saveMaps(maps, cwd);
|
|
140
|
+
return { state, formattedMap: formatEvidenceMap(state) };
|
|
141
|
+
}
|
|
142
|
+
case "add": {
|
|
143
|
+
const { maps, state } = requireMap(action.taskId, cwd);
|
|
144
|
+
const entry = {
|
|
145
|
+
id: nextEntryId(state.entries),
|
|
146
|
+
claim: validateClaim(action.claim),
|
|
147
|
+
status: action.status,
|
|
148
|
+
receipt: action.receipt,
|
|
149
|
+
criticalPath: action.criticalPath ?? false,
|
|
150
|
+
unknownType: action.unknownType
|
|
151
|
+
};
|
|
152
|
+
state.entries.push(entry);
|
|
153
|
+
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
154
|
+
maps[action.taskId] = state;
|
|
155
|
+
saveMaps(maps, cwd);
|
|
156
|
+
return { state, entry, formattedMap: formatEvidenceMap(state) };
|
|
157
|
+
}
|
|
158
|
+
case "update": {
|
|
159
|
+
const { maps, state } = requireMap(action.taskId, cwd);
|
|
160
|
+
const entry = state.entries.find((candidate) => candidate.id === action.id);
|
|
161
|
+
if (!entry) {
|
|
162
|
+
throw new Error(`Evidence entry not found: ${action.id}`);
|
|
163
|
+
}
|
|
164
|
+
entry.status = action.status;
|
|
165
|
+
entry.receipt = action.receipt;
|
|
166
|
+
state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
167
|
+
maps[action.taskId] = state;
|
|
168
|
+
saveMaps(maps, cwd);
|
|
169
|
+
return { state, entry, formattedMap: formatEvidenceMap(state) };
|
|
170
|
+
}
|
|
171
|
+
case "get": {
|
|
172
|
+
const { state } = requireMap(action.taskId, cwd);
|
|
173
|
+
return { state, formattedMap: formatEvidenceMap(state) };
|
|
174
|
+
}
|
|
175
|
+
case "gate": {
|
|
176
|
+
const { state } = requireMap(action.taskId, cwd);
|
|
177
|
+
return {
|
|
178
|
+
state,
|
|
179
|
+
gate: evaluateGate(state, action.retryCount ?? 0),
|
|
180
|
+
formattedMap: formatEvidenceMap(state)
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
case "list": {
|
|
184
|
+
const states = Object.values(loadMaps(cwd)).sort(
|
|
185
|
+
(left, right) => left.createdAt.localeCompare(right.createdAt)
|
|
186
|
+
);
|
|
187
|
+
return { states };
|
|
188
|
+
}
|
|
189
|
+
case "delete": {
|
|
190
|
+
const maps = loadMaps(cwd);
|
|
191
|
+
if (!(action.taskId in maps)) {
|
|
192
|
+
return { deleted: false };
|
|
193
|
+
}
|
|
194
|
+
delete maps[action.taskId];
|
|
195
|
+
saveMaps(maps, cwd);
|
|
196
|
+
return { deleted: true };
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
export {
|
|
201
|
+
evidenceMap
|
|
202
|
+
};
|
|
203
|
+
//# sourceMappingURL=evidence-map.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface FileSummaryOptions {
|
|
2
|
+
path: string;
|
|
3
|
+
previewLines?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface FileSummaryResult {
|
|
6
|
+
path: string;
|
|
7
|
+
lines: number;
|
|
8
|
+
language: string;
|
|
9
|
+
imports: string[];
|
|
10
|
+
exports: string[];
|
|
11
|
+
functions: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
line: number;
|
|
14
|
+
exported: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
classes: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
line: number;
|
|
19
|
+
exported: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
interfaces: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
line: number;
|
|
24
|
+
}>;
|
|
25
|
+
types: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
line: number;
|
|
28
|
+
}>;
|
|
29
|
+
estimatedTokens: number;
|
|
30
|
+
}
|
|
31
|
+
export declare function fileSummary(options: FileSummaryOptions): Promise<FileSummaryResult>;
|
|
32
|
+
//# sourceMappingURL=file-summary.d.ts.map
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
async function fileSummary(options) {
|
|
3
|
+
const { path, previewLines: _previewLines = 3 } = options;
|
|
4
|
+
const content = await readFile(path, "utf-8");
|
|
5
|
+
const lines = content.split("\n");
|
|
6
|
+
const extension = path.split(".").pop() ?? "";
|
|
7
|
+
const imports = [];
|
|
8
|
+
const exports = [];
|
|
9
|
+
const functions = [];
|
|
10
|
+
const classes = [];
|
|
11
|
+
const interfaces = [];
|
|
12
|
+
const types = [];
|
|
13
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
14
|
+
const line = lines[index];
|
|
15
|
+
const lineNumber = index + 1;
|
|
16
|
+
if (/^import\s+.+/.test(line)) {
|
|
17
|
+
imports.push(line.trim());
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const exportedFunctionMatch = line.match(/^export\s+(?:async\s+)?function\s+(\w+)/);
|
|
21
|
+
if (exportedFunctionMatch) {
|
|
22
|
+
functions.push({ name: exportedFunctionMatch[1], line: lineNumber, exported: true });
|
|
23
|
+
exports.push(exportedFunctionMatch[1]);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const functionMatch = line.match(/^(?:async\s+)?function\s+(\w+)/);
|
|
27
|
+
if (functionMatch) {
|
|
28
|
+
functions.push({ name: functionMatch[1], line: lineNumber, exported: false });
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const constFunctionMatch = line.match(/^(export\s+)?const\s+(\w+)\s*=.*(?:=>|\bfunction\b)/);
|
|
32
|
+
if (constFunctionMatch) {
|
|
33
|
+
const exported = Boolean(constFunctionMatch[1]);
|
|
34
|
+
functions.push({ name: constFunctionMatch[2], line: lineNumber, exported });
|
|
35
|
+
if (exported) exports.push(constFunctionMatch[2]);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const exportConstMatch = line.match(/^export\s+const\s+(\w+)\s*=/);
|
|
39
|
+
if (exportConstMatch) {
|
|
40
|
+
exports.push(exportConstMatch[1]);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const classMatch = line.match(/^(export\s+)?(?:abstract\s+)?class\s+(\w+)/);
|
|
44
|
+
if (classMatch) {
|
|
45
|
+
const exported = Boolean(classMatch[1]);
|
|
46
|
+
classes.push({ name: classMatch[2], line: lineNumber, exported });
|
|
47
|
+
if (exported) exports.push(classMatch[2]);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const interfaceMatch = line.match(/^(?:export\s+)?interface\s+(\w+)/);
|
|
51
|
+
if (interfaceMatch) {
|
|
52
|
+
interfaces.push({ name: interfaceMatch[1], line: lineNumber });
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const typeMatch = line.match(/^(?:export\s+)?type\s+(\w+)/);
|
|
56
|
+
if (typeMatch) {
|
|
57
|
+
types.push({ name: typeMatch[1], line: lineNumber });
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const reExportMatch = line.match(/^export\s+\{(.+)\}/);
|
|
61
|
+
if (reExportMatch) {
|
|
62
|
+
const names = reExportMatch[1].split(",").map(
|
|
63
|
+
(name) => name.trim().split(/\s+as\s+/).pop()?.trim() ?? ""
|
|
64
|
+
).filter(Boolean);
|
|
65
|
+
exports.push(...names);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
path,
|
|
70
|
+
lines: lines.length,
|
|
71
|
+
language: detectLanguage(extension),
|
|
72
|
+
imports,
|
|
73
|
+
exports,
|
|
74
|
+
functions,
|
|
75
|
+
classes,
|
|
76
|
+
interfaces,
|
|
77
|
+
types,
|
|
78
|
+
estimatedTokens: Math.ceil(content.length / 4)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function detectLanguage(extension) {
|
|
82
|
+
const map = {
|
|
83
|
+
ts: "typescript",
|
|
84
|
+
tsx: "typescript-jsx",
|
|
85
|
+
js: "javascript",
|
|
86
|
+
jsx: "javascript-jsx",
|
|
87
|
+
py: "python",
|
|
88
|
+
rs: "rust",
|
|
89
|
+
go: "go",
|
|
90
|
+
java: "java",
|
|
91
|
+
rb: "ruby",
|
|
92
|
+
md: "markdown",
|
|
93
|
+
json: "json",
|
|
94
|
+
yaml: "yaml",
|
|
95
|
+
yml: "yaml",
|
|
96
|
+
css: "css",
|
|
97
|
+
html: "html",
|
|
98
|
+
sh: "shell",
|
|
99
|
+
bash: "shell"
|
|
100
|
+
};
|
|
101
|
+
return map[extension] ?? extension;
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
fileSummary
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=file-summary.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const DEFAULT_TOOL_EXTENSIONS: string[];
|
|
2
|
+
export declare function matchesGlobPattern(path: string, pattern: string): boolean;
|
|
3
|
+
export declare function walkFiles(rootPath: string, extensions: string[], exclude: string[]): Promise<string[]>;
|
|
4
|
+
//# sourceMappingURL=file-walk.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import { extname, join, relative } from "node:path";
|
|
3
|
+
const DEFAULT_TOOL_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx"];
|
|
4
|
+
const DEFAULT_WALK_EXCLUDES = /* @__PURE__ */ new Set([
|
|
5
|
+
"node_modules",
|
|
6
|
+
".git",
|
|
7
|
+
"dist",
|
|
8
|
+
"build",
|
|
9
|
+
"coverage",
|
|
10
|
+
".turbo",
|
|
11
|
+
".cache",
|
|
12
|
+
"cdk.out",
|
|
13
|
+
".kb-state"
|
|
14
|
+
]);
|
|
15
|
+
function normalizePath(path) {
|
|
16
|
+
return path.replace(/\\/g, "/");
|
|
17
|
+
}
|
|
18
|
+
function escapeRegex(value) {
|
|
19
|
+
return value.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
20
|
+
}
|
|
21
|
+
function matchesGlobPattern(path, pattern) {
|
|
22
|
+
const normalizedPath = normalizePath(path);
|
|
23
|
+
const normalizedPattern = normalizePath(pattern).trim();
|
|
24
|
+
if (!normalizedPattern) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const regexSource = escapeRegex(normalizedPattern).replace(/\*\*/g, "::DOUBLE_STAR::").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/::DOUBLE_STAR::/g, ".*");
|
|
28
|
+
const regex = new RegExp(`^${regexSource}$`);
|
|
29
|
+
return regex.test(normalizedPath);
|
|
30
|
+
}
|
|
31
|
+
function isExcluded(path, exclude, isDirectory) {
|
|
32
|
+
return exclude.some((pattern) => {
|
|
33
|
+
if (matchesGlobPattern(path, pattern)) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (isDirectory) {
|
|
37
|
+
return matchesGlobPattern(`${path}/`, pattern);
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async function walkFiles(rootPath, extensions, exclude) {
|
|
43
|
+
const matchedFiles = [];
|
|
44
|
+
const normalizedExtensions = extensions.map((extension) => extension.toLowerCase());
|
|
45
|
+
async function visit(currentPath) {
|
|
46
|
+
const entries = await readdir(currentPath);
|
|
47
|
+
for (const entry of entries) {
|
|
48
|
+
if (DEFAULT_WALK_EXCLUDES.has(entry)) continue;
|
|
49
|
+
const absolutePath = join(currentPath, entry);
|
|
50
|
+
const entryStat = await stat(absolutePath);
|
|
51
|
+
const relativePath = normalizePath(relative(rootPath, absolutePath));
|
|
52
|
+
if (entryStat.isDirectory()) {
|
|
53
|
+
if (!isExcluded(relativePath, exclude, true)) {
|
|
54
|
+
await visit(absolutePath);
|
|
55
|
+
}
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (isExcluded(relativePath, exclude, false)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (normalizedExtensions.includes(extname(entry).toLowerCase())) {
|
|
62
|
+
matchedFiles.push(absolutePath);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
await visit(rootPath);
|
|
67
|
+
matchedFiles.sort((left, right) => left.localeCompare(right));
|
|
68
|
+
return matchedFiles;
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
DEFAULT_TOOL_EXTENSIONS,
|
|
72
|
+
matchesGlobPattern,
|
|
73
|
+
walkFiles
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=file-walk.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IEmbedder } from '@kb/embeddings';
|
|
2
|
+
import type { IKnowledgeStore } from '@kb/store';
|
|
3
|
+
export interface FindExamplesOptions {
|
|
4
|
+
/** Symbol or pattern to find examples of */
|
|
5
|
+
query: string;
|
|
6
|
+
/** Max examples to return (default: 5) */
|
|
7
|
+
limit?: number;
|
|
8
|
+
/** Filter by content type */
|
|
9
|
+
contentType?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface Example {
|
|
12
|
+
path: string;
|
|
13
|
+
startLine: number;
|
|
14
|
+
endLine: number;
|
|
15
|
+
content: string;
|
|
16
|
+
relevance: number;
|
|
17
|
+
context: string;
|
|
18
|
+
}
|
|
19
|
+
export interface FindExamplesResult {
|
|
20
|
+
query: string;
|
|
21
|
+
examples: Example[];
|
|
22
|
+
totalFound: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function findExamples(embedder: IEmbedder, store: IKnowledgeStore, options: FindExamplesOptions): Promise<FindExamplesResult>;
|
|
25
|
+
//# sourceMappingURL=find-examples.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
async function findExamples(embedder, store, options) {
|
|
2
|
+
const { query, limit = 5, contentType } = options;
|
|
3
|
+
const usageQuery = `usage example of ${query}`;
|
|
4
|
+
const vector = await embedder.embed(usageQuery);
|
|
5
|
+
const results = await store.search(vector, {
|
|
6
|
+
limit: limit * 3,
|
|
7
|
+
contentType
|
|
8
|
+
});
|
|
9
|
+
const queryPattern = new RegExp(`\\b${escapeRegExp(query)}\\b`, "i");
|
|
10
|
+
const matching = results.filter((result) => queryPattern.test(result.record.content));
|
|
11
|
+
const examples = matching.map((result) => {
|
|
12
|
+
const content = result.record.content;
|
|
13
|
+
const isDefinition = /export\s+(?:async\s+)?(?:function|class|const|interface|type)\s/.test(
|
|
14
|
+
content
|
|
15
|
+
);
|
|
16
|
+
const isImport = /^\s*import\s/m.test(content);
|
|
17
|
+
const isTest = /(?:^|[\\/])(test|tests|__tests__|spec)(?:[\\/]|$)/i.test(result.record.sourcePath) || /\.(test|spec)\.[jt]sx?$/i.test(result.record.sourcePath);
|
|
18
|
+
let relevanceBoost = 0;
|
|
19
|
+
if (!isDefinition) relevanceBoost += 0.1;
|
|
20
|
+
if (!isImport) relevanceBoost += 0.05;
|
|
21
|
+
if (isTest) relevanceBoost += 0.05;
|
|
22
|
+
const lines = content.split("\n");
|
|
23
|
+
const matchLine = lines.findIndex((line) => queryPattern.test(line));
|
|
24
|
+
const contextStart = Math.max(0, matchLine - 2);
|
|
25
|
+
const contextEnd = Math.min(lines.length, matchLine + 5);
|
|
26
|
+
const context = lines.slice(contextStart, contextEnd).join("\n");
|
|
27
|
+
return {
|
|
28
|
+
path: result.record.sourcePath,
|
|
29
|
+
startLine: result.record.startLine,
|
|
30
|
+
endLine: result.record.endLine,
|
|
31
|
+
content: context || content.slice(0, 300),
|
|
32
|
+
relevance: Math.min(1, result.score + relevanceBoost),
|
|
33
|
+
context: isTest ? "test" : isDefinition ? "definition" : "usage"
|
|
34
|
+
};
|
|
35
|
+
}).sort((left, right) => right.relevance - left.relevance).slice(0, limit);
|
|
36
|
+
return {
|
|
37
|
+
query,
|
|
38
|
+
examples,
|
|
39
|
+
totalFound: matching.length
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function escapeRegExp(value) {
|
|
43
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
findExamples
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=find-examples.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kb_find — Federated search across vector similarity, keyword (FTS), and file glob.
|
|
3
|
+
*
|
|
4
|
+
* Combines multiple search strategies in a single call, deduplicates,
|
|
5
|
+
* and returns unified results with source attribution.
|
|
6
|
+
*/
|
|
7
|
+
import type { IEmbedder } from '@kb/embeddings';
|
|
8
|
+
import type { IKnowledgeStore } from '@kb/store';
|
|
9
|
+
export interface FindOptions {
|
|
10
|
+
/** Semantic search query (optional) */
|
|
11
|
+
query?: string;
|
|
12
|
+
/** File glob pattern (optional) */
|
|
13
|
+
glob?: string;
|
|
14
|
+
/** Keyword/regex pattern for text search (optional) */
|
|
15
|
+
pattern?: string;
|
|
16
|
+
/** Max results per strategy (default: 10) */
|
|
17
|
+
limit?: number;
|
|
18
|
+
/** Filter by content type */
|
|
19
|
+
contentType?: string;
|
|
20
|
+
/** Working directory for glob resolution (default: cwd) */
|
|
21
|
+
cwd?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FindResult {
|
|
24
|
+
/** File path (relative to cwd) */
|
|
25
|
+
path: string;
|
|
26
|
+
/** How this result was found */
|
|
27
|
+
source: 'vector' | 'keyword' | 'glob' | 'pattern';
|
|
28
|
+
/** Relevance score (0-1 for vector/keyword, 1 for glob/pattern matches) */
|
|
29
|
+
score: number;
|
|
30
|
+
/** Line range if from KB search */
|
|
31
|
+
lineRange?: {
|
|
32
|
+
start: number;
|
|
33
|
+
end: number;
|
|
34
|
+
};
|
|
35
|
+
/** Content preview */
|
|
36
|
+
preview?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface FindResults {
|
|
39
|
+
results: FindResult[];
|
|
40
|
+
strategies: string[];
|
|
41
|
+
totalFound: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Run federated search across multiple strategies.
|
|
45
|
+
*/
|
|
46
|
+
export declare function find(embedder: IEmbedder, store: IKnowledgeStore, options: FindOptions): Promise<FindResults>;
|
|
47
|
+
//# sourceMappingURL=find.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
async function find(embedder, store, options) {
|
|
2
|
+
const {
|
|
3
|
+
query,
|
|
4
|
+
glob: globPattern,
|
|
5
|
+
pattern,
|
|
6
|
+
limit = 10,
|
|
7
|
+
contentType,
|
|
8
|
+
cwd = process.cwd()
|
|
9
|
+
} = options;
|
|
10
|
+
const strategies = [];
|
|
11
|
+
const allResults = [];
|
|
12
|
+
const seen = /* @__PURE__ */ new Set();
|
|
13
|
+
if (query) {
|
|
14
|
+
strategies.push("vector");
|
|
15
|
+
const queryVector = await embedder.embed(query);
|
|
16
|
+
const searchOpts = { limit, contentType };
|
|
17
|
+
const vectorResults = await store.search(queryVector, searchOpts);
|
|
18
|
+
for (const r of vectorResults) {
|
|
19
|
+
const key = `${r.record.sourcePath}:${r.record.startLine}`;
|
|
20
|
+
if (!seen.has(key)) {
|
|
21
|
+
seen.add(key);
|
|
22
|
+
allResults.push({
|
|
23
|
+
path: r.record.sourcePath,
|
|
24
|
+
source: "vector",
|
|
25
|
+
score: r.score,
|
|
26
|
+
lineRange: { start: r.record.startLine, end: r.record.endLine },
|
|
27
|
+
preview: r.record.content.slice(0, 200)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (query) {
|
|
33
|
+
strategies.push("keyword");
|
|
34
|
+
try {
|
|
35
|
+
const ftsResults = await store.ftsSearch(query, { limit, contentType });
|
|
36
|
+
for (const r of ftsResults) {
|
|
37
|
+
const key = `${r.record.sourcePath}:${r.record.startLine}`;
|
|
38
|
+
if (!seen.has(key)) {
|
|
39
|
+
seen.add(key);
|
|
40
|
+
allResults.push({
|
|
41
|
+
path: r.record.sourcePath,
|
|
42
|
+
source: "keyword",
|
|
43
|
+
score: r.score,
|
|
44
|
+
lineRange: { start: r.record.startLine, end: r.record.endLine },
|
|
45
|
+
preview: r.record.content.slice(0, 200)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (globPattern) {
|
|
53
|
+
strategies.push("glob");
|
|
54
|
+
try {
|
|
55
|
+
const { globSync: nodeGlob } = await import("node:fs");
|
|
56
|
+
const files = nodeGlob(globPattern, { cwd });
|
|
57
|
+
const GLOB_EXCLUDES = /* @__PURE__ */ new Set([
|
|
58
|
+
"node_modules",
|
|
59
|
+
".git",
|
|
60
|
+
"dist",
|
|
61
|
+
"build",
|
|
62
|
+
"coverage",
|
|
63
|
+
".turbo",
|
|
64
|
+
".cache",
|
|
65
|
+
"cdk.out",
|
|
66
|
+
".kb-state",
|
|
67
|
+
".kb-data"
|
|
68
|
+
]);
|
|
69
|
+
const filtered = files.filter((f) => {
|
|
70
|
+
const segments = f.replace(/\\/g, "/").split("/");
|
|
71
|
+
return !segments.some((s) => GLOB_EXCLUDES.has(s));
|
|
72
|
+
});
|
|
73
|
+
for (const file of filtered.slice(0, limit)) {
|
|
74
|
+
const key = `glob:${file}`;
|
|
75
|
+
if (!seen.has(key)) {
|
|
76
|
+
seen.add(key);
|
|
77
|
+
allResults.push({
|
|
78
|
+
path: file,
|
|
79
|
+
source: "glob",
|
|
80
|
+
score: 1
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (pattern) {
|
|
88
|
+
strategies.push("pattern");
|
|
89
|
+
try {
|
|
90
|
+
const regex = new RegExp(pattern, "i");
|
|
91
|
+
const ftsResults = await store.ftsSearch(pattern, { limit: limit * 2, contentType });
|
|
92
|
+
for (const r of ftsResults) {
|
|
93
|
+
if (regex.test(r.record.content)) {
|
|
94
|
+
const key = `${r.record.sourcePath}:${r.record.startLine}`;
|
|
95
|
+
if (!seen.has(key)) {
|
|
96
|
+
seen.add(key);
|
|
97
|
+
allResults.push({
|
|
98
|
+
path: r.record.sourcePath,
|
|
99
|
+
source: "pattern",
|
|
100
|
+
score: r.score,
|
|
101
|
+
lineRange: { start: r.record.startLine, end: r.record.endLine },
|
|
102
|
+
preview: r.record.content.slice(0, 200)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch {
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
allResults.sort((a, b) => b.score - a.score);
|
|
111
|
+
return {
|
|
112
|
+
results: allResults.slice(0, limit),
|
|
113
|
+
strategies,
|
|
114
|
+
totalFound: allResults.length
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
find
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=find.js.map
|