mindlore 0.5.9 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/README.md +20 -13
  2. package/SCHEMA.md +3 -2
  3. package/dist/scripts/fetch-raw.js +24 -0
  4. package/dist/scripts/fetch-raw.js.map +1 -1
  5. package/dist/scripts/init.js +48 -7
  6. package/dist/scripts/init.js.map +1 -1
  7. package/dist/scripts/lib/backfill.d.ts.map +1 -1
  8. package/dist/scripts/lib/backfill.js +5 -18
  9. package/dist/scripts/lib/backfill.js.map +1 -1
  10. package/dist/scripts/lib/constants.d.ts +4 -0
  11. package/dist/scripts/lib/constants.d.ts.map +1 -1
  12. package/dist/scripts/lib/constants.js +13 -1
  13. package/dist/scripts/lib/constants.js.map +1 -1
  14. package/dist/scripts/lib/contradiction.d.ts.map +1 -1
  15. package/dist/scripts/lib/contradiction.js +11 -20
  16. package/dist/scripts/lib/contradiction.js.map +1 -1
  17. package/dist/scripts/lib/daemon.d.ts +1 -0
  18. package/dist/scripts/lib/daemon.d.ts.map +1 -1
  19. package/dist/scripts/lib/daemon.js +1 -0
  20. package/dist/scripts/lib/daemon.js.map +1 -1
  21. package/dist/scripts/lib/decay.d.ts.map +1 -1
  22. package/dist/scripts/lib/decay.js +3 -0
  23. package/dist/scripts/lib/decay.js.map +1 -1
  24. package/dist/scripts/lib/embedding.js +4 -4
  25. package/dist/scripts/lib/embedding.js.map +1 -1
  26. package/dist/scripts/lib/hybrid-search.d.ts +1 -0
  27. package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
  28. package/dist/scripts/lib/hybrid-search.js +16 -1
  29. package/dist/scripts/lib/hybrid-search.js.map +1 -1
  30. package/dist/scripts/lib/migrations-v061.d.ts +3 -0
  31. package/dist/scripts/lib/migrations-v061.d.ts.map +1 -0
  32. package/dist/scripts/lib/migrations-v061.js +58 -0
  33. package/dist/scripts/lib/migrations-v061.js.map +1 -0
  34. package/dist/scripts/maintain-cleanup.d.ts +13 -0
  35. package/dist/scripts/maintain-cleanup.d.ts.map +1 -0
  36. package/dist/scripts/maintain-cleanup.js +93 -0
  37. package/dist/scripts/maintain-cleanup.js.map +1 -0
  38. package/dist/scripts/mindlore-daemon.js +1 -0
  39. package/dist/scripts/mindlore-daemon.js.map +1 -1
  40. package/dist/scripts/mindlore-doctor.d.ts +17 -0
  41. package/dist/scripts/mindlore-doctor.d.ts.map +1 -0
  42. package/dist/scripts/mindlore-doctor.js +218 -0
  43. package/dist/scripts/mindlore-doctor.js.map +1 -0
  44. package/dist/scripts/mindlore-fts5-index.js +16 -3
  45. package/dist/scripts/mindlore-fts5-index.js.map +1 -1
  46. package/dist/scripts/mindlore-fts5-search.js +12 -10
  47. package/dist/scripts/mindlore-fts5-search.js.map +1 -1
  48. package/dist/scripts/mindlore-perf.d.ts +22 -0
  49. package/dist/scripts/mindlore-perf.d.ts.map +1 -0
  50. package/dist/scripts/mindlore-perf.js +128 -0
  51. package/dist/scripts/mindlore-perf.js.map +1 -0
  52. package/dist/tests/decay.test.js +29 -0
  53. package/dist/tests/decay.test.js.map +1 -1
  54. package/dist/tests/doctor.test.d.ts +2 -0
  55. package/dist/tests/doctor.test.d.ts.map +1 -0
  56. package/dist/tests/doctor.test.js +69 -0
  57. package/dist/tests/doctor.test.js.map +1 -0
  58. package/dist/tests/embedding-hf-integration.test.d.ts +2 -0
  59. package/dist/tests/embedding-hf-integration.test.d.ts.map +1 -0
  60. package/dist/tests/embedding-hf-integration.test.js +52 -0
  61. package/dist/tests/embedding-hf-integration.test.js.map +1 -0
  62. package/dist/tests/embedding.test.d.ts +1 -1
  63. package/dist/tests/embedding.test.js +2 -2
  64. package/dist/tests/embedding.test.js.map +1 -1
  65. package/dist/tests/fts5.test.js +28 -0
  66. package/dist/tests/fts5.test.js.map +1 -1
  67. package/dist/tests/hook-smoke.test.js +27 -0
  68. package/dist/tests/hook-smoke.test.js.map +1 -1
  69. package/dist/tests/hybrid-search.test.js +25 -0
  70. package/dist/tests/hybrid-search.test.js.map +1 -1
  71. package/dist/tests/maintain-cleanup.test.d.ts +2 -0
  72. package/dist/tests/maintain-cleanup.test.d.ts.map +1 -0
  73. package/dist/tests/maintain-cleanup.test.js +65 -0
  74. package/dist/tests/maintain-cleanup.test.js.map +1 -0
  75. package/dist/tests/migrations-v061.test.d.ts +2 -0
  76. package/dist/tests/migrations-v061.test.d.ts.map +1 -0
  77. package/dist/tests/migrations-v061.test.js +70 -0
  78. package/dist/tests/migrations-v061.test.js.map +1 -0
  79. package/dist/tests/quality-populate.test.js +10 -0
  80. package/dist/tests/quality-populate.test.js.map +1 -1
  81. package/dist/tests/session-focus.test.js +15 -0
  82. package/dist/tests/session-focus.test.js.map +1 -1
  83. package/dist/tests/sqlite-vec-v12.test.d.ts +2 -0
  84. package/dist/tests/sqlite-vec-v12.test.d.ts.map +1 -0
  85. package/dist/tests/sqlite-vec-v12.test.js +72 -0
  86. package/dist/tests/sqlite-vec-v12.test.js.map +1 -0
  87. package/dist/tests/telemetry-perf.test.d.ts +2 -0
  88. package/dist/tests/telemetry-perf.test.d.ts.map +1 -0
  89. package/dist/tests/telemetry-perf.test.js +58 -0
  90. package/dist/tests/telemetry-perf.test.js.map +1 -0
  91. package/dist/tests/telemetry.test.d.ts +2 -0
  92. package/dist/tests/telemetry.test.d.ts.map +1 -0
  93. package/dist/tests/telemetry.test.js +55 -0
  94. package/dist/tests/telemetry.test.js.map +1 -0
  95. package/hooks/lib/mindlore-common.cjs +104 -9
  96. package/hooks/mindlore-cwd-changed.cjs +2 -2
  97. package/hooks/mindlore-decision-detector.cjs +5 -2
  98. package/hooks/mindlore-dont-repeat.cjs +2 -2
  99. package/hooks/mindlore-fts5-sync.cjs +14 -5
  100. package/hooks/mindlore-index.cjs +5 -2
  101. package/hooks/mindlore-model-router.cjs +2 -2
  102. package/hooks/mindlore-post-compact.cjs +5 -2
  103. package/hooks/mindlore-post-read.cjs +2 -2
  104. package/hooks/mindlore-pre-compact.cjs +6 -2
  105. package/hooks/mindlore-read-guard.cjs +2 -2
  106. package/hooks/mindlore-research-guard.cjs +2 -2
  107. package/hooks/mindlore-search.cjs +24 -12
  108. package/hooks/mindlore-session-end.cjs +22 -10
  109. package/hooks/mindlore-session-focus.cjs +27 -25
  110. package/package.json +7 -4
  111. package/plugin.json +1 -1
  112. package/templates/SCHEMA.md +2 -0
  113. package/templates/config.json +1 -1
