mindlore 0.5.2 → 0.5.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.
Files changed (72) hide show
  1. package/README.md +2 -1
  2. package/dist/scripts/cc-memory-bulk-sync.d.ts +26 -0
  3. package/dist/scripts/cc-memory-bulk-sync.d.ts.map +1 -0
  4. package/dist/scripts/cc-memory-bulk-sync.js +177 -0
  5. package/dist/scripts/cc-memory-bulk-sync.js.map +1 -0
  6. package/dist/scripts/lib/consolidation.d.ts +17 -0
  7. package/dist/scripts/lib/consolidation.d.ts.map +1 -0
  8. package/dist/scripts/lib/consolidation.js +55 -0
  9. package/dist/scripts/lib/consolidation.js.map +1 -0
  10. package/dist/scripts/lib/constants.d.ts +3 -0
  11. package/dist/scripts/lib/constants.d.ts.map +1 -1
  12. package/dist/scripts/lib/constants.js +4 -1
  13. package/dist/scripts/lib/constants.js.map +1 -1
  14. package/dist/scripts/lib/decay.d.ts +21 -0
  15. package/dist/scripts/lib/decay.d.ts.map +1 -0
  16. package/dist/scripts/lib/decay.js +50 -0
  17. package/dist/scripts/lib/decay.js.map +1 -0
  18. package/dist/scripts/lib/migrations-v053.d.ts +3 -0
  19. package/dist/scripts/lib/migrations-v053.d.ts.map +1 -0
  20. package/dist/scripts/lib/migrations-v053.js +52 -0
  21. package/dist/scripts/lib/migrations-v053.js.map +1 -0
  22. package/dist/scripts/mindlore-backup.d.ts +1 -1
  23. package/dist/scripts/mindlore-backup.d.ts.map +1 -1
  24. package/dist/scripts/mindlore-backup.js +23 -0
  25. package/dist/scripts/mindlore-backup.js.map +1 -1
  26. package/dist/scripts/mindlore-fts5-index.js +2 -1
  27. package/dist/scripts/mindlore-fts5-index.js.map +1 -1
  28. package/dist/scripts/mindlore-health-check.js +35 -1
  29. package/dist/scripts/mindlore-health-check.js.map +1 -1
  30. package/dist/tests/cc-memory-bulk-sync.test.d.ts +2 -0
  31. package/dist/tests/cc-memory-bulk-sync.test.d.ts.map +1 -0
  32. package/dist/tests/cc-memory-bulk-sync.test.js +116 -0
  33. package/dist/tests/cc-memory-bulk-sync.test.js.map +1 -0
  34. package/dist/tests/consolidation.test.d.ts +2 -0
  35. package/dist/tests/consolidation.test.d.ts.map +1 -0
  36. package/dist/tests/consolidation.test.js +77 -0
  37. package/dist/tests/consolidation.test.js.map +1 -0
  38. package/dist/tests/decay.test.d.ts +2 -0
  39. package/dist/tests/decay.test.d.ts.map +1 -0
  40. package/dist/tests/decay.test.js +92 -0
  41. package/dist/tests/decay.test.js.map +1 -0
  42. package/dist/tests/git-snapshot.test.d.ts +2 -0
  43. package/dist/tests/git-snapshot.test.d.ts.map +1 -0
  44. package/dist/tests/git-snapshot.test.js +36 -0
  45. package/dist/tests/git-snapshot.test.js.map +1 -0
  46. package/dist/tests/migrations-v053.test.d.ts +2 -0
  47. package/dist/tests/migrations-v053.test.d.ts.map +1 -0
  48. package/dist/tests/migrations-v053.test.js +113 -0
  49. package/dist/tests/migrations-v053.test.js.map +1 -0
  50. package/dist/tests/recall-telemetry.test.d.ts +2 -0
  51. package/dist/tests/recall-telemetry.test.d.ts.map +1 -0
  52. package/dist/tests/recall-telemetry.test.js +56 -0
  53. package/dist/tests/recall-telemetry.test.js.map +1 -0
  54. package/dist/tests/skill-path-resolution.test.d.ts +2 -0
  55. package/dist/tests/skill-path-resolution.test.d.ts.map +1 -0
  56. package/dist/tests/skill-path-resolution.test.js +42 -0
  57. package/dist/tests/skill-path-resolution.test.js.map +1 -0
  58. package/hooks/lib/mindlore-common.cjs +29 -1
  59. package/hooks/mindlore-search.cjs +10 -1
  60. package/hooks/mindlore-session-focus.cjs +12 -0
  61. package/package.json +3 -2
  62. package/plugin.json +6 -1
  63. package/skills/mindlore-decide/SKILL.md +9 -0
  64. package/skills/mindlore-diary/SKILL.md +12 -3
  65. package/skills/mindlore-evolve/SKILL.md +24 -1
  66. package/skills/mindlore-health/SKILL.md +10 -1
  67. package/skills/mindlore-ingest/SKILL.md +26 -6
  68. package/skills/mindlore-log/SKILL.md +9 -0
  69. package/skills/mindlore-maintain/SKILL.md +119 -0
  70. package/skills/mindlore-query/SKILL.md +9 -0
  71. package/skills/mindlore-reflect/SKILL.md +31 -4
  72. package/templates/config.json +8 -1
@@ -0,0 +1,113 @@
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
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const schema_version_js_1 = require("../scripts/lib/schema-version.js");
11
+ const migrations_js_1 = require("../scripts/lib/migrations.js");
12
+ const migrations_v052_js_1 = require("../scripts/lib/migrations-v052.js");
13
+ const migrations_v053_js_1 = require("../scripts/lib/migrations-v053.js");
14
+ const ALL_MIGRATIONS = [...migrations_js_1.V050_MIGRATIONS, ...migrations_js_1.V051_MIGRATIONS, ...migrations_v052_js_1.V052_MIGRATIONS, ...migrations_v053_js_1.V053_MIGRATIONS];
15
+ const { SQL_FTS_CREATE } = require('../hooks/lib/mindlore-common.cjs');
16
+ function createBaseDb(dbPath) {
17
+ const db = new better_sqlite3_1.default(dbPath);
18
+ db.pragma('journal_mode = WAL');
19
+ db.exec(SQL_FTS_CREATE);
20
+ db.exec(`
21
+ CREATE TABLE IF NOT EXISTS file_hashes (
22
+ path TEXT PRIMARY KEY,
23
+ content_hash TEXT NOT NULL,
24
+ last_indexed TEXT NOT NULL
25
+ );
26
+ `);
27
+ (0, schema_version_js_1.ensureSchemaTable)(db);
28
+ return db;
29
+ }
30
+ function addEpisodesTable(db) {
31
+ db.exec(`
32
+ CREATE TABLE IF NOT EXISTS episodes (
33
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34
+ session_id TEXT NOT NULL,
35
+ timestamp TEXT NOT NULL,
36
+ summary TEXT NOT NULL,
37
+ project TEXT,
38
+ tags TEXT,
39
+ quality REAL DEFAULT 0.5
40
+ );
41
+ `);
42
+ }
43
+ describe('v0.5.3 Migrations', () => {
44
+ let tmpDir;
45
+ let dbPath;
46
+ beforeEach(() => {
47
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-v053-'));
48
+ dbPath = path_1.default.join(tmpDir, 'test.db');
49
+ });
50
+ afterEach(() => {
51
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
52
+ });
53
+ test('v4 should add recall_count and last_recalled_at to file_hashes', () => {
54
+ const db = createBaseDb(dbPath);
55
+ (0, schema_version_js_1.runMigrations)(db, ALL_MIGRATIONS);
56
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- test: pragma returns array of objects
57
+ const cols = db.pragma('table_info(file_hashes)');
58
+ const colNames = cols.map(c => c.name);
59
+ expect(colNames).toContain('recall_count');
60
+ expect(colNames).toContain('last_recalled_at');
61
+ expect(colNames).toContain('archived_at');
62
+ expect(colNames).toContain('importance');
63
+ db.close();
64
+ });
65
+ test('v5 should add consolidation columns to episodes', () => {
66
+ const db = createBaseDb(dbPath);
67
+ addEpisodesTable(db);
68
+ (0, schema_version_js_1.runMigrations)(db, ALL_MIGRATIONS);
69
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- test: pragma returns array of objects
70
+ const cols = db.pragma('table_info(episodes)');
71
+ const colNames = cols.map(c => c.name);
72
+ expect(colNames).toContain('consolidation_status');
73
+ expect(colNames).toContain('consolidated_into');
74
+ expect(colNames).toContain('decay_score');
75
+ expect(colNames).toContain('last_decay_calc');
76
+ db.close();
77
+ });
78
+ test('v4+v5 should not corrupt existing data (backward compat)', () => {
79
+ const db = createBaseDb(dbPath);
80
+ addEpisodesTable(db);
81
+ const now = new Date().toISOString();
82
+ db.prepare('INSERT INTO file_hashes (path, content_hash, last_indexed) VALUES (?, ?, ?)').run('/test/file.md', 'abc123', now);
83
+ db.prepare('INSERT INTO episodes (session_id, timestamp, summary, project) VALUES (?, ?, ?, ?)').run('sess-1', now, 'Test episode summary', 'mindlore');
84
+ (0, schema_version_js_1.runMigrations)(db, ALL_MIGRATIONS);
85
+ // Verify existing file_hashes row intact + new column defaults
86
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- test: better-sqlite3 .get() returns unknown
87
+ const fhRow = db.prepare('SELECT * FROM file_hashes WHERE path = ?').get('/test/file.md');
88
+ expect(fhRow.content_hash).toBe('abc123');
89
+ expect(fhRow.recall_count).toBe(0);
90
+ expect(fhRow.importance).toBe(1.0);
91
+ expect(fhRow.last_recalled_at).toBeNull();
92
+ expect(fhRow.archived_at).toBeNull();
93
+ // Verify existing episodes row intact + new column defaults
94
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- test: better-sqlite3 .get() returns unknown
95
+ const epRow = db.prepare('SELECT * FROM episodes WHERE session_id = ?').get('sess-1');
96
+ expect(epRow.summary).toBe('Test episode summary');
97
+ expect(epRow.consolidation_status).toBe('raw');
98
+ expect(epRow.consolidated_into).toBeNull();
99
+ expect(epRow.decay_score).toBeNull();
100
+ expect(epRow.last_decay_calc).toBeNull();
101
+ db.close();
102
+ });
103
+ test('migrations should be idempotent', () => {
104
+ const db = createBaseDb(dbPath);
105
+ addEpisodesTable(db);
106
+ expect(() => {
107
+ (0, schema_version_js_1.runMigrations)(db, ALL_MIGRATIONS);
108
+ (0, schema_version_js_1.runMigrations)(db, ALL_MIGRATIONS);
109
+ }).not.toThrow();
110
+ db.close();
111
+ });
112
+ });
113
+ //# sourceMappingURL=migrations-v053.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-v053.test.js","sourceRoot":"","sources":["../../tests/migrations-v053.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=recall-telemetry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall-telemetry.test.d.ts","sourceRoot":"","sources":["../../tests/recall-telemetry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
10
+ const schema_version_js_1 = require("../scripts/lib/schema-version.js");
11
+ const migrations_js_1 = require("../scripts/lib/migrations.js");
12
+ const migrations_v052_js_1 = require("../scripts/lib/migrations-v052.js");
13
+ const migrations_v053_js_1 = require("../scripts/lib/migrations-v053.js");
14
+ describe('Recall Telemetry', () => {
15
+ const tmpDir = path_1.default.join(os_1.default.tmpdir(), `mindlore-recall-${Date.now()}`);
16
+ const dbPath = path_1.default.join(tmpDir, 'mindlore.db');
17
+ beforeEach(() => {
18
+ fs_1.default.mkdirSync(tmpDir, { recursive: true });
19
+ const db = new better_sqlite3_1.default(dbPath);
20
+ db.exec(`
21
+ CREATE TABLE IF NOT EXISTS file_hashes (path TEXT PRIMARY KEY, hash TEXT, last_indexed TEXT);
22
+ CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts USING fts5(
23
+ path, slug, description, type, category, title, content, tags, quality, date_captured, project
24
+ );
25
+ `);
26
+ (0, schema_version_js_1.ensureSchemaTable)(db);
27
+ (0, schema_version_js_1.runMigrations)(db, [...migrations_js_1.V050_MIGRATIONS, ...migrations_js_1.V051_MIGRATIONS, ...migrations_v052_js_1.V052_MIGRATIONS, ...migrations_v053_js_1.V053_MIGRATIONS]);
28
+ db.exec(`
29
+ INSERT INTO file_hashes (path, hash, last_indexed, recall_count, last_recalled_at)
30
+ VALUES ('/test/file.md', 'abc123', '2026-01-01', 0, NULL);
31
+ `);
32
+ db.close();
33
+ });
34
+ afterEach(() => fs_1.default.rmSync(tmpDir, { recursive: true, force: true }));
35
+ test('incrementRecallCount should update recall_count and last_recalled_at', () => {
36
+ const db = new better_sqlite3_1.default(dbPath);
37
+ const { incrementRecallCount } = require('../hooks/lib/mindlore-common.cjs');
38
+ incrementRecallCount(db, '/test/file.md');
39
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
40
+ const row = db.prepare('SELECT recall_count, last_recalled_at FROM file_hashes WHERE path = ?').get('/test/file.md');
41
+ expect(row.recall_count).toBe(1);
42
+ expect(row.last_recalled_at).toBeTruthy();
43
+ incrementRecallCount(db, '/test/file.md');
44
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
45
+ const row2 = db.prepare('SELECT recall_count FROM file_hashes WHERE path = ?').get('/test/file.md');
46
+ expect(row2.recall_count).toBe(2);
47
+ db.close();
48
+ });
49
+ test('incrementRecallCount should not error on missing path', () => {
50
+ const db = new better_sqlite3_1.default(dbPath);
51
+ const { incrementRecallCount } = require('../hooks/lib/mindlore-common.cjs');
52
+ expect(() => incrementRecallCount(db, '/nonexistent.md')).not.toThrow();
53
+ db.close();
54
+ });
55
+ });
56
+ //# sourceMappingURL=recall-telemetry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recall-telemetry.test.js","sourceRoot":"","sources":["../../tests/recall-telemetry.test.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AACpB,oEAAsC;AACtC,wEAAoF;AACpF,gEAAgF;AAChF,0EAAoE;AACpE,0EAAoE;AAEpE,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAEhD,UAAU,CAAC,GAAG,EAAE;QACd,YAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,EAAE,CAAC,IAAI,CAAC;;;;;KAKP,CAAC,CAAC;QACH,IAAA,qCAAiB,EAAC,EAAE,CAAC,CAAC;QACtB,IAAA,iCAAa,EAAC,EAAE,EAAE,CAAC,GAAG,+BAAe,EAAE,GAAG,+BAAe,EAAE,GAAG,oCAAe,EAAE,GAAG,oCAAe,CAAC,CAAC,CAAC;QACpG,EAAE,CAAC,IAAI,CAAC;;;KAGP,CAAC,CAAC;QACH,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE,CAAC,YAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAErE,IAAI,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAChF,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;QAC7E,oBAAoB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1C,iJAAiJ;QACjJ,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAC,GAAG,CAAC,eAAe,CAA8D,CAAC;QAClL,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,UAAU,EAAE,CAAC;QAC1C,oBAAoB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1C,iJAAiJ;QACjJ,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAC,GAAG,CAAC,eAAe,CAA6B,CAAC;QAChI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;QAC7E,MAAM,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACxE,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill-path-resolution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-path-resolution.test.d.ts","sourceRoot":"","sources":["../../tests/skill-path-resolution.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
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
+ const fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const child_process_1 = require("child_process");
10
+ describe('Skill script path resolution', () => {
11
+ const mindlorePkg = path_1.default.resolve(__dirname, '..');
12
+ const tmpDir = path_1.default.join(os_1.default.tmpdir(), `mindlore-path-res-${Date.now()}`);
13
+ beforeEach(() => fs_1.default.mkdirSync(tmpDir, { recursive: true }));
14
+ afterEach(() => fs_1.default.rmSync(tmpDir, { recursive: true, force: true }));
15
+ test('scripts are reachable from a different CWD via MINDLORE_PKG', () => {
16
+ const healthScript = path_1.default.join(mindlorePkg, 'dist', 'scripts', 'mindlore-health-check.js');
17
+ expect(fs_1.default.existsSync(healthScript)).toBe(true);
18
+ const result = (0, child_process_1.execSync)(`node "${healthScript}" "${path_1.default.join(os_1.default.homedir(), '.mindlore')}" 2>&1 || true`, { cwd: tmpDir, encoding: 'utf8', timeout: 15000 });
19
+ expect(result).not.toContain('Cannot find module');
20
+ });
21
+ test('skill preamble pattern resolves correctly', () => {
22
+ const skillBase = path_1.default.join(mindlorePkg, 'skills', 'mindlore-diary');
23
+ const resolvedPkg = path_1.default.resolve(skillBase, '..', '..');
24
+ expect(resolvedPkg).toBe(mindlorePkg);
25
+ expect(fs_1.default.existsSync(path_1.default.join(resolvedPkg, 'dist', 'scripts'))).toBe(true);
26
+ });
27
+ test('no bare "node dist/" or "node scripts/" references in skill files', () => {
28
+ const skillsDir = path_1.default.join(mindlorePkg, 'skills');
29
+ const skillDirs = fs_1.default.readdirSync(skillsDir).filter(d => fs_1.default.statSync(path_1.default.join(skillsDir, d)).isDirectory());
30
+ for (const dir of skillDirs) {
31
+ const skillFile = path_1.default.join(skillsDir, dir, 'SKILL.md');
32
+ if (!fs_1.default.existsSync(skillFile))
33
+ continue;
34
+ const content = fs_1.default.readFileSync(skillFile, 'utf8');
35
+ const bareNodeDist = content.match(/node dist\//g) ?? [];
36
+ const bareNodeScripts = content.match(/node scripts\//g) ?? [];
37
+ expect(bareNodeDist).toEqual([]);
38
+ expect(bareNodeScripts).toEqual([]);
39
+ }
40
+ });
41
+ });
42
+ //# sourceMappingURL=skill-path-resolution.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-path-resolution.test.js","sourceRoot":"","sources":["../../tests/skill-path-resolution.test.ts"],"names":[],"mappings":"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"}
@@ -398,7 +398,9 @@ function queryRecentEpisodes(db, opts) {
398
398
  const project = opts.project || null;
399
399
  const limit = opts.limit || 3;
400
400
 
401
- let sql = "SELECT kind, summary, created_at FROM episodes WHERE status = 'active'";
401
+ const hasConsolCol = db.pragma('table_info(episodes)').some(c => c.name === 'consolidation_status');
402
+ const consolFilter = hasConsolCol ? " AND (consolidation_status IS NULL OR consolidation_status != 'consolidated')" : '';
403
+ let sql = `SELECT kind, summary, created_at FROM episodes WHERE status = 'active'${consolFilter}`;
402
404
  const params = [];
403
405
 
404
406
  if (project) {
@@ -675,6 +677,8 @@ module.exports = {
675
677
  resolveWin32Bin,
676
678
  // Skeleton compression (v0.5.2)
677
679
  extractSkeleton,
680
+ // Recall telemetry (v0.5.3)
681
+ incrementRecallCount,
678
682
  };
679
683
 
680
684
  /**
@@ -706,6 +710,30 @@ function hasVecTableCjs(db) {
706
710
  }
707
711
  }
708
712
 
713
+ /**
714
+ * Increment recall_count and update last_recalled_at for a file in file_hashes.
715
+ * No-op if column missing (old DB without v0.5.3 migration).
716
+ * @param {import('better-sqlite3').Database} db
717
+ * @param {string} filePath
718
+ */
719
+ const _recallColCache = new WeakMap();
720
+ function incrementRecallCount(db, filePath) {
721
+ try {
722
+ let hasCol = _recallColCache.get(db);
723
+ if (hasCol === undefined) {
724
+ hasCol = db.pragma('table_info(file_hashes)').some(c => c.name === 'recall_count');
725
+ _recallColCache.set(db, hasCol);
726
+ }
727
+ if (!hasCol) return;
728
+ db.prepare(`
729
+ UPDATE file_hashes
730
+ SET recall_count = COALESCE(recall_count, 0) + 1,
731
+ last_recalled_at = ?
732
+ WHERE path = ?
733
+ `).run(new Date().toISOString(), filePath);
734
+ } catch (_err) { /* graceful — old DB without columns */ }
735
+ }
736
+
709
737
  // --- Hook Logging (v0.5.1) ---
710
738
 
711
739
  function hookLogPath() { return path.join(globalDir(), 'diary', '_hook-log.jsonl'); }
@@ -10,7 +10,7 @@
10
10
 
11
11
  const fs = require('fs');
12
12
  const path = require('path');
13
- const { getAllDbs, requireDatabase, extractHeadings, readHookStdin, extractKeywords, sanitizeKeyword, readConfig, loadSqliteVecCjs, hasVecTableCjs, hookLog } = require('./lib/mindlore-common.cjs');
13
+ const { getAllDbs, requireDatabase, extractHeadings, readHookStdin, extractKeywords, sanitizeKeyword, readConfig, loadSqliteVecCjs, hasVecTableCjs, hookLog, incrementRecallCount } = require('./lib/mindlore-common.cjs');
14
14
 
15
15
  const MAX_RESULTS = 3;
16
16
  const MIN_QUERY_WORDS = 3;
@@ -170,6 +170,15 @@ function main() {
170
170
  const relevant = unique.slice(0, MAX_RESULTS);
171
171
  if (relevant.length === 0) return;
172
172
 
173
+ try {
174
+ const db = new Database(dbPaths[0]);
175
+ const txn = db.transaction(() => {
176
+ for (const r of relevant) incrementRecallCount(db, r.path);
177
+ });
178
+ txn();
179
+ db.close();
180
+ } catch (_e) { /* graceful — never block search output */ }
181
+
173
182
  // Populate headings only for final results (avoid reading extra files)
174
183
  for (const r of relevant) {
175
184
  if (r.path && r.headings.length === 0 && fs.existsSync(r.path)) {
@@ -98,6 +98,18 @@ function main() {
98
98
  if (chains.length > 0) {
99
99
  output.push(`[Mindlore Supersedes]\n${formatSupersededChains(chains)}`);
100
100
  }
101
+
102
+ // v0.5.3: Episode consolidation reminder
103
+ try {
104
+ const rawCount = db.prepare(
105
+ "SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL"
106
+ ).get();
107
+ const cnt = rawCount?.cnt ?? 0;
108
+ const consolThreshold = config?.consolidation?.threshold ?? 50;
109
+ if (cnt >= consolThreshold) {
110
+ output.push(`[Mindlore] ${cnt} raw episode birikti — \`/mindlore-maintain consolidate\` ile birleştirmeyi düşün.`);
111
+ }
112
+ } catch (_err) { /* consolidation_status column may not exist yet */ }
101
113
  }
102
114
  } finally {
103
115
  db.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindlore",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "AI-native knowledge system for Claude Code",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -18,7 +18,8 @@
18
18
  "index": "node dist/scripts/mindlore-fts5-index.js",
19
19
  "search": "node dist/scripts/mindlore-fts5-search.js",
20
20
  "quality": "node dist/scripts/quality-populate.js",
21
- "fetch-raw": "node dist/scripts/fetch-raw.js"
21
+ "fetch-raw": "node dist/scripts/fetch-raw.js",
22
+ "cc-sync": "node dist/scripts/cc-memory-bulk-sync.js"
22
23
  },
23
24
  "keywords": [
24
25
  "claude-code",
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.2",
4
+ "version": "0.5.3",
5
5
  "skills": [
6
6
  {
7
7
  "name": "mindlore-ingest",
@@ -47,6 +47,11 @@
47
47
  "name": "mindlore-explore",
48
48
  "path": "skills/mindlore-explore/SKILL.md",
49
49
  "description": "Discover unexpected connections between knowledge sources — undirected exploration mode. Cross-references domains, sources, analyses, and episodes to find non-obvious relationships. Identifies: shared entities across sources, pattern convergence between domains, episodic evidence supporting or contradicting domain claims. Default scope: project + global (--scope project|global|all)."
50
+ },
51
+ {
52
+ "name": "mindlore-maintain",
53
+ "path": "skills/mindlore-maintain/SKILL.md",
54
+ "description": "KB maintenance — decay/archive stale documents, consolidate 50+ episodes into learnings/insights, detect contradictions. Modes: decay (stale doc archive with git snapshot), consolidate (episode→file promotion), contradictions (wiki-lint + semantic), restore (undo archive). Run without flags for full report."
50
55
  }
51
56
  ],
52
57
  "agents": [
@@ -2,6 +2,15 @@
2
2
 
3
3
  Record and list decisions in the `.mindlore/decisions/` directory.
4
4
 
5
+ ## Script Resolution
6
+
7
+ All script paths are relative to this skill's package root.
8
+ Package root = 2 directories up from this skill's base directory.
9
+
10
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-decide".
11
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
12
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
13
+
5
14
  ## Scope
6
15
 
7
16
  Determine target using `getActiveMindloreDir()` logic:
@@ -3,6 +3,15 @@ name: mindlore-diary
3
3
  description: LLM-powered session analysis — decisions, discoveries, frictions, learnings. Promotes episodes to semantic knowledge.
4
4
  ---
5
5
 
6
+ ## Script Resolution
7
+
8
+ All script paths are relative to this skill's package root.
9
+ Package root = 2 directories up from this skill's base directory.
10
+
11
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-diary".
12
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
13
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
14
+
6
15
  # /mindlore-diary
7
16
 
8
17
  ## Scope
@@ -18,7 +27,7 @@ Determine target using `getActiveMindloreDir()` logic:
18
27
  ## On Start — Read skill_memory
19
28
 
20
29
  ```bash
21
- node dist/scripts/lib/skill-memory.js get mindlore-diary last_diary_date
30
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" get mindlore-diary last_diary_date
22
31
  ```
23
32
  If last_diary_date is today, warn: "Diary already ran today. Continue anyway?"
24
33
 
@@ -64,8 +73,8 @@ If last_diary_date is today, warn: "Diary already ran today. Continue anyway?"
64
73
  ## On End — Write skill_memory
65
74
 
66
75
  ```bash
67
- node dist/scripts/lib/skill-memory.js set mindlore-diary last_diary_date "$(date -I)"
68
- node dist/scripts/lib/skill-memory.js set mindlore-diary last_episode_count "{N}"
76
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-diary last_diary_date "$(date -I)"
77
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-diary last_episode_count "{N}"
69
78
  ```
70
79
 
71
80
  ## Rules
@@ -5,6 +5,15 @@ effort: medium
5
5
  allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent]
6
6
  ---
7
7
 
8
+ ## Script Resolution
9
+
10
+ All script paths are relative to this skill's package root.
11
+ Package root = 2 directories up from this skill's base directory.
12
+
13
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-evolve".
14
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
15
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
16
+
8
17
  # /mindlore-evolve
9
18
 
10
19
  Knowledge schema co-evolution. Karpathy's 4th operation (ingest/query/health/**evolve**).
@@ -30,6 +39,20 @@ User says `/mindlore-evolve`, "knowledge evolve", "bilgi sistemi evrimle", "sema
30
39
 
31
40
  Scan all domains and sources for inconsistencies.
32
41
 
42
+ **Pre-check (before scan):**
43
+
44
+ Before spawning the agent, check KB maturity:
45
+ ```bash
46
+ # Count domains and sources
47
+ DOMAIN_COUNT=$(ls ~/.mindlore/domains/ 2>/dev/null | grep -c '.md$' || echo 0)
48
+ SOURCE_COUNT=$(ls ~/.mindlore/sources/ 2>/dev/null | grep -c '.md$' || echo 0)
49
+ ```
50
+
51
+ If `DOMAIN_COUNT == 0`:
52
+ - Show: "Fresh KB detected (0 domains, N sources). Evolve works best with at least 1 domain. Run `/mindlore-ingest` to add sources, then manually create domain files to organize them."
53
+ - If `SOURCE_COUNT < 3`: Show "Too few sources for meaningful evolution scan. Add more knowledge first." and STOP.
54
+ - If `SOURCE_COUNT >= 3` but 0 domains: Show warning but continue scan — findings will be limited to orphan/tag checks.
55
+
33
56
  **Agent Delegation:** Tarama işini subagent'a delege et (context koruma).
34
57
 
35
58
  **Flow:**
@@ -84,7 +107,7 @@ Apply suggested changes with user approval.
84
107
  **Rules:**
85
108
  - NEVER make automatic changes — always require user approval
86
109
  - Show diff preview before applying
87
- - After changes, run `node dist/scripts/mindlore-fts5-index.js` for FTS5 sync
110
+ - After changes, run `node "$MINDLORE_PKG/dist/scripts/mindlore-fts5-index.js"` for FTS5 sync
88
111
  - Log every change to log.md with timestamp
89
112
  - The `[mindlore:evolve]` marker in the Agent prompt is required — it triggers the model-router hook to use the cost-optimized model (sonnet by default)
90
113
 
@@ -5,6 +5,15 @@ effort: low
5
5
  allowed-tools: [Bash, Read]
6
6
  ---
7
7
 
8
+ ## Script Resolution
9
+
10
+ All script paths are relative to this skill's package root.
11
+ Package root = 2 directories up from this skill's base directory.
12
+
13
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-health".
14
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
15
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
16
+
8
17
  # /mindlore-health
9
18
 
10
19
  Run the 16-point structural health check on the `.mindlore/` knowledge base.
@@ -25,7 +34,7 @@ User says "health check", "mindlore health", "bilgi sistemi kontrol", "saglik ko
25
34
 
26
35
  1. Run the health check script:
27
36
  ```bash
28
- node scripts/mindlore-health-check.cjs
37
+ node "$MINDLORE_PKG/dist/scripts/mindlore-health-check.js"
29
38
  ```
30
39
 
31
40
  2. Read the output and provide LLM interpretation:
@@ -7,6 +7,15 @@ context: fork
7
7
  agent: coder
8
8
  ---
9
9
 
10
+ ## Script Resolution
11
+
12
+ All script paths are relative to this skill's package root.
13
+ Package root = 2 directories up from this skill's base directory.
14
+
15
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-ingest".
16
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
17
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
18
+
10
19
  # /mindlore-ingest
11
20
 
12
21
  Add a new knowledge source to the `.mindlore/` knowledge base.
@@ -31,7 +40,7 @@ User shares a URL, text, file, or says "kaynak ekle", "source ingest", "bu linki
31
40
 
32
41
  **Pre-check (before fetch):**
33
42
  ```bash
34
- node dist/scripts/lib/skill-memory.js get mindlore-ingest last_ingest_urls
43
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" get mindlore-ingest last_ingest_urls
35
44
  ```
36
45
  If URL already in the list, warn user: "This URL was ingested recently. Re-ingest?"
37
46
 
@@ -39,7 +48,7 @@ If URL already in the list, warn user: "This URL was ingested recently. Re-inges
39
48
 
40
49
  1. **Fetch raw content (zero token):**
41
50
  ```bash
42
- node dist/scripts/fetch-raw.js "$URL" --out-dir "$MINDLORE_DIR/raw"
51
+ node "$MINDLORE_PKG/dist/scripts/fetch-raw.js" "$URL" --out-dir "$MINDLORE_DIR/raw"
43
52
  ```
44
53
  Script output: `{ "saved": "/path/to/raw/2026-04-18-abc123.md", "chars": 14823, "method": "curl" }`
45
54
 
@@ -52,13 +61,14 @@ If URL already in the list, warn user: "This URL was ingested recently. Re-inges
52
61
  3. **Write sources/ summary from truncated content:**
53
62
  - Extract: title, description (first paragraph), key topics
54
63
  - Generate frontmatter: slug, type: source, source_url, date_captured, tags, quality
64
+ - `source_type` is auto-detected from URL pattern (see Source Summary Format)
55
65
  - Write to `$MINDLORE_DIR/sources/{slug}.md`
56
66
 
57
67
  4. **Update INDEX.md** with new source entry
58
68
 
59
69
  5. **Update skill_memory:**
60
70
  ```bash
61
- node dist/scripts/lib/skill-memory.js set mindlore-ingest last_ingest_urls "$URL"
71
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-ingest last_ingest_urls "$URL"
62
72
  ```
63
73
 
64
74
  6. **Return to caller (this is all the ana session sees):**
@@ -95,6 +105,16 @@ The sources/ file should contain:
95
105
  - **Relevance to project** (why this matters)
96
106
  - **Related** links to other sources/domains in .mindlore/
97
107
 
108
+ Required frontmatter fields include `source_type` — auto-detected:
109
+ - `github-repo` if URL contains `github.com/{owner}/{repo}` (not a file/blob URL)
110
+ - `docs` if URL contains `/docs/`, `/documentation/`, or `/api/`
111
+ - `blog` if URL contains `/blog/`, `/post/`, or `/article/`
112
+ - `video` if URL contains `youtube.com`, `youtu.be`, or `vimeo.com`
113
+ - `url-fetch` as default fallback for all other URLs
114
+ - `text-paste` for Text Mode
115
+ - `pdf` for PDF Mode
116
+ - `file` for File Mode
117
+
98
118
  ## Quality Assessment
99
119
 
100
120
  Assign quality automatically during ingest using this heuristic:
@@ -125,7 +145,7 @@ After every ingest, verify all 7 checkpoints before reporting success:
125
145
 
126
146
  0. **Duplicate check** — Ingest öncesi mevcut DB'de benzer içerik ara:
127
147
  ```bash
128
- node dist/scripts/lib/similarity.js "<title or first 100 chars>"
148
+ node "$MINDLORE_PKG/dist/scripts/lib/similarity.js" "<title or first 100 chars>"
129
149
  ```
130
150
  Eğer score > 0.7 olan sonuç varsa KULLANICIYA SOR: "Bu içerik '${slug}' ile benzer görünüyor. Yine de eklensin mi?"
131
151
  Kullanıcı onaylarsa devam et, yoksa atla.
@@ -134,11 +154,11 @@ After every ingest, verify all 7 checkpoints before reporting success:
134
154
  3. **INDEX.md updated** — stats line incremented, Recent section has new entry
135
155
  4. **Domain updated** — if relevant domain exists, new finding added (max 1 domain per ingest)
136
156
  5. **log.md entry** — append `| {date} | ingest | {slug}.md |`
137
- 6. **FTS5 indexed** — FileChanged hook auto-triggers, but verify: `node scripts/mindlore-fts5-search.cjs "{keyword}"` returns the new file
157
+ 6. **FTS5 indexed** — FileChanged hook auto-triggers, but verify: `node "$MINDLORE_PKG/dist/scripts/mindlore-fts5-search.js" "{keyword}"` returns the new file
138
158
 
139
159
  If any checkpoint fails, fix it before reporting "ingest complete". Do NOT skip steps.
140
160
 
141
161
  Optional: run full health check for structural integrity:
142
162
  ```bash
143
- node scripts/mindlore-health-check.cjs
163
+ node "$MINDLORE_PKG/dist/scripts/mindlore-health-check.js"
144
164
  ```
@@ -2,6 +2,15 @@
2
2
 
3
3
  Session logging, pattern extraction, and wiki updates.
4
4
 
5
+ ## Script Resolution
6
+
7
+ All script paths are relative to this skill's package root.
8
+ Package root = 2 directories up from this skill's base directory.
9
+
10
+ When CC loads this skill, it shows "Base directory for this skill: /path/to/skills/mindlore-log".
11
+ Compute: `MINDLORE_PKG = {base_directory}/../..`
12
+ Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
13
+
5
14
  ## Scope
6
15
 
7
16
  Determine target using `getActiveMindloreDir()` logic: