mindlore 0.6.1 → 0.6.3
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 +661 -21
- package/README.md +3 -3
- package/dist/scripts/cc-session-sync.d.ts +2 -0
- package/dist/scripts/cc-session-sync.d.ts.map +1 -1
- package/dist/scripts/cc-session-sync.js +56 -0
- package/dist/scripts/cc-session-sync.js.map +1 -1
- package/dist/scripts/fetch-raw.js +133 -8
- package/dist/scripts/fetch-raw.js.map +1 -1
- package/dist/scripts/init.js +28 -43
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/chunker.d.ts +12 -0
- package/dist/scripts/lib/chunker.d.ts.map +1 -0
- package/dist/scripts/lib/chunker.js +94 -0
- package/dist/scripts/lib/chunker.js.map +1 -0
- package/dist/scripts/lib/episodes.d.ts +1 -1
- package/dist/scripts/lib/episodes.d.ts.map +1 -1
- package/dist/scripts/lib/episodes.js +1 -1
- package/dist/scripts/lib/episodes.js.map +1 -1
- package/dist/scripts/lib/fuzzy.d.ts +10 -0
- package/dist/scripts/lib/fuzzy.d.ts.map +1 -0
- package/dist/scripts/lib/fuzzy.js +88 -0
- package/dist/scripts/lib/fuzzy.js.map +1 -0
- package/dist/scripts/lib/hybrid-search.d.ts +1 -0
- package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
- package/dist/scripts/lib/hybrid-search.js.map +1 -1
- package/dist/scripts/lib/merge-defaults.d.ts +5 -0
- package/dist/scripts/lib/merge-defaults.d.ts.map +1 -0
- package/dist/scripts/lib/merge-defaults.js +25 -0
- package/dist/scripts/lib/merge-defaults.js.map +1 -0
- package/dist/scripts/lib/migrations-v062.d.ts +3 -0
- package/dist/scripts/lib/migrations-v062.d.ts.map +1 -0
- package/dist/scripts/lib/migrations-v062.js +35 -0
- package/dist/scripts/lib/migrations-v062.js.map +1 -0
- package/dist/scripts/lib/migrations-v063.d.ts +7 -0
- package/dist/scripts/lib/migrations-v063.d.ts.map +1 -0
- package/dist/scripts/lib/migrations-v063.js +58 -0
- package/dist/scripts/lib/migrations-v063.js.map +1 -0
- package/dist/scripts/lib/proximity.d.ts +3 -0
- package/dist/scripts/lib/proximity.d.ts.map +1 -0
- package/dist/scripts/lib/proximity.js +53 -0
- package/dist/scripts/lib/proximity.js.map +1 -0
- package/dist/scripts/lib/rrf.d.ts +23 -0
- package/dist/scripts/lib/rrf.d.ts.map +1 -0
- package/dist/scripts/lib/rrf.js +63 -0
- package/dist/scripts/lib/rrf.js.map +1 -0
- package/dist/scripts/lib/search-cache.d.ts +20 -0
- package/dist/scripts/lib/search-cache.d.ts.map +1 -0
- package/dist/scripts/lib/search-cache.js +60 -0
- package/dist/scripts/lib/search-cache.js.map +1 -0
- package/dist/scripts/lib/search-engine.d.ts +22 -0
- package/dist/scripts/lib/search-engine.d.ts.map +1 -0
- package/dist/scripts/lib/search-engine.js +105 -0
- package/dist/scripts/lib/search-engine.js.map +1 -0
- package/dist/scripts/lib/session-payload.d.ts +2 -4
- package/dist/scripts/lib/session-payload.d.ts.map +1 -1
- package/dist/scripts/lib/session-payload.js +43 -43
- package/dist/scripts/lib/session-payload.js.map +1 -1
- package/dist/scripts/lib/snippet.d.ts +2 -0
- package/dist/scripts/lib/snippet.d.ts.map +1 -0
- package/dist/scripts/lib/snippet.js +32 -0
- package/dist/scripts/lib/snippet.js.map +1 -0
- package/dist/scripts/lib/triage.d.ts +18 -0
- package/dist/scripts/lib/triage.d.ts.map +1 -0
- package/dist/scripts/lib/triage.js +81 -0
- package/dist/scripts/lib/triage.js.map +1 -0
- package/dist/scripts/mindlore-doctor.d.ts +1 -0
- package/dist/scripts/mindlore-doctor.d.ts.map +1 -1
- package/dist/scripts/mindlore-doctor.js +26 -1
- package/dist/scripts/mindlore-doctor.js.map +1 -1
- package/dist/scripts/mindlore-fts5-index.js +44 -3
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-fts5-search.d.ts +3 -5
- package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -1
- package/dist/scripts/mindlore-fts5-search.js +41 -116
- package/dist/scripts/mindlore-fts5-search.js.map +1 -1
- package/dist/scripts/mindlore-health-check.d.ts +10 -0
- package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
- package/dist/scripts/mindlore-health-check.js +26 -1
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/scripts/mindlore-perf.d.ts +3 -3
- package/dist/scripts/mindlore-perf.d.ts.map +1 -1
- package/dist/scripts/mindlore-perf.js +10 -8
- package/dist/scripts/mindlore-perf.js.map +1 -1
- package/dist/tests/chunker.test.d.ts +2 -0
- package/dist/tests/chunker.test.d.ts.map +1 -0
- package/dist/tests/chunker.test.js +40 -0
- package/dist/tests/chunker.test.js.map +1 -0
- package/dist/tests/chunks-migration.test.d.ts +2 -0
- package/dist/tests/chunks-migration.test.d.ts.map +1 -0
- package/dist/tests/chunks-migration.test.js +55 -0
- package/dist/tests/chunks-migration.test.js.map +1 -0
- package/dist/tests/compaction-snapshot.test.d.ts +2 -0
- package/dist/tests/compaction-snapshot.test.d.ts.map +1 -0
- package/dist/tests/compaction-snapshot.test.js +102 -0
- package/dist/tests/compaction-snapshot.test.js.map +1 -0
- package/dist/tests/daemon-integration.test.js +5 -5
- package/dist/tests/daemon-integration.test.js.map +1 -1
- package/dist/tests/diary.test.js +3 -3
- package/dist/tests/diary.test.js.map +1 -1
- package/dist/tests/doctor.test.js +13 -0
- package/dist/tests/doctor.test.js.map +1 -1
- package/dist/tests/fetch-raw.test.js +12 -5
- package/dist/tests/fetch-raw.test.js.map +1 -1
- package/dist/tests/fuzzy.test.d.ts +2 -0
- package/dist/tests/fuzzy.test.d.ts.map +1 -0
- package/dist/tests/fuzzy.test.js +70 -0
- package/dist/tests/fuzzy.test.js.map +1 -0
- package/dist/tests/health-check-memory.test.js +27 -0
- package/dist/tests/health-check-memory.test.js.map +1 -1
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js +4 -1
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/init.test.js +20 -0
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/merge-defaults.test.d.ts +2 -0
- package/dist/tests/merge-defaults.test.d.ts.map +1 -0
- package/dist/tests/merge-defaults.test.js +35 -0
- package/dist/tests/merge-defaults.test.js.map +1 -0
- package/dist/tests/migrations-v062.test.d.ts +2 -0
- package/dist/tests/migrations-v062.test.d.ts.map +1 -0
- package/dist/tests/migrations-v062.test.js +61 -0
- package/dist/tests/migrations-v062.test.js.map +1 -0
- package/dist/tests/migrations-v063.test.d.ts +2 -0
- package/dist/tests/migrations-v063.test.d.ts.map +1 -0
- package/dist/tests/migrations-v063.test.js +84 -0
- package/dist/tests/migrations-v063.test.js.map +1 -0
- package/dist/tests/nomination.test.js +1 -1
- package/dist/tests/proximity.test.d.ts +2 -0
- package/dist/tests/proximity.test.d.ts.map +1 -0
- package/dist/tests/proximity.test.js +31 -0
- package/dist/tests/proximity.test.js.map +1 -0
- package/dist/tests/rrf.test.d.ts +2 -0
- package/dist/tests/rrf.test.d.ts.map +1 -0
- package/dist/tests/rrf.test.js +100 -0
- package/dist/tests/rrf.test.js.map +1 -0
- package/dist/tests/savings.test.d.ts +2 -0
- package/dist/tests/savings.test.d.ts.map +1 -0
- package/dist/tests/savings.test.js +87 -0
- package/dist/tests/savings.test.js.map +1 -0
- package/dist/tests/search-cache.test.d.ts +2 -0
- package/dist/tests/search-cache.test.d.ts.map +1 -0
- package/dist/tests/search-cache.test.js +95 -0
- package/dist/tests/search-cache.test.js.map +1 -0
- package/dist/tests/search-engine.test.d.ts +2 -0
- package/dist/tests/search-engine.test.d.ts.map +1 -0
- package/dist/tests/search-engine.test.js +125 -0
- package/dist/tests/search-engine.test.js.map +1 -0
- package/dist/tests/search-hook.test.js +3 -3
- package/dist/tests/search-hook.test.js.map +1 -1
- package/dist/tests/session-payload.test.d.ts +1 -1
- package/dist/tests/session-payload.test.js +1 -14
- package/dist/tests/session-payload.test.js.map +1 -1
- package/dist/tests/session-summary.test.d.ts +2 -0
- package/dist/tests/session-summary.test.d.ts.map +1 -0
- package/dist/tests/session-summary.test.js +138 -0
- package/dist/tests/session-summary.test.js.map +1 -0
- package/dist/tests/snippet.test.d.ts +2 -0
- package/dist/tests/snippet.test.d.ts.map +1 -0
- package/dist/tests/snippet.test.js +30 -0
- package/dist/tests/snippet.test.js.map +1 -0
- package/dist/tests/telemetry-perf.test.js +7 -0
- package/dist/tests/telemetry-perf.test.js.map +1 -1
- package/dist/tests/triage.test.d.ts +2 -0
- package/dist/tests/triage.test.d.ts.map +1 -0
- package/dist/tests/triage.test.js +69 -0
- package/dist/tests/triage.test.js.map +1 -0
- package/hooks/lib/mindlore-common.cjs +74 -13
- package/hooks/mindlore-index.cjs +6 -0
- package/hooks/mindlore-post-compact.cjs +23 -3
- package/hooks/mindlore-pre-compact.cjs +86 -3
- package/hooks/mindlore-search.cjs +90 -214
- package/hooks/mindlore-session-end.cjs +22 -18
- package/hooks/mindlore-session-focus.cjs +92 -71
- package/package.json +6 -5
- package/plugin.json +1 -1
- package/skills/mindlore-maintain/SKILL.md +1 -0
- package/templates/config.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proximity.d.ts","sourceRoot":"","sources":["../../../scripts/lib/proximity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAwCvD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAU1F"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rerankByProximity = rerankByProximity;
|
|
4
|
+
function findMinSpan(content, terms) {
|
|
5
|
+
const lower = content.toLowerCase();
|
|
6
|
+
const positions = terms.map(t => {
|
|
7
|
+
const pos = [];
|
|
8
|
+
let idx = lower.indexOf(t);
|
|
9
|
+
while (idx !== -1) {
|
|
10
|
+
pos.push(idx);
|
|
11
|
+
idx = lower.indexOf(t, idx + 1);
|
|
12
|
+
}
|
|
13
|
+
return pos;
|
|
14
|
+
});
|
|
15
|
+
if (positions.some(p => p.length === 0))
|
|
16
|
+
return Infinity;
|
|
17
|
+
let minSpan = Infinity;
|
|
18
|
+
for (let i = 0; i < positions[0].length; i++) {
|
|
19
|
+
let maxPos = positions[0][i];
|
|
20
|
+
let minPos = positions[0][i];
|
|
21
|
+
for (let t = 1; t < terms.length; t++) {
|
|
22
|
+
let bestDist = Infinity;
|
|
23
|
+
let bestPos = 0;
|
|
24
|
+
for (let j = 0; j < positions[t].length; j++) {
|
|
25
|
+
const dist = Math.abs(positions[t][j] - positions[0][i]);
|
|
26
|
+
if (dist < bestDist) {
|
|
27
|
+
bestDist = dist;
|
|
28
|
+
bestPos = positions[t][j];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (bestPos > maxPos)
|
|
32
|
+
maxPos = bestPos;
|
|
33
|
+
if (bestPos < minPos)
|
|
34
|
+
minPos = bestPos;
|
|
35
|
+
}
|
|
36
|
+
const span = maxPos - minPos;
|
|
37
|
+
if (span < minSpan)
|
|
38
|
+
minSpan = span;
|
|
39
|
+
}
|
|
40
|
+
return minSpan;
|
|
41
|
+
}
|
|
42
|
+
function rerankByProximity(results, terms) {
|
|
43
|
+
if (terms.length < 2)
|
|
44
|
+
return results;
|
|
45
|
+
return results
|
|
46
|
+
.map(r => {
|
|
47
|
+
const span = findMinSpan(r.content ?? '', terms);
|
|
48
|
+
const boost = span === Infinity ? 1.0 : 1.0 + (1.0 / (1 + span / 50));
|
|
49
|
+
return { ...r, score: r.score * boost };
|
|
50
|
+
})
|
|
51
|
+
.sort((a, b) => b.score - a.score);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=proximity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proximity.js","sourceRoot":"","sources":["../../../scripts/lib/proximity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
export declare function sanitizeFtsQuery(query: string): string;
|
|
4
|
+
export interface RankedResult {
|
|
5
|
+
slug: string;
|
|
6
|
+
rank: number;
|
|
7
|
+
path: string;
|
|
8
|
+
score: number;
|
|
9
|
+
description?: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
category?: string;
|
|
12
|
+
tags?: string;
|
|
13
|
+
content?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RRFOptions {
|
|
16
|
+
k?: number;
|
|
17
|
+
dedupByPath?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function computeRRF(porterResults: RankedResult[], trigramResults: RankedResult[], options?: RRFOptions): RankedResult[];
|
|
20
|
+
export declare function searchPorter(db: Database, query: string, limit: number, project?: string): RankedResult[];
|
|
21
|
+
export declare function searchTrigram(db: Database, query: string, limit: number, project?: string): RankedResult[];
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=rrf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rrf.d.ts","sourceRoot":"","sources":["../../../scripts/lib/rrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAGvC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,UAAU,CACxB,aAAa,EAAE,YAAY,EAAE,EAC7B,cAAc,EAAE,YAAY,EAAE,EAC9B,OAAO,GAAE,UAAe,GACvB,YAAY,EAAE,CA4BhB;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,YAAY,EAAE,CAQhB;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,YAAY,EAAE,CAYhB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeFtsQuery = sanitizeFtsQuery;
|
|
4
|
+
exports.computeRRF = computeRRF;
|
|
5
|
+
exports.searchPorter = searchPorter;
|
|
6
|
+
exports.searchTrigram = searchTrigram;
|
|
7
|
+
const db_helpers_js_1 = require("./db-helpers.js");
|
|
8
|
+
function sanitizeFtsQuery(query) {
|
|
9
|
+
return query.replace(/["*(){}[\]^~:]/g, '').trim();
|
|
10
|
+
}
|
|
11
|
+
function computeRRF(porterResults, trigramResults, options = {}) {
|
|
12
|
+
const k = options.k ?? 60;
|
|
13
|
+
const scores = new Map();
|
|
14
|
+
for (const list of [porterResults, trigramResults]) {
|
|
15
|
+
for (const r of list) {
|
|
16
|
+
const existing = scores.get(r.slug);
|
|
17
|
+
const rrfScore = 1 / (k + r.rank);
|
|
18
|
+
if (existing) {
|
|
19
|
+
existing.score += rrfScore;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
scores.set(r.slug, { ...r, score: rrfScore });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
let results = Array.from(scores.values()).sort((a, b) => b.score - a.score);
|
|
27
|
+
if (options.dedupByPath) {
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
results = results.filter(r => {
|
|
30
|
+
if (seen.has(r.path))
|
|
31
|
+
return false;
|
|
32
|
+
seen.add(r.path);
|
|
33
|
+
return true;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return results;
|
|
37
|
+
}
|
|
38
|
+
function searchPorter(db, query, limit, project) {
|
|
39
|
+
const sanitized = sanitizeFtsQuery(query);
|
|
40
|
+
if (!sanitized)
|
|
41
|
+
return [];
|
|
42
|
+
const sql = project
|
|
43
|
+
? 'SELECT path, slug, description, title, category, tags, content, bm25(mindlore_fts, 1, 1, 1, 5.0, 1, 1) as bm FROM mindlore_fts WHERE mindlore_fts MATCH ? AND project = ? ORDER BY bm LIMIT ?'
|
|
44
|
+
: 'SELECT path, slug, description, title, category, tags, content, bm25(mindlore_fts, 1, 1, 1, 5.0, 1, 1) as bm FROM mindlore_fts WHERE mindlore_fts MATCH ? ORDER BY bm LIMIT ?';
|
|
45
|
+
const params = project ? [sanitized, project, limit] : [sanitized, limit];
|
|
46
|
+
return (0, db_helpers_js_1.dbAll)(db, sql, ...params).map((r, i) => ({ ...r, rank: i + 1, score: 0 }));
|
|
47
|
+
}
|
|
48
|
+
function searchTrigram(db, query, limit, project) {
|
|
49
|
+
const sanitized = sanitizeFtsQuery(query);
|
|
50
|
+
if (!sanitized)
|
|
51
|
+
return [];
|
|
52
|
+
try {
|
|
53
|
+
const sql = project
|
|
54
|
+
? 'SELECT path, slug, description, title, category, tags, content, rank FROM mindlore_fts_trigram WHERE mindlore_fts_trigram MATCH ? AND project = ? ORDER BY rank LIMIT ?'
|
|
55
|
+
: 'SELECT path, slug, description, title, category, tags, content, rank FROM mindlore_fts_trigram WHERE mindlore_fts_trigram MATCH ? ORDER BY rank LIMIT ?';
|
|
56
|
+
const params = project ? [sanitized, project, limit] : [sanitized, limit];
|
|
57
|
+
return (0, db_helpers_js_1.dbAll)(db, sql, ...params).map((r, i) => ({ ...r, rank: i + 1, score: 0 }));
|
|
58
|
+
}
|
|
59
|
+
catch (_err) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=rrf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rrf.js","sourceRoot":"","sources":["../../../scripts/lib/rrf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
import type { SearchResult } from './search-engine.js';
|
|
4
|
+
export interface SearchCacheOptions {
|
|
5
|
+
ttlMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class SearchCache {
|
|
8
|
+
private db;
|
|
9
|
+
private ttlMs;
|
|
10
|
+
constructor(db: Database, options?: SearchCacheOptions);
|
|
11
|
+
private hash;
|
|
12
|
+
get(query: string): SearchResult[] | null;
|
|
13
|
+
set(query: string, results: SearchResult[]): void;
|
|
14
|
+
invalidate(): void;
|
|
15
|
+
cleanup(): void;
|
|
16
|
+
incrementCallCount(sessionId: string): number;
|
|
17
|
+
getMaxResults(callCount: number): number;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=search-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-cache.d.ts","sourceRoot":"","sources":["../../../scripts/lib/search-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,KAAK,CAAS;gBAEV,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAE,kBAAuB;IAK1D,OAAO,CAAC,IAAI;IAIZ,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,GAAG,IAAI;IAczC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI;IAQjD,UAAU,IAAI,IAAI;IAIlB,OAAO,IAAI,IAAI;IAIf,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAY7C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAKzC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SearchCache = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
class SearchCache {
|
|
9
|
+
db;
|
|
10
|
+
ttlMs;
|
|
11
|
+
constructor(db, options = {}) {
|
|
12
|
+
this.db = db;
|
|
13
|
+
this.ttlMs = options.ttlMs ?? 300000;
|
|
14
|
+
}
|
|
15
|
+
hash(query) {
|
|
16
|
+
return crypto_1.default.createHash('sha256').update(query).digest('hex').slice(0, 16);
|
|
17
|
+
}
|
|
18
|
+
get(query) {
|
|
19
|
+
const h = this.hash(query);
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
|
|
21
|
+
const row = this.db.prepare('SELECT results_json FROM search_cache WHERE query_hash = ? AND expires_at > ?').get(h, new Date().toISOString());
|
|
22
|
+
if (!row) {
|
|
23
|
+
this.cleanup();
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSON stored by set()
|
|
27
|
+
return JSON.parse(row.results_json);
|
|
28
|
+
}
|
|
29
|
+
set(query, results) {
|
|
30
|
+
const h = this.hash(query);
|
|
31
|
+
const expiresAt = new Date(Date.now() + this.ttlMs).toISOString();
|
|
32
|
+
this.db.prepare('INSERT OR REPLACE INTO search_cache (query_hash, results_json, expires_at) VALUES (?, ?, ?)').run(h, JSON.stringify(results), expiresAt);
|
|
33
|
+
}
|
|
34
|
+
invalidate() {
|
|
35
|
+
this.db.exec('DELETE FROM search_cache');
|
|
36
|
+
}
|
|
37
|
+
cleanup() {
|
|
38
|
+
this.db.prepare('DELETE FROM search_cache WHERE expires_at < ?').run(new Date().toISOString());
|
|
39
|
+
}
|
|
40
|
+
incrementCallCount(sessionId) {
|
|
41
|
+
const now = new Date().toISOString();
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
|
|
43
|
+
const row = this.db.prepare(`
|
|
44
|
+
INSERT INTO search_throttle (session_id, call_count, last_call)
|
|
45
|
+
VALUES (?, 1, ?)
|
|
46
|
+
ON CONFLICT(session_id) DO UPDATE SET call_count = call_count + 1, last_call = ?
|
|
47
|
+
RETURNING call_count
|
|
48
|
+
`).get(sessionId, now, now);
|
|
49
|
+
return row?.call_count ?? 1;
|
|
50
|
+
}
|
|
51
|
+
getMaxResults(callCount) {
|
|
52
|
+
if (callCount <= 10)
|
|
53
|
+
return 3;
|
|
54
|
+
if (callCount <= 20)
|
|
55
|
+
return 1;
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.SearchCache = SearchCache;
|
|
60
|
+
//# sourceMappingURL=search-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-cache.js","sourceRoot":"","sources":["../../../scripts/lib/search-cache.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAS5B,MAAa,WAAW;IACd,EAAE,CAAW;IACb,KAAK,CAAS;IAEtB,YAAY,EAAY,EAAE,UAA8B,EAAE;QACxD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;IACvC,CAAC;IAEO,IAAI,CAAC,KAAa;QACxB,OAAO,gBAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,GAAG,CAAC,KAAa;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,gHAAgH;QAChH,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzB,+EAA+E,CAChF,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAyC,CAAC;QAC3E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;QACD,+FAA+F;QAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAmB,CAAC;IACxD,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,OAAuB;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QAClE,IAAI,CAAC,EAAE,CAAC,OAAO,CACb,6FAA6F,CAC9F,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,UAAU;QACR,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,kBAAkB,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,gHAAgH;QAChH,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;KAK3B,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAuC,CAAC;QAClE,OAAO,GAAG,EAAE,UAAU,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,aAAa,CAAC,SAAiB;QAC7B,IAAI,SAAS,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,SAAS,IAAI,EAAE;YAAE,OAAO,CAAC,CAAC;QAC9B,OAAO,CAAC,CAAC;IACX,CAAC;CACF;AA5DD,kCA4DC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type BetterSqlite3 from 'better-sqlite3';
|
|
2
|
+
type Database = BetterSqlite3.Database;
|
|
3
|
+
export interface SearchOptions {
|
|
4
|
+
project?: string;
|
|
5
|
+
maxResults?: number;
|
|
6
|
+
synonyms?: Record<string, string[]>;
|
|
7
|
+
}
|
|
8
|
+
export interface SearchResult {
|
|
9
|
+
slug: string;
|
|
10
|
+
path: string;
|
|
11
|
+
title: string;
|
|
12
|
+
description: string;
|
|
13
|
+
category: string;
|
|
14
|
+
tags: string;
|
|
15
|
+
score: number;
|
|
16
|
+
snippet?: string;
|
|
17
|
+
content?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function extractKeywords(text: string): string[];
|
|
20
|
+
export declare function search(db: Database, query: string, options: SearchOptions): SearchResult[];
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=search-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-engine.d.ts","sourceRoot":"","sources":["../../../scripts/lib/search-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAChD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAOvC,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAeD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMtD;AAyCD,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,YAAY,EAAE,CAsD1F"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractKeywords = extractKeywords;
|
|
4
|
+
exports.search = search;
|
|
5
|
+
const rrf_js_1 = require("./rrf.js");
|
|
6
|
+
const fuzzy_js_1 = require("./fuzzy.js");
|
|
7
|
+
const proximity_js_1 = require("./proximity.js");
|
|
8
|
+
const snippet_js_1 = require("./snippet.js");
|
|
9
|
+
const constants_js_1 = require("./constants.js");
|
|
10
|
+
const STOP_WORDS = new Set([
|
|
11
|
+
'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
|
|
12
|
+
'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
|
|
13
|
+
'should', 'may', 'might', 'can', 'shall', 'must', 'need', 'not',
|
|
14
|
+
'and', 'or', 'but', 'if', 'then', 'else', 'when', 'where', 'how',
|
|
15
|
+
'what', 'which', 'who', 'whom', 'this', 'that', 'these', 'those',
|
|
16
|
+
'i', 'me', 'my', 'we', 'our', 'you', 'your', 'he', 'she', 'it',
|
|
17
|
+
'they', 'them', 'their', 'its', 'of', 'in', 'to', 'for', 'with',
|
|
18
|
+
'on', 'at', 'by', 'from', 'as', 'into', 'about', 'between',
|
|
19
|
+
'ne', 'bir', 'bu', 'da', 'de', 'mi', 'mu', 'mı',
|
|
20
|
+
'var', 'yok', 'ile', 'için', 'gibi', 'daha', 'çok', 'en',
|
|
21
|
+
]);
|
|
22
|
+
function extractKeywords(text) {
|
|
23
|
+
return text
|
|
24
|
+
.replace(/[^\w\sçğıöşüÇĞİÖŞÜ-]/g, ' ')
|
|
25
|
+
.split(/\s+/)
|
|
26
|
+
.filter(w => w.length >= 2 && !STOP_WORDS.has(w.toLowerCase()))
|
|
27
|
+
.map(w => w.toLowerCase());
|
|
28
|
+
}
|
|
29
|
+
function expandWithSynonyms(keywords, synonyms) {
|
|
30
|
+
if (!synonyms)
|
|
31
|
+
return keywords;
|
|
32
|
+
const expanded = [...keywords];
|
|
33
|
+
for (const kw of keywords) {
|
|
34
|
+
const syns = synonyms[kw];
|
|
35
|
+
if (syns)
|
|
36
|
+
expanded.push(...syns);
|
|
37
|
+
}
|
|
38
|
+
return expanded;
|
|
39
|
+
}
|
|
40
|
+
const CATEGORY_WEIGHTS = {
|
|
41
|
+
sources: 1.2,
|
|
42
|
+
analyses: 1.15,
|
|
43
|
+
domains: 1.1,
|
|
44
|
+
episodes: 1.0,
|
|
45
|
+
decisions: 1.0,
|
|
46
|
+
raw: 0.9,
|
|
47
|
+
sessions: 0.85,
|
|
48
|
+
cc_memory: 1.3,
|
|
49
|
+
};
|
|
50
|
+
const DEBUG_KEYWORDS = ['debug', 'fix', 'hata', 'bug', 'error', 'crash', 'fail'];
|
|
51
|
+
const RESEARCH_KEYWORDS = ['araştır', 'bul', 'search', 'nedir', 'nasıl', 'compare'];
|
|
52
|
+
function detectIntent(query) {
|
|
53
|
+
const lower = query.toLowerCase();
|
|
54
|
+
if (DEBUG_KEYWORDS.some(k => lower.includes(k)))
|
|
55
|
+
return 'debug';
|
|
56
|
+
if (RESEARCH_KEYWORDS.some(k => lower.includes(k)))
|
|
57
|
+
return 'research';
|
|
58
|
+
return 'implementation';
|
|
59
|
+
}
|
|
60
|
+
const INTENT_BOOSTS = {
|
|
61
|
+
debug: { episodes: 1.3, raw: 1.1 },
|
|
62
|
+
research: { sources: 1.3, analyses: 1.2 },
|
|
63
|
+
implementation: { domains: 1.2, sessions: 1.1 },
|
|
64
|
+
};
|
|
65
|
+
function search(db, query, options) {
|
|
66
|
+
const maxResults = options.maxResults ?? 3;
|
|
67
|
+
const keywords = extractKeywords(query);
|
|
68
|
+
if (keywords.length === 0)
|
|
69
|
+
return [];
|
|
70
|
+
const expanded = expandWithSynonyms(keywords, options.synonyms);
|
|
71
|
+
const queryStr = (0, constants_js_1.fixVersionTokens)(expanded.join(' '));
|
|
72
|
+
const limit = 20;
|
|
73
|
+
function fusedSearch(q) {
|
|
74
|
+
return (0, rrf_js_1.computeRRF)((0, rrf_js_1.searchPorter)(db, q, limit, options.project), (0, rrf_js_1.searchTrigram)(db, q, limit, options.project), { dedupByPath: true });
|
|
75
|
+
}
|
|
76
|
+
let fused = fusedSearch(queryStr);
|
|
77
|
+
if (fused.length === 0) {
|
|
78
|
+
const corrected = (0, fuzzy_js_1.correctQuery)(db, keywords);
|
|
79
|
+
if (corrected) {
|
|
80
|
+
fused = fusedSearch((0, constants_js_1.fixVersionTokens)(corrected.join(' ')));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const intent = detectIntent(query);
|
|
84
|
+
const intentBoosts = INTENT_BOOSTS[intent];
|
|
85
|
+
for (const r of fused) {
|
|
86
|
+
r.score *= CATEGORY_WEIGHTS[r.category ?? ''] ?? 1.0;
|
|
87
|
+
r.score *= intentBoosts[r.category ?? ''] ?? 1.0;
|
|
88
|
+
}
|
|
89
|
+
fused.sort((a, b) => b.score - a.score);
|
|
90
|
+
const ranked = (0, proximity_js_1.rerankByProximity)(fused.map(r => ({
|
|
91
|
+
slug: r.slug,
|
|
92
|
+
path: r.path,
|
|
93
|
+
title: r.title ?? '',
|
|
94
|
+
description: r.description ?? '',
|
|
95
|
+
category: r.category ?? '',
|
|
96
|
+
tags: r.tags ?? '',
|
|
97
|
+
score: r.score,
|
|
98
|
+
content: r.content,
|
|
99
|
+
})), keywords);
|
|
100
|
+
return ranked.slice(0, maxResults).map(r => ({
|
|
101
|
+
...r,
|
|
102
|
+
snippet: r.content ? (0, snippet_js_1.extractSnippet)(r.content, keywords) : undefined,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=search-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-engine.js","sourceRoot":"","sources":["../../../scripts/lib/search-engine.ts"],"names":[],"mappings":";;AAuCA,0CAMC;AAyCD,wBAsDC;AA1ID,qCAAmE;AACnE,yCAA0C;AAC1C,iDAAmD;AACnD,6CAA8C;AAC9C,iDAAkD;AAoBlD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO;IACnE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IACnE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK;IAC/D,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;IAChE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAChE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;IAC9D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM;IAC/D,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;IAC1D,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC/C,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI;CACzD,CAAC,CAAC;AAEH,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI;SACR,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC;SACrC,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAkB,EAAE,QAAmC;IACjF,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC/B,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC/B,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,gBAAgB,GAA2B;IAC/C,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,GAAG;IACd,GAAG,EAAE,GAAG;IACR,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,GAAG;CACf,CAAC;AAIF,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACjF,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAEpF,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC;IAChE,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC;IACtE,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,aAAa,GAA2C;IAC5D,KAAK,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;IAClC,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;IACzC,cAAc,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;CAChD,CAAC;AAEF,SAAgB,MAAM,CAAC,EAAY,EAAE,KAAa,EAAE,OAAsB;IACxE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,IAAA,+BAAgB,EAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,EAAE,CAAC;IAEjB,SAAS,WAAW,CAAC,CAAS;QAC5B,OAAO,IAAA,mBAAU,EACf,IAAA,qBAAY,EAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAC3C,IAAA,sBAAa,EAAC,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EAC5C,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAElC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAA,uBAAY,EAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,GAAG,WAAW,CAAC,IAAA,+BAAgB,EAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAE3C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,CAAC,CAAC,KAAK,IAAI,gBAAgB,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC;QACrD,CAAC,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAExC,MAAM,MAAM,GAAG,IAAA,gCAAiB,EAC9B,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;QACpB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;QAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE;QAC1B,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,CAAC,CAAC,OAAO;KACnB,CAAC,CAAC,EACH,QAAQ,CACT,CAAC;IAEF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3C,GAAG,CAAC;QACJ,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAA,2BAAc,EAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS;KACrE,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* session-payload — builds 4 structured injection sections for SessionStart.
|
|
3
|
-
* Token budget enforcement + content-hash
|
|
3
|
+
* Token budget enforcement + content-hash.
|
|
4
4
|
*/
|
|
5
5
|
import Database from 'better-sqlite3';
|
|
6
6
|
export interface SessionSection {
|
|
@@ -12,8 +12,6 @@ export interface SessionPayload {
|
|
|
12
12
|
sections: SessionSection[];
|
|
13
13
|
totalTokens: number;
|
|
14
14
|
contentHash: string;
|
|
15
|
-
skipInjection: boolean;
|
|
16
15
|
}
|
|
17
|
-
export declare function
|
|
18
|
-
export declare function buildSessionPayload(db: Database.Database, baseDir: string, project: string, tokenBudget?: number): SessionPayload;
|
|
16
|
+
export declare function buildSessionPayload(db: Database.Database, baseDir: string, project: string, tokenBudget?: number, latestDeltaContent?: string): SessionPayload;
|
|
19
17
|
//# sourceMappingURL=session-payload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-payload.d.ts","sourceRoot":"","sources":["../../../scripts/lib/session-payload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session-payload.d.ts","sourceRoot":"","sources":["../../../scripts/lib/session-payload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAwDD,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAAa,EAC1B,kBAAkB,CAAC,EAAE,MAAM,GAC1B,cAAc,CAuChB"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* session-payload — builds 4 structured injection sections for SessionStart.
|
|
4
|
-
* Token budget enforcement + content-hash
|
|
4
|
+
* Token budget enforcement + content-hash.
|
|
5
5
|
*/
|
|
6
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
8
|
};
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.resetCache = resetCache;
|
|
11
10
|
exports.buildSessionPayload = buildSessionPayload;
|
|
12
11
|
const fs_1 = __importDefault(require("fs"));
|
|
13
12
|
const path_1 = __importDefault(require("path"));
|
|
@@ -16,11 +15,11 @@ const CHARS_PER_TOKEN = 4;
|
|
|
16
15
|
function estimateTokens(text) {
|
|
17
16
|
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
18
17
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
function buildSessionSummary(baseDir, latestDeltaContent) {
|
|
19
|
+
if (latestDeltaContent) {
|
|
20
|
+
const lines = latestDeltaContent.split('\n').filter(l => l.startsWith('- ') || l.startsWith('# '));
|
|
21
|
+
return lines.slice(0, 10).join('\n') || 'No previous session data.';
|
|
22
|
+
}
|
|
24
23
|
const diaryDir = path_1.default.join(baseDir, 'diary');
|
|
25
24
|
if (!fs_1.default.existsSync(diaryDir))
|
|
26
25
|
return 'No previous session data.';
|
|
@@ -32,43 +31,46 @@ function buildSessionSummary(baseDir) {
|
|
|
32
31
|
const lines = latest.split('\n').filter(l => l.startsWith('- ') || l.startsWith('# '));
|
|
33
32
|
return lines.slice(0, 10).join('\n');
|
|
34
33
|
}
|
|
35
|
-
function
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .all() returns unknown[]
|
|
37
|
-
const decisions = db.prepare(`SELECT summary, created_at FROM episodes
|
|
38
|
-
WHERE kind = 'decision' AND status = 'active' AND project = ?
|
|
39
|
-
ORDER BY created_at DESC LIMIT 5`).all(project);
|
|
40
|
-
if (decisions.length === 0)
|
|
41
|
-
return 'No recent decisions.';
|
|
42
|
-
return decisions.map(d => `- ${d.summary} (${d.created_at.slice(0, 10)})`).join('\n');
|
|
43
|
-
}
|
|
44
|
-
function buildFriction(db, project) {
|
|
34
|
+
function buildEpisodeSections(db, project) {
|
|
45
35
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .all() returns unknown[]
|
|
46
|
-
const
|
|
47
|
-
WHERE
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
36
|
+
const rows = db.prepare(`SELECT kind, summary, created_at FROM episodes
|
|
37
|
+
WHERE status = 'active' AND project = ?
|
|
38
|
+
AND kind IN ('decision', 'friction', 'learning')
|
|
39
|
+
ORDER BY kind, created_at DESC`).all(project);
|
|
40
|
+
const grouped = { decision: [], friction: [], learning: [] };
|
|
41
|
+
for (const row of rows) {
|
|
42
|
+
const kind = row.kind;
|
|
43
|
+
if (kind === 'decision' || kind === 'friction' || kind === 'learning') {
|
|
44
|
+
grouped[kind].push(row);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const fmt = (items, limit) => items.slice(0, limit).map(r => `- ${r.summary} (${r.created_at.slice(0, 10)})`).join('\n');
|
|
48
|
+
return {
|
|
49
|
+
decisions: grouped.decision.length > 0 ? fmt(grouped.decision, 5) : 'No recent decisions.',
|
|
50
|
+
friction: grouped.friction.length > 0 ? fmt(grouped.friction, 3) : 'No active friction points.',
|
|
51
|
+
learnings: grouped.learning.length > 0 ? fmt(grouped.learning, 5) : 'No recent learnings.',
|
|
52
|
+
};
|
|
61
53
|
}
|
|
62
|
-
function buildSessionPayload(db, baseDir, project, tokenBudget = 2000) {
|
|
54
|
+
function buildSessionPayload(db, baseDir, project, tokenBudget = 2000, latestDeltaContent) {
|
|
63
55
|
const sections = [];
|
|
64
|
-
const summary = buildSessionSummary(baseDir);
|
|
56
|
+
const summary = buildSessionSummary(baseDir, latestDeltaContent);
|
|
65
57
|
sections.push({ label: 'Session', content: summary, tokens: estimateTokens(summary) });
|
|
66
|
-
const
|
|
67
|
-
sections.push({ label: 'Decisions', content: decisions, tokens: estimateTokens(decisions) });
|
|
68
|
-
|
|
69
|
-
sections.push({ label: '
|
|
70
|
-
|
|
71
|
-
|
|
58
|
+
const episodes = buildEpisodeSections(db, project);
|
|
59
|
+
sections.push({ label: 'Decisions', content: episodes.decisions, tokens: estimateTokens(episodes.decisions) });
|
|
60
|
+
sections.push({ label: 'Friction', content: episodes.friction, tokens: estimateTokens(episodes.friction) });
|
|
61
|
+
sections.push({ label: 'Learnings', content: episodes.learnings, tokens: estimateTokens(episodes.learnings) });
|
|
62
|
+
// Session summaries from recent sessions (#9)
|
|
63
|
+
try {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .all() returns unknown[]
|
|
65
|
+
const summaries = db.prepare(`SELECT session_summary, created_at FROM episodes
|
|
66
|
+
WHERE kind = 'session-summary' AND project = ? AND session_summary IS NOT NULL
|
|
67
|
+
ORDER BY created_at DESC LIMIT 3`).all(project);
|
|
68
|
+
if (summaries.length > 0) {
|
|
69
|
+
const content = summaries.map(s => `- ${s.created_at.slice(0, 16)}: ${s.session_summary}`).join('\n');
|
|
70
|
+
sections.push({ label: 'Past Sessions', content: `# Son Sessionlar\n${content}`, tokens: estimateTokens(content) });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch { /* session_summary column may not exist */ }
|
|
72
74
|
let totalTokens = sections.reduce((sum, s) => sum + s.tokens, 0);
|
|
73
75
|
while (totalTokens > tokenBudget && sections.length > 1) {
|
|
74
76
|
const removed = sections.pop();
|
|
@@ -78,8 +80,6 @@ function buildSessionPayload(db, baseDir, project, tokenBudget = 2000) {
|
|
|
78
80
|
}
|
|
79
81
|
const allContent = sections.map(s => s.content).join('|');
|
|
80
82
|
const contentHash = crypto_1.default.createHash('md5').update(allContent).digest('hex').slice(0, 8);
|
|
81
|
-
|
|
82
|
-
lastHash = contentHash;
|
|
83
|
-
return { sections, totalTokens, contentHash, skipInjection };
|
|
83
|
+
return { sections, totalTokens, contentHash };
|
|
84
84
|
}
|
|
85
85
|
//# sourceMappingURL=session-payload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-payload.js","sourceRoot":"","sources":["../../../scripts/lib/session-payload.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;
|
|
1
|
+
{"version":3,"file":"session-payload.js","sourceRoot":"","sources":["../../../scripts/lib/session-payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippet.d.ts","sourceRoot":"","sources":["../../../scripts/lib/snippet.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,SAAM,GAAG,MAAM,CA2BrF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractSnippet = extractSnippet;
|
|
4
|
+
function extractSnippet(content, terms, maxLen = 300) {
|
|
5
|
+
if (!content || content.length <= maxLen)
|
|
6
|
+
return content;
|
|
7
|
+
const lower = content.toLowerCase();
|
|
8
|
+
let bestPos = 0;
|
|
9
|
+
let bestScore = 0;
|
|
10
|
+
for (const term of terms) {
|
|
11
|
+
const idx = lower.indexOf(term.toLowerCase());
|
|
12
|
+
if (idx !== -1) {
|
|
13
|
+
const windowStart = Math.max(0, idx - Math.floor(maxLen / 2));
|
|
14
|
+
const windowEnd = Math.min(lower.length, idx + Math.floor(maxLen / 2));
|
|
15
|
+
const window = lower.slice(windowStart, windowEnd);
|
|
16
|
+
const termCount = terms.filter(t => window.includes(t.toLowerCase())).length;
|
|
17
|
+
if (termCount > bestScore) {
|
|
18
|
+
bestScore = termCount;
|
|
19
|
+
bestPos = idx;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const start = Math.max(0, bestPos - Math.floor(maxLen / 3));
|
|
24
|
+
const end = Math.min(content.length, start + maxLen);
|
|
25
|
+
let snippet = content.slice(start, end);
|
|
26
|
+
if (start > 0)
|
|
27
|
+
snippet = '...' + snippet;
|
|
28
|
+
if (end < content.length)
|
|
29
|
+
snippet = snippet + '...';
|
|
30
|
+
return snippet;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=snippet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippet.js","sourceRoot":"","sources":["../../../scripts/lib/snippet.ts"],"names":[],"mappings":";;AAAA,wCA2BC;AA3BD,SAAgB,cAAc,CAAC,OAAe,EAAE,KAAe,EAAE,MAAM,GAAG,GAAG;IAC3E,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IAEzD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9C,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YACvE,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;YAC7E,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;gBAC1B,SAAS,GAAG,SAAS,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;IACrD,IAAI,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IACzC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM;QAAE,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACpD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|