@@ -18,7 +18,7 @@
18
18
  const fs = require('fs');
19
19
  const path = require('path');
20
20
  const os = require('os');
21
- const { findMindloreDir, getProjectName, hookLog } = require('./lib/mindlore-common.cjs');
21
+ const { findMindloreDir, getProjectName, hookLog, withTelemetrySync } = require('./lib/mindlore-common.cjs');
22
22
 
23
23
  /**
24
24
  * File-persisted pattern cache — survives across process invocations.
@@ -219,4 +219,4 @@ function main() {
219
219
  });
220
220
  }
221
221
 
222
- try { main(); } catch (err) { hookLog('dont-repeat', 'error', err?.message ?? String(err)); }
222
+ try { withTelemetrySync('mindlore-dont-repeat', main); } catch (err) { hookLog('dont-repeat', 'error', err?.message ?? String(err)); }
@@ -13,7 +13,7 @@
13
13
 
14
14
  const fs = require('fs');
15
15
  const path = require('path');
16
- const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName, resolveProject, hookLog } = require('./lib/mindlore-common.cjs');
16
+ const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName, resolveProject, hookLog, withTelemetry, SQL_FTS_SESSIONS_INSERT, isSessionCategory } = require('./lib/mindlore-common.cjs');
17
17
 
18
18
  function main() {
19
19
  const filePath = readHookStdin(['path', 'file_path']);
@@ -39,6 +39,8 @@ function main() {
39
39
 
40
40
  const getHash = db.prepare('SELECT content_hash FROM file_hashes WHERE path = ?');
41
41
  const deleteFts = db.prepare('DELETE FROM mindlore_fts WHERE path = ?');
42
+ const deleteFtsSessions = db.prepare('DELETE FROM mindlore_fts_sessions WHERE path = ?');
43
+ const insertFtsSessions = db.prepare(SQL_FTS_SESSIONS_INSERT);
42
44
  const upsertHash = db.prepare(`
43
45
  INSERT INTO file_hashes (path, content_hash, last_indexed)
44
46
  VALUES (?, ?, ?)
@@ -61,8 +63,14 @@ function main() {
61
63
 
62
64
  const { meta, body } = parseFrontmatter(content);
63
65
  const { slug, description, type, category, title, tags, quality, dateCaptured, project: ftsProject } = extractFtsMetadata(meta, body, file, baseDir);
66
+ const resolvedProject = resolveProject(ftsProject, file, project);
64
67
  deleteFts.run(file);
65
- insertFtsRow(db, { path: file, slug, description, type, category, title, content: body, tags, quality, dateCaptured, project: resolveProject(ftsProject, file, project) });
68
+ deleteFtsSessions.run(file);
69
+ if (isSessionCategory(category)) {
70
+ insertFtsSessions.run(file, slug, description, type, category, title, body, tags, quality ?? null, dateCaptured ?? null, resolvedProject);
71
+ } else {
72
+ insertFtsRow(db, { path: file, slug, description, type, category, title, content: body, tags, quality, dateCaptured, project: resolvedProject });
73
+ }
66
74
  upsertHash.run(file, hash, now);
67
75
  }
68
76
  });
@@ -71,8 +79,9 @@ function main() {
71
79
  db.close();
72
80
  }
73
81
 
74
- // FileChanged event stdout'u yutulur — log gerekiyorsa dosyaya yaz
75
- // process.stdout.write kaldırıldı (kimse görmüyor)
76
82
  }
77
83
 
78
- try { main(); } catch (err) { hookLog('fts5-sync', 'error', err?.message ?? String(err)); }
84
+ withTelemetry('mindlore-fts5-sync', main).catch(err => {
85
+ hookLog('mindlore-fts5-sync', 'error', err?.message ?? String(err));
86
+ process.exit(0);
87
+ });
@@ -10,7 +10,7 @@
10
10
 
11
11
  const fs = require('fs');
12
12
  const path = require('path');
13
- const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getProjectName, resolveProject, globalDir, hookLog } = require('./lib/mindlore-common.cjs');
13
+ const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getProjectName, resolveProject, globalDir, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
14
14
 
15
15
  function main() {
16
16
  const filePath = readHookStdin(['path', 'file_path']);
@@ -218,4 +218,7 @@ function catchUpScan(baseDir, dbPath) {
218
218
  }
219
219
  }
220
220
 
221
- main();
221
+ withTelemetry('mindlore-index', main).catch(err => {
222
+ hookLog('mindlore-index', 'error', err?.message ?? String(err));
223
+ process.exit(0);
224
+ });
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  const fs = require('fs');
9
- const { findMindloreDir, readConfig, DEFAULT_MODELS, hookLog } = require('./lib/mindlore-common.cjs');
9
+ const { findMindloreDir, readConfig, DEFAULT_MODELS, hookLog, withTelemetrySync } = require('./lib/mindlore-common.cjs');
10
10
 
11
11
  const SKILL_KEYS = Object.keys(DEFAULT_MODELS).filter((k) => k !== 'default');
12
12
  const MARKER_REGEX = new RegExp(`\\[mindlore:(${SKILL_KEYS.join('|')})\\]`);
@@ -51,4 +51,4 @@ function main() {
51
51
  process.stdout.write(JSON.stringify(output));
52
52
  }
53
53
 
54
- try { main(); } catch (err) { hookLog('model-router', 'error', err?.message ?? String(err)); }
54
+ try { withTelemetrySync('mindlore-model-router', main); } catch (err) { hookLog('model-router', 'error', err?.message ?? String(err)); }
@@ -14,7 +14,7 @@
14
14
 
15
15
  const fs = require('fs');
16
16
  const path = require('path');
17
- const { findMindloreDir, getLatestDelta, hookLog } = require('./lib/mindlore-common.cjs');
17
+ const { findMindloreDir, getLatestDelta, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
18
18
 
19
19
  function main() {
20
20
  const baseDir = findMindloreDir();
@@ -43,4 +43,7 @@ function main() {
43
43
  }
44
44
  }
45
45
 
46
- try { main(); } catch (err) { hookLog('post-compact', 'error', err?.message ?? String(err)); }
46
+ withTelemetry('mindlore-post-compact', main).catch(err => {
47
+ hookLog('mindlore-post-compact', 'error', err?.message ?? String(err));
48
+ process.exit(0);
49
+ });
@@ -13,7 +13,7 @@
13
13
 
14
14
  const fs = require('fs');
15
15
  const path = require('path');
16
- const { findMindloreDir, getProjectName, hookLog } = require('./lib/mindlore-common.cjs');
16
+ const { findMindloreDir, getProjectName, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
17
17
 
18
18
  const CODE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.rs', '.go', '.java', '.c', '.cpp', '.h', '.css', '.scss', '.sql', '.sh', '.yaml', '.yml', '.json', '.toml', '.xml', '.cjs', '.mjs']);
19
19
  const PROSE_EXTS = new Set(['.md', '.txt', '.rst', '.adoc']);
@@ -103,4 +103,4 @@ function main() {
103
103
  });
104
104
  }
105
105
 
106
- try { main(); } catch (err) { hookLog('post-read', 'error', err?.message ?? String(err)); }
106
+ withTelemetry('mindlore-post-read', main).catch(err => { hookLog('post-read', 'error', err?.message ?? String(err)); });
@@ -11,7 +11,7 @@
11
11
 
12
12
  const fs = require('fs');
13
13
  const path = require('path');
14
- const { findMindloreDir, hookLog } = require('./lib/mindlore-common.cjs');
14
+ const { findMindloreDir, hookLog, withTelemetry } = require('./lib/mindlore-common.cjs');
15
15
 
16
16
  function main() {
17
17
  const baseDir = findMindloreDir();
@@ -25,6 +25,7 @@ function main() {
25
25
  spawnSync('node', [indexScript, baseDir], {
26
26
  timeout: 10000,
27
27
  stdio: 'pipe',
28
+ windowsHide: true,
28
29
  });
29
30
  } catch (_err) {
30
31
  // Non-fatal — index might fail if better-sqlite3 not available
@@ -63,4 +64,7 @@ function main() {
63
64
  process.stdout.write('[Mindlore: pre-compact FTS5 flush complete]\n');
64
65
  }
65
66
 
66
- try { main(); } catch (err) { hookLog('pre-compact', 'error', err?.message ?? String(err)); }
67
+ withTelemetry('mindlore-pre-compact', main).catch(err => {
68
+ hookLog('mindlore-pre-compact', 'error', err?.message ?? String(err));
69
+ process.exit(0);
70
+ });
@@ -14,7 +14,7 @@
14
14
 
15
15
  const fs = require('fs');
16
16
  const path = require('path');
17
- const { findMindloreDir, readHookStdin, getProjectName, hookLog, extractSkeleton } = require('./lib/mindlore-common.cjs');
17
+ const { findMindloreDir, readHookStdin, getProjectName, hookLog, extractSkeleton, withTelemetrySync } = require('./lib/mindlore-common.cjs');
18
18
 
19
19
  function main() {
20
20
  const baseDir = findMindloreDir();
@@ -102,4 +102,4 @@ function main() {
102
102
  }
103
103
  }
104
104
 
105
- try { main(); } catch (err) { hookLog('read-guard', 'error', err?.message ?? String(err)); }
105
+ try { withTelemetrySync('mindlore-read-guard', main); } catch (err) { hookLog('read-guard', 'error', err?.message ?? String(err)); }
@@ -14,7 +14,7 @@
14
14
 
15
15
  const fs = require('fs');
16
16
  const path = require('path');
17
- const { getAllDbs, requireDatabase, extractKeywords, sanitizeKeyword, hookLog } = require('./lib/mindlore-common.cjs');
17
+ const { getAllDbs, requireDatabase, extractKeywords, sanitizeKeyword, hookLog, withTelemetrySync } = require('./lib/mindlore-common.cjs');
18
18
 
19
19
  // Keywords that signal a research/web-search intent in agent prompts
20
20
  // Note: entries with dots/stars are regex patterns, rest are literals
@@ -173,4 +173,4 @@ function main() {
173
173
  process.stdout.write(JSON.stringify(output));
174
174
  }
175
175
 
176
- try { main(); } catch (err) { hookLog('research-guard', 'error', err?.message ?? String(err)); }
176
+ try { withTelemetrySync('mindlore-research-guard', main); } catch (err) { hookLog('research-guard', 'error', err?.message ?? String(err)); }
@@ -10,7 +10,7 @@
10
10
 
11
11
  const fs = require('fs');
12
12
  const path = require('path');
13
- const { getAllDbs, openDatabase, extractHeadings, readHookStdin, extractKeywords, sanitizeKeyword, readConfig, loadSqliteVecCjs, hasVecTableCjs, hookLog, incrementRecallCount, getDaemonPortFile } = require('./lib/mindlore-common.cjs');
13
+ const { getAllDbs, openDatabase, extractHeadings, readHookStdin, extractKeywords, sanitizeKeyword, readConfig, loadSqliteVecCjs, hasVecTableCjs, hookLog, incrementRecallCount, getDaemonPortFile, withTelemetry, fixVersionTokens } = require('./lib/mindlore-common.cjs');
14
14
 
15
15
  const { execFileSync } = require('child_process');
16
16
 
@@ -33,7 +33,7 @@ function requestEmbeddingSync(query) {
33
33
  const clientScript = path.join(__dirname, '..', 'scripts', 'lib', 'daemon-client.js');
34
34
  if (!fs.existsSync(clientScript)) return null;
35
35
  const result = execFileSync(process.execPath, [clientScript, portFile, query, '300'], {
36
- timeout: 500, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe']
36
+ timeout: 500, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true,
37
37
  });
38
38
  const parsed = JSON.parse(result.trim());
39
39
  return parsed.type === 'embedding' ? parsed.embedding : null;
@@ -122,11 +122,21 @@ function searchDb(dbPath, keywords) {
122
122
  const sanitized = keywords.map(sanitizeKeyword).filter(Boolean);
123
123
  if (sanitized.length === 0) { db.close(); return results; }
124
124
 
125
- const ftsQuery = sanitized.join(' OR ');
126
- const rows = db.prepare(
125
+ const ftsQuery = fixVersionTokens(sanitized.join(' OR '));
126
+ const project = path.basename(process.cwd());
127
+
128
+ // v0.6.1: Project-scoped search with global fallback
129
+ let rows = db.prepare(
127
130
  `SELECT path, slug, description, category, title, tags, rank
128
- FROM mindlore_fts WHERE mindlore_fts MATCH ? ORDER BY rank LIMIT ?`
129
- ).all(ftsQuery, MAX_RESULTS * 2);
131
+ FROM mindlore_fts WHERE project = ? AND mindlore_fts MATCH ? ORDER BY rank LIMIT ?`
132
+ ).all(project, ftsQuery, MAX_RESULTS * 2);
133
+
134
+ if (rows.length === 0) {
135
+ rows = db.prepare(
136
+ `SELECT path, slug, description, category, title, tags, rank
137
+ FROM mindlore_fts WHERE mindlore_fts MATCH ? ORDER BY rank LIMIT ?`
138
+ ).all(ftsQuery, MAX_RESULTS * 2);
139
+ }
130
140
 
131
141
  for (const r of rows) {
132
142
  results.push({
@@ -237,17 +247,16 @@ function main() {
237
247
  let totalUsed = 0;
238
248
  for (const r of relevant) {
239
249
  if (totalUsed >= totalChars) break;
240
- const meta = r.meta || {};
241
250
  const relativePath = path.relative(r.baseDir, r.path).replace(/\\/g, '/');
242
251
 
243
252
  const headings = r.headings || [];
244
253
 
245
- const category = meta.category || path.dirname(relativePath).split('/')[0];
246
- const title = meta.title || meta.slug || path.basename(r.path, '.md');
247
- const description = meta.description || '';
254
+ const category = r.category || path.dirname(relativePath).split('/')[0];
255
+ const title = r.title || r.slug || path.basename(r.path, '.md');
256
+ const description = r.description || '';
248
257
 
249
258
  const headingStr = headings.length > 0 ? `\nBasliklar: ${headings.join(', ')}` : '';
250
- const tagsStr = meta.tags ? `\nTags: ${meta.tags}` : '';
259
+ const tagsStr = r.tags ? `\nTags: ${r.tags}` : '';
251
260
  const entry = `[Mindlore: ${category}/${title}] ${description}\nDosya: ${relativePath}${tagsStr}${headingStr}`;
252
261
  const truncated = entry.slice(0, perResultChars);
253
262
  totalUsed += truncated.length;
@@ -307,4 +316,7 @@ function main() {
307
316
  }
308
317
  }
309
318
 
310
- try { main(); } catch (err) { hookLog('search', 'error', err?.message ?? String(err)); }
319
+ withTelemetry('mindlore-search', main).catch(err => {
320
+ hookLog('mindlore-search', 'error', err?.message ?? String(err));
321
+ process.exit(0);
322
+ });
@@ -13,7 +13,7 @@ const fs = require('fs');
13
13
  const path = require('path');
14
14
  const os = require('os');
15
15
  const { execSync, execFileSync, spawn } = require('child_process');
16
- const { findMindloreDir, globalDir, getProjectName, openDatabase, ensureEpisodesTable, hasEpisodesTable, insertBareEpisode, insertFtsRow, hookLog, SHARED_EXPORT_DIRS, resolveWin32Bin } = require('./lib/mindlore-common.cjs');
16
+ const { findMindloreDir, globalDir, getProjectName, openDatabase, ensureEpisodesTable, hasEpisodesTable, insertBareEpisode, insertFtsRow, hookLog, SHARED_EXPORT_DIRS, resolveWin32Bin, withTelemetry } = require('./lib/mindlore-common.cjs');
17
17
 
18
18
  const EXPORT_DIRS = SHARED_EXPORT_DIRS;
19
19
 
@@ -54,6 +54,7 @@ if (process.argv.includes('--worker')) {
54
54
  execFileSync(nodeExe, [scriptPath, ...args], {
55
55
  timeout: timeoutMs,
56
56
  env: { ...process.env, MINDLORE_HOME: baseDir },
57
+ windowsHide: true,
57
58
  });
58
59
  hookLog('session-end', 'info', label + ' completed');
59
60
  } catch (err) {
@@ -112,6 +113,7 @@ function getRecentGitInfo() {
112
113
  encoding: 'utf8',
113
114
  timeout: 5000,
114
115
  stdio: ['pipe', 'pipe', 'pipe'],
116
+ windowsHide: true,
115
117
  }).trim();
116
118
  if (!raw) return { commits: [], changedFiles: [] };
117
119
 
@@ -234,6 +236,7 @@ function main() {
234
236
  detached: true,
235
237
  stdio: 'ignore',
236
238
  cwd: process.cwd(),
239
+ windowsHide: true,
237
240
  });
238
241
  child.unref();
239
242
  } catch (_err) {
@@ -369,19 +372,25 @@ function writeEpisodeFile(baseDir, project, commits, changedFiles, reads) {
369
372
  fs.writeFileSync(filePath, lines.join('\n'), 'utf8');
370
373
  }
371
374
 
375
+ let _obsidianHelpersCache = undefined; // undefined = not yet attempted
372
376
  /**
373
377
  * Load obsidian-helpers from compiled dist (single source of truth for wikilink conversion).
374
378
  * Returns null if helpers not available (e.g. dev environment without build).
379
+ * Result is cached — require() runs at most once per process.
375
380
  */
