mindlore 0.5.1 → 0.5.2

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 (90) hide show
  1. package/README.md +15 -2
  2. package/dist/scripts/fetch-raw.d.ts +2 -0
  3. package/dist/scripts/fetch-raw.d.ts.map +1 -0
  4. package/dist/scripts/fetch-raw.js +124 -0
  5. package/dist/scripts/fetch-raw.js.map +1 -0
  6. package/dist/scripts/lib/constants.d.ts +2 -0
  7. package/dist/scripts/lib/constants.d.ts.map +1 -1
  8. package/dist/scripts/lib/constants.js +13 -4
  9. package/dist/scripts/lib/constants.js.map +1 -1
  10. package/dist/scripts/lib/db-helpers.d.ts +12 -2
  11. package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
  12. package/dist/scripts/lib/db-helpers.js +36 -0
  13. package/dist/scripts/lib/db-helpers.js.map +1 -1
  14. package/dist/scripts/lib/hybrid-search.d.ts +0 -2
  15. package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
  16. package/dist/scripts/lib/hybrid-search.js +7 -1
  17. package/dist/scripts/lib/hybrid-search.js.map +1 -1
  18. package/dist/scripts/lib/migrations-v052.d.ts +3 -0
  19. package/dist/scripts/lib/migrations-v052.d.ts.map +1 -0
  20. package/dist/scripts/lib/migrations-v052.js +23 -0
  21. package/dist/scripts/lib/migrations-v052.js.map +1 -0
  22. package/dist/scripts/lib/skeleton.d.ts +2 -0
  23. package/dist/scripts/lib/skeleton.d.ts.map +1 -0
  24. package/dist/scripts/lib/skeleton.js +99 -0
  25. package/dist/scripts/lib/skeleton.js.map +1 -0
  26. package/dist/scripts/lib/skill-memory.d.ts +13 -0
  27. package/dist/scripts/lib/skill-memory.d.ts.map +1 -0
  28. package/dist/scripts/lib/skill-memory.js +94 -0
  29. package/dist/scripts/lib/skill-memory.js.map +1 -0
  30. package/dist/scripts/mindlore-fts5-index.js +2 -1
  31. package/dist/scripts/mindlore-fts5-index.js.map +1 -1
  32. package/dist/scripts/mindlore-health-check.d.ts +1 -1
  33. package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
  34. package/dist/scripts/mindlore-health-check.js +110 -142
  35. package/dist/scripts/mindlore-health-check.js.map +1 -1
  36. package/dist/tests/catch-up.test.d.ts +2 -0
  37. package/dist/tests/catch-up.test.d.ts.map +1 -0
  38. package/dist/tests/catch-up.test.js +88 -0
  39. package/dist/tests/catch-up.test.js.map +1 -0
  40. package/dist/tests/episode-file.test.js +9 -6
  41. package/dist/tests/episode-file.test.js.map +1 -1
  42. package/dist/tests/fetch-raw.test.d.ts +2 -0
  43. package/dist/tests/fetch-raw.test.d.ts.map +1 -0
  44. package/dist/tests/fetch-raw.test.js +43 -0
  45. package/dist/tests/fetch-raw.test.js.map +1 -0
  46. package/dist/tests/resolve-hook-common.test.d.ts +2 -0
  47. package/dist/tests/resolve-hook-common.test.d.ts.map +1 -0
  48. package/dist/tests/resolve-hook-common.test.js +30 -0
  49. package/dist/tests/resolve-hook-common.test.js.map +1 -0
  50. package/dist/tests/search-offload.test.d.ts +2 -0
  51. package/dist/tests/search-offload.test.d.ts.map +1 -0
  52. package/dist/tests/search-offload.test.js +34 -0
  53. package/dist/tests/search-offload.test.js.map +1 -0
  54. package/dist/tests/skeleton.test.d.ts +2 -0
  55. package/dist/tests/skeleton.test.d.ts.map +1 -0
  56. package/dist/tests/skeleton.test.js +116 -0
  57. package/dist/tests/skeleton.test.js.map +1 -0
  58. package/dist/tests/skill-memory-api.test.d.ts +2 -0
  59. package/dist/tests/skill-memory-api.test.d.ts.map +1 -0
  60. package/dist/tests/skill-memory-api.test.js +62 -0
  61. package/dist/tests/skill-memory-api.test.js.map +1 -0
  62. package/dist/tests/skill-memory.test.d.ts +2 -0
  63. package/dist/tests/skill-memory.test.d.ts.map +1 -0
  64. package/dist/tests/skill-memory.test.js +67 -0
  65. package/dist/tests/skill-memory.test.js.map +1 -0
  66. package/dist/tests/wiki-lint.test.d.ts +2 -0
  67. package/dist/tests/wiki-lint.test.d.ts.map +1 -0
  68. package/dist/tests/wiki-lint.test.js +47 -0
  69. package/dist/tests/wiki-lint.test.js.map +1 -0
  70. package/hooks/lib/mindlore-common.cjs +24 -5
  71. package/hooks/mindlore-cwd-changed.cjs +2 -2
  72. package/hooks/mindlore-decision-detector.cjs +2 -2
  73. package/hooks/mindlore-dont-repeat.cjs +2 -2
  74. package/hooks/mindlore-fts5-sync.cjs +2 -2
  75. package/hooks/mindlore-index.cjs +60 -2
  76. package/hooks/mindlore-model-router.cjs +2 -2
  77. package/hooks/mindlore-post-compact.cjs +2 -2
  78. package/hooks/mindlore-post-read.cjs +2 -2
  79. package/hooks/mindlore-pre-compact.cjs +2 -2
  80. package/hooks/mindlore-read-guard.cjs +15 -3
  81. package/hooks/mindlore-research-guard.cjs +2 -2
  82. package/hooks/mindlore-search.cjs +20 -2
  83. package/hooks/mindlore-session-end.cjs +1 -1
  84. package/package.json +3 -2
  85. package/plugin.json +29 -2
  86. package/skills/mindlore-diary/SKILL.md +76 -0
  87. package/skills/mindlore-ingest/SKILL.md +41 -49
  88. package/skills/mindlore-log/SKILL.md +3 -143
  89. package/skills/mindlore-reflect/SKILL.md +104 -0
  90. package/templates/config.json +1 -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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"}
