mindlore 0.5.1 → 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 (144) hide show
  1. package/README.md +16 -2
  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/fetch-raw.d.ts +2 -0
  7. package/dist/scripts/fetch-raw.d.ts.map +1 -0
  8. package/dist/scripts/fetch-raw.js +124 -0
  9. package/dist/scripts/fetch-raw.js.map +1 -0
  10. package/dist/scripts/lib/consolidation.d.ts +17 -0
  11. package/dist/scripts/lib/consolidation.d.ts.map +1 -0
  12. package/dist/scripts/lib/consolidation.js +55 -0
  13. package/dist/scripts/lib/consolidation.js.map +1 -0
  14. package/dist/scripts/lib/constants.d.ts +5 -0
  15. package/dist/scripts/lib/constants.d.ts.map +1 -1
  16. package/dist/scripts/lib/constants.js +16 -4
  17. package/dist/scripts/lib/constants.js.map +1 -1
  18. package/dist/scripts/lib/db-helpers.d.ts +12 -2
  19. package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
  20. package/dist/scripts/lib/db-helpers.js +36 -0
  21. package/dist/scripts/lib/db-helpers.js.map +1 -1
  22. package/dist/scripts/lib/decay.d.ts +21 -0
  23. package/dist/scripts/lib/decay.d.ts.map +1 -0
  24. package/dist/scripts/lib/decay.js +50 -0
  25. package/dist/scripts/lib/decay.js.map +1 -0
  26. package/dist/scripts/lib/hybrid-search.d.ts +0 -2
  27. package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
  28. package/dist/scripts/lib/hybrid-search.js +7 -1
  29. package/dist/scripts/lib/hybrid-search.js.map +1 -1
  30. package/dist/scripts/lib/migrations-v052.d.ts +3 -0
  31. package/dist/scripts/lib/migrations-v052.d.ts.map +1 -0
  32. package/dist/scripts/lib/migrations-v052.js +23 -0
  33. package/dist/scripts/lib/migrations-v052.js.map +1 -0
  34. package/dist/scripts/lib/migrations-v053.d.ts +3 -0
  35. package/dist/scripts/lib/migrations-v053.d.ts.map +1 -0
  36. package/dist/scripts/lib/migrations-v053.js +52 -0
  37. package/dist/scripts/lib/migrations-v053.js.map +1 -0
  38. package/dist/scripts/lib/skeleton.d.ts +2 -0
  39. package/dist/scripts/lib/skeleton.d.ts.map +1 -0
  40. package/dist/scripts/lib/skeleton.js +99 -0
  41. package/dist/scripts/lib/skeleton.js.map +1 -0
  42. package/dist/scripts/lib/skill-memory.d.ts +13 -0
  43. package/dist/scripts/lib/skill-memory.d.ts.map +1 -0
  44. package/dist/scripts/lib/skill-memory.js +94 -0
  45. package/dist/scripts/lib/skill-memory.js.map +1 -0
  46. package/dist/scripts/mindlore-backup.d.ts +1 -1
  47. package/dist/scripts/mindlore-backup.d.ts.map +1 -1
  48. package/dist/scripts/mindlore-backup.js +23 -0
  49. package/dist/scripts/mindlore-backup.js.map +1 -1
  50. package/dist/scripts/mindlore-fts5-index.js +3 -1
  51. package/dist/scripts/mindlore-fts5-index.js.map +1 -1
  52. package/dist/scripts/mindlore-health-check.d.ts +1 -1
  53. package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
  54. package/dist/scripts/mindlore-health-check.js +138 -136
  55. package/dist/scripts/mindlore-health-check.js.map +1 -1
  56. package/dist/tests/catch-up.test.d.ts +2 -0
  57. package/dist/tests/catch-up.test.d.ts.map +1 -0
  58. package/dist/tests/catch-up.test.js +88 -0
  59. package/dist/tests/catch-up.test.js.map +1 -0
  60. package/dist/tests/cc-memory-bulk-sync.test.d.ts +2 -0
  61. package/dist/tests/cc-memory-bulk-sync.test.d.ts.map +1 -0
  62. package/dist/tests/cc-memory-bulk-sync.test.js +116 -0
  63. package/dist/tests/cc-memory-bulk-sync.test.js.map +1 -0
  64. package/dist/tests/consolidation.test.d.ts +2 -0
  65. package/dist/tests/consolidation.test.d.ts.map +1 -0
  66. package/dist/tests/consolidation.test.js +77 -0
  67. package/dist/tests/consolidation.test.js.map +1 -0
  68. package/dist/tests/decay.test.d.ts +2 -0
  69. package/dist/tests/decay.test.d.ts.map +1 -0
  70. package/dist/tests/decay.test.js +92 -0
  71. package/dist/tests/decay.test.js.map +1 -0
  72. package/dist/tests/episode-file.test.js +9 -6
  73. package/dist/tests/episode-file.test.js.map +1 -1
  74. package/dist/tests/fetch-raw.test.d.ts +2 -0
  75. package/dist/tests/fetch-raw.test.d.ts.map +1 -0
  76. package/dist/tests/fetch-raw.test.js +43 -0
  77. package/dist/tests/fetch-raw.test.js.map +1 -0
  78. package/dist/tests/git-snapshot.test.d.ts +2 -0
  79. package/dist/tests/git-snapshot.test.d.ts.map +1 -0
  80. package/dist/tests/git-snapshot.test.js +36 -0
  81. package/dist/tests/git-snapshot.test.js.map +1 -0
  82. package/dist/tests/migrations-v053.test.d.ts +2 -0
  83. package/dist/tests/migrations-v053.test.d.ts.map +1 -0
  84. package/dist/tests/migrations-v053.test.js +113 -0
  85. package/dist/tests/migrations-v053.test.js.map +1 -0
  86. package/dist/tests/recall-telemetry.test.d.ts +2 -0
  87. package/dist/tests/recall-telemetry.test.d.ts.map +1 -0
  88. package/dist/tests/recall-telemetry.test.js +56 -0
  89. package/dist/tests/recall-telemetry.test.js.map +1 -0
  90. package/dist/tests/resolve-hook-common.test.d.ts +2 -0
  91. package/dist/tests/resolve-hook-common.test.d.ts.map +1 -0
  92. package/dist/tests/resolve-hook-common.test.js +30 -0
  93. package/dist/tests/resolve-hook-common.test.js.map +1 -0
  94. package/dist/tests/search-offload.test.d.ts +2 -0
  95. package/dist/tests/search-offload.test.d.ts.map +1 -0
  96. package/dist/tests/search-offload.test.js +34 -0
  97. package/dist/tests/search-offload.test.js.map +1 -0
  98. package/dist/tests/skeleton.test.d.ts +2 -0
  99. package/dist/tests/skeleton.test.d.ts.map +1 -0
  100. package/dist/tests/skeleton.test.js +116 -0
  101. package/dist/tests/skeleton.test.js.map +1 -0
  102. package/dist/tests/skill-memory-api.test.d.ts +2 -0
  103. package/dist/tests/skill-memory-api.test.d.ts.map +1 -0
  104. package/dist/tests/skill-memory-api.test.js +62 -0
  105. package/dist/tests/skill-memory-api.test.js.map +1 -0
  106. package/dist/tests/skill-memory.test.d.ts +2 -0
  107. package/dist/tests/skill-memory.test.d.ts.map +1 -0
  108. package/dist/tests/skill-memory.test.js +67 -0
  109. package/dist/tests/skill-memory.test.js.map +1 -0
  110. package/dist/tests/skill-path-resolution.test.d.ts +2 -0
  111. package/dist/tests/skill-path-resolution.test.d.ts.map +1 -0
  112. package/dist/tests/skill-path-resolution.test.js +42 -0
  113. package/dist/tests/skill-path-resolution.test.js.map +1 -0
  114. package/dist/tests/wiki-lint.test.d.ts +2 -0
  115. package/dist/tests/wiki-lint.test.d.ts.map +1 -0
  116. package/dist/tests/wiki-lint.test.js +47 -0
  117. package/dist/tests/wiki-lint.test.js.map +1 -0
  118. package/hooks/lib/mindlore-common.cjs +53 -6
  119. package/hooks/mindlore-cwd-changed.cjs +2 -2
  120. package/hooks/mindlore-decision-detector.cjs +2 -2
  121. package/hooks/mindlore-dont-repeat.cjs +2 -2
  122. package/hooks/mindlore-fts5-sync.cjs +2 -2
  123. package/hooks/mindlore-index.cjs +60 -2
  124. package/hooks/mindlore-model-router.cjs +2 -2
  125. package/hooks/mindlore-post-compact.cjs +2 -2
  126. package/hooks/mindlore-post-read.cjs +2 -2
  127. package/hooks/mindlore-pre-compact.cjs +2 -2
  128. package/hooks/mindlore-read-guard.cjs +15 -3
  129. package/hooks/mindlore-research-guard.cjs +2 -2
  130. package/hooks/mindlore-search.cjs +30 -3
  131. package/hooks/mindlore-session-end.cjs +1 -1
  132. package/hooks/mindlore-session-focus.cjs +12 -0
  133. package/package.json +4 -2
  134. package/plugin.json +34 -2
  135. package/skills/mindlore-decide/SKILL.md +9 -0
  136. package/skills/mindlore-diary/SKILL.md +85 -0
  137. package/skills/mindlore-evolve/SKILL.md +24 -1
  138. package/skills/mindlore-health/SKILL.md +10 -1
  139. package/skills/mindlore-ingest/SKILL.md +64 -52
  140. package/skills/mindlore-log/SKILL.md +12 -143
  141. package/skills/mindlore-maintain/SKILL.md +119 -0
  142. package/skills/mindlore-query/SKILL.md +9 -0
  143. package/skills/mindlore-reflect/SKILL.md +131 -0
  144. package/templates/config.json +8 -1
@@ -0,0 +1,88 @@
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 child_process_1 = require("child_process");
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ describe('FTS5 catch-up mechanism', () => {
13
+ let tmpDir;
14
+ let mindloreDir;
15
+ let rawDir;
16
+ let dbPath;
17
+ beforeEach(() => {
18
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-catchup-'));
19
+ mindloreDir = path_1.default.join(tmpDir, '.mindlore');
20
+ rawDir = path_1.default.join(mindloreDir, 'raw');
21
+ dbPath = path_1.default.join(mindloreDir, 'mindlore.db');
22
+ fs_1.default.mkdirSync(rawDir, { recursive: true });
23
+ const db = new better_sqlite3_1.default(dbPath);
24
+ db.exec(`
25
+ CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts USING fts5(
26
+ path, slug, description, type, category, title, content, tags, quality, date_captured, project,
27
+ tokenize='porter unicode61'
28
+ );
29
+ CREATE TABLE IF NOT EXISTS file_hashes (
30
+ path TEXT PRIMARY KEY,
31
+ content_hash TEXT,
32
+ last_indexed TEXT
33
+ );
34
+ `);
35
+ db.close();
36
+ });
37
+ afterEach(() => { fs_1.default.rmSync(tmpDir, { recursive: true, force: true }); });
38
+ it('indexes untracked files when INDEX.md triggers hook', () => {
39
+ const untracked = path_1.default.join(rawDir, 'untracked-source.md');
40
+ fs_1.default.writeFileSync(untracked, '---\nslug: untracked\ntype: raw\n---\nSome content here', 'utf8');
41
+ const indexMd = path_1.default.join(mindloreDir, 'INDEX.md');
42
+ fs_1.default.writeFileSync(indexMd, '# Index', 'utf8');
43
+ const hookPath = path_1.default.resolve(__dirname, '..', 'hooks', 'mindlore-index.cjs');
44
+ const input = JSON.stringify({ path: indexMd });
45
+ try {
46
+ (0, child_process_1.execSync)(`node "${hookPath}"`, {
47
+ input,
48
+ encoding: 'utf8',
49
+ timeout: 10000,
50
+ env: { ...process.env, MINDLORE_HOME: mindloreDir },
51
+ });
52
+ }
53
+ catch { /* hook may exit with non-zero */ }
54
+ const db = new better_sqlite3_1.default(dbPath, { readonly: true });
55
+ const row = db.prepare('SELECT * FROM file_hashes WHERE path = ?').get(untracked);
56
+ db.close();
57
+ expect(row).toBeDefined();
58
+ });
59
+ it('skips already-indexed files (hash dedup)', () => {
60
+ const tracked = path_1.default.join(rawDir, 'tracked.md');
61
+ const content = '---\nslug: tracked\ntype: raw\n---\nAlready indexed';
62
+ fs_1.default.writeFileSync(tracked, content, 'utf8');
63
+ const hash = crypto_1.default.createHash('sha256').update(content).digest('hex');
64
+ const db = new better_sqlite3_1.default(dbPath);
65
+ db.prepare('INSERT INTO file_hashes (path, content_hash, last_indexed) VALUES (?, ?, ?)')
66
+ .run(tracked, hash, new Date().toISOString());
67
+ db.close();
68
+ const indexMd = path_1.default.join(mindloreDir, 'INDEX.md');
69
+ fs_1.default.writeFileSync(indexMd, '# Index', 'utf8');
70
+ const hookPath = path_1.default.resolve(__dirname, '..', 'hooks', 'mindlore-index.cjs');
71
+ const input = JSON.stringify({ path: indexMd });
72
+ try {
73
+ (0, child_process_1.execSync)(`node "${hookPath}"`, {
74
+ input,
75
+ encoding: 'utf8',
76
+ timeout: 10000,
77
+ env: { ...process.env, MINDLORE_HOME: mindloreDir },
78
+ });
79
+ }
80
+ catch { /* hook may exit with non-zero */ }
81
+ const db2 = new better_sqlite3_1.default(dbPath, { readonly: true });
82
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
83
+ const count = db2.prepare('SELECT COUNT(*) as c FROM file_hashes').get();
84
+ db2.close();
85
+ expect(count.c).toBe(1);
86
+ });
87
+ });
88
+ //# sourceMappingURL=catch-up.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catch-up.test.js","sourceRoot":"","sources":["../../tests/catch-up.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cc-memory-bulk-sync.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-memory-bulk-sync.test.d.ts","sourceRoot":"","sources":["../../tests/cc-memory-bulk-sync.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
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 path_1 = __importDefault(require("path"));
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const cc_memory_bulk_sync_js_1 = require("../scripts/cc-memory-bulk-sync.js");
10
+ const db_js_1 = require("./helpers/db.js");
11
+ const TEST_DIR = path_1.default.join(os_1.default.tmpdir(), 'mindlore-cc-bulk-sync-test');
12
+ const CLAUDE_DIR = path_1.default.join(TEST_DIR, '.claude');
13
+ const MINDLORE_DIR = path_1.default.join(TEST_DIR, '.mindlore');
14
+ const DB_PATH = path_1.default.join(MINDLORE_DIR, 'mindlore.db');
15
+ const PROJECT_NAME = 'C--test-project';
16
+ const MEMORY_DIR = path_1.default.join(CLAUDE_DIR, 'projects', PROJECT_NAME, 'memory');
17
+ const FILE_A_CONTENT = [
18
+ '---',
19
+ 'slug: note-a',
20
+ 'type: learning',
21
+ 'title: Note A',
22
+ 'tags: [test, sync]',
23
+ 'quality: medium',
24
+ 'date_captured: 2026-04-18',
25
+ '---',
26
+ '',
27
+ '# Note A',
28
+ '',
29
+ 'This is a CC memory note.',
30
+ ].join('\n');
31
+ const FILE_B_CONTENT = [
32
+ '---',
33
+ 'slug: note-b',
34
+ 'type: learning',
35
+ 'title: Note B',
36
+ 'tags: [test]',
37
+ 'quality: low',
38
+ '---',
39
+ '',
40
+ '# Note B',
41
+ '',
42
+ 'Another CC memory note.',
43
+ ].join('\n');
44
+ beforeEach(() => {
45
+ (0, db_js_1.setupTestDir)(TEST_DIR);
46
+ fs_1.default.mkdirSync(MEMORY_DIR, { recursive: true });
47
+ fs_1.default.mkdirSync(MINDLORE_DIR, { recursive: true });
48
+ fs_1.default.mkdirSync(path_1.default.join(MINDLORE_DIR, 'memory'), { recursive: true });
49
+ // MEMORY.md (should be skipped)
50
+ fs_1.default.writeFileSync(path_1.default.join(MEMORY_DIR, 'MEMORY.md'), '# Index\n- [Note A](note-a.md)\n');
51
+ // Two real memory files
52
+ fs_1.default.writeFileSync(path_1.default.join(MEMORY_DIR, 'note-a.md'), FILE_A_CONTENT);
53
+ fs_1.default.writeFileSync(path_1.default.join(MEMORY_DIR, 'note-b.md'), FILE_B_CONTENT);
54
+ const db = (0, db_js_1.createTestDb)(DB_PATH);
55
+ db.close();
56
+ });
57
+ afterEach(() => {
58
+ (0, db_js_1.teardownTestDir)(TEST_DIR);
59
+ });
60
+ describe('discoverCcMemoryFiles', () => {
61
+ test('finds .md files and skips MEMORY.md', () => {
62
+ const files = (0, cc_memory_bulk_sync_js_1.discoverCcMemoryFiles)(CLAUDE_DIR);
63
+ expect(files.length).toBe(2);
64
+ const names = files.map(f => path_1.default.basename(f)).sort();
65
+ expect(names).toEqual(['note-a.md', 'note-b.md']);
66
+ // MEMORY.md must not appear
67
+ expect(files.every(f => path_1.default.basename(f) !== 'MEMORY.md')).toBe(true);
68
+ });
69
+ test('returns empty array when claude dir does not exist', () => {
70
+ const files = (0, cc_memory_bulk_sync_js_1.discoverCcMemoryFiles)(path_1.default.join(TEST_DIR, 'nonexistent'));
71
+ expect(files).toEqual([]);
72
+ });
73
+ });
74
+ describe('syncToDb', () => {
75
+ test('inserts files into DB with category cc-memory', () => {
76
+ const files = (0, cc_memory_bulk_sync_js_1.discoverCcMemoryFiles)(CLAUDE_DIR);
77
+ const result = (0, cc_memory_bulk_sync_js_1.syncToDb)(DB_PATH, files, MINDLORE_DIR);
78
+ expect(result.errors).toEqual([]);
79
+ expect(result.synced).toBe(2);
80
+ expect(result.skipped).toBe(0);
81
+ const Database = require('better-sqlite3');
82
+ const db = new Database(DB_PATH);
83
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- .get() returns unknown
84
+ const row = db.prepare("SELECT count(*) as cnt FROM mindlore_fts WHERE category = 'cc-memory'").get();
85
+ expect(row.cnt).toBe(2);
86
+ db.close();
87
+ });
88
+ test('is idempotent — second call synced=0, skipped=2', () => {
89
+ const files = (0, cc_memory_bulk_sync_js_1.discoverCcMemoryFiles)(CLAUDE_DIR);
90
+ const first = (0, cc_memory_bulk_sync_js_1.syncToDb)(DB_PATH, files, MINDLORE_DIR);
91
+ expect(first.synced).toBe(2);
92
+ expect(first.skipped).toBe(0);
93
+ const second = (0, cc_memory_bulk_sync_js_1.syncToDb)(DB_PATH, files, MINDLORE_DIR);
94
+ expect(second.synced).toBe(0);
95
+ expect(second.skipped).toBe(2);
96
+ expect(second.errors).toEqual([]);
97
+ // FTS row count stays 2, not 4
98
+ const Database = require('better-sqlite3');
99
+ const db = new Database(DB_PATH);
100
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- .get() returns unknown
101
+ const row = db.prepare("SELECT count(*) as cnt FROM mindlore_fts WHERE category = 'cc-memory'").get();
102
+ expect(row.cnt).toBe(2);
103
+ db.close();
104
+ });
105
+ test('copies files to .mindlore/memory/ with project prefix', () => {
106
+ const files = (0, cc_memory_bulk_sync_js_1.discoverCcMemoryFiles)(CLAUDE_DIR);
107
+ (0, cc_memory_bulk_sync_js_1.syncToDb)(DB_PATH, files, MINDLORE_DIR);
108
+ const destDir = path_1.default.join(MINDLORE_DIR, 'memory');
109
+ const copied = fs_1.default.readdirSync(destDir).sort();
110
+ expect(copied).toEqual([
111
+ `${PROJECT_NAME}_note-a.md`,
112
+ `${PROJECT_NAME}_note-b.md`,
113
+ ]);
114
+ });
115
+ });
116
+ //# sourceMappingURL=cc-memory-bulk-sync.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cc-memory-bulk-sync.test.js","sourceRoot":"","sources":["../../tests/cc-memory-bulk-sync.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=consolidation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidation.test.d.ts","sourceRoot":"","sources":["../../tests/consolidation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const db_js_1 = require("./helpers/db.js");
4
+ const schema_version_js_1 = require("../scripts/lib/schema-version.js");
5
+ const migrations_js_1 = require("../scripts/lib/migrations.js");
6
+ const migrations_v051_js_1 = require("../scripts/lib/migrations-v051.js");
7
+ const migrations_v052_js_1 = require("../scripts/lib/migrations-v052.js");
8
+ const migrations_v053_js_1 = require("../scripts/lib/migrations-v053.js");
9
+ const consolidation_js_1 = require("../scripts/lib/consolidation.js");
10
+ let env;
11
+ beforeEach(() => {
12
+ env = (0, db_js_1.createEpisodesTestEnv)('consolidation');
13
+ (0, schema_version_js_1.ensureSchemaTable)(env.db);
14
+ (0, schema_version_js_1.runMigrations)(env.db, [
15
+ ...migrations_js_1.V050_MIGRATIONS,
16
+ ...migrations_v051_js_1.V051_MIGRATIONS,
17
+ ...migrations_v052_js_1.V052_MIGRATIONS,
18
+ ...migrations_v053_js_1.V053_MIGRATIONS,
19
+ ]);
20
+ });
21
+ afterEach(() => {
22
+ (0, db_js_1.destroyEpisodesTestEnv)(env);
23
+ });
24
+ function insertEpisode(db, opts) {
25
+ db.prepare(`
26
+ INSERT INTO episodes (id, kind, scope, summary, status, created_at, consolidation_status)
27
+ VALUES (?, ?, 'project', ?, ?, ?, ?)
28
+ `).run(opts.id, opts.kind, opts.summary, opts.status ?? 'active', new Date().toISOString(), opts.consolidation_status ?? 'raw');
29
+ }
30
+ describe('countRawEpisodes', () => {
31
+ test('returns correct count of raw episodes', () => {
32
+ insertEpisode(env.db, { id: 'ep-1', kind: 'session', summary: 'First' });
33
+ insertEpisode(env.db, { id: 'ep-2', kind: 'decision', summary: 'Second' });
34
+ insertEpisode(env.db, { id: 'ep-3', kind: 'session', summary: 'Third', consolidation_status: 'consolidated' });
35
+ expect((0, consolidation_js_1.countRawEpisodes)(env.db)).toBe(2);
36
+ });
37
+ });
38
+ describe('groupEpisodesByKind', () => {
39
+ test('groups raw active episodes by kind', () => {
40
+ insertEpisode(env.db, { id: 'ep-1', kind: 'session', summary: 'Session A' });
41
+ insertEpisode(env.db, { id: 'ep-2', kind: 'session', summary: 'Session B' });
42
+ insertEpisode(env.db, { id: 'ep-3', kind: 'decision', summary: 'Decision A' });
43
+ insertEpisode(env.db, { id: 'ep-4', kind: 'session', summary: 'Consolidated', consolidation_status: 'consolidated' });
44
+ insertEpisode(env.db, { id: 'ep-5', kind: 'insight', summary: 'Inactive', status: 'inactive' });
45
+ const groups = (0, consolidation_js_1.groupEpisodesByKind)(env.db);
46
+ expect(groups.size).toBe(2);
47
+ expect(groups.get('session')).toHaveLength(2);
48
+ expect(groups.get('decision')).toHaveLength(1);
49
+ expect(groups.has('insight')).toBe(false);
50
+ });
51
+ });
52
+ describe('markConsolidated', () => {
53
+ test('updates episode consolidation_status and consolidated_into', () => {
54
+ insertEpisode(env.db, { id: 'ep-1', kind: 'session', summary: 'A' });
55
+ insertEpisode(env.db, { id: 'ep-2', kind: 'session', summary: 'B' });
56
+ (0, consolidation_js_1.markConsolidated)(env.db, ['ep-1', 'ep-2'], 'consolidated/2026-04.md');
57
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
58
+ const ep1 = env.db.prepare('SELECT consolidation_status, consolidated_into FROM episodes WHERE id = ?').get('ep-1');
59
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
60
+ const ep2 = env.db.prepare('SELECT consolidation_status, consolidated_into FROM episodes WHERE id = ?').get('ep-2');
61
+ expect(ep1.consolidation_status).toBe('consolidated');
62
+ expect(ep1.consolidated_into).toBe('consolidated/2026-04.md');
63
+ expect(ep2.consolidation_status).toBe('consolidated');
64
+ expect(ep2.consolidated_into).toBe('consolidated/2026-04.md');
65
+ expect((0, consolidation_js_1.countRawEpisodes)(env.db)).toBe(0);
66
+ });
67
+ });
68
+ describe('needsConsolidation', () => {
69
+ test('returns true when raw episode count meets threshold', () => {
70
+ for (let i = 0; i < 51; i++) {
71
+ insertEpisode(env.db, { id: `ep-${i}`, kind: 'session', summary: `Episode ${i}` });
72
+ }
73
+ expect((0, consolidation_js_1.needsConsolidation)(env.db, 50)).toBe(true);
74
+ expect((0, consolidation_js_1.needsConsolidation)(env.db, 52)).toBe(false);
75
+ });
76
+ });
77
+ //# sourceMappingURL=consolidation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidation.test.js","sourceRoot":"","sources":["../../tests/consolidation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=decay.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decay.test.d.ts","sourceRoot":"","sources":["../../tests/decay.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
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 os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const db_js_1 = require("./helpers/db.js");
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_v051_js_1 = require("../scripts/lib/migrations-v051.js");
13
+ const migrations_v052_js_1 = require("../scripts/lib/migrations-v052.js");
14
+ const migrations_v053_js_1 = require("../scripts/lib/migrations-v053.js");
15
+ const decay_js_1 = require("../scripts/lib/decay.js");
16
+ function createDecayTestDb(dbPath) {
17
+ const db = (0, db_js_1.createTestDb)(dbPath);
18
+ (0, schema_version_js_1.ensureSchemaTable)(db);
19
+ (0, schema_version_js_1.runMigrations)(db, [
20
+ ...migrations_js_1.V050_MIGRATIONS,
21
+ ...migrations_v051_js_1.V051_MIGRATIONS,
22
+ ...migrations_v052_js_1.V052_MIGRATIONS,
23
+ ...migrations_v053_js_1.V053_MIGRATIONS,
24
+ ]);
25
+ return db;
26
+ }
27
+ let tmpDir;
28
+ let db;
29
+ beforeEach(() => {
30
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-decay-'));
31
+ db = createDecayTestDb(path_1.default.join(tmpDir, 'test.db'));
32
+ });
33
+ afterEach(() => {
34
+ db.close();
35
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
36
+ });
37
+ describe('calculateDecayScore', () => {
38
+ test('returns >0.8 for recently accessed doc with high recall', () => {
39
+ const score = (0, decay_js_1.calculateDecayScore)({
40
+ created_at: new Date().toISOString(),
41
+ last_recalled_at: new Date().toISOString(),
42
+ recall_count: 20,
43
+ importance: 1.0,
44
+ });
45
+ expect(score).toBeGreaterThan(0.8);
46
+ });
47
+ test('returns <0.3 for 90-day old unaccessed doc', () => {
48
+ const ninetyDaysAgo = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString();
49
+ const score = (0, decay_js_1.calculateDecayScore)({
50
+ created_at: ninetyDaysAgo,
51
+ last_recalled_at: null,
52
+ recall_count: 0,
53
+ importance: 1.0,
54
+ });
55
+ expect(score).toBeLessThan(0.3);
56
+ });
57
+ });
58
+ describe('archiveDocument / restoreDocument', () => {
59
+ test('archiveDocument sets archived_at, restoreDocument clears it', () => {
60
+ db.prepare(`INSERT INTO file_hashes (path, content_hash, last_indexed, recall_count, last_recalled_at, importance)
61
+ VALUES (?, ?, ?, ?, ?, ?)`).run('/test/doc.md', 'abc123', new Date().toISOString(), 0, null, 1.0);
62
+ (0, decay_js_1.archiveDocument)(db, '/test/doc.md');
63
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
64
+ const afterArchive = db.prepare('SELECT archived_at FROM file_hashes WHERE path = ?').get('/test/doc.md');
65
+ expect(afterArchive.archived_at).not.toBeNull();
66
+ (0, decay_js_1.restoreDocument)(db, '/test/doc.md');
67
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown, narrowing to expected row shape
68
+ const afterRestore = db.prepare('SELECT archived_at FROM file_hashes WHERE path = ?').get('/test/doc.md');
69
+ expect(afterRestore.archived_at).toBeNull();
70
+ });
71
+ });
72
+ describe('listStaleDocuments', () => {
73
+ test('returns docs below threshold and excludes active ones', () => {
74
+ const ninetyDaysAgo = new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString();
75
+ const now = new Date().toISOString();
76
+ // Stale: old, never recalled
77
+ db.prepare(`INSERT INTO file_hashes (path, content_hash, last_indexed, recall_count, last_recalled_at, importance)
78
+ VALUES (?, ?, ?, ?, ?, ?)`).run('/test/stale.md', 'hash1', ninetyDaysAgo, 0, null, 1.0);
79
+ // Active: recently recalled with high recall_count
80
+ db.prepare(`INSERT INTO file_hashes (path, content_hash, last_indexed, recall_count, last_recalled_at, importance)
81
+ VALUES (?, ?, ?, ?, ?, ?)`).run('/test/active.md', 'hash2', now, 20, now, 1.0);
82
+ const stale = (0, decay_js_1.listStaleDocuments)(db, 0.3);
83
+ const paths = stale.map(d => d.path);
84
+ expect(paths).toContain('/test/stale.md');
85
+ expect(paths).not.toContain('/test/active.md');
86
+ // Results sorted by decay_score ascending
87
+ if (stale.length > 1) {
88
+ expect(stale[0].decay_score).toBeLessThanOrEqual(stale[stale.length - 1].decay_score);
89
+ }
90
+ });
91
+ });
92
+ //# sourceMappingURL=decay.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decay.test.js","sourceRoot":"","sources":["../../tests/decay.test.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,4CAAoB;AACpB,gDAAwB;AAExB,2CAA+C;AAC/C,wEAAoF;AACpF,gEAA+D;AAC/D,0EAAoE;AACpE,0EAAoE;AACpE,0EAAoE;AACpE,sDAKiC;AAEjC,SAAS,iBAAiB,CAAC,MAAc;IACvC,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,MAAM,CAAC,CAAC;IAChC,IAAA,qCAAiB,EAAC,EAAE,CAAC,CAAC;IACtB,IAAA,iCAAa,EAAC,EAAE,EAAE;QAChB,GAAG,+BAAe;QAClB,GAAG,oCAAe;QAClB,GAAG,oCAAe;QAClB,GAAG,oCAAe;KACnB,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,IAAI,MAAc,CAAC;AACnB,IAAI,EAAqB,CAAC;AAE1B,UAAU,CAAC,GAAG,EAAE;IACd,MAAM,GAAG,YAAE,CAAC,WAAW,CAAC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACnE,EAAE,GAAG,iBAAiB,CAAC,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,YAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACnE,MAAM,KAAK,GAAG,IAAA,8BAAmB,EAAC;YAChC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,gBAAgB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC1C,YAAY,EAAE,EAAE;YAChB,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACtD,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACpF,MAAM,KAAK,GAAG,IAAA,8BAAmB,EAAC;YAChC,UAAU,EAAE,aAAa;YACzB,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,IAAI,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACvE,EAAE,CAAC,OAAO,CACR;iCAC2B,CAC5B,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAExE,IAAA,0BAAe,EAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAEpC,iJAAiJ;QACjJ,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAC7B,oDAAoD,CACrD,CAAC,GAAG,CAAC,cAAc,CAAmC,CAAC;QACxD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAEhD,IAAA,0BAAe,EAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QAEpC,iJAAiJ;QACjJ,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAC7B,oDAAoD,CACrD,CAAC,GAAG,CAAC,cAAc,CAAmC,CAAC;QACxD,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QACpF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,6BAA6B;QAC7B,EAAE,CAAC,OAAO,CACR;iCAC2B,CAC5B,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAE9D,mDAAmD;QACnD,EAAE,CAAC,OAAO,CACR;iCAC2B,CAC5B,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAErD,MAAM,KAAK,GAAG,IAAA,6BAAkB,EAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAE1C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAE/C,0CAA0C;QAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,WAAW,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -19,18 +19,20 @@ afterEach(() => {
19
19
  * Run the writeEpisodeFile function in an isolated child process.