376
- function loadObsidianHelpers() {
381
+ function getObsidianHelpers() {
382
+ if (_obsidianHelpersCache !== undefined) return _obsidianHelpersCache;
377
383
  try {
378
- // Resolve from package root (hooks/ is sibling to dist/)
379
384
  const hookDir = __dirname;
380
385
  const pkgRoot = path.dirname(hookDir);
381
386
  const helpersPath = path.join(pkgRoot, 'dist', 'scripts', 'lib', 'obsidian-helpers.js');
382
- if (!fs.existsSync(helpersPath)) return null;
383
- return require(helpersPath);
384
- } catch (_err) {
387
+ _obsidianHelpersCache = require(helpersPath);
388
+ return _obsidianHelpersCache;
389
+ } catch (err) {
390
+ if (process.env.MINDLORE_DEBUG === '1') {
391
+ process.stderr.write(`[mindlore] obsidian-helpers not available: ${err.message}\n`);
392
+ }
393
+ _obsidianHelpersCache = null;
385
394
  return null;
386
395
  }
387
396
  }
@@ -419,7 +428,7 @@ function syncObsidian(baseDir) {
419
428
  if (!vaultPath || typeof vaultPath !== 'string') return;
420
429
  if (!fs.existsSync(vaultPath)) return;
421
430
 
422
- const helpers = loadObsidianHelpers();
431
+ const helpers = getObsidianHelpers();
423
432
  // Fallback regex if helpers unavailable (strips path prefixes like the canonical version)
424
433
  const convertFn = helpers?.convertToWikilinks
425
434
  ?? ((c) => c.replace(/\[([^\]]+)\]\((?:\.\.?\/)?(?:[\w-]+\/)*([^/)]+)\.md\)/g, '[[$2]]'));
