@plebeiantech/lat.md 0.12.3-fork.15 → 0.12.3-fork.17
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 +1 -1
- package/dist/src/cli/checklist-menu.d.ts +2 -1
- package/dist/src/cli/checklist-menu.js +3 -2
- package/dist/src/cli/index.js +59 -16
- package/dist/src/cli/init-preferences.d.ts +4 -0
- package/dist/src/cli/init-preferences.js +35 -0
- package/dist/src/cli/init.js +10 -5
- package/dist/src/cli/reindex.js +4 -8
- package/dist/src/cli/search.d.ts +3 -2
- package/dist/src/cli/search.js +71 -66
- package/dist/src/cli/ui-build-server.d.ts +12 -0
- package/dist/src/cli/ui-build-server.js +26 -0
- package/dist/src/cli/ui-build.js +1 -1
- package/dist/src/cli/ui.js +1 -1
- package/dist/src/format.d.ts +5 -0
- package/dist/src/format.js +32 -4
- package/dist/src/lattice-model.d.ts +8 -1
- package/dist/src/lattice-model.js +4 -1
- package/dist/src/lattice.d.ts +2 -2
- package/dist/src/lattice.js +17 -34
- package/dist/src/markdown-analysis.d.ts +11 -0
- package/dist/src/markdown-analysis.js +31 -1
- package/dist/src/mcp/server.js +6 -6
- package/dist/src/parser-cache.d.ts +1 -1
- package/dist/src/parser-cache.js +1 -1
- package/dist/src/search/cache.d.ts +3 -0
- package/dist/src/search/cache.js +71 -0
- package/dist/src/search/chunks.d.ts +23 -0
- package/dist/src/search/chunks.js +197 -0
- package/dist/src/search/db.d.ts +27 -16
- package/dist/src/search/db.js +108 -38
- package/dist/src/search/index.d.ts +5 -2
- package/dist/src/search/index.js +173 -69
- package/dist/src/search/lexical.d.ts +6 -0
- package/dist/src/search/lexical.js +36 -0
- package/dist/src/search/lock.d.ts +2 -0
- package/dist/src/search/lock.js +23 -0
- package/dist/src/search/query.d.ts +6 -3
- package/dist/src/search/query.js +45 -26
- package/dist/src/search/search.d.ts +13 -8
- package/dist/src/search/search.js +155 -23
- package/dist/src/search/types.d.ts +31 -0
- package/dist/src/search/types.js +1 -0
- package/dist/src/source-formats.d.ts +1 -1
- package/dist/src/source-formats.js +4 -0
- package/dist/src/source-parser.js +397 -1
- package/dist/src/view/client/assets/GraphView-BWlRdQM4.js +456 -0
- package/dist/src/view/client/assets/{MarkdownEditor-B7quqPb8.js → MarkdownEditor-MW-Ck1O0.js} +8 -8
- package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-Bn3RshMV.js +1 -0
- package/dist/src/view/client/assets/{arc-BnwR8Bu7.js → arc-En9tdFQF.js} +1 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-B-9J1VAM.js +36 -0
- package/dist/src/view/client/assets/{blockDiagram-I7D4REHJ-DETl8e_H.js → blockDiagram-I7D4REHJ-QlznwalP.js} +2 -2
- package/dist/src/view/client/assets/{c4Diagram-7LVT6UL2-DJRAT1Ve.js → c4Diagram-7LVT6UL2-Bp2y8B4_.js} +2 -2
- package/dist/src/view/client/assets/channel-uy0fFvcW.js +1 -0
- package/dist/src/view/client/assets/{chunk-2Q5K7J3B-C0TmOC1Q.js → chunk-2Q5K7J3B-CnBKL-lm.js} +1 -1
- package/dist/src/view/client/assets/{chunk-5VM5RSS4-dfBOrYE6.js → chunk-5VM5RSS4-LLYMi_n6.js} +1 -1
- package/dist/src/view/client/assets/{chunk-F27PBJKO-DAnks99K.js → chunk-F27PBJKO-VIeO7VF0.js} +1 -1
- package/dist/src/view/client/assets/{chunk-IMKFNOWR-CPjB07if.js → chunk-IMKFNOWR-D5i67DVD.js} +1 -1
- package/dist/src/view/client/assets/{chunk-JWPE2WC7-VvU_gZI6.js → chunk-JWPE2WC7-D4qAtoL3.js} +1 -1
- package/dist/src/view/client/assets/{chunk-POPQ4Y6H-DDUbVF55.js → chunk-POPQ4Y6H-BMzOyiW_.js} +1 -1
- package/dist/src/view/client/assets/{chunk-SVP7TREG-BHROkr6D.js → chunk-SVP7TREG-DWy5nbfp.js} +1 -1
- package/dist/src/view/client/assets/{chunk-TICWLB2K-95PzGIOg.js → chunk-TICWLB2K-CVqCANFB.js} +1 -1
- package/dist/src/view/client/assets/{chunk-XXDRQBXY-MdmuLhIs.js → chunk-XXDRQBXY-Bp23h6Tf.js} +1 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-DbSEqjA5.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-DbSEqjA5.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-BCw7fCC2.js +1 -0
- package/dist/src/view/client/assets/{cynefin-OW5HDTMX-CeA8IKWo.js → cynefin-OW5HDTMX--lYN4N9m.js} +1 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-9sK5EV7v.js +62 -0
- package/dist/src/view/client/assets/{dagre-GXQ25YYZ-DLQwTa3H.js → dagre-GXQ25YYZ-CoMdEFCq.js} +2 -2
- package/dist/src/view/client/assets/{diagram-S7CK7UJ4-kbKdIyXG.js → diagram-S7CK7UJ4-D13dyWdd.js} +2 -2
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-PdwLPPPA.js +41 -0
- package/dist/src/view/client/assets/{diagram-VSXAHHWV-EXJTU8qq.js → diagram-VSXAHHWV-CtWWa_A7.js} +2 -2
- package/dist/src/view/client/assets/diagram-VX7I27RA-BeCYcSU-.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-DiWabOBM.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-CZQ3MD_K.js +1 -0
- package/dist/src/view/client/assets/{erDiagram-RLTQ6QDP-C925J5A3.js → erDiagram-RLTQ6QDP-B1AhXIrP.js} +2 -2
- package/dist/src/view/client/assets/{flowDiagram-HODETNUW-DzoCa-Nq.js → flowDiagram-HODETNUW-Bhr0JM6P.js} +1 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-CbP8iAkg.js +292 -0
- package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B9uuGdLF.js +106 -0
- package/dist/src/view/client/assets/index-DG0Ez15D.css +1 -0
- package/dist/src/view/client/assets/index-nBmbYfun.js +13 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-BrfwQ_Cq.js +2 -0
- package/dist/src/view/client/assets/{ishikawaDiagram-5VMMS53U-CW4mto2d.js → ishikawaDiagram-5VMMS53U-CHtJ36re.js} +2 -2
- package/dist/src/view/client/assets/{journeyDiagram-3NMN7TZE-8R4eacFW.js → journeyDiagram-3NMN7TZE-BChcgX1s.js} +2 -2
- package/dist/src/view/client/assets/{kanban-definition-UXKFOSKX-Cy9ioXEJ.js → kanban-definition-UXKFOSKX-BnwFsKiB.js} +6 -6
- package/dist/src/view/client/assets/{layout-C0MFuhth.js → layout-Dnd0pLdb.js} +1 -1
- package/dist/src/view/client/assets/{linear-Dv3N4dQR.js → linear-CFhW2ozn.js} +1 -1
- package/dist/src/view/client/assets/{maplibre-gl-DnqZgfUS.js → maplibre-gl-CDX6Zuow.js} +1 -1
- package/dist/src/view/client/assets/{mermaid.core-bds9A7e2.js → mermaid.core--OP6lXtW.js} +11 -11
- package/dist/src/view/client/assets/{mindmap-definition-YA3MSWOX-DjmGW355.js → mindmap-definition-YA3MSWOX-D51y2zbm.js} +2 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB--zyQJDvI.js +1 -0
- package/dist/src/view/client/assets/{pieDiagram-E7YTZNPT-CCH2gGR-.js → pieDiagram-E7YTZNPT-Cj8mvpJy.js} +2 -2
- package/dist/src/view/client/assets/{quadrantDiagram-AXDQQJYC-CjocPJFz.js → quadrantDiagram-AXDQQJYC-qvhJrnBf.js} +4 -4
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-CtWvxpSo.js +1 -0
- package/dist/src/view/client/assets/{requirementDiagram-BXWQKSXE-Ct6AoXRr.js → requirementDiagram-BXWQKSXE-CBxen_KG.js} +2 -2
- package/dist/src/view/client/assets/{sankeyDiagram-P5KCCOFB-CIpgGN_w.js → sankeyDiagram-P5KCCOFB-B_fUkmfc.js} +2 -2
- package/dist/src/view/client/assets/{sequenceDiagram-WJ2MYXX4-DrmLFj6w.js → sequenceDiagram-WJ2MYXX4-Dclv4p68.js} +2 -2
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-GfG0sMTZ.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-YQWPnzxU.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-gUj6Hzgl.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-5yiCveVS.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-DR7JhrxL.js +8 -0
- package/dist/src/view/client/assets/{timeline-definition-24CTP7MA-BExPu6X5.js → timeline-definition-24CTP7MA-BvAbB5Zs.js} +2 -2
- package/dist/src/view/client/assets/{vennDiagram-4TSXK5OY-PC1MU3si.js → vennDiagram-4TSXK5OY-guC-r60n.js} +2 -2
- package/dist/src/view/client/assets/{wardleyDiagram-VM6X3IG4-DNWqU3fa.js → wardleyDiagram-VM6X3IG4-C0yXcU2x.js} +2 -2
- package/dist/src/view/client/assets/{xychartDiagram-S5SC5T6Z-E1uA28_D.js → xychartDiagram-S5SC5T6Z-RPmkPNfK.js} +2 -2
- package/dist/src/view/client/index.html +2 -2
- package/dist/src/view/document-route.d.ts +2 -0
- package/dist/src/view/document-route.js +40 -7
- package/dist/src/view/graph.d.ts +2 -2
- package/dist/src/view/graph.js +7 -3
- package/dist/src/view/highlight.js +207 -203
- package/dist/src/view/markdown.js +19 -0
- package/dist/src/view/preindexed-search.d.ts +15 -0
- package/dist/src/view/preindexed-search.js +25 -0
- package/dist/src/view/protocol.d.ts +10 -1
- package/dist/src/view/references.js +6 -7
- package/dist/src/view/repository.js +10 -2
- package/dist/src/view/search-result.d.ts +4 -0
- package/dist/src/view/search-result.js +25 -0
- package/dist/src/view/search.d.ts +7 -2
- package/dist/src/view/search.js +23 -30
- package/dist/src/view/server-build.d.ts +21 -0
- package/dist/src/view/server-build.js +145 -0
- package/dist/src/view/server-deployment.d.ts +32 -0
- package/dist/src/view/server-deployment.js +134 -0
- package/dist/src/view/server-index-worker.d.ts +6 -0
- package/dist/src/view/server-index-worker.js +14 -0
- package/dist/src/view/server.js +25 -7
- package/dist/src/view/source-target.d.ts +2 -0
- package/dist/src/view/source-target.js +24 -0
- package/dist/src/view/static-build.d.ts +16 -1
- package/dist/src/view/static-build.js +187 -89
- package/dist/src/view/static-protocol.d.ts +7 -0
- package/dist/src/view/static-protocol.js +5 -0
- package/dist/src/view/store.js +17 -7
- package/dist/src/view/vercel-build.d.ts +24 -0
- package/dist/src/view/vercel-build.js +140 -0
- package/dist/src/view/vercel-server-build.d.ts +10 -0
- package/dist/src/view/vercel-server-build.js +61 -0
- package/dist/vendor/lat.md-server/index.d.ts +1 -1
- package/dist/vendor/lat.md-server/index.js +1 -1
- package/package.json +20 -5
- package/templates/AGENTS.md +1 -1
- package/templates/cursor-rules.md +1 -1
- package/templates/skill/SKILL.md +1 -1
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-V7-T6qsl.js +0 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +0 -36
- package/dist/src/view/client/assets/channel-BwQbnWCN.js +0 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +0 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +0 -62
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +0 -41
- package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +0 -24
- package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +0 -24
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +0 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +0 -292
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +0 -106
- package/dist/src/view/client/assets/index-D0ajr_Ja.css +0 -1
- package/dist/src/view/client/assets/index-KZcnpXJH.js +0 -321
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +0 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +0 -1
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +0 -1
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +0 -1
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +0 -1
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +0 -8
- /package/dist/src/view/client/assets/{logo-small-RR_KBOAT.svg → logo-RR_KBOAT.svg} +0 -0
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SearchDb } from './db.js';
|
|
2
2
|
import type { Embedder } from './embedder.js';
|
|
3
|
+
import type { SearchResult } from './types.js';
|
|
4
|
+
export type { SearchResult, SearchEvidence, SearchDiagnostics, } from './types.js';
|
|
3
5
|
export declare const DEFAULT_SEARCH_LIMIT = 5;
|
|
4
|
-
export declare const
|
|
5
|
-
export type
|
|
6
|
-
id:
|
|
7
|
-
|
|
8
|
-
heading: string;
|
|
9
|
-
content: string;
|
|
6
|
+
export declare const DEFAULT_MIN_SIMILARITY = 0.2;
|
|
7
|
+
export type Candidate = {
|
|
8
|
+
id: number;
|
|
9
|
+
sectionId: string;
|
|
10
10
|
score: number;
|
|
11
|
+
exact?: boolean;
|
|
11
12
|
};
|
|
12
|
-
export declare function
|
|
13
|
+
export declare function collapse(candidates: Candidate[]): Map<string, Candidate & {
|
|
14
|
+
rank: number;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function literalFtsQuery(query: string): string;
|
|
17
|
+
export declare function searchSections(db: SearchDb, query: string, embedder: Embedder, limit?: number, minSimilarity?: number): Promise<SearchResult[]>;
|
|
@@ -1,25 +1,157 @@
|
|
|
1
|
+
import { lexicalTokens } from './lexical.js';
|
|
1
2
|
export const DEFAULT_SEARCH_LIMIT = 5;
|
|
2
|
-
export const
|
|
3
|
-
export
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
export const DEFAULT_MIN_SIMILARITY = 0.2;
|
|
4
|
+
export function collapse(candidates) {
|
|
5
|
+
const unique = new Map();
|
|
6
|
+
for (const c of candidates)
|
|
7
|
+
if (!unique.has(c.sectionId))
|
|
8
|
+
unique.set(c.sectionId, c);
|
|
9
|
+
let rank = 0, previous;
|
|
10
|
+
return new Map([...unique].map(([id, c]) => {
|
|
11
|
+
if (!previous ||
|
|
12
|
+
c.score !== previous.score ||
|
|
13
|
+
!!c.exact !== !!previous.exact)
|
|
14
|
+
rank++;
|
|
15
|
+
previous = c;
|
|
16
|
+
return [id, { ...c, rank }];
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
export function literalFtsQuery(query) {
|
|
20
|
+
const stopwords = new Set('a an and are as at be by do does for from how i in is it of on or our that the their this to we what when where which who why with you your use uses used have has had can could would should'.split(' '));
|
|
21
|
+
return (query.match(/[\p{L}\p{N}_]+/gu) ?? [])
|
|
22
|
+
.filter((t) => !stopwords.has(t.toLowerCase()))
|
|
23
|
+
.flatMap((t) => lexicalTokens(t))
|
|
24
|
+
.map((t) => `"${t.replaceAll('"', '\\"')}"`)
|
|
25
|
+
.join(' OR ');
|
|
26
|
+
}
|
|
27
|
+
export async function searchSections(db, query, embedder, limit = DEFAULT_SEARCH_LIMIT, minSimilarity = DEFAULT_MIN_SIMILARITY) {
|
|
28
|
+
query = query.trim();
|
|
29
|
+
if (!query)
|
|
30
|
+
return [];
|
|
31
|
+
if (!Number.isInteger(limit) || limit < 1)
|
|
32
|
+
throw new Error('limit must be a positive integer');
|
|
33
|
+
if (!Number.isFinite(minSimilarity) || minSimilarity < 0 || minSimilarity > 1)
|
|
34
|
+
throw new Error('min-similarity must be a number from 0 to 1');
|
|
35
|
+
if (embedder.countTokens(query) > embedder.maxInputTokens)
|
|
36
|
+
throw new Error('Search query exceeds the embedding model token limit; shorten the query.');
|
|
37
|
+
const [vector] = await embedder.embed([query]);
|
|
38
|
+
if (!vector ||
|
|
39
|
+
vector.length !== embedder.dimensions ||
|
|
40
|
+
vector.some((n) => !Number.isFinite(n)))
|
|
41
|
+
throw new Error('Embedding backend returned an invalid query vector');
|
|
42
|
+
const vectorJson = JSON.stringify(vector), fts = literalFtsQuery(query);
|
|
43
|
+
const target = Math.max(50, limit), cap = 10 * target;
|
|
44
|
+
const owners = new Map((await db.execute('SELECT id,section_id FROM chunks')).rows.map((r) => [
|
|
45
|
+
r.id,
|
|
46
|
+
r.section_id,
|
|
47
|
+
]));
|
|
48
|
+
const exactRows = (await db.execute({
|
|
49
|
+
sql: 'SELECT chunk_id FROM identifiers WHERE token=? LIMIT ?',
|
|
50
|
+
args: [query.toLowerCase(), cap],
|
|
51
|
+
})).rows;
|
|
52
|
+
const exact = exactRows.map((r) => ({
|
|
53
|
+
id: r.chunk_id,
|
|
54
|
+
sectionId: owners.get(r.chunk_id),
|
|
55
|
+
score: 0,
|
|
56
|
+
exact: true,
|
|
57
|
+
}));
|
|
58
|
+
async function retrieve(channel) {
|
|
59
|
+
let count = 2 * target, candidates = [], capped = false;
|
|
60
|
+
while (true) {
|
|
61
|
+
const rows = channel === 'lexical'
|
|
62
|
+
? fts
|
|
63
|
+
? (await db.execute({
|
|
64
|
+
sql: 'SELECT id,fts_score(body,heading,path,?) AS score FROM lexical_chunks ORDER BY score DESC LIMIT ?',
|
|
65
|
+
args: [fts, count],
|
|
66
|
+
})).rows
|
|
67
|
+
: []
|
|
68
|
+
: (await db.execute({
|
|
69
|
+
sql: 'SELECT c.id,1-vector_distance_cos(e.embedding,vector32(?)) AS score FROM chunks c JOIN embeddings e ON c.input_hash=e.hash ORDER BY score DESC LIMIT ?',
|
|
70
|
+
args: [vectorJson, count],
|
|
71
|
+
})).rows;
|
|
72
|
+
const hits = rows
|
|
73
|
+
.filter((r) => channel === 'lexical' ? r.score > 0 : r.score >= minSimilarity)
|
|
74
|
+
.map((r) => ({
|
|
75
|
+
id: r.id,
|
|
76
|
+
sectionId: owners.get(r.id),
|
|
77
|
+
score: Number(r.score),
|
|
78
|
+
}));
|
|
79
|
+
if (channel === 'lexical') {
|
|
80
|
+
const exactIds = new Set(exact.map((c) => c.id));
|
|
81
|
+
candidates = [...exact, ...hits.filter((c) => !exactIds.has(c.id))];
|
|
82
|
+
}
|
|
83
|
+
else
|
|
84
|
+
candidates = hits;
|
|
85
|
+
candidates.sort((a, b) => Number(!!b.exact) - Number(!!a.exact) ||
|
|
86
|
+
b.score - a.score ||
|
|
87
|
+
a.sectionId.localeCompare(b.sectionId) ||
|
|
88
|
+
a.id - b.id);
|
|
89
|
+
if (new Set(candidates.map((c) => c.sectionId)).size >= target ||
|
|
90
|
+
rows.length < count ||
|
|
91
|
+
hits.length < rows.length ||
|
|
92
|
+
!rows.length)
|
|
93
|
+
break;
|
|
94
|
+
if (count >= cap) {
|
|
95
|
+
capped = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
count = Math.min(cap, count * 2);
|
|
99
|
+
}
|
|
100
|
+
return { list: collapse(candidates), capped, count: candidates.length };
|
|
101
|
+
}
|
|
102
|
+
const lexical = await retrieve('lexical'), semantic = await retrieve('semantic');
|
|
103
|
+
const all = new Set([...lexical.list.keys(), ...semantic.list.keys()]);
|
|
104
|
+
const ranked = [...all]
|
|
105
|
+
.map((id) => ({ id, l: lexical.list.get(id), v: semantic.list.get(id) }))
|
|
106
|
+
.map((r) => ({
|
|
107
|
+
...r,
|
|
108
|
+
rankScore: (r.l ? 1 / (60 + r.l.rank) : 0) + (r.v ? 1 / (60 + r.v.rank) : 0),
|
|
109
|
+
}))
|
|
110
|
+
.sort((a, b) => b.rankScore - a.rankScore || a.id.localeCompare(b.id))
|
|
111
|
+
.slice(0, limit);
|
|
112
|
+
const results = [];
|
|
113
|
+
for (const r of ranked) {
|
|
114
|
+
const s = (await db.execute({
|
|
115
|
+
sql: 'SELECT * FROM sections WHERE id=?',
|
|
116
|
+
args: [r.id],
|
|
117
|
+
})).rows[0];
|
|
118
|
+
if (!s)
|
|
119
|
+
continue;
|
|
120
|
+
const channels = [
|
|
121
|
+
...(r.l ? [{ candidate: r.l, channel: 'lexical' }] : []),
|
|
122
|
+
...(r.v ? [{ candidate: r.v, channel: 'semantic' }] : []),
|
|
123
|
+
].sort((a, b) => a.candidate.rank - b.candidate.rank);
|
|
124
|
+
const seen = new Set(), evidence = [];
|
|
125
|
+
for (const { candidate, channel } of channels)
|
|
126
|
+
if (!seen.has(candidate.id)) {
|
|
127
|
+
seen.add(candidate.id);
|
|
128
|
+
const p = (await db.execute({
|
|
129
|
+
sql: 'SELECT source_id,body,spans FROM chunks WHERE id=?',
|
|
130
|
+
args: [candidate.id],
|
|
131
|
+
})).rows[0];
|
|
132
|
+
evidence.push({
|
|
133
|
+
chunkId: p.source_id,
|
|
134
|
+
text: p.body,
|
|
135
|
+
spans: JSON.parse(p.spans),
|
|
136
|
+
channel,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
results.push({
|
|
140
|
+
id: s.id,
|
|
141
|
+
file: s.file,
|
|
142
|
+
heading: s.heading,
|
|
143
|
+
content: s.content,
|
|
144
|
+
rankScore: r.rankScore,
|
|
145
|
+
...(r.v ? { semanticSimilarity: r.v.score, semanticRank: r.v.rank } : {}),
|
|
146
|
+
...(r.l ? { lexicalScore: r.l.score, lexicalRank: r.l.rank } : {}),
|
|
147
|
+
evidence,
|
|
148
|
+
diagnostics: {
|
|
149
|
+
lexicalCapped: lexical.capped,
|
|
150
|
+
semanticCapped: semantic.capped,
|
|
151
|
+
lexicalCandidates: lexical.count,
|
|
152
|
+
semanticCandidates: semantic.count,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return results;
|
|
25
157
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type SourceSpan = {
|
|
2
|
+
start: number;
|
|
3
|
+
end: number;
|
|
4
|
+
startLine: number;
|
|
5
|
+
endLine: number;
|
|
6
|
+
};
|
|
7
|
+
export type SearchEvidence = {
|
|
8
|
+
chunkId: string;
|
|
9
|
+
text: string;
|
|
10
|
+
spans: SourceSpan[];
|
|
11
|
+
channel: 'lexical' | 'semantic';
|
|
12
|
+
};
|
|
13
|
+
export type SearchDiagnostics = {
|
|
14
|
+
lexicalCapped: boolean;
|
|
15
|
+
semanticCapped: boolean;
|
|
16
|
+
lexicalCandidates: number;
|
|
17
|
+
semanticCandidates: number;
|
|
18
|
+
};
|
|
19
|
+
export type SearchResult = {
|
|
20
|
+
id: string;
|
|
21
|
+
file: string;
|
|
22
|
+
heading: string;
|
|
23
|
+
content: string;
|
|
24
|
+
rankScore: number;
|
|
25
|
+
semanticSimilarity?: number;
|
|
26
|
+
semanticRank?: number;
|
|
27
|
+
lexicalScore?: number;
|
|
28
|
+
lexicalRank?: number;
|
|
29
|
+
evidence: SearchEvidence[];
|
|
30
|
+
diagnostics: SearchDiagnostics;
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Source file extensions supported by Lat's parser and code-reference scan. */
|
|
2
|
-
export declare const SOURCE_FILE_EXTENSIONS: readonly [".c", ".dart", ".go", ".h", ".java", ".js", ".jsx", ".py", ".rs", ".ts", ".tsx"];
|
|
2
|
+
export declare const SOURCE_FILE_EXTENSIONS: readonly [".c", ".dart", ".erb", ".go", ".h", ".java", ".js", ".jsx", ".php", ".py", ".rake", ".rb", ".rs", ".ts", ".tsx"];
|
|
3
3
|
/** A source extension supported everywhere Lat accepts source files. */
|
|
4
4
|
export type SourceFileExtension = (typeof SOURCE_FILE_EXTENSIONS)[number];
|
|
5
5
|
export declare function isSourceFileExtension(extension: string): extension is SourceFileExtension;
|