@cstart/coldstart 2.0.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.
- package/README.md +236 -0
- package/dist/cache/disk-cache.d.ts +14 -0
- package/dist/cache/disk-cache.d.ts.map +1 -0
- package/dist/cache/disk-cache.js +371 -0
- package/dist/cache/disk-cache.js.map +1 -0
- package/dist/cli.d.ts +18 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +206 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +111 -0
- package/dist/constants.js.map +1 -0
- package/dist/daemon-lock.d.ts +63 -0
- package/dist/daemon-lock.d.ts.map +1 -0
- package/dist/daemon-lock.js +218 -0
- package/dist/daemon-lock.js.map +1 -0
- package/dist/daemon-log.d.ts +26 -0
- package/dist/daemon-log.d.ts.map +1 -0
- package/dist/daemon-log.js +110 -0
- package/dist/daemon-log.js.map +1 -0
- package/dist/index-manager.d.ts +103 -0
- package/dist/index-manager.d.ts.map +1 -0
- package/dist/index-manager.js +361 -0
- package/dist/index-manager.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +724 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/content-tokens.d.ts +74 -0
- package/dist/indexer/content-tokens.d.ts.map +1 -0
- package/dist/indexer/content-tokens.js +406 -0
- package/dist/indexer/content-tokens.js.map +1 -0
- package/dist/indexer/cpp-include-roots.d.ts +7 -0
- package/dist/indexer/cpp-include-roots.d.ts.map +1 -0
- package/dist/indexer/cpp-include-roots.js +166 -0
- package/dist/indexer/cpp-include-roots.js.map +1 -0
- package/dist/indexer/csharp-synthetic.d.ts +9 -0
- package/dist/indexer/csharp-synthetic.d.ts.map +1 -0
- package/dist/indexer/csharp-synthetic.js +51 -0
- package/dist/indexer/csharp-synthetic.js.map +1 -0
- package/dist/indexer/django-synthetic.d.ts +12 -0
- package/dist/indexer/django-synthetic.d.ts.map +1 -0
- package/dist/indexer/django-synthetic.js +49 -0
- package/dist/indexer/django-synthetic.js.map +1 -0
- package/dist/indexer/extractors/angularjs.d.ts +16 -0
- package/dist/indexer/extractors/angularjs.d.ts.map +1 -0
- package/dist/indexer/extractors/angularjs.js +49 -0
- package/dist/indexer/extractors/angularjs.js.map +1 -0
- package/dist/indexer/extractors/cpp.d.ts +9 -0
- package/dist/indexer/extractors/cpp.d.ts.map +1 -0
- package/dist/indexer/extractors/cpp.js +254 -0
- package/dist/indexer/extractors/cpp.js.map +1 -0
- package/dist/indexer/extractors/csharp.d.ts +19 -0
- package/dist/indexer/extractors/csharp.d.ts.map +1 -0
- package/dist/indexer/extractors/csharp.js +327 -0
- package/dist/indexer/extractors/csharp.js.map +1 -0
- package/dist/indexer/extractors/env.d.ts +9 -0
- package/dist/indexer/extractors/env.d.ts.map +1 -0
- package/dist/indexer/extractors/env.js +43 -0
- package/dist/indexer/extractors/env.js.map +1 -0
- package/dist/indexer/extractors/go.d.ts +9 -0
- package/dist/indexer/extractors/go.d.ts.map +1 -0
- package/dist/indexer/extractors/go.js +227 -0
- package/dist/indexer/extractors/go.js.map +1 -0
- package/dist/indexer/extractors/graphql.d.ts +22 -0
- package/dist/indexer/extractors/graphql.d.ts.map +1 -0
- package/dist/indexer/extractors/graphql.js +88 -0
- package/dist/indexer/extractors/graphql.js.map +1 -0
- package/dist/indexer/extractors/groovy.d.ts +9 -0
- package/dist/indexer/extractors/groovy.d.ts.map +1 -0
- package/dist/indexer/extractors/groovy.js +356 -0
- package/dist/indexer/extractors/groovy.js.map +1 -0
- package/dist/indexer/extractors/java.d.ts +10 -0
- package/dist/indexer/extractors/java.d.ts.map +1 -0
- package/dist/indexer/extractors/java.js +586 -0
- package/dist/indexer/extractors/java.js.map +1 -0
- package/dist/indexer/extractors/kotlin.d.ts +10 -0
- package/dist/indexer/extractors/kotlin.d.ts.map +1 -0
- package/dist/indexer/extractors/kotlin.js +398 -0
- package/dist/indexer/extractors/kotlin.js.map +1 -0
- package/dist/indexer/extractors/node-helpers.d.ts +13 -0
- package/dist/indexer/extractors/node-helpers.d.ts.map +1 -0
- package/dist/indexer/extractors/node-helpers.js +17 -0
- package/dist/indexer/extractors/node-helpers.js.map +1 -0
- package/dist/indexer/extractors/parser-factory.d.ts +4 -0
- package/dist/indexer/extractors/parser-factory.d.ts.map +1 -0
- package/dist/indexer/extractors/parser-factory.js +28 -0
- package/dist/indexer/extractors/parser-factory.js.map +1 -0
- package/dist/indexer/extractors/php.d.ts +17 -0
- package/dist/indexer/extractors/php.d.ts.map +1 -0
- package/dist/indexer/extractors/php.js +363 -0
- package/dist/indexer/extractors/php.js.map +1 -0
- package/dist/indexer/extractors/python.d.ts +14 -0
- package/dist/indexer/extractors/python.d.ts.map +1 -0
- package/dist/indexer/extractors/python.js +449 -0
- package/dist/indexer/extractors/python.js.map +1 -0
- package/dist/indexer/extractors/ruby.d.ts +10 -0
- package/dist/indexer/extractors/ruby.d.ts.map +1 -0
- package/dist/indexer/extractors/ruby.js +996 -0
- package/dist/indexer/extractors/ruby.js.map +1 -0
- package/dist/indexer/extractors/rust.d.ts +9 -0
- package/dist/indexer/extractors/rust.d.ts.map +1 -0
- package/dist/indexer/extractors/rust.js +322 -0
- package/dist/indexer/extractors/rust.js.map +1 -0
- package/dist/indexer/extractors/toml.d.ts +9 -0
- package/dist/indexer/extractors/toml.d.ts.map +1 -0
- package/dist/indexer/extractors/toml.js +84 -0
- package/dist/indexer/extractors/toml.js.map +1 -0
- package/dist/indexer/extractors/xml.d.ts +9 -0
- package/dist/indexer/extractors/xml.d.ts.map +1 -0
- package/dist/indexer/extractors/xml.js +163 -0
- package/dist/indexer/extractors/xml.js.map +1 -0
- package/dist/indexer/extractors/yaml.d.ts +9 -0
- package/dist/indexer/extractors/yaml.d.ts.map +1 -0
- package/dist/indexer/extractors/yaml.js +117 -0
- package/dist/indexer/extractors/yaml.js.map +1 -0
- package/dist/indexer/git.d.ts +19 -0
- package/dist/indexer/git.d.ts.map +1 -0
- package/dist/indexer/git.js +55 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/graph.d.ts +7 -0
- package/dist/indexer/graph.d.ts.map +1 -0
- package/dist/indexer/graph.js +20 -0
- package/dist/indexer/graph.js.map +1 -0
- package/dist/indexer/indexed-file.d.ts +15 -0
- package/dist/indexer/indexed-file.d.ts.map +1 -0
- package/dist/indexer/indexed-file.js +50 -0
- package/dist/indexer/indexed-file.js.map +1 -0
- package/dist/indexer/invariants.d.ts +15 -0
- package/dist/indexer/invariants.d.ts.map +1 -0
- package/dist/indexer/invariants.js +96 -0
- package/dist/indexer/invariants.js.map +1 -0
- package/dist/indexer/laravel-synthetic.d.ts +10 -0
- package/dist/indexer/laravel-synthetic.d.ts.map +1 -0
- package/dist/indexer/laravel-synthetic.js +78 -0
- package/dist/indexer/laravel-synthetic.js.map +1 -0
- package/dist/indexer/parser.d.ts +4 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +499 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/patch.d.ts +3 -0
- package/dist/indexer/patch.d.ts.map +1 -0
- package/dist/indexer/patch.js +291 -0
- package/dist/indexer/patch.js.map +1 -0
- package/dist/indexer/rails-synthetic.d.ts +11 -0
- package/dist/indexer/rails-synthetic.d.ts.map +1 -0
- package/dist/indexer/rails-synthetic.js +80 -0
- package/dist/indexer/rails-synthetic.js.map +1 -0
- package/dist/indexer/reconcile.d.ts +9 -0
- package/dist/indexer/reconcile.d.ts.map +1 -0
- package/dist/indexer/reconcile.js +96 -0
- package/dist/indexer/reconcile.js.map +1 -0
- package/dist/indexer/resolvers/cpp.d.ts +15 -0
- package/dist/indexer/resolvers/cpp.d.ts.map +1 -0
- package/dist/indexer/resolvers/cpp.js +35 -0
- package/dist/indexer/resolvers/cpp.js.map +1 -0
- package/dist/indexer/resolvers/csharp.d.ts +2 -0
- package/dist/indexer/resolvers/csharp.d.ts.map +1 -0
- package/dist/indexer/resolvers/csharp.js +89 -0
- package/dist/indexer/resolvers/csharp.js.map +1 -0
- package/dist/indexer/resolvers/generic.d.ts +10 -0
- package/dist/indexer/resolvers/generic.d.ts.map +1 -0
- package/dist/indexer/resolvers/generic.js +35 -0
- package/dist/indexer/resolvers/generic.js.map +1 -0
- package/dist/indexer/resolvers/go.d.ts +2 -0
- package/dist/indexer/resolvers/go.d.ts.map +1 -0
- package/dist/indexer/resolvers/go.js +171 -0
- package/dist/indexer/resolvers/go.js.map +1 -0
- package/dist/indexer/resolvers/index.d.ts +26 -0
- package/dist/indexer/resolvers/index.d.ts.map +1 -0
- package/dist/indexer/resolvers/index.js +301 -0
- package/dist/indexer/resolvers/index.js.map +1 -0
- package/dist/indexer/resolvers/java.d.ts +17 -0
- package/dist/indexer/resolvers/java.d.ts.map +1 -0
- package/dist/indexer/resolvers/java.js +104 -0
- package/dist/indexer/resolvers/java.js.map +1 -0
- package/dist/indexer/resolvers/php.d.ts +2 -0
- package/dist/indexer/resolvers/php.d.ts.map +1 -0
- package/dist/indexer/resolvers/php.js +108 -0
- package/dist/indexer/resolvers/php.js.map +1 -0
- package/dist/indexer/resolvers/python.d.ts +17 -0
- package/dist/indexer/resolvers/python.d.ts.map +1 -0
- package/dist/indexer/resolvers/python.js +63 -0
- package/dist/indexer/resolvers/python.js.map +1 -0
- package/dist/indexer/resolvers/ruby.d.ts +13 -0
- package/dist/indexer/resolvers/ruby.d.ts.map +1 -0
- package/dist/indexer/resolvers/ruby.js +199 -0
- package/dist/indexer/resolvers/ruby.js.map +1 -0
- package/dist/indexer/resolvers/rust.d.ts +12 -0
- package/dist/indexer/resolvers/rust.d.ts.map +1 -0
- package/dist/indexer/resolvers/rust.js +61 -0
- package/dist/indexer/resolvers/rust.js.map +1 -0
- package/dist/indexer/resolvers/shared.d.ts +18 -0
- package/dist/indexer/resolvers/shared.d.ts.map +1 -0
- package/dist/indexer/resolvers/shared.js +71 -0
- package/dist/indexer/resolvers/shared.js.map +1 -0
- package/dist/indexer/rust-workspace.d.ts +25 -0
- package/dist/indexer/rust-workspace.d.ts.map +1 -0
- package/dist/indexer/rust-workspace.js +155 -0
- package/dist/indexer/rust-workspace.js.map +1 -0
- package/dist/indexer/symbol-edges.d.ts +19 -0
- package/dist/indexer/symbol-edges.d.ts.map +1 -0
- package/dist/indexer/symbol-edges.js +117 -0
- package/dist/indexer/symbol-edges.js.map +1 -0
- package/dist/indexer/tokenize.d.ts +26 -0
- package/dist/indexer/tokenize.d.ts.map +1 -0
- package/dist/indexer/tokenize.js +200 -0
- package/dist/indexer/tokenize.js.map +1 -0
- package/dist/indexer/ts-parser.d.ts +10 -0
- package/dist/indexer/ts-parser.d.ts.map +1 -0
- package/dist/indexer/ts-parser.js +605 -0
- package/dist/indexer/ts-parser.js.map +1 -0
- package/dist/indexer/walker.d.ts +9 -0
- package/dist/indexer/walker.d.ts.map +1 -0
- package/dist/indexer/walker.js +91 -0
- package/dist/indexer/walker.js.map +1 -0
- package/dist/init.d.ts +111 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +787 -0
- package/dist/init.js.map +1 -0
- package/dist/kb/cli.d.ts +2 -0
- package/dist/kb/cli.d.ts.map +1 -0
- package/dist/kb/cli.js +377 -0
- package/dist/kb/cli.js.map +1 -0
- package/dist/kb/commit.d.ts +6 -0
- package/dist/kb/commit.d.ts.map +1 -0
- package/dist/kb/commit.js +84 -0
- package/dist/kb/commit.js.map +1 -0
- package/dist/kb/fold.d.ts +42 -0
- package/dist/kb/fold.d.ts.map +1 -0
- package/dist/kb/fold.js +285 -0
- package/dist/kb/fold.js.map +1 -0
- package/dist/kb/freshness.d.ts +9 -0
- package/dist/kb/freshness.d.ts.map +1 -0
- package/dist/kb/freshness.js +52 -0
- package/dist/kb/freshness.js.map +1 -0
- package/dist/kb/git.d.ts +4 -0
- package/dist/kb/git.d.ts.map +1 -0
- package/dist/kb/git.js +28 -0
- package/dist/kb/git.js.map +1 -0
- package/dist/kb/ids.d.ts +8 -0
- package/dist/kb/ids.d.ts.map +1 -0
- package/dist/kb/ids.js +42 -0
- package/dist/kb/ids.js.map +1 -0
- package/dist/kb/lint.d.ts +23 -0
- package/dist/kb/lint.d.ts.map +1 -0
- package/dist/kb/lint.js +102 -0
- package/dist/kb/lint.js.map +1 -0
- package/dist/kb/lookup.d.ts +55 -0
- package/dist/kb/lookup.d.ts.map +1 -0
- package/dist/kb/lookup.js +92 -0
- package/dist/kb/lookup.js.map +1 -0
- package/dist/kb/notes-index.d.ts +31 -0
- package/dist/kb/notes-index.d.ts.map +1 -0
- package/dist/kb/notes-index.js +0 -0
- package/dist/kb/notes-index.js.map +1 -0
- package/dist/kb/raw-log.d.ts +34 -0
- package/dist/kb/raw-log.d.ts.map +1 -0
- package/dist/kb/raw-log.js +106 -0
- package/dist/kb/raw-log.js.map +1 -0
- package/dist/kb/render.d.ts +17 -0
- package/dist/kb/render.d.ts.map +1 -0
- package/dist/kb/render.js +101 -0
- package/dist/kb/render.js.map +1 -0
- package/dist/kb/search.d.ts +110 -0
- package/dist/kb/search.d.ts.map +1 -0
- package/dist/kb/search.js +453 -0
- package/dist/kb/search.js.map +1 -0
- package/dist/kb/store.d.ts +35 -0
- package/dist/kb/store.d.ts.map +1 -0
- package/dist/kb/store.js +160 -0
- package/dist/kb/store.js.map +1 -0
- package/dist/kb/types.d.ts +142 -0
- package/dist/kb/types.d.ts.map +1 -0
- package/dist/kb/types.js +13 -0
- package/dist/kb/types.js.map +1 -0
- package/dist/kb/view-template.d.ts +8 -0
- package/dist/kb/view-template.d.ts.map +1 -0
- package/dist/kb/view-template.js +8 -0
- package/dist/kb/view-template.js.map +1 -0
- package/dist/kb/view.d.ts +42 -0
- package/dist/kb/view.d.ts.map +1 -0
- package/dist/kb/view.js +118 -0
- package/dist/kb/view.js.map +1 -0
- package/dist/kb/write.d.ts +72 -0
- package/dist/kb/write.d.ts.map +1 -0
- package/dist/kb/write.js +345 -0
- package/dist/kb/write.js.map +1 -0
- package/dist/keeper-state.d.ts +29 -0
- package/dist/keeper-state.d.ts.map +1 -0
- package/dist/keeper-state.js +89 -0
- package/dist/keeper-state.js.map +1 -0
- package/dist/keeper.d.ts +23 -0
- package/dist/keeper.d.ts.map +1 -0
- package/dist/keeper.js +105 -0
- package/dist/keeper.js.map +1 -0
- package/dist/migrate.d.ts +9 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +102 -0
- package/dist/migrate.js.map +1 -0
- package/dist/restart.d.ts +15 -0
- package/dist/restart.d.ts.map +1 -0
- package/dist/restart.js +48 -0
- package/dist/restart.js.map +1 -0
- package/dist/server/find.d.ts +39 -0
- package/dist/server/find.d.ts.map +1 -0
- package/dist/server/find.js +979 -0
- package/dist/server/find.js.map +1 -0
- package/dist/server/mcp.d.ts +117 -0
- package/dist/server/mcp.d.ts.map +1 -0
- package/dist/server/mcp.js +301 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/searcher.d.ts +14 -0
- package/dist/server/searcher.d.ts.map +1 -0
- package/dist/server/searcher.js +146 -0
- package/dist/server/searcher.js.map +1 -0
- package/dist/server/tools.d.ts +17 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +875 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/status.d.ts +12 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +157 -0
- package/dist/status.js.map +1 -0
- package/dist/types.d.ts +138 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher.d.ts +11 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +67 -0
- package/dist/watcher.js.map +1 -0
- package/hooks/canonical-find-key.mjs +68 -0
- package/hooks/codex-find-nudge.mjs +15 -0
- package/hooks/codex-find-preguard.mjs +14 -0
- package/hooks/codex-kb-elicit.mjs +329 -0
- package/hooks/codex-kb-recall.mjs +151 -0
- package/hooks/codex-nudge-handler.mjs +370 -0
- package/hooks/codex-preguard-handler.mjs +75 -0
- package/hooks/codex-run-hook.mjs +132 -0
- package/hooks/coldstart-call.mjs +58 -0
- package/hooks/cursor-find-nudge.mjs +15 -0
- package/hooks/cursor-find-preguard.mjs +14 -0
- package/hooks/cursor-input.mjs +72 -0
- package/hooks/cursor-kb-elicit.mjs +335 -0
- package/hooks/cursor-kb-recall.mjs +138 -0
- package/hooks/cursor-nudge-handler.mjs +33 -0
- package/hooks/cursor-preguard-handler.mjs +39 -0
- package/hooks/cursor-run-hook.mjs +129 -0
- package/hooks/find-nudge.mjs +15 -0
- package/hooks/find-preguard.mjs +14 -0
- package/hooks/kb-elicit.mjs +334 -0
- package/hooks/kb-recall.mjs +151 -0
- package/hooks/nudge-handler.mjs +370 -0
- package/hooks/preguard-handler.mjs +75 -0
- package/hooks/run-hook.mjs +132 -0
- package/package.json +69 -0
- package/templates/coldstart.cli.md +60 -0
- package/templates/coldstart.mcp.md +59 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
import { stampCoversTerms } from './notes-index.js';
|
|
2
|
+
import { parseTerms } from '../server/find.js';
|
|
3
|
+
import { stampAnchors, freshnessLine } from './freshness.js';
|
|
4
|
+
import { loadAll, logMetric } from './store.js';
|
|
5
|
+
import { NOTES_REL } from './raw-log.js';
|
|
6
|
+
import { renderNote } from './render.js';
|
|
7
|
+
// English glue words that survive parseTerms' ≥3-char rule but carry zero
|
|
8
|
+
// signal over prose notes. (find doesn't need this — code rarely contains
|
|
9
|
+
// "the" as an identifier; note bodies always do.)
|
|
10
|
+
const STOPWORDS = new Set([
|
|
11
|
+
'the', 'and', 'for', 'with', 'that', 'this', 'from', 'into', 'when', 'where',
|
|
12
|
+
'what', 'which', 'how', 'why', 'does', 'not', 'are', 'was', 'were', 'has',
|
|
13
|
+
'have', 'had', 'can', 'could', 'should', 'would', 'will', 'you', 'your',
|
|
14
|
+
'its', 'her', 'his', 'they', 'them', 'there', 'here', 'about', 'after',
|
|
15
|
+
'before', 'over', 'under', 'then', 'than', 'all', 'any', 'each', 'more',
|
|
16
|
+
'some', 'such', 'only', 'also', 'just', 'being', 'been', 'did', 'do',
|
|
17
|
+
'get', 'gets', 'let', 'lets', 'like', 'make', 'makes', 'need', 'needs',
|
|
18
|
+
'please', 'want', 'use', 'used', 'using', 'way', 'now', 'new', 'out',
|
|
19
|
+
]);
|
|
20
|
+
const norm = (s) => s.toLowerCase();
|
|
21
|
+
const squash = (s) => s.toLowerCase().replace(/[-_/.\s]+/g, '');
|
|
22
|
+
function haystacksFor(note) {
|
|
23
|
+
const name = [note.title, ...note.aliases].join(' ');
|
|
24
|
+
// Facet symbols are addresses — they sit in the anchor channel with the
|
|
25
|
+
// other (path, symbol) vocabulary; facet details are prose (body).
|
|
26
|
+
const anchor = [
|
|
27
|
+
...note.anchors.map((a) => [a.path, ...(a.symbols ?? [])].join(' ')),
|
|
28
|
+
...note.facets.map((f) => f.symbol),
|
|
29
|
+
].join(' ');
|
|
30
|
+
const body = [
|
|
31
|
+
note.summary ?? '',
|
|
32
|
+
note.body ?? '',
|
|
33
|
+
...note.facets.map((f) => f.detail),
|
|
34
|
+
...note.behaviors.map((b) => `${b.concept_id} ${(b.symbols ?? []).join(' ')} ${b.detail}`),
|
|
35
|
+
...note.features.map((f) => `${f.concept_id} ${f.role}`),
|
|
36
|
+
...note.steps.map((s) => `${s.path} ${(s.symbols ?? []).join(' ')} ${s.role}`),
|
|
37
|
+
...note.invariants,
|
|
38
|
+
...(note.scope?.terms ?? []),
|
|
39
|
+
].join(' ');
|
|
40
|
+
return { name: norm(name), nameSquash: squash(name), nameRaw: name, anchor: norm(anchor), anchorSquash: squash(anchor), body: norm(body) };
|
|
41
|
+
}
|
|
42
|
+
// ---- BM25 (tool-mode scoring) ------------------------------------------------
|
|
43
|
+
// In-house BM25F-lite: per-term score = idf · saturation(weighted tf, doc length).
|
|
44
|
+
// Rare terms discriminate (idf), repeated matches saturate (k1), and long notes
|
|
45
|
+
// stop winning on vocabulary volume (b · len/avgLen) — the length normalization
|
|
46
|
+
// the old coverage formula lacked. Channel weights name×3 / anchor×2 / body×1
|
|
47
|
+
// are DEFAULTS; tune against the validation-run corpus, not incidents.
|
|
48
|
+
const BM25_K1 = 1.2;
|
|
49
|
+
const BM25_B = 0.75;
|
|
50
|
+
const CHANNEL_W = { name: 3, anchor: 2, body: 1 };
|
|
51
|
+
/** Results-page relevance floor: a hit scoring below this fraction of the top
|
|
52
|
+
* hit is a graze, not an answer. Two uses, one constant: renderResultsPage
|
|
53
|
+
* drops sub-floor hits from the page, and kbSearch counts cap-omitted hits
|
|
54
|
+
* ABOVE it to decide whether the --max footer is worth showing (a floor-only
|
|
55
|
+
* tail isn't — widening would surface nothing new). */
|
|
56
|
+
const RESULTS_FLOOR = 0.25;
|
|
57
|
+
/** Hook-mode injection gate: the top hit must be matched by at least one
|
|
58
|
+
* DISCRIMINATING term — df ≤ ceil(N/DIVISOR) (rare in this notebook's own
|
|
59
|
+
* vocabulary). Boilerplate prompts ("list the files", "fix the bug and
|
|
60
|
+
* update the tests") match only common words; a real task always names its
|
|
61
|
+
* mechanism. Scale-free — a df ratio, not a score constant — so it neither
|
|
62
|
+
* drifts as the corpus grows nor silences terse single-symbol prompts the
|
|
63
|
+
* way an absolute score floor would. Applied only in the calibrated regime
|
|
64
|
+
* (≥ MIN notes): on a young notebook every df is small, rarity means
|
|
65
|
+
* nothing, and a weak pointer page costs a glance, not a poisoning. */
|
|
66
|
+
const HOOK_RARITY_DIVISOR = 10;
|
|
67
|
+
const HOOK_FLOOR_MIN_NOTES = 30;
|
|
68
|
+
const rarityMax = (n) => Math.ceil(n / HOOK_RARITY_DIVISOR);
|
|
69
|
+
/** Convergence override on the rarity gate: a top hit with no RARE term still
|
|
70
|
+
* injects when ≥ this many distinct eligible terms land in its name/anchor
|
|
71
|
+
* channels. Rarity tests one term's discrimination; this tests agreement —
|
|
72
|
+
* a prompt whose mechanism is named entirely in common words ("how the ids
|
|
73
|
+
* search filter works") converges 4+ minority words on the right note, while
|
|
74
|
+
* a boilerplate graze shares 1–2 ("fix the failing tests" → a tests/ note).
|
|
75
|
+
* Scale-free like the df ratio: each counted term must already be a minority
|
|
76
|
+
* word (df·2 ≤ N), so common vocabulary drops out of the count as the corpus
|
|
77
|
+
* grows instead of inflating it. Calibrated on the 117-note replay corpus
|
|
78
|
+
* (2026-07-08): boilerplate max 2, known-graze 3, false suppressions 4–5.
|
|
79
|
+
* strongTerms is logged on every injection decision for re-calibration. */
|
|
80
|
+
const HOOK_CONVERGE_MIN = 4;
|
|
81
|
+
const tokenCount = (s) => (s ? s.split(/\s+/).filter(Boolean).length : 0);
|
|
82
|
+
/** Substring occurrence count in normalized text; a squash-only match counts 1. */
|
|
83
|
+
function countOcc(hay, haySquash, term) {
|
|
84
|
+
const t = norm(term);
|
|
85
|
+
let n = 0;
|
|
86
|
+
for (let i = hay.indexOf(t); i >= 0; i = hay.indexOf(t, i + t.length))
|
|
87
|
+
n++;
|
|
88
|
+
if (!n && haySquash.includes(squash(term)))
|
|
89
|
+
n = 1;
|
|
90
|
+
return n;
|
|
91
|
+
}
|
|
92
|
+
/** Weighted doc length for BM25 normalization (same channel weights as tf). */
|
|
93
|
+
function bm25Len(h) {
|
|
94
|
+
return CHANNEL_W.name * tokenCount(h.name) + CHANNEL_W.anchor * tokenCount(h.anchor) + CHANNEL_W.body * tokenCount(h.body);
|
|
95
|
+
}
|
|
96
|
+
/** Determine if a term has code shape beyond single leading capital.
|
|
97
|
+
* Code-shaped means it contains digits, underscores, hyphens, or uppercase
|
|
98
|
+
* letters in non-initial positions (camelCase, PascalCase, ALLCAPS).
|
|
99
|
+
* Single-capital words like "Add" are not code-shaped (they're prose with
|
|
100
|
+
* sentence-initial capitalization). */
|
|
101
|
+
function isCodeShaped(term) {
|
|
102
|
+
// Contains digit, underscore, or hyphen
|
|
103
|
+
if (/[0-9_-]/.test(term))
|
|
104
|
+
return true;
|
|
105
|
+
// Contains uppercase at position > 0 (interior caps, ALLCAPS)
|
|
106
|
+
if (term.length > 1 && /[A-Z]/.test(term.slice(1)))
|
|
107
|
+
return true;
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/** Whole-word, case-insensitive hit — "error" must not match "LoadErrors". */
|
|
111
|
+
function wordHit(hay, term) {
|
|
112
|
+
return new RegExp(`\\b${term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i').test(hay);
|
|
113
|
+
}
|
|
114
|
+
/** Case- and separator-insensitive containment (LoadStaging ≡ load_staging). */
|
|
115
|
+
function hits(hay, haySquash, term) {
|
|
116
|
+
const t = norm(term);
|
|
117
|
+
return hay.includes(t) || haySquash.includes(squash(term));
|
|
118
|
+
}
|
|
119
|
+
/** Lane 2: term → anchored files it names (path or a symbol DECLARED in the
|
|
120
|
+
* file, per the keeper's per-anchor inventory — no code-index scan). */
|
|
121
|
+
function resolveTermToAnchors(kb, term) {
|
|
122
|
+
const out = new Set();
|
|
123
|
+
const t = norm(term);
|
|
124
|
+
for (const [path, symbols] of Object.entries(kb.anchors)) {
|
|
125
|
+
if (norm(path).includes(t) || symbols.some((s) => norm(s).includes(t)))
|
|
126
|
+
out.add(path);
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
/** Convergence channel: files where the term matches a DECLARED SYMBOL only —
|
|
131
|
+
* stricter than lane 2 (path-segment grazes don't count). Calibrated on the
|
|
132
|
+
* 27q corpus: symbol agreement was 100%-precise at rank 0; path inclusion
|
|
133
|
+
* wasn't part of that measurement, so it stays out of the gate. */
|
|
134
|
+
function resolveTermToSymbolFiles(kb, term) {
|
|
135
|
+
const out = new Set();
|
|
136
|
+
const t = norm(term);
|
|
137
|
+
for (const [path, symbols] of Object.entries(kb.anchors)) {
|
|
138
|
+
if (symbols.some((s) => norm(s).includes(t)))
|
|
139
|
+
out.add(path);
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
/** An absence note's verdict comes from the keeper's stamp (it re-runs the
|
|
144
|
+
* stored search on every code/notebook change) — never from a live scan here. */
|
|
145
|
+
function absenceVerdict(note, kb) {
|
|
146
|
+
if (note.kind !== 'absence' || !note.scope?.terms.length)
|
|
147
|
+
return undefined;
|
|
148
|
+
const stamp = kb?.absence[note.id];
|
|
149
|
+
// No stamp, or the note's terms changed since the keeper last looked → unverified.
|
|
150
|
+
if (!stampCoversTerms(stamp, note.scope.terms))
|
|
151
|
+
return '[absence not re-verified — no keeper stamp yet]';
|
|
152
|
+
const paths = stamp.matches;
|
|
153
|
+
if (!paths.length)
|
|
154
|
+
return '[absence holds — search still returns nothing]';
|
|
155
|
+
return `[absence STALE — now matches: ${paths.slice(0, 3).join(', ')}${paths.length > 3 ? ` +${paths.length - 3} more` : ''}]`;
|
|
156
|
+
}
|
|
157
|
+
export async function kbSearch(root, query, opts = {}) {
|
|
158
|
+
const max = opts.maxResults ?? 3;
|
|
159
|
+
const { notes, warnings } = loadAll(root);
|
|
160
|
+
const terms = parseTerms(query).filter((t) => !STOPWORDS.has(t.toLowerCase()));
|
|
161
|
+
if (!notes.length || !terms.length) {
|
|
162
|
+
if (notes.length && !opts.noMissLog)
|
|
163
|
+
logMetric(root, 'miss-log', { query, source: opts.source ?? 'tool', reason: 'no-terms' });
|
|
164
|
+
return { hits: [], terms, warnings };
|
|
165
|
+
}
|
|
166
|
+
const stacks = notes.map(haystacksFor);
|
|
167
|
+
// Lane 2: term → anchored files via the keeper's notes index.
|
|
168
|
+
const termFiles = new Map();
|
|
169
|
+
if (opts.notesIndex)
|
|
170
|
+
for (const t of terms)
|
|
171
|
+
termFiles.set(t, resolveTermToAnchors(opts.notesIndex, t));
|
|
172
|
+
// idf over the note corpus — rare terms discriminate, ubiquitous ones don't.
|
|
173
|
+
const df = terms.map((t) => stacks.filter((h) => hits(h.name + ' ' + h.anchor + ' ' + h.body, h.nameSquash + h.anchorSquash, t)).length);
|
|
174
|
+
const idf = (k) => Math.log(1 + notes.length / (1 + df[k]));
|
|
175
|
+
// BM25 length normalization inputs (tool mode).
|
|
176
|
+
const lens = stacks.map(bm25Len);
|
|
177
|
+
const avgLen = Math.max(1, lens.reduce((a, b) => a + b, 0) / Math.max(1, lens.length));
|
|
178
|
+
// Convergence channel: code-shaped term → files where it's a declared symbol.
|
|
179
|
+
const symFiles = new Map();
|
|
180
|
+
if (opts.notesIndex) {
|
|
181
|
+
for (const t of terms)
|
|
182
|
+
if (isCodeShaped(t))
|
|
183
|
+
symFiles.set(t, resolveTermToSymbolFiles(opts.notesIndex, t));
|
|
184
|
+
}
|
|
185
|
+
const rareMax = rarityMax(notes.length);
|
|
186
|
+
const scored = [];
|
|
187
|
+
for (let i = 0; i < notes.length; i++) {
|
|
188
|
+
const note = notes[i];
|
|
189
|
+
const h = stacks[i];
|
|
190
|
+
let covered = 0;
|
|
191
|
+
let boost = 0;
|
|
192
|
+
let strong = false;
|
|
193
|
+
let strongTerms = 0;
|
|
194
|
+
let convergence = false;
|
|
195
|
+
let rare = false;
|
|
196
|
+
for (let k = 0; k < terms.length; k++) {
|
|
197
|
+
const t = terms[k];
|
|
198
|
+
const inName = hits(h.name, h.nameSquash, t);
|
|
199
|
+
let inAnchor = hits(h.anchor, h.anchorSquash, t);
|
|
200
|
+
// Lane-2 admission (term matches ONLY via the keeper's symbol inventory)
|
|
201
|
+
// stays off in strongOnly: an arbitrary sentence sharing one symbol with
|
|
202
|
+
// a hub anchor file (datatypes.py declares hundreds) is a graze, not a
|
|
203
|
+
// hit — enabling it here produced false implants on the 27q replay. The
|
|
204
|
+
// convergence gate below still uses the inventory, but only to CONFIRM a
|
|
205
|
+
// term the note matched in its own text (two independent channels).
|
|
206
|
+
if (!inAnchor && !opts.strongOnly && termFiles.get(t)?.size) {
|
|
207
|
+
const files = termFiles.get(t);
|
|
208
|
+
inAnchor = note.anchors.some((a) => files.has(a.path));
|
|
209
|
+
}
|
|
210
|
+
const inBody = h.body.includes(norm(t));
|
|
211
|
+
if (!inName && !inAnchor && !inBody)
|
|
212
|
+
continue;
|
|
213
|
+
// Hook-mode term eligibility — the query is an arbitrary English
|
|
214
|
+
// sentence, so a term counts only when it (a) DISCRIMINATES (a word
|
|
215
|
+
// matching half the notebook — "save", "files" — identifies nothing)
|
|
216
|
+
// and (b) matches by shape: a code-shaped term (LoadStaging, file-list,
|
|
217
|
+
// max_files) may substring-match any name/anchor, but a plain English
|
|
218
|
+
// word must whole-word-match the AUTHORED name channel — "error" inside
|
|
219
|
+
// "LoadErrors" or "base" inside "base.py" is a collision, not a hit.
|
|
220
|
+
if (opts.strongOnly) {
|
|
221
|
+
const minority = df[k] === 1 || df[k] * 2 <= notes.length;
|
|
222
|
+
const shapeOk = isCodeShaped(t) ? inName || inAnchor : wordHit(h.nameRaw, t);
|
|
223
|
+
if (!minority || !shapeOk)
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
covered++;
|
|
227
|
+
if (inName || inAnchor) {
|
|
228
|
+
strong = true;
|
|
229
|
+
strongTerms++;
|
|
230
|
+
}
|
|
231
|
+
if (df[k] <= rareMax)
|
|
232
|
+
rare = true;
|
|
233
|
+
const files = symFiles.get(t);
|
|
234
|
+
if (files?.size && note.anchors.some((a) => files.has(a.path)))
|
|
235
|
+
convergence = true;
|
|
236
|
+
if (opts.strongOnly) {
|
|
237
|
+
// Hook mode keeps its calibrated presence·idf boost (unwired in the
|
|
238
|
+
// validation config; kept intact for a possible injection A/B).
|
|
239
|
+
boost += ((inName ? 3 : 0) + (inAnchor ? 2 : 0) + (inBody ? 1 : 0)) * idf(k);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// BM25: term frequency across weighted channels, saturated by k1,
|
|
243
|
+
// normalized by doc length. Lane-2 anchor admission (presence with no
|
|
244
|
+
// text occurrence) counts as one anchor-channel occurrence.
|
|
245
|
+
const wtf = CHANNEL_W.name * countOcc(h.name, h.nameSquash, t) +
|
|
246
|
+
CHANNEL_W.anchor * Math.max(countOcc(h.anchor, h.anchorSquash, t), inAnchor ? 1 : 0) +
|
|
247
|
+
CHANNEL_W.body * countOcc(h.body, '', t);
|
|
248
|
+
const idfB = Math.log(1 + (notes.length - df[k] + 0.5) / (df[k] + 0.5));
|
|
249
|
+
boost += (idfB * (wtf * (BM25_K1 + 1))) / (wtf + BM25_K1 * (1 - BM25_B + (BM25_B * lens[i]) / avgLen));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (!covered)
|
|
253
|
+
continue;
|
|
254
|
+
if (opts.strongOnly && !strong)
|
|
255
|
+
continue; // body-word coverage ≠ a hit on an arbitrary sentence
|
|
256
|
+
scored.push({ note, score: boost, convergence, rare, strongTerms });
|
|
257
|
+
}
|
|
258
|
+
if (!scored.length) {
|
|
259
|
+
if (!opts.noMissLog)
|
|
260
|
+
logMetric(root, 'miss-log', { query, terms, source: opts.source ?? 'tool' });
|
|
261
|
+
return { hits: [], terms, warnings };
|
|
262
|
+
}
|
|
263
|
+
// Freshness NOW for everything scored, then hard-tier: fresh+active first.
|
|
264
|
+
const rareById = new Map(scored.map((s) => [s.note.id, s.rare]));
|
|
265
|
+
const withTier = scored.map(({ note, score, convergence, strongTerms }) => {
|
|
266
|
+
const stamped = stampAnchors(root, note.anchors);
|
|
267
|
+
const stale = stamped.some((s) => s.state === 'changed' || s.state === 'missing');
|
|
268
|
+
const tier = note.status !== 'active' ? 2 : stale ? 1 : 0;
|
|
269
|
+
return { note, score, tier, stamped, absence: absenceVerdict(note, opts.notesIndex), convergence, strongTerms };
|
|
270
|
+
});
|
|
271
|
+
withTier.sort((a, b) => a.tier - b.tier || b.score - a.score || (a.note.id < b.note.id ? -1 : 1));
|
|
272
|
+
// Hook-mode rarity gate (calibrated 2026-07-06, 117-note arches corpus:
|
|
273
|
+
// 27/27 real prompts inject, 8/8 boilerplate probes silent): a top hit
|
|
274
|
+
// matched only by common vocabulary ("list the files", "fix the bug and
|
|
275
|
+
// update the tests") is a graze, and the whole page is suppressed —
|
|
276
|
+
// silence, zero tax. Scale-free (a df ratio, not a score constant), so
|
|
277
|
+
// terse single-symbol prompts still inject and nothing drifts as the
|
|
278
|
+
// corpus grows. Every suppression is metric-logged for re-calibration.
|
|
279
|
+
// The convergence override (HOOK_CONVERGE_MIN) rescues the one measured
|
|
280
|
+
// false-suppression mode: a real task named entirely in common words.
|
|
281
|
+
if (opts.strongOnly && notes.length >= HOOK_FLOOR_MIN_NOTES && withTier.length &&
|
|
282
|
+
!rareById.get(withTier[0].note.id) && withTier[0].strongTerms < HOOK_CONVERGE_MIN) {
|
|
283
|
+
if (!opts.noMissLog)
|
|
284
|
+
logMetric(root, 'inject-log', { query: query.slice(0, 200), suppressed: true, top: withTier[0].note.id, score: Math.round(withTier[0].score * 10) / 10, strongTerms: withTier[0].strongTerms });
|
|
285
|
+
return { hits: [], terms, warnings };
|
|
286
|
+
}
|
|
287
|
+
// Hook mode: hits far below the best are padding (a generic path segment
|
|
288
|
+
// grazing an anchor), not a second answer — don't inject them.
|
|
289
|
+
const trimmed = opts.strongOnly && withTier.length > 1
|
|
290
|
+
? withTier.filter((h) => h.score >= 0.4 * withTier[0].score)
|
|
291
|
+
: withTier;
|
|
292
|
+
// Hits the cap dropped that still clear the results floor — a genuine second
|
|
293
|
+
// page. The footer offers --max only when this is non-zero; a tail trimmed
|
|
294
|
+
// by the floor (not the cap) isn't worth widening for.
|
|
295
|
+
const top = trimmed[0]?.score ?? 0;
|
|
296
|
+
const omitted = trimmed.slice(max).filter((h) => h.score >= RESULTS_FLOOR * top).length;
|
|
297
|
+
return { hits: trimmed.slice(0, max), terms, warnings, omitted, maxUsed: max };
|
|
298
|
+
}
|
|
299
|
+
/** Body section of the rendered md (frontmatter stripped) for inlining. */
|
|
300
|
+
function noteBody(note) {
|
|
301
|
+
const md = renderNote(note);
|
|
302
|
+
const end = md.indexOf('\n---\n', 3);
|
|
303
|
+
return end >= 0 ? md.slice(end + 5).trim() : md.trim();
|
|
304
|
+
}
|
|
305
|
+
/** Implant gate — should the TOP hit's full body ride in the injection?
|
|
306
|
+
*
|
|
307
|
+
* Layered, no absolute score constant (27q calibration, 2026-07-05):
|
|
308
|
+
* 1. convergence — a code-shaped query term is a declared symbol in the
|
|
309
|
+
* note's anchor files (index agrees with text): 11/11 precise at rank 0.
|
|
310
|
+
* 2. dominance — sole surviving hit, or top score ≥ 1.8× the runner-up. A
|
|
311
|
+
* scale-free ratio within one query's own result list; unlike an absolute
|
|
312
|
+
* cut it doesn't drift with notebook size or repo vocabulary.
|
|
313
|
+
* Together: 22/23 relevant implanted, zero false implants on that corpus.
|
|
314
|
+
* Neither fires → gist tier, which is the pre-implant behavior. */
|
|
315
|
+
export function shouldImplantTop(result) {
|
|
316
|
+
const h = result.hits;
|
|
317
|
+
if (!h.length)
|
|
318
|
+
return false;
|
|
319
|
+
if (h[0].convergence)
|
|
320
|
+
return true;
|
|
321
|
+
return h.length === 1 || h[0].score >= 1.8 * h[1].score;
|
|
322
|
+
}
|
|
323
|
+
const gistLines = (hit) => {
|
|
324
|
+
const n = hit.note;
|
|
325
|
+
const kind = n.type === 'lesson' && n.kind ? `/${n.kind}` : '';
|
|
326
|
+
const status = n.status !== 'active' ? ` · ${n.status.toUpperCase()}` : '';
|
|
327
|
+
const changed = hit.stamped.filter((s) => s.state === 'changed' || s.state === 'missing');
|
|
328
|
+
const fresh = !hit.stamped.length ? '' :
|
|
329
|
+
changed.length ? ` · [evidence changed: ${changed.slice(0, 2).map((s) => s.path).join(', ')}${changed.length > 2 ? ` +${changed.length - 2}` : ''}]` :
|
|
330
|
+
hit.stamped.every((s) => s.state === 'fresh') ? ' · anchors [fresh]' : ' · [not fully verified]';
|
|
331
|
+
// Hub file notes carry knowledge in facets, not a body — their gist is the
|
|
332
|
+
// symbol inventory (what the note knows about), not prose.
|
|
333
|
+
const facetGist = n.facets.length ? `facets: ${n.facets.map((f) => f.symbol).join(', ')}` : '';
|
|
334
|
+
const gistSrc = (n.summary || n.body || facetGist || n.invariants[0] || '').replace(/\s+/g, ' ').trim();
|
|
335
|
+
const lines = [`- **${n.title}** [${n.type}${kind}${status}]${fresh}`];
|
|
336
|
+
lines.push(` → open: ${NOTES_REL}/${n.id}.md`);
|
|
337
|
+
// Same preview grade as the kb search results page (user ruling 2026-07-08:
|
|
338
|
+
// precise delivery may not always work — every hit carries enough preview to
|
|
339
|
+
// judge, and depth is one Read of the open: path away). Still never a full
|
|
340
|
+
// body: the boilerplate-poisoning ruling stands.
|
|
341
|
+
let prose = gistSrc;
|
|
342
|
+
if (prose.length > 340)
|
|
343
|
+
prose = prose.slice(0, 340) + '…';
|
|
344
|
+
for (const l of wrapText(prose, 110))
|
|
345
|
+
lines.push(` ${l}`);
|
|
346
|
+
if (hit.absence)
|
|
347
|
+
lines.push(` ${hit.absence}`);
|
|
348
|
+
return lines;
|
|
349
|
+
};
|
|
350
|
+
/** Hook-mode page — PREVIEW GRADE, never full-body (structural ruling
|
|
351
|
+
* 2026-07-06, after the boilerplate-poisoning incident: a wrong full-body
|
|
352
|
+
* implant demotes the right notes; a wrong preview costs one glance).
|
|
353
|
+
* Every hit renders as title + freshness + `→ open:` path + the same
|
|
354
|
+
* ~340-char wrapped preview as the kb search results page (2026-07-08:
|
|
355
|
+
* a lone surgical gist gave the agent nothing to judge it against — q14
|
|
356
|
+
* wrong-prime; candidates with previews let it pick or reject). Full depth
|
|
357
|
+
* is one Read of the open: path. shouldImplantTop stays exported for a
|
|
358
|
+
* future injection A/B. Injected context is re-read every turn, so the
|
|
359
|
+
* page stays small. */
|
|
360
|
+
export function renderCompactPage(query, result) {
|
|
361
|
+
if (!result.hits.length) {
|
|
362
|
+
return `No notebook notes match "${query}". Fall through to \`coldstart find\` as usual.`;
|
|
363
|
+
}
|
|
364
|
+
const lines = [];
|
|
365
|
+
for (const hit of result.hits)
|
|
366
|
+
lines.push(...gistLines(hit));
|
|
367
|
+
return lines.join('\n');
|
|
368
|
+
}
|
|
369
|
+
/** Tool-mode results page — search-engine shape (user ruling 2026-07-08):
|
|
370
|
+
* many ranked results, each title + live freshness + an OPENABLE note-file
|
|
371
|
+
* path + a ~3-line preview. Depth is one Read away, so breadth is cheap and
|
|
372
|
+
* a ranker miss costs a glance, not the answer. The relative score floor
|
|
373
|
+
* drops tail grazes (a generic path segment matching one anchor) that a
|
|
374
|
+
* wider page would otherwise pad with. */
|
|
375
|
+
export function renderResultsPage(query, result) {
|
|
376
|
+
if (!result.hits.length) {
|
|
377
|
+
return `No notebook notes match "${query}". Fall through to \`coldstart find\` as usual.`;
|
|
378
|
+
}
|
|
379
|
+
const shown = result.hits.filter((h) => h.score >= RESULTS_FLOOR * result.hits[0].score);
|
|
380
|
+
const parts = [`# Notebook results for: ${query} (${shown.length} match${shown.length === 1 ? '' : 'es'})`, ''];
|
|
381
|
+
shown.forEach((hit, i) => {
|
|
382
|
+
const n = hit.note;
|
|
383
|
+
const kind = n.type === 'lesson' && n.kind ? `/${n.kind}` : '';
|
|
384
|
+
const changed = hit.stamped.filter((s) => s.state === 'changed' || s.state === 'missing');
|
|
385
|
+
const fresh = n.status !== 'active' ? n.status.toUpperCase() :
|
|
386
|
+
!hit.stamped.length ? 'unverified' :
|
|
387
|
+
changed.length ? `evidence changed: ${changed.slice(0, 2).map((s) => s.path).join(', ')}${changed.length > 2 ? ` +${changed.length - 2}` : ''}` :
|
|
388
|
+
hit.stamped.every((s) => s.state === 'fresh') ? 'fresh' : 'not fully verified';
|
|
389
|
+
parts.push(`${i + 1}. ${n.title} [${n.type}${kind} · ${fresh} · ${n.updated.slice(0, 10)}]`);
|
|
390
|
+
parts.push(` → open: ${NOTES_REL}/${n.id}.md`);
|
|
391
|
+
const facetGist = n.facets.length ? `facets: ${n.facets.map((f) => f.symbol).join(', ')}` : '';
|
|
392
|
+
let prose = (n.summary || n.body || n.invariants[0] || facetGist || '').replace(/\s+/g, ' ').trim();
|
|
393
|
+
if (prose.length > 340)
|
|
394
|
+
prose = prose.slice(0, 340) + '…';
|
|
395
|
+
for (const l of wrapText(prose, 110))
|
|
396
|
+
parts.push(` ${l}`);
|
|
397
|
+
if (hit.absence)
|
|
398
|
+
parts.push(` ${hit.absence}`);
|
|
399
|
+
parts.push('');
|
|
400
|
+
});
|
|
401
|
+
if (result.omitted && result.omitted > 0) {
|
|
402
|
+
const next = (result.maxUsed ?? shown.length) + result.omitted;
|
|
403
|
+
parts.push(`+${result.omitted} more note${result.omitted === 1 ? '' : 's'} matched above the relevance floor but were cut by the result cap — re-run with \`--max ${next}\` to see them.`, '');
|
|
404
|
+
}
|
|
405
|
+
parts.push('Open a result\'s note file (Read/cat) for the full detail — flow steps, invariants, per-symbol facets, exact anchors. ' +
|
|
406
|
+
'Anything marked [evidence changed] must be re-verified against the cited file before you rely on it.');
|
|
407
|
+
return parts.join('\n');
|
|
408
|
+
}
|
|
409
|
+
function wrapText(s, width) {
|
|
410
|
+
if (!s)
|
|
411
|
+
return [];
|
|
412
|
+
const words = s.split(' ');
|
|
413
|
+
const lines = [];
|
|
414
|
+
let cur = '';
|
|
415
|
+
for (const w of words) {
|
|
416
|
+
if (cur && cur.length + 1 + w.length > width) {
|
|
417
|
+
lines.push(cur);
|
|
418
|
+
cur = w;
|
|
419
|
+
}
|
|
420
|
+
else
|
|
421
|
+
cur = cur ? `${cur} ${w}` : w;
|
|
422
|
+
}
|
|
423
|
+
if (cur)
|
|
424
|
+
lines.push(cur);
|
|
425
|
+
return lines;
|
|
426
|
+
}
|
|
427
|
+
/** Full-body page: every hit inlined whole. Kept for `--json` (programmatic
|
|
428
|
+
* consumers get the complete page per hit) — tool mode now renders the
|
|
429
|
+
* search-engine page above. */
|
|
430
|
+
export function renderSearchPage(root, query, result) {
|
|
431
|
+
if (!result.hits.length) {
|
|
432
|
+
return `No notebook notes match "${query}". Fall through to \`coldstart find\` as usual.`;
|
|
433
|
+
}
|
|
434
|
+
const parts = [`# Notebook notes for: ${query}`, ''];
|
|
435
|
+
for (const hit of result.hits) {
|
|
436
|
+
const n = hit.note;
|
|
437
|
+
const kind = n.type === 'lesson' && n.kind ? ` · ${n.kind}` : '';
|
|
438
|
+
parts.push(`## ${n.title} [${n.type}${kind} · ${n.status}]`);
|
|
439
|
+
parts.push(`id: ${n.id} · updated ${n.updated.slice(0, 10)}`);
|
|
440
|
+
if (n.status === 'superseded' && n.supersededBy)
|
|
441
|
+
parts.push(`superseded by: ${n.supersededBy}`);
|
|
442
|
+
if (n.aliases.length)
|
|
443
|
+
parts.push(`aka: ${n.aliases.join(' · ')}`);
|
|
444
|
+
for (const s of hit.stamped)
|
|
445
|
+
parts.push(freshnessLine(s));
|
|
446
|
+
if (hit.absence)
|
|
447
|
+
parts.push(hit.absence);
|
|
448
|
+
parts.push('', noteBody(n), '');
|
|
449
|
+
}
|
|
450
|
+
parts.push('Anything marked [evidence changed] must be re-verified against the file before you rely on it.');
|
|
451
|
+
return parts.join('\n');
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/kb/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { FoldedNote } from './types.js';
|
|
2
|
+
export { notebookDir, rawDir, rawPath } from './raw-log.js';
|
|
3
|
+
export declare function notesDir(root: string): string;
|
|
4
|
+
export declare function notePath(root: string, id: string): string;
|
|
5
|
+
export declare function metricsDir(root: string): string;
|
|
6
|
+
export declare function notebookExists(root: string): boolean;
|
|
7
|
+
/** Create the on-disk skeleton (idempotent). Does NOT touch hooks/coldstart.md —
|
|
8
|
+
* that is `kb init`'s wiring layer. */
|
|
9
|
+
export declare function initSkeleton(root: string): void;
|
|
10
|
+
export interface LoadResult {
|
|
11
|
+
notes: FoldedNote[];
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Fold one note from its `.raw` log. null when the log is absent/empty. */
|
|
15
|
+
export declare function loadNote(root: string, id: string): {
|
|
16
|
+
note: FoldedNote | null;
|
|
17
|
+
warnings: string[];
|
|
18
|
+
};
|
|
19
|
+
/** Fold every note in the notebook. Search consumes THIS — md is never load-bearing. */
|
|
20
|
+
export declare function loadAll(root: string): LoadResult;
|
|
21
|
+
/** Render one folded note to its derived md file. */
|
|
22
|
+
export declare function writeNoteMd(root: string, note: FoldedNote): string;
|
|
23
|
+
/** Re-fold + re-render the given ids (or all). Returns rendered ids. */
|
|
24
|
+
export declare function renderIds(root: string, ids?: string[]): string[];
|
|
25
|
+
/**
|
|
26
|
+
* The notebook's table of contents — `notes/_index.md`, one line per active
|
|
27
|
+
* note, regenerated mechanically on every write/render (never by an LLM).
|
|
28
|
+
* The wiki-entrypoint pattern: an agent reads this page first and follows
|
|
29
|
+
* links, so retrieval works even with zero search. Leading underscore keeps
|
|
30
|
+
* it outside the note-id namespace (ids must start [a-z0-9]).
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeIndexMd(root: string): string;
|
|
33
|
+
/** Append a metrics event (miss-log, capture, inject decisions). Best-effort, never throws. */
|
|
34
|
+
export declare function logMetric(root: string, file: 'miss-log' | 'capture' | 'inject-log', event: Record<string, unknown>): void;
|
|
35
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/kb/store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AACD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzD;AACD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;wCACwC;AACxC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQ/C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAKD,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAgBlG;AAED,wFAAwF;AACxF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAShD;AAYD,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,CAMlE;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWhE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA8BjD;AAED,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,SAAS,GAAG,YAAY,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAOzH"}
|