@@ -484,7 +493,7 @@ function syncGlobalRepo() {
484
493
  if (!fs.existsSync(gitDir)) return;
485
494
 
486
495
  const git = resolveGitBin();
487
- const execOpts = (timeout) => ({ cwd: gDir, encoding: 'utf8', timeout, stdio: 'pipe' });
496
+ const execOpts = (timeout) => ({ cwd: gDir, encoding: 'utf8', timeout, stdio: 'pipe', windowsHide: true });
488
497
 
489
498
  // Check for changes
490
499
  const status = execSync(`"${git}" status --porcelain`, execOpts(5000)).trim();
@@ -496,12 +505,15 @@ function syncGlobalRepo() {
496
505
 
497
506
  // Push — graceful fail if no remote or offline
498
507
  try {
499
- execSync(`"${git}" push`, execOpts(15000));
508
+ execSync(`"${git}" push`, execOpts(30000));
500
509
  } catch (_pushErr) {
501
510
  hookLog('session-end', 'warn', 'git push failed (offline?): ' + (_pushErr?.message ?? '').slice(0, 100));
502
511
  }
503
512
  }
504
513
 
505
514
  if (!process.argv.includes('--worker')) {
506
- main();
515
+ withTelemetry('mindlore-session-end', main).catch(err => {
516
+ hookLog('mindlore-session-end', 'error', err?.message ?? String(err));
517
+ process.exit(0);
518
+ });
507
519
  }
@@ -10,7 +10,7 @@
10
10
 
11
11
  const fs = require('fs');
12
12
  const path = require('path');
13
- const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, isDaemonRunning, getDaemonPidFile } = require('./lib/mindlore-common.cjs');
13
+ const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry } = require('./lib/mindlore-common.cjs');
14
14
 