@@ -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=resolve-hook-common.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-hook-common.test.d.ts","sourceRoot":"","sources":["../../tests/resolve-hook-common.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
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 constants_1 = require("../scripts/lib/constants");
9
+ describe('resolveHookCommon', () => {
10
+ it('resolves from scripts/lib/ (source)', () => {
11
+ const result = (0, constants_1.resolveHookCommon)(path_1.default.join(__dirname, '..', 'scripts', 'lib'));
12
+ expect(fs_1.default.existsSync(result)).toBe(true);
13
+ expect(result).toContain('mindlore-common.cjs');
14
+ });
15
+ it('resolves from dist/scripts/lib/ (compiled)', () => {
16
+ const distDir = path_1.default.join(__dirname, '..', 'dist', 'scripts', 'lib');
17
+ if (fs_1.default.existsSync(distDir)) {
18
+ const result = (0, constants_1.resolveHookCommon)(distDir);
19
+ expect(fs_1.default.existsSync(result)).toBe(true);
20
+ expect(result).toContain('mindlore-common.cjs');
21
+ }
22
+ });
23
+ it('resolves from deeply nested dist path', () => {
24
+ const projectRoot = path_1.default.join(__dirname, '..');
25
+ const fakeDeep = path_1.default.join(projectRoot, 'dist', 'scripts', 'lib');
26
+ const result = (0, constants_1.resolveHookCommon)(fakeDeep);
27
+ expect(result).toContain('mindlore-common.cjs');
28
+ });
29
+ });
30
+ //# sourceMappingURL=resolve-hook-common.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-hook-common.test.js","sourceRoot":"","sources":["../../tests/resolve-hook-common.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,4CAAoB;AACpB,wDAA6D;AAE7D,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG,IAAA,6BAAiB,EAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QAC/E,MAAM,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,IAAI,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAA,6BAAiB,EAAC,OAAO,CAAC,CAAC;YAC1C,MAAM,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAA,6BAAiB,EAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-offload.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-offload.test.d.ts","sourceRoot":"","sources":["../../tests/search-offload.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
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
+ describe('search hook offload+pointer', () => {
10
+ const tmpDir = path_1.default.join(os_1.default.tmpdir(), 'mindlore-offload-' + Date.now());
11
+ const mindloreDir = path_1.default.join(tmpDir, '.mindlore');
12
+ const tmpSubDir = path_1.default.join(mindloreDir, 'tmp');
13
+ beforeEach(() => { fs_1.default.mkdirSync(tmpSubDir, { recursive: true }); });
14
+ afterEach(() => { fs_1.default.rmSync(tmpDir, { recursive: true, force: true }); });
15
+ it('offloads results >10KB to tmp/ and returns pointer', () => {
16
+ const largeContent = 'x'.repeat(12000);
17
+ const resultPath = path_1.default.join(tmpSubDir, 'search-result-test.md');
18
+ fs_1.default.writeFileSync(resultPath, largeContent, 'utf8');
19
+ // Verify file was written and is >10KB
20
+ const stat = fs_1.default.statSync(resultPath);
21
+ expect(stat.size).toBeGreaterThan(10240);
22
+ expect(fs_1.default.existsSync(resultPath)).toBe(true);
23
+ // Verify pointer format
24
+ const pointer = `[Mindlore Search: ${largeContent.length} chars offloaded to ${resultPath}]\nSummary: ${largeContent.slice(0, 500).trim()}...\n[Read full results: ${resultPath}]`;
25
+ expect(pointer).toContain('offloaded to');
26
+ expect(pointer).toContain('Read full results');
27
+ });
28
+ it('keeps results under 10KB inline', () => {
29
+ const smallContent = 'y'.repeat(5000);
30
+ // Under threshold — should not offload
31
+ expect(smallContent.length).toBeLessThan(10240);
32
+ });
33
+ });
34
+ //# sourceMappingURL=search-offload.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-offload.test.js","sourceRoot":"","sources":["../../tests/search-offload.test.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,4CAAoB;AAEpB,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACxE,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAEhD,UAAU,CAAC,GAAG,EAAE,GAAG,YAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,SAAS,CAAC,GAAG,EAAE,GAAG,YAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1E,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;QACjE,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;QAEnD,uCAAuC;QACvC,MAAM,IAAI,GAAG,YAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE7C,wBAAwB;QACxB,MAAM,OAAO,GAAG,qBAAqB,YAAY,CAAC,MAAM,uBAAuB,UAAU,eAAe,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,4BAA4B,UAAU,GAAG,CAAC;QACnL,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtC,uCAAuC;QACvC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skeleton.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.test.d.ts","sourceRoot":"","sources":["../../tests/skeleton.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const skeleton_1 = require("../scripts/lib/skeleton");
4
+ describe('extractSkeleton', () => {
5
+ describe('JavaScript/TypeScript', () => {
6
+ it('keeps imports and top-level declarations', () => {
7
+ const input = `import fs from 'fs';
8
+ import path from 'path';
9
+
10
+ const THRESHOLD = 30;
11
+
12
+ function doSomething(a: string, b: number): boolean {
13
+ const result = a.length > b;
14
+ if (result) {
15
+ console.log('yes');
16
+ return true;
17
+ }
18
+ return false;
19
+ }
20
+
21
+ export class MyClass {
22
+ private name: string;
23
+ constructor(name: string) {
24
+ this.name = name;
25
+ }
26
+ getName(): string {
27
+ return this.name;
28
+ }
29
+ }`;
30
+ const result = (0, skeleton_1.extractSkeleton)(input, 'ts');
31
+ expect(result).toContain("import fs from 'fs'");
32
+ expect(result).toContain("import path from 'path'");
33
+ expect(result).toContain('const THRESHOLD = 30');
34
+ expect(result).toContain('function doSomething');
35
+ expect(result).toContain('export class MyClass');
36
+ expect(result).not.toContain("console.log('yes')");
37
+ expect(result).not.toContain('return this.name');
38
+ });
39
+ it('keeps interface and type declarations', () => {
40
+ const input = `interface Config {
41
+ name: string;
42
+ value: number;
43
+ nested: {
44
+ deep: boolean;
45
+ };
46
+ }
47
+
48
+ type Result = Config | null;`;
49
+ const result = (0, skeleton_1.extractSkeleton)(input, 'ts');
50
+ expect(result).toContain('interface Config');
51
+ expect(result).toContain('type Result');
52
+ });
53
+ });
54
+ describe('Python', () => {
55
+ it('keeps imports, defs, classes', () => {
56
+ const input = `import os
57
+ from pathlib import Path
58
+
59
+ CONSTANT = 42
60
+
61
+ def process(data: list) -> dict:
62
+ """Process the data."""
63
+ result = {}
64
+ for item in data:
65
+ result[item] = True
66
+ return result
67
+
68
+ class Handler:
69
+ def __init__(self, name):
70
+ self.name = name
71
+ def run(self):
72
+ pass`;
73
+ const result = (0, skeleton_1.extractSkeleton)(input, 'py');
74
+ expect(result).toContain('import os');
75
+ expect(result).toContain('from pathlib import Path');
76
+ expect(result).toContain('CONSTANT = 42');
77
+ expect(result).toContain('def process');
78
+ expect(result).toContain('class Handler');
79
+ expect(result).not.toContain('for item in data');
80
+ });
81
+ });
82
+ describe('Markdown', () => {
83
+ it('keeps headings only', () => {
84
+ const input = `# Title
85
+
86
+ Some long paragraph about something.
87
+
88
+ ## Section 1
89
+
90
+ More content here with details.
91
+
92
+ ### Subsection
93
+
94
+ Even more details.`;
95
+ const result = (0, skeleton_1.extractSkeleton)(input, 'md');
96
+ expect(result).toContain('# Title');
97
+ expect(result).toContain('## Section 1');
98
+ expect(result).toContain('### Subsection');
99
+ expect(result).not.toContain('Some long paragraph');
100
+ });
101
+ });
102
+ it('returns full content for unsupported extensions', () => {
103
+ const input = 'just plain text';
104
+ const result = (0, skeleton_1.extractSkeleton)(input, 'xyz');
105
+ expect(result).toBe(input);
106
+ });
107
+ it('returns full content if skeleton is >75% of original', () => {
108
+ const input = `import a from 'a';
109
+ import b from 'b';
110
+ import c from 'c';
111
+ const x = 1;`;
112
+ const result = (0, skeleton_1.extractSkeleton)(input, 'ts');
113
+ expect(result).toBe(input);
114
+ });
115
+ });
116
+ //# sourceMappingURL=skeleton.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.test.js","sourceRoot":"","sources":["../../tests/skeleton.test.ts"],"names":[],"mappings":";;AAAA,sDAA0D;AAE1D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;EAsBlB,CAAC;YAEG,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YACnD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,KAAK,GAAG;;;;;;;;6BAQS,CAAC;YAExB,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;aAgBP,CAAC;YAER,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC1C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,KAAK,GAAG;;;;;;;;;;mBAUD,CAAC;YAEd,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;YACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,KAAK,GAAG,iBAAiB,CAAC;QAChC,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,KAAK,GAAG;;;aAGL,CAAC;QACV,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill-memory-api.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-memory-api.test.d.ts","sourceRoot":"","sources":["../../tests/skill-memory-api.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
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_1 = require("../scripts/lib/schema-version");
11
+ const migrations_v052_1 = require("../scripts/lib/migrations-v052");
12
+ const skill_memory_1 = require("../scripts/lib/skill-memory");
13
+ describe('skill-memory API', () => {
14
+ let dbPath;
15
+ let tmpDir;
16
+ beforeEach(() => {
17
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-skillmem-api-'));
18
+ dbPath = path_1.default.join(tmpDir, 'test.db');
19
+ const db = new better_sqlite3_1.default(dbPath);
20
+ db.pragma('journal_mode = WAL');
21
+ (0, schema_version_1.ensureSchemaTable)(db);
22
+ (0, schema_version_1.runMigrations)(db, migrations_v052_1.V052_MIGRATIONS);
23
+ db.close();
24
+ });
25
+ afterEach(() => {
26
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
27
+ });
28
+ it('setSkillMem + getSkillMem roundtrip', () => {
29
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-diary', 'last_date', '2026-04-18');
30
+ const value = (0, skill_memory_1.getSkillMem)(dbPath, 'mindlore-diary', 'last_date');
31
+ expect(value).toBe('2026-04-18');
32
+ });
33
+ it('getSkillMem returns null for missing key', () => {
34
+ const value = (0, skill_memory_1.getSkillMem)(dbPath, 'mindlore-diary', 'nonexistent');
35
+ expect(value).toBeNull();
36
+ });
37
+ it('setSkillMem overwrites existing value', () => {
38
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-ingest', 'urls', '["a.com"]');
39
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-ingest', 'urls', '["a.com","b.com"]');
40
+ const value = (0, skill_memory_1.getSkillMem)(dbPath, 'mindlore-ingest', 'urls');
41
+ expect(value).toBe('["a.com","b.com"]');
42
+ });
43
+ it('bumpAccess increments access_count', () => {
44
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-query', 'log', '[]');
45
+ (0, skill_memory_1.bumpAccess)(dbPath, 'mindlore-query', 'log');
46
+ (0, skill_memory_1.bumpAccess)(dbPath, 'mindlore-query', 'log');
47
+ const db2 = new better_sqlite3_1.default(dbPath, { readonly: true });
48
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
49
+ const row = db2.prepare('SELECT access_count FROM skill_memory WHERE skill_name = ? AND key = ?').get('mindlore-query', 'log');
50
+ db2.close();
51
+ expect(row.access_count).toBe(2);
52
+ });
53
+ it('listSkillMem returns all keys for a skill', () => {
54
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-diary', 'last_date', '2026-04-18');
55
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-diary', 'session_count', '5');
56
+ (0, skill_memory_1.setSkillMem)(dbPath, 'mindlore-ingest', 'urls', '[]');
57
+ const keys = (0, skill_memory_1.listSkillMem)(dbPath, 'mindlore-diary');
58
+ expect(keys).toHaveLength(2);
59
+ expect(keys.map(k => k.key).sort()).toEqual(['last_date', 'session_count']);
60
+ });
61
+ });
62
+ //# sourceMappingURL=skill-memory-api.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-memory-api.test.js","sourceRoot":"","sources":["../../tests/skill-memory-api.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill-memory.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-memory.test.d.ts","sourceRoot":"","sources":["../../tests/skill-memory.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
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_1 = require("../scripts/lib/schema-version");
11
+ const migrations_v052_1 = require("../scripts/lib/migrations-v052");
12
+ describe('skill_memory table', () => {
13
+ let db;
14
+ let tmpDir;
15
+ beforeEach(() => {
16
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-skillmem-'));
17
+ const dbPath = path_1.default.join(tmpDir, 'test.db');
18
+ db = new better_sqlite3_1.default(dbPath);
19
+ db.pragma('journal_mode = WAL');
20
+ (0, schema_version_1.ensureSchemaTable)(db);
21
+ (0, schema_version_1.runMigrations)(db, migrations_v052_1.V052_MIGRATIONS);
22
+ });
23
+ afterEach(() => {
24
+ db.close();
25
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
26
+ });
27
+ it('creates skill_memory table', () => {
28
+ const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='skill_memory'").all();
29
+ expect(tables).toHaveLength(1);
30
+ });
31
+ it('inserts and retrieves skill memory', () => {
32
+ db.prepare(`INSERT INTO skill_memory (skill_name, key, value, updated_at)
33
+ VALUES (?, ?, ?, ?)`).run('mindlore-ingest', 'last_ingest_urls', '["https://example.com"]', new Date().toISOString());
34
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
35
+ const row = db.prepare('SELECT * FROM skill_memory WHERE skill_name = ? AND key = ?').get('mindlore-ingest', 'last_ingest_urls');
36
+ expect(row).toBeDefined();
37
+ expect(row.value).toBe('["https://example.com"]');
38
+ expect(row.access_count).toBe(0);
39
+ });
40
+ it('enforces UNIQUE(skill_name, key) constraint', () => {
41
+ const insert = db.prepare(`INSERT INTO skill_memory (skill_name, key, value, updated_at)
42
+ VALUES (?, ?, ?, ?)`);
43
+ insert.run('mindlore-query', 'log', '[]', new Date().toISOString());
44
+ expect(() => {
45
+ insert.run('mindlore-query', 'log', '["x"]', new Date().toISOString());
46
+ }).toThrow();
47
+ });
48
+ it('upserts with ON CONFLICT', () => {
49
+ const upsert = db.prepare(`INSERT INTO skill_memory (skill_name, key, value, updated_at)
50
+ VALUES (?, ?, ?, ?)
51
+ ON CONFLICT(skill_name, key) DO UPDATE SET
52
+ value = excluded.value,
53
+ updated_at = excluded.updated_at,
54
+ access_count = access_count + 1`);
55
+ const now = new Date().toISOString();
56
+ upsert.run('mindlore-diary', 'last_date', '"2026-04-18"', now);
57
+ upsert.run('mindlore-diary', 'last_date', '"2026-04-19"', now);
58
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- better-sqlite3 .get() returns unknown
59
+ const row = db.prepare('SELECT * FROM skill_memory WHERE skill_name = ? AND key = ?').get('mindlore-diary', 'last_date');
60
+ expect(row.value).toBe('"2026-04-19"');
61
+ expect(row.access_count).toBe(1);
62
+ });
63
+ it('migration is idempotent', () => {
64
+ expect(() => (0, schema_version_1.runMigrations)(db, migrations_v052_1.V052_MIGRATIONS)).not.toThrow();
65
+ });
66
+ });
67
+ //# sourceMappingURL=skill-memory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-memory.test.js","sourceRoot":"","sources":["../../tests/skill-memory.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=wiki-lint.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki-lint.test.d.ts","sourceRoot":"","sources":["../../tests/wiki-lint.test.ts"],"names":[],"mappings":""}