mindlore 0.6.4 → 0.6.5
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/scripts/cc-memory-bulk-sync.js +1 -1
- package/dist/scripts/cc-memory-bulk-sync.js.map +1 -1
- package/dist/scripts/cc-session-sync.js +2 -2
- package/dist/scripts/cc-session-sync.js.map +1 -1
- package/dist/scripts/fetch-raw.js +17 -8
- package/dist/scripts/fetch-raw.js.map +1 -1
- package/dist/scripts/init.js +8 -8
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/daemon.d.ts.map +1 -1
- package/dist/scripts/lib/daemon.js +3 -0
- package/dist/scripts/lib/daemon.js.map +1 -1
- package/dist/scripts/lib/input-validation.d.ts +5 -0
- package/dist/scripts/lib/input-validation.d.ts.map +1 -0
- package/dist/scripts/lib/input-validation.js +48 -0
- package/dist/scripts/lib/input-validation.js.map +1 -0
- package/dist/scripts/lib/privacy-filter.d.ts.map +1 -1
- package/dist/scripts/lib/privacy-filter.js +3 -0
- package/dist/scripts/lib/privacy-filter.js.map +1 -1
- package/dist/scripts/lib/rrf.d.ts.map +1 -1
- package/dist/scripts/lib/rrf.js +10 -10
- package/dist/scripts/lib/rrf.js.map +1 -1
- package/dist/scripts/lib/search-cache.d.ts +1 -0
- package/dist/scripts/lib/search-cache.d.ts.map +1 -1
- package/dist/scripts/lib/search-cache.js +6 -0
- package/dist/scripts/lib/search-cache.js.map +1 -1
- package/dist/scripts/lib/search-engine.d.ts +1 -1
- package/dist/scripts/lib/search-engine.d.ts.map +1 -1
- package/dist/scripts/lib/search-engine.js +3 -2
- package/dist/scripts/lib/search-engine.js.map +1 -1
- package/dist/scripts/mindlore-daemon.js +1 -3
- package/dist/scripts/mindlore-daemon.js.map +1 -1
- package/dist/scripts/mindlore-obsidian.js +4 -0
- package/dist/scripts/mindlore-obsidian.js.map +1 -1
- package/dist/tests/fetch-raw-security.test.d.ts +2 -0
- package/dist/tests/fetch-raw-security.test.d.ts.map +1 -0
- package/dist/tests/fetch-raw-security.test.js +72 -0
- package/dist/tests/fetch-raw-security.test.js.map +1 -0
- package/dist/tests/fetch-raw.test.js +4 -4
- package/dist/tests/fetch-raw.test.js.map +1 -1
- package/dist/tests/fts5.test.js +0 -22
- package/dist/tests/fts5.test.js.map +1 -1
- package/dist/tests/input-validation.test.d.ts +2 -0
- package/dist/tests/input-validation.test.d.ts.map +1 -0
- package/dist/tests/input-validation.test.js +113 -0
- package/dist/tests/input-validation.test.js.map +1 -0
- package/dist/tests/privacy-filter.test.js +25 -50
- package/dist/tests/privacy-filter.test.js.map +1 -1
- package/dist/tests/search-hook.test.js +0 -44
- package/dist/tests/search-hook.test.js.map +1 -1
- package/dist/tests/sec-regression.test.d.ts +2 -0
- package/dist/tests/sec-regression.test.d.ts.map +1 -0
- package/dist/tests/sec-regression.test.js +174 -0
- package/dist/tests/sec-regression.test.js.map +1 -0
- package/dist/tests/stop-words.test.js +26 -0
- package/dist/tests/stop-words.test.js.map +1 -1
- package/hooks/lib/mindlore-common.cjs +23 -4
- package/hooks/mindlore-fts5-sync.cjs +4 -3
- package/hooks/mindlore-index.cjs +6 -7
- package/hooks/mindlore-pre-compact.cjs +5 -4
- package/hooks/mindlore-session-end.cjs +10 -10
- package/hooks/mindlore-session-focus.cjs +11 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/templates/SCHEMA.md +10 -108
- package/templates/config.json +1 -1
- package/dist/scripts/lib/hybrid-search.d.ts +0 -62
- package/dist/scripts/lib/hybrid-search.d.ts.map +0 -1
- package/dist/scripts/lib/hybrid-search.js +0 -171
- package/dist/scripts/lib/hybrid-search.js.map +0 -1
- package/dist/tests/hybrid-search.test.d.ts +0 -2
- package/dist/tests/hybrid-search.test.d.ts.map +0 -1
- package/dist/tests/hybrid-search.test.js +0 -139
- package/dist/tests/hybrid-search.test.js.map +0 -1
- package/dist/tests/index-cli-embed.test.d.ts +0 -7
- package/dist/tests/index-cli-embed.test.d.ts.map +0 -1
- package/dist/tests/index-cli-embed.test.js +0 -128
- package/dist/tests/index-cli-embed.test.js.map +0 -1
- package/dist/tests/search-cli-hybrid.test.d.ts +0 -6
- package/dist/tests/search-cli-hybrid.test.d.ts.map +0 -1
- package/dist/tests/search-cli-hybrid.test.js +0 -103
- package/dist/tests/search-cli-hybrid.test.js.map +0 -1
|
@@ -44,6 +44,21 @@ function getActiveMindloreDir() {
|
|
|
44
44
|
return globalDir();
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function isInsideMindloreDir(resolvedPath) {
|
|
48
|
+
return resolvedPath.includes(path.sep + MINDLORE_DIR + path.sep)
|
|
49
|
+
|| resolvedPath.endsWith(path.sep + MINDLORE_DIR);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function extractMindloreBaseDir(resolvedPath) {
|
|
53
|
+
const sepDir = path.sep + MINDLORE_DIR;
|
|
54
|
+
let idx = resolvedPath.lastIndexOf(sepDir + path.sep);
|
|
55
|
+
if (idx === -1 && resolvedPath.endsWith(sepDir)) {
|
|
56
|
+
idx = resolvedPath.length - sepDir.length;
|
|
57
|
+
}
|
|
58
|
+
if (idx === -1) return null;
|
|
59
|
+
return resolvedPath.slice(0, idx + sepDir.length);
|
|
60
|
+
}
|
|
61
|
+
|
|
47
62
|
/**
|
|
48
63
|
* Return the single global mindlore DB path.
|
|
49
64
|
* v0.3.3: multi-DB layered search removed — single global DB with project column.
|
|
@@ -656,7 +671,9 @@ function _rotateFile(filePath, maxBytes, keepLines) {
|
|
|
656
671
|
const stat = fs.statSync(filePath);
|
|
657
672
|
if (stat.size > maxBytes) {
|
|
658
673
|
const lines = fs.readFileSync(filePath, 'utf8').trim().split('\n');
|
|
659
|
-
|
|
674
|
+
const tmpPath = filePath + '.tmp';
|
|
675
|
+
fs.writeFileSync(tmpPath, lines.slice(-keepLines).join('\n') + '\n', { mode: 0o600 });
|
|
676
|
+
fs.renameSync(tmpPath, filePath);
|
|
660
677
|
}
|
|
661
678
|
} catch { /* file may not exist yet */ }
|
|
662
679
|
}
|
|
@@ -666,7 +683,7 @@ let _telDirEnsured = false;
|
|
|
666
683
|
function _writeTelemetry({ hookName, duration_ms, ok, extra }) {
|
|
667
684
|
try {
|
|
668
685
|
if (!_telDirEnsured) {
|
|
669
|
-
fs.mkdirSync(GLOBAL_MINDLORE_DIR, { recursive: true });
|
|
686
|
+
fs.mkdirSync(GLOBAL_MINDLORE_DIR, { recursive: true, mode: 0o700 });
|
|
670
687
|
_telDirEnsured = true;
|
|
671
688
|
}
|
|
672
689
|
const telPath = path.join(GLOBAL_MINDLORE_DIR, 'telemetry.jsonl');
|
|
@@ -799,6 +816,9 @@ module.exports = {
|
|
|
799
816
|
isDaemonRunning,
|
|
800
817
|
getDaemonPortFile,
|
|
801
818
|
getDaemonPidFile,
|
|
819
|
+
_rotateFile,
|
|
820
|
+
isInsideMindloreDir,
|
|
821
|
+
extractMindloreBaseDir,
|
|
802
822
|
// Telemetry (v0.6.0)
|
|
803
823
|
withTelemetry,
|
|
804
824
|
withTelemetrySync,
|
|
@@ -851,9 +871,8 @@ function getUnpromotedRawFiles(baseDir) {
|
|
|
851
871
|
}
|
|
852
872
|
|
|
853
873
|
function isDaemonRunning(pidFile) {
|
|
854
|
-
if (!fs.existsSync(pidFile)) return { running: false };
|
|
855
|
-
const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim());
|
|
856
874
|
try {
|
|
875
|
+
const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim());
|
|
857
876
|
process.kill(pid, 0);
|
|
858
877
|
return { running: true, pid };
|
|
859
878
|
} catch {
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const {
|
|
16
|
+
const { DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName, resolveProject, hookLog, withTelemetry, SQL_FTS_SESSIONS_INSERT, isSessionCategory, isInsideMindloreDir } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
function main() {
|
|
19
19
|
const filePath = readHookStdin(['path', 'file_path']);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
if (!filePath) return;
|
|
22
|
+
const resolved = path.resolve(filePath);
|
|
23
|
+
if (!isInsideMindloreDir(resolved)) return;
|
|
23
24
|
|
|
24
25
|
// Skip if this is a single .md file change — mindlore-index.cjs handles those.
|
|
25
26
|
// This hook is for bulk changes (git pull, manual batch edits).
|
package/hooks/mindlore-index.cjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
-
const {
|
|
13
|
+
const { DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getProjectName, resolveProject, globalDir, hookLog, withTelemetry, isInsideMindloreDir, extractMindloreBaseDir } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
function invalidateSearchCache(db) {
|
|
16
16
|
try { db.exec('DELETE FROM search_cache'); } catch (_) { /* table may not exist */ }
|
|
@@ -23,7 +23,7 @@ function main() {
|
|
|
23
23
|
// Only process .md files inside .mindlore/ (resolved path check prevents traversal)
|
|
24
24
|
if (!filePath.endsWith('.md')) return;
|
|
25
25
|
const resolvedFile = path.resolve(filePath);
|
|
26
|
-
if (!
|
|
26
|
+
if (!isInsideMindloreDir(resolvedFile)) {
|
|
27
27
|
// CC memory path (~/.claude/projects/*/memory/*.md) — index to global mindlore DB
|
|
28
28
|
const isCcMemory = resolvedFile.includes(path.sep + '.claude' + path.sep + 'projects' + path.sep)
|
|
29
29
|
&& resolvedFile.includes(path.sep + 'memory' + path.sep)
|
|
@@ -37,9 +37,8 @@ function main() {
|
|
|
37
37
|
|
|
38
38
|
const fileName = path.basename(filePath);
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const baseDir = filePath.slice(0, mindloreIdx + MINDLORE_DIR.length);
|
|
40
|
+
const baseDir = extractMindloreBaseDir(resolvedFile);
|
|
41
|
+
if (!baseDir) return;
|
|
43
42
|
const dbPath = path.join(baseDir, DB_NAME);
|
|
44
43
|
|
|
45
44
|
if (!fs.existsSync(dbPath)) return;
|
|
@@ -165,9 +164,9 @@ function indexCcMemory(filePath) {
|
|
|
165
164
|
|
|
166
165
|
// Copy to ~/.mindlore/memory/{project}/ for git-sync + obsidian
|
|
167
166
|
const memoryDir = path.join(globalBase, 'memory', projectScope || '_global');
|
|
168
|
-
fs.mkdirSync(memoryDir, { recursive: true });
|
|
167
|
+
fs.mkdirSync(memoryDir, { recursive: true, mode: 0o700 });
|
|
169
168
|
const destPath = path.join(memoryDir, path.basename(filePath));
|
|
170
|
-
fs.writeFileSync(destPath, cleaned, 'utf8');
|
|
169
|
+
fs.writeFileSync(destPath, cleaned, { encoding: 'utf8', mode: 0o600 });
|
|
171
170
|
} finally {
|
|
172
171
|
db.close();
|
|
173
172
|
}
|
|
@@ -45,10 +45,11 @@ function collectRecentEpisodes(baseDir) {
|
|
|
45
45
|
|
|
46
46
|
function collectGitDiff() {
|
|
47
47
|
try {
|
|
48
|
-
const {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const { execFileSync } = require('child_process');
|
|
49
|
+
let diffStat = '';
|
|
50
|
+
try {
|
|
51
|
+
diffStat = execFileSync('git', ['diff', '--stat', 'HEAD'], { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
52
|
+
} catch { diffStat = ''; }
|
|
52
53
|
if (diffStat) return ['## Changed Files (uncommitted)', '```', diffStat, '```'];
|
|
53
54
|
return [];
|
|
54
55
|
} catch (_err) {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const os = require('os');
|
|
15
|
-
const {
|
|
15
|
+
const { execFileSync, spawn } = require('child_process');
|
|
16
16
|
const { findMindloreDir, globalDir, getProjectName, openDatabase, ensureEpisodesTable, hasEpisodesTable, insertBareEpisode, insertFtsRow, hookLog, SHARED_EXPORT_DIRS, resolveWin32Bin, withTelemetry, getUnpromotedRawFiles } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
const EXPORT_DIRS = SHARED_EXPORT_DIRS;
|
|
@@ -117,7 +117,7 @@ function formatDate(date) {
|
|
|
117
117
|
function getRecentGitInfo() {
|
|
118
118
|
try {
|
|
119
119
|
// --name-only includes file names after each commit entry
|
|
120
|
-
const raw =
|
|
120
|
+
const raw = execFileSync('git', ['log', '--oneline', '-5', '--name-only'], {
|
|
121
121
|
encoding: 'utf8',
|
|
122
122
|
timeout: 5000,
|
|
123
123
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -220,7 +220,7 @@ function main() {
|
|
|
220
220
|
|
|
221
221
|
sections.push('');
|
|
222
222
|
|
|
223
|
-
fs.writeFileSync(deltaPath, sections.join('\n'), 'utf8');
|
|
223
|
+
fs.writeFileSync(deltaPath, sections.join('\n'), { encoding: 'utf8', mode: 0o600 });
|
|
224
224
|
|
|
225
225
|
// Append to log.md
|
|
226
226
|
const logPath = path.join(baseDir, 'log.md');
|
|
@@ -235,7 +235,7 @@ function main() {
|
|
|
235
235
|
try {
|
|
236
236
|
const workerData = JSON.stringify({ baseDir, project, commits, changedFiles, reads });
|
|
237
237
|
const tmpFile = path.join(os.tmpdir(), `mindlore-worker-${Date.now()}.json`);
|
|
238
|
-
fs.writeFileSync(tmpFile, workerData, 'utf8');
|
|
238
|
+
fs.writeFileSync(tmpFile, workerData, { encoding: 'utf8', mode: 0o600 });
|
|
239
239
|
// Use system node instead of process.execPath — CC's embedded Node
|
|
240
240
|
// may not work as a standalone binary for detached worker processes.
|
|
241
241
|
// Resolve full path to avoid shell:true deprecation warning on Windows.
|
|
@@ -377,7 +377,7 @@ function writeEpisodeFile(baseDir, project, commits, changedFiles, reads) {
|
|
|
377
377
|
lines.push('');
|
|
378
378
|
}
|
|
379
379
|
|
|
380
|
-
fs.writeFileSync(filePath, lines.join('\n'), 'utf8');
|
|
380
|
+
fs.writeFileSync(filePath, lines.join('\n'), { encoding: 'utf8', mode: 0o600 });
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
let _obsidianHelpersCache = undefined; // undefined = not yet attempted
|
|
@@ -474,7 +474,7 @@ function syncObsidian(baseDir) {
|
|
|
474
474
|
if (exported > 0) {
|
|
475
475
|
config.obsidian.lastExport = new Date().toISOString();
|
|
476
476
|
config.obsidian.lastExportCount = exported;
|
|
477
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
|
|
477
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), { encoding: 'utf8', mode: 0o600 });
|
|
478
478
|
}
|
|
479
479
|
} catch (err) {
|
|
480
480
|
hookLog('session-end', 'error', `obsidian internal: ${err?.message ?? err}`);
|
|
@@ -500,16 +500,16 @@ function syncGlobalRepo() {
|
|
|
500
500
|
const execOpts = (timeout) => ({ cwd: gDir, encoding: 'utf8', timeout, stdio: 'pipe', windowsHide: true });
|
|
501
501
|
|
|
502
502
|
// Check for changes
|
|
503
|
-
const status =
|
|
503
|
+
const status = execFileSync(git, ['status', '--porcelain'], execOpts(5000)).trim();
|
|
504
504
|
if (!status) return; // nothing to commit
|
|
505
505
|
|
|
506
|
-
|
|
506
|
+
execFileSync(git, ['add', '*.md', 'mindlore.db', 'diary/', 'sources/', 'domains/', 'analyses/', 'decisions/', 'raw/', 'connections/', 'insights/', 'learnings/'], execOpts(10000));
|
|
507
507
|
const now = new Date().toISOString().slice(0, 19);
|
|
508
|
-
|
|
508
|
+
execFileSync(git, ['commit', '-m', `mindlore auto-sync ${now}`], execOpts(15000));
|
|
509
509
|
|
|
510
510
|
// Push — graceful fail if no remote or offline
|
|
511
511
|
try {
|
|
512
|
-
|
|
512
|
+
execFileSync(git, ['push'], execOpts(30000));
|
|
513
513
|
} catch (_pushErr) {
|
|
514
514
|
hookLog('session-end', 'warn', 'git push failed (offline?): ' + (_pushErr?.message ?? '').slice(0, 100));
|
|
515
515
|
}
|
|
@@ -12,6 +12,16 @@ const fs = require('fs');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry, withTimeoutDb, listSnapshots, isCorruptionError, recoverCorruptDb } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
|
+
function truncateCommits(content) {
|
|
16
|
+
const commitMatch = content.match(/(## Commits\n)((?:- [^\n]+\n?)+)/);
|
|
17
|
+
if (!commitMatch) return content;
|
|
18
|
+
const lines = commitMatch[2].trim().split('\n');
|
|
19
|
+
if (lines.length <= 5) return content;
|
|
20
|
+
const kept = lines.slice(0, 5).join('\n');
|
|
21
|
+
const truncated = kept + `\n- ...ve ${lines.length - 5} commit daha`;
|
|
22
|
+
return content.replace(commitMatch[2].trim(), truncated);
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
function tryOpenDb(dbPath) {
|
|
16
26
|
return openDatabase(dbPath, { readonly: true });
|
|
17
27
|
}
|
|
@@ -107,7 +117,7 @@ function main() {
|
|
|
107
117
|
const deltaProject = meta.project || null;
|
|
108
118
|
const currentProject = getProjectName();
|
|
109
119
|
if (!deltaProject || deltaProject.toLowerCase() === currentProject.toLowerCase()) {
|
|
110
|
-
output.push(`[Mindlore Delta: ${latestName}]\n${deltaContent}`);
|
|
120
|
+
output.push(`[Mindlore Delta: ${latestName}]\n${truncateCommits(deltaContent)}`);
|
|
111
121
|
}
|
|
112
122
|
}
|
|
113
123
|
|
package/package.json
CHANGED
package/plugin.json
CHANGED
package/templates/SCHEMA.md
CHANGED
|
@@ -44,21 +44,6 @@ Mindlore uses a single global directory:
|
|
|
44
44
|
- Files MUST live in the directory matching their `type`
|
|
45
45
|
- The health check script validates this cross-reference
|
|
46
46
|
|
|
47
|
-
### Session Storage (v0.5.3)
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
raw/sessions/
|
|
51
|
-
├── kastell/ # Proje bazlı CC session dosyaları
|
|
52
|
-
├── mindlore/
|
|
53
|
-
├── Stok-Takip/
|
|
54
|
-
└── {project-slug}/ # cc-session-sync.ts tarafından yazılır
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Session dosyaları `cc-session-sync.ts` tarafından `~/.claude/projects/*/` altından taranır,
|
|
58
|
-
`projectSlug()` ile temiz isme dönüştürülür (ör. `C--Users-Omrfc-Documents-kastell` → `kastell`),
|
|
59
|
-
ve `raw/sessions/{slug}/{date}-{shortId}.md` olarak yazılır.
|
|
60
|
-
Frontmatter: `type: raw, project: {slug}, category: cc-session`
|
|
61
|
-
|
|
62
47
|
## 3. Frontmatter
|
|
63
48
|
|
|
64
49
|
Every `.md` file in `.mindlore/` MUST have YAML frontmatter. Format:
|
|
@@ -105,7 +90,7 @@ tags: [tag1, tag2]
|
|
|
105
90
|
- `raw_slug`: slug of the raw/ file this source was processed from (source→raw traceability)
|
|
106
91
|
- `status`: `stub` | `active` | `archived` (domain maturity indicator)
|
|
107
92
|
|
|
108
|
-
## 4.
|
|
93
|
+
## 4. Seven Operations
|
|
109
94
|
|
|
110
95
|
### 4.1 Ingest (skill: /mindlore-ingest)
|
|
111
96
|
|
|
@@ -116,7 +101,7 @@ Add new knowledge. Flow: capture → raw/ → process → sources/ → update do
|
|
|
116
101
|
- PDF mode: CC Read tool (max 20 pages/request) → raw/ → summarize → sources/
|
|
117
102
|
- **markitdown is NOT used for PDF** — quality is poor. Use CC Read tool or Marker/Chandra (v0.3+)
|
|
118
103
|
|
|
119
|
-
### 4.2 Query (skill: /mindlore-query
|
|
104
|
+
### 4.2 Query (skill: /mindlore-query, v0.2 — PLANNED, not yet implemented)
|
|
120
105
|
|
|
121
106
|
Search and retrieve knowledge. Four modes:
|
|
122
107
|
- `search`: FTS5 keyword search, return top 3 matches with snippets
|
|
@@ -134,7 +119,7 @@ Run 16-point structural check:
|
|
|
134
119
|
- Orphan file detection (files not in FTS5)
|
|
135
120
|
- Frontmatter validation (type-directory cross-reference)
|
|
136
121
|
|
|
137
|
-
### 4.4 Log (skill: /mindlore-log
|
|
122
|
+
### 4.4 Log (skill: /mindlore-log, v0.2 — PLANNED, not yet implemented)
|
|
138
123
|
|
|
139
124
|
Session logging with four modes:
|
|
140
125
|
- `log`: Write session/task record to diary/
|
|
@@ -142,44 +127,33 @@ Session logging with four modes:
|
|
|
142
127
|
- `status`: Recent N sessions summary, trends, open items
|
|
143
128
|
- `save`: Structured delta + log.md append + wiki update
|
|
144
129
|
|
|
145
|
-
### 4.5 Decide (skill: /mindlore-decide
|
|
130
|
+
### 4.5 Decide (skill: /mindlore-decide, v0.2 — PLANNED, not yet implemented)
|
|
146
131
|
|
|
147
132
|
Record decisions with context, options considered, rationale, and outcome.
|
|
148
133
|
Supports `supersedes` chain for decision evolution.
|
|
149
134
|
|
|
150
|
-
### 4.6 Evolve (skill: /mindlore-evolve
|
|
135
|
+
### 4.6 Evolve (skill: /mindlore-evolve, v0.3 — PLANNED, not yet implemented)
|
|
151
136
|
|
|
152
137
|
Schema co-evolution. Scan domains + sources, suggest structural updates.
|
|
153
138
|
Run monthly or after major changes.
|
|
154
139
|
|
|
155
|
-
### 4.7 Explore (skill: /mindlore-explore
|
|
140
|
+
### 4.7 Explore (skill: /mindlore-explore, v0.3 — PLANNED, not yet implemented)
|
|
156
141
|
|
|
157
142
|
Discover unexpected connections between sources. Cross-reference analysis.
|
|
158
143
|
|
|
159
|
-
### 4.8 Diary (skill: /mindlore-diary) — IMPLEMENTED (v0.5.3)
|
|
160
|
-
|
|
161
|
-
Session analysis — decisions, discoveries, frictions, learnings.
|
|
162
|
-
|
|
163
|
-
### 4.9 Reflect (skill: /mindlore-reflect) — IMPLEMENTED (v0.5.3)
|
|
164
|
-
|
|
165
|
-
Pattern extraction from episodes, CLAUDE.md update proposals.
|
|
166
|
-
|
|
167
|
-
### 4.10 Maintain (skill: /mindlore-maintain) — IMPLEMENTED (v0.5.3)
|
|
168
|
-
|
|
169
|
-
Decay/archive, episode consolidation, contradiction detection.
|
|
170
|
-
|
|
171
144
|
## 5. Search Behavior
|
|
172
145
|
|
|
173
146
|
### FTS5 Search (hooks + scripts)
|
|
174
147
|
|
|
175
148
|
- Database: `.mindlore/mindlore.db`
|
|
176
|
-
- Table: `mindlore_fts` (
|
|
177
|
-
-
|
|
149
|
+
- Table: `mindlore_fts` — knowledge content (sources, domains, analyses, decisions, diary)
|
|
150
|
+
- Table: `mindlore_fts_sessions` — session content (cc-subagent, cc-session) — v0.6.1
|
|
151
|
+
- Dedup: `file_hashes` table with SHA256 content-hash + `table_target` column (v0.6.1)
|
|
178
152
|
- Tokenizer: `unicode61`
|
|
179
153
|
- Max results: 3 per query (BM25 ranking)
|
|
180
154
|
- Hook injects: file path + first 2 headings
|
|
181
155
|
|
|
182
|
-
### FTS5 Columns (11-col schema, v0.
|
|
156
|
+
### FTS5 Columns (11-col schema, v0.3.3)
|
|
183
157
|
|
|
184
158
|
| Column | Indexed | Source |
|
|
185
159
|
|--------|---------|--------|
|
|
@@ -316,75 +290,3 @@ tags: [testing, jest, mock]
|
|
|
316
290
|
- Stats line: "N source, N analysis, N total"
|
|
317
291
|
- Last 5 added (initially empty)
|
|
318
292
|
- NO full file listing — discovery via FTS5
|
|
319
|
-
|
|
320
|
-
## 10. Database Tables
|
|
321
|
-
|
|
322
|
-
### mindlore_fts (FTS5 virtual table)
|
|
323
|
-
|
|
324
|
-
11 kolon: path (UNINDEXED), slug, description, type (UNINDEXED), category, title, content, tags, quality (UNINDEXED), date_captured (UNINDEXED), project (UNINDEXED)
|
|
325
|
-
|
|
326
|
-
Tokenizer: `porter unicode61`
|
|
327
|
-
|
|
328
|
-
### file_hashes
|
|
329
|
-
|
|
330
|
-
Dedup tablosu — content-hash ile aynı dosyanın tekrar indexlenmesini engeller.
|
|
331
|
-
|
|
332
|
-
| Kolon | Tip | Açıklama |
|
|
333
|
-
|-------|-----|----------|
|
|
334
|
-
| path | TEXT PK | Dosya tam yolu |
|
|
335
|
-
| content_hash | TEXT | SHA256 hash |
|
|
336
|
-
| last_indexed | TEXT | Son index zamanı |
|
|
337
|
-
| created_at | TEXT | İlk index zamanı |
|
|
338
|
-
| updated_at | TEXT | Son güncelleme zamanı |
|
|
339
|
-
| source_type | TEXT | Kaynak tipi (cc-session, cc-subagent, vb.) |
|
|
340
|
-
| project_scope | TEXT | Proje adı |
|
|
341
|
-
| recall_count | INTEGER | Kaç kez recall edildi |
|
|
342
|
-
| last_recalled_at | TEXT | Son recall zamanı |
|
|
343
|
-
| archived_at | TEXT | Arşivlenme zamanı (null = aktif) |
|
|
344
|
-
| importance | REAL | Kalite→önem dönüşümü (0.0–1.0) |
|
|
345
|
-
|
|
346
|
-
> v0.6.0: `QUALITY_HEURISTICS` artık `cc-session`/`cc-subagent` source_type'larını tanıyor (önce eksikti).
|
|
347
|
-
|
|
348
|
-
### episodes
|
|
349
|
-
|
|
350
|
-
Session ve bilgi olayları — decision, discovery, friction, learning, reflection.
|
|
351
|
-
|
|
352
|
-
| Kolon | Tip | Açıklama |
|
|
353
|
-
|-------|-----|----------|
|
|
354
|
-
| id | TEXT PK | `ep-{kind}-{timestamp}-{random}` |
|
|
355
|
-
| kind | TEXT | decision, discovery, friction, learning, reflection, correction |
|
|
356
|
-
| scope | TEXT | session, cross-session, global |
|
|
357
|
-
| project | TEXT | Proje adı |
|
|
358
|
-
| summary | TEXT | Tek satır özet |
|
|
359
|
-
| body | TEXT | Detaylı içerik |
|
|
360
|
-
| tags | TEXT | Virgülle ayrılmış etiketler |
|
|
361
|
-
| entities | TEXT | İlgili entity'ler |
|
|
362
|
-
| parent_id | TEXT | Üst episode referansı |
|
|
363
|
-
| status | TEXT | active, archived |
|
|
364
|
-
| supersedes | TEXT | Geçersiz kıldığı episode ID |
|
|
365
|
-
| source | TEXT | Kaynak (session ID, hook adı) |
|
|
366
|
-
| created_at | TEXT | Oluşturulma zamanı |
|
|
367
|
-
| consolidation_status | TEXT | raw, consolidated |
|
|
368
|
-
| consolidated_into | TEXT | Konsolide edildiği episode ID |
|
|
369
|
-
| decay_score | REAL | 0.0–1.0 (1.0 = taze) |
|
|
370
|
-
| last_decay_calc | TEXT | Son decay hesaplama zamanı |
|
|
371
|
-
|
|
372
|
-
### skill_memory
|
|
373
|
-
|
|
374
|
-
Skill'lerin kalıcı belleği — fork'lar arası veri paylaşımı.
|
|
375
|
-
|
|
376
|
-
| Kolon | Tip | Açıklama |
|
|
377
|
-
|-------|-----|----------|
|
|
378
|
-
| key | TEXT PK | Skill + anahtar adı |
|
|
379
|
-
| value | TEXT | JSON veya düz metin |
|
|
380
|
-
| updated_at | TEXT | Son güncelleme |
|
|
381
|
-
|
|
382
|
-
## 11. Agents
|
|
383
|
-
|
|
384
|
-
3 agent tanımlı (`agents/` dizini). Model routing `model-router` hook'u tarafından yapılır.
|
|
385
|
-
|
|
386
|
-
| Agent | Model | Görev |
|
|
387
|
-
|-------|-------|-------|
|
|
388
|
-
| mindlore-assistant | sonnet | Genel KB asistanı — query, ingest yönlendirme |
|
|
389
|
-
| mindlore-researcher | sonnet | Araştırma — web fetch, kaynak analizi |
|
|
390
|
-
| mindlore-librarian | haiku | Organizasyon — tag, kategori, duplicate tespiti |
|
package/templates/config.json
CHANGED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/** @deprecated Use search-engine.ts + rrf.ts instead. Kept for backward compat until Faz 3. */
|
|
2
|
-
import type BetterSqlite3 from 'better-sqlite3';
|
|
3
|
-
type Database = BetterSqlite3.Database;
|
|
4
|
-
export interface FtsResult {
|
|
5
|
-
slug: string;
|
|
6
|
-
rank: number;
|
|
7
|
-
path?: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
title?: string;
|
|
10
|
-
category?: string;
|
|
11
|
-
tags?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface VecResult {
|
|
14
|
-
slug: string;
|
|
15
|
-
distance: number;
|
|
16
|
-
}
|
|
17
|
-
export interface FusedResult {
|
|
18
|
-
slug: string;
|
|
19
|
-
score: number;
|
|
20
|
-
ftsRank?: number;
|
|
21
|
-
vecDistance?: number;
|
|
22
|
-
path?: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
title?: string;
|
|
25
|
-
category?: string;
|
|
26
|
-
tags?: string;
|
|
27
|
-
}
|
|
28
|
-
export interface RRFOptions {
|
|
29
|
-
k?: number;
|
|
30
|
-
ftsWeight?: number;
|
|
31
|
-
vecWeight?: number;
|
|
32
|
-
}
|
|
33
|
-
export interface HybridSearchOptions {
|
|
34
|
-
maxResults?: number;
|
|
35
|
-
k?: number;
|
|
36
|
-
ftsWeight?: number;
|
|
37
|
-
vecWeight?: number;
|
|
38
|
-
synonyms?: Record<string, string[]>;
|
|
39
|
-
project?: string;
|
|
40
|
-
queryEmbedding?: number[];
|
|
41
|
-
}
|
|
42
|
-
export declare function getCategoryWeight(category: string): number;
|
|
43
|
-
/**
|
|
44
|
-
* Convert L2 distance to cosine similarity.
|
|
45
|
-
* For normalized vectors: cosine_sim = 1.0 - (l2_dist² / 2.0)
|
|
46
|
-
*/
|
|
47
|
-
export declare function l2ToCosine(l2Distance: number): number;
|
|
48
|
-
/**
|
|
49
|
-
* Normalize FTS5 BM25 rank to 0-1 range.
|
|
50
|
-
* FTS5 returns negative rank — more negative = better match.
|
|
51
|
-
*/
|
|
52
|
-
export declare function normalizeBM25(rank: number): number;
|
|
53
|
-
export declare function computeRRF(ftsResults: FtsResult[], vecResults: VecResult[], options?: RRFOptions): FusedResult[];
|
|
54
|
-
export declare function searchFts5(db: Database, query: string, limit?: number, project?: string): FtsResult[];
|
|
55
|
-
export declare function searchVec(db: Database, queryEmbedding: number[], limit?: number): VecResult[];
|
|
56
|
-
/**
|
|
57
|
-
* Main hybrid search entry point.
|
|
58
|
-
* Falls back to pure FTS5 when vec table or embedding is not available.
|
|
59
|
-
*/
|
|
60
|
-
export declare function hybridSearch(db: Database, query: string, options?: HybridSearchOptions): FusedResult[];
|
|
61
|
-
export {};
|
|
62
|
-
//# sourceMappingURL=hybrid-search.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../scripts/lib/hybrid-search.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,KAAK,aAAa,MAAM,gBAAgB,CAAC;AAIhD,KAAK,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,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;CACf;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,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;CACf;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAcD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGrD;AAKD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAID,wBAAgB,UAAU,CACxB,UAAU,EAAE,SAAS,EAAE,EACvB,UAAU,EAAE,SAAS,EAAE,EACvB,OAAO,GAAE,UAAe,GACvB,WAAW,EAAE,CAsDf;AAID,wBAAgB,UAAU,CACxB,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAW,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,SAAS,EAAE,CA8Bb;AAED,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,EACZ,cAAc,EAAE,MAAM,EAAE,EACxB,KAAK,GAAE,MAAW,GACjB,SAAS,EAAE,CAeb;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,WAAW,EAAE,CAoCf"}
|