15
15
  function main() {
16
16
  const baseDir = findMindloreDir();
@@ -71,7 +71,28 @@ function main() {
71
71
  try {
72
72
  const dbPath = path.join(baseDir, 'mindlore.db');
73
73
  const db = openDatabase(dbPath, { readonly: true });
74
+
74
75
  if (db) {
76
+ // v0.6.1: Integrity check — auto-recover corrupt DB
77
+ const recoverCorruptDb = (reason) => {
78
+ db.close();
79
+ const bakPath = dbPath + '.corrupt.bak';
80
+ try { fs.copyFileSync(dbPath, bakPath); } catch { /* best effort */ }
81
+ try { fs.unlinkSync(dbPath); } catch { /* best effort */ }
82
+ hookLog('session-focus', 'warn', reason);
83
+ if (output.length > 0) process.stdout.write(output.join('\n\n'));
84
+ };
85
+ try {
86
+ const check = db.pragma('integrity_check(1)');
87
+ const result = Array.isArray(check) ? check[0]?.integrity_check : check;
88
+ if (result !== 'ok') {
89
+ recoverCorruptDb(`Corrupt DB detected, backed up. Run 'npm run index' to rebuild.`);
90
+ return;
91
+ }
92
+ } catch (err) {
93
+ recoverCorruptDb(`DB integrity check failed: ${err.message}`);
94
+ return;
95
+ }
75
96
  try {
76
97
  // Session payload: Session summary, Decisions, Friction, Learnings
77
98
  try {
@@ -137,33 +158,14 @@ function main() {
137
158
  joined = joined.slice(0, maxInjectChars) + '\n[...truncated by token budget]';
138
159
  }
139
160
 
140
- // v0.5.5: Auto-start embedding daemon if not already running
141
- // Skip in test environments to avoid file lock issues
142
- const skipDaemon = process.env.NODE_ENV === 'test' || baseDir.includes('.test-');
143
- if (!skipDaemon) {
144
- try {
145
- const status = isDaemonRunning(getDaemonPidFile());
146
- if (!status.running) {
147
- const daemonScript = path.join(__dirname, '..', 'dist', 'scripts', 'mindlore-daemon.js');
148
- if (fs.existsSync(daemonScript)) {
149
- const { spawn } = require('child_process');
150
- const child = spawn(process.execPath, [daemonScript, 'start'], {
151
- detached: true,
152
- stdio: 'ignore',
153
- windowsHide: true,
154
- });
155
- child.unref();
156
- hookLog('session-focus', 'info', 'Daemon auto-started, pid=' + child.pid);
157
- }
158
- }
159
- } catch (_err) {
160
- hookLog('session-focus', 'warn', 'Daemon auto-start failed: ' + (_err?.message || _err));
161
- }
162
- }
161
+ // v0.6.1: Daemon auto-start removed (daemon deprecated MCP Server in v0.7)
163
162
 
164
163
  if (joined.length > 0) {
165
164
  process.stdout.write(joined + '\n');
166
165
  }
167
166
  }
168
167
 
169
- main();
168
+ withTelemetry('mindlore-session-focus', main).catch(err => {
169
+ hookLog('mindlore-session-focus', 'error', err?.message ?? String(err));
170
+ process.exit(0);
171
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindlore",
3
- "version": "0.5.9",
3
+ "version": "0.6.1",
4
4
  "description": "AI-native knowledge system for Claude Code",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -19,7 +19,10 @@
19
19
  "search": "node dist/scripts/mindlore-fts5-search.js",
20
20
  "quality": "node dist/scripts/quality-populate.js",
21
21
  "fetch-raw": "node dist/scripts/fetch-raw.js",
22
- "cc-sync": "node dist/scripts/cc-memory-bulk-sync.js"
22
+ "cc-sync": "node dist/scripts/cc-memory-bulk-sync.js",
23
+ "cleanup": "node dist/scripts/maintain-cleanup.js",
24
+ "perf": "node dist/scripts/mindlore-perf.js",
25
+ "doctor": "node dist/scripts/mindlore-doctor.js"
23
26
  },
24
27
  "keywords": [
25
28
  "claude-code",
@@ -45,7 +48,7 @@
45
48
  "node": ">=20.0.0"
46
49
  },
47
50
  "dependencies": {
48
- "better-sqlite3": "^11.10.0",
51
+ "better-sqlite3": "^12.9.0",
49
52
  "zod": "^4.3.6"
50
53
  },
51
54
  "devDependencies": {
@@ -54,7 +57,7 @@
54
57
  "@types/node": "^25.6.0",
55
58
  "@typescript-eslint/eslint-plugin": "^8.58.1",
56
59
  "@typescript-eslint/parser": "^8.58.1",
57
- "@xenova/transformers": "^2.17.2",
60
+ "@huggingface/transformers": "^4.2.0",
58
61
  "eslint": "^10.2.0",
59
62
  "globals": "^17.5.0",
60
63
  "jest": "^30.3.0",
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mindlore",
3
3
  "description": "AI-native knowledge system for Claude Code. Persistent, searchable, evolving knowledge base with FTS5.",
4
- "version": "0.5.9",
4
+ "version": "0.6.1",
5
5
  "skills": [
6
6
  {
7
7
  "name": "mindlore-ingest",
@@ -343,6 +343,8 @@ Dedup tablosu — content-hash ile aynı dosyanın tekrar indexlenmesini engelle
343
343
  | archived_at | TEXT | Arşivlenme zamanı (null = aktif) |
344
344
  | importance | REAL | Kalite→önem dönüşümü (0.0–1.0) |
345
345
 
346
+ > v0.6.0: `QUALITY_HEURISTICS` artık `cc-session`/`cc-subagent` source_type'larını tanıyor (önce eksikti).
347
+
346
348
  ### episodes
347
349
 
348
350
  Session ve bilgi olayları — decision, discovery, friction, learning, reflection.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.9",
2
+ "version": "0.6.1",
3
3
  "models": {
4
4
  "ingest": "haiku",
5
5
  "evolve": "sonnet",