20
20
  * The function is internal to session-end hook, so we extract and call it directly.
21
21
  */
22
- function runWriteEpisodeFile(baseDir, project, commits, changedFiles, reads) {
22
+ function runWriteEpisodeFile(baseDir, project, commits, changedFiles, reads, episodeTs) {
23
23
  // Since writeEpisodeFile is not exported, test via the hook's worker mode
24
24
  // by calling the hook with a crafted payload
25
25
  const payload = JSON.stringify({ baseDir, project, commits, changedFiles, reads });
26
26
  const tmpFile = path_1.default.join(os_1.default.tmpdir(), `mindlore-test-epfile-${Date.now()}.json`);
27
27
  fs_1.default.writeFileSync(tmpFile, payload, 'utf8');
28
28
  const hookFile = path_1.default.join(__dirname, '..', 'hooks', 'mindlore-session-end.cjs');
29
- // Set MINDLORE_HOME so hookLog writes to our tmpDir
29
+ const env = { ...process.env, MINDLORE_HOME: tmpDir };
30
+ if (episodeTs)
31
+ env.MINDLORE_EPISODE_TS = episodeTs;
30
32
  (0, child_process_1.execSync)(`node "${hookFile}" --worker "${tmpFile}"`, {
31
33
  timeout: 10000,
32
34
  encoding: 'utf8',
33
- env: { ...process.env, MINDLORE_HOME: tmpDir },
35
+ env,
34
36
  cwd: process.cwd(),
35
37
  });
36
38
  }
@@ -58,11 +60,12 @@ describe('writeEpisodeFile', () => {
58
60
  expect(content).not.toContain('## Commits');
59
61
  });
60
62
  test('is idempotent — second call does not overwrite', () => {
61
- runWriteEpisodeFile(tmpDir, 'idem-proj', ['aaa commit'], ['x.ts'], null);
63
+ const fixedTs = '2026-01-15T10:30:00.000Z';
64
+ runWriteEpisodeFile(tmpDir, 'idem-proj', ['aaa commit'], ['x.ts'], null, fixedTs);
62
65
  const projDir = path_1.default.join(tmpDir, 'diary', 'idem-proj');
63
66
  const files1 = fs_1.default.readdirSync(projDir).filter(f => f.startsWith('episode-'));
64
- // Run again within same minute — should not create duplicate
65
- runWriteEpisodeFile(tmpDir, 'idem-proj', ['bbb different'], ['y.ts'], null);
67
+ // Run again with same timestamp — should not create duplicate
68
+ runWriteEpisodeFile(tmpDir, 'idem-proj', ['bbb different'], ['y.ts'], null, fixedTs);
66
69
  const files2 = fs_1.default.readdirSync(projDir).filter(f => f.startsWith('episode-'));
67
70
  expect(files2.length).toBe(files1.length);
68
71
  // Content should still be from first call
@@ -1 +1 @@
1
- {"version":3,"file":"episode-file.test.js","sourceRoot":"","sources":["../../tests/episode-file.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"episode-file.test.js","sourceRoot":"","sources":["../../tests/episode-file.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fetch-raw.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-raw.test.d.ts","sourceRoot":"","sources":["../../tests/fetch-raw.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
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 child_process_1 = require("child_process");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ describe('fetch-raw script', () => {
11
+ const tmpDir = path_1.default.join(os_1.default.tmpdir(), 'mindlore-fetch-test-' + Date.now());
12
+ beforeAll(() => { fs_1.default.mkdirSync(tmpDir, { recursive: true }); });
13
+ afterAll(() => { fs_1.default.rmSync(tmpDir, { recursive: true, force: true }); });
14
+ it('fetches a URL and saves to output dir', () => {
15
+ const result = (0, child_process_1.execSync)(`node dist/scripts/fetch-raw.js https://raw.githubusercontent.com/anthropics/claude-code/main/README.md --out-dir "${tmpDir}"`, { encoding: 'utf8', timeout: 30000 });
16
+ const parsed = JSON.parse(result.trim());
17
+ expect(parsed.saved).toBeTruthy();
18
+ expect(parsed.chars).toBeGreaterThan(100);
19
+ expect(fs_1.default.existsSync(parsed.saved)).toBe(true);
20
+ });
21
+ it('outputs valid JSON with saved path and char count', () => {
22
+ const result = (0, child_process_1.execSync)(`node dist/scripts/fetch-raw.js https://raw.githubusercontent.com/anthropics/claude-code/main/README.md --out-dir "${tmpDir}"`, { encoding: 'utf8', timeout: 30000 });
23
+ const parsed = JSON.parse(result.trim());
24
+ expect(parsed).toHaveProperty('saved');
25
+ expect(parsed).toHaveProperty('chars');
26
+ expect(typeof parsed.chars).toBe('number');
27
+ });
28
+ it('generates frontmatter with slug and date', () => {
29
+ const result = (0, child_process_1.execSync)(`node dist/scripts/fetch-raw.js https://raw.githubusercontent.com/anthropics/claude-code/main/README.md --out-dir "${tmpDir}"`, { encoding: 'utf8', timeout: 30000 });
30
+ const parsed = JSON.parse(result.trim());
31
+ const content = fs_1.default.readFileSync(parsed.saved, 'utf8');
32
+ expect(content).toContain('---');
33
+ expect(content).toContain('slug:');
34
+ expect(content).toContain('date_captured:');
35
+ expect(content).toContain('source_url:');
36
+ });
37
+ it('exits with error when no URL provided', () => {
38
+ expect(() => {
39
+ (0, child_process_1.execSync)(`node dist/scripts/fetch-raw.js --out-dir "${tmpDir}"`, { encoding: 'utf8', timeout: 5000 });
40
+ }).toThrow();
41
+ });
42
+ });
43
+ //# sourceMappingURL=fetch-raw.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-raw.test.js","sourceRoot":"","sources":["../../tests/fetch-raw.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=git-snapshot.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-snapshot.test.d.ts","sourceRoot":"","sources":["../../tests/git-snapshot.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
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('Git Snapshot (Pre-Eviction)', () => {
11
+ const tmpDir = path_1.default.join(os_1.default.tmpdir(), `mindlore-snapshot-${Date.now()}`);
12
+ const mindloreDir = path_1.default.join(tmpDir, '.mindlore');
13
+ beforeEach(() => {
14
+ fs_1.default.mkdirSync(mindloreDir, { recursive: true });
15
+ (0, child_process_1.execSync)('git init', { cwd: mindloreDir });
16
+ (0, child_process_1.execSync)('git config user.email "test@test.com"', { cwd: mindloreDir });
17
+ (0, child_process_1.execSync)('git config user.name "Test"', { cwd: mindloreDir });
18
+ fs_1.default.writeFileSync(path_1.default.join(mindloreDir, 'test.md'), '# Test', 'utf8');
19
+ (0, child_process_1.execSync)('git add . && git commit -m "init"', { cwd: mindloreDir });
20
+ });
21
+ afterEach(() => fs_1.default.rmSync(tmpDir, { recursive: true, force: true }));
22
+ test('createPreEvictionTag creates a git tag with date prefix', async () => {
23
+ const { createPreEvictionTag } = await import('../scripts/mindlore-backup.js');
24
+ const tag = createPreEvictionTag(mindloreDir);
25
+ expect(tag).toMatch(/^pre-eviction-\d{4}-\d{2}-\d{2}/);
26
+ const tags = (0, child_process_1.execSync)('git tag', { cwd: mindloreDir, encoding: 'utf8' });
27
+ expect(tags).toContain(tag);
28
+ });
29
+ test('createPreEvictionTag is idempotent (no error on same-day call)', async () => {
30
+ const { createPreEvictionTag } = await import('../scripts/mindlore-backup.js');
31
+ createPreEvictionTag(mindloreDir);
32
+ const tag2 = createPreEvictionTag(mindloreDir);
33
+ expect(tag2).toBeTruthy();
34
+ });
35
+ });
36
+ //# sourceMappingURL=git-snapshot.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-snapshot.test.js","sourceRoot":"","sources":["../../tests/git-snapshot.test.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AACpB,iDAAyC;AAEzC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,qBAAqB,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEnD,UAAU,CAAC,GAAG,EAAE;QACd,YAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAA,wBAAQ,EAAC,UAAU,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC3C,IAAA,wBAAQ,EAAC,uCAAuC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QACxE,IAAA,wBAAQ,EAAC,6BAA6B,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9D,YAAE,CAAC,aAAa,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACtE,IAAA,wBAAQ,EAAC,mCAAmC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;IACtE,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,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAC/E,MAAM,GAAG,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,IAAA,wBAAQ,EAAC,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;QAC/E,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=migrations-v053.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations-v053.test.d.ts","sourceRoot":"","sources":["../../tests/migrations-v053.test.ts"],"names":[],"mappings":""}