mindlore 0.2.0 → 0.3.0

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 (153) hide show
  1. package/README.md +15 -9
  2. package/SCHEMA.md +15 -2
  3. package/dist/scripts/init.d.ts +10 -0
  4. package/dist/scripts/init.d.ts.map +1 -0
  5. package/dist/scripts/init.js +406 -0
  6. package/dist/scripts/init.js.map +1 -0
  7. package/dist/scripts/lib/constants.d.ts +56 -0
  8. package/dist/scripts/lib/constants.d.ts.map +1 -0
  9. package/dist/scripts/lib/constants.js +131 -0
  10. package/dist/scripts/lib/constants.js.map +1 -0
  11. package/dist/scripts/lib/schemas.d.ts +93 -0
  12. package/dist/scripts/lib/schemas.d.ts.map +1 -0
  13. package/dist/scripts/lib/schemas.js +108 -0
  14. package/dist/scripts/lib/schemas.js.map +1 -0
  15. package/dist/scripts/mindlore-fts5-index.d.ts +9 -0
  16. package/dist/scripts/mindlore-fts5-index.d.ts.map +1 -0
  17. package/dist/scripts/mindlore-fts5-index.js +88 -0
  18. package/dist/scripts/mindlore-fts5-index.js.map +1 -0
  19. package/dist/scripts/mindlore-fts5-search.d.ts +10 -0
  20. package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -0
  21. package/dist/scripts/mindlore-fts5-search.js +121 -0
  22. package/dist/scripts/mindlore-fts5-search.js.map +1 -0
  23. package/dist/scripts/mindlore-health-check.d.ts +10 -0
  24. package/dist/scripts/mindlore-health-check.d.ts.map +1 -0
  25. package/dist/scripts/mindlore-health-check.js +337 -0
  26. package/dist/scripts/mindlore-health-check.js.map +1 -0
  27. package/dist/scripts/uninstall.d.ts +10 -0
  28. package/dist/scripts/uninstall.d.ts.map +1 -0
  29. package/dist/scripts/uninstall.js +153 -0
  30. package/dist/scripts/uninstall.js.map +1 -0
  31. package/dist/tests/compounding.test.d.ts +8 -0
  32. package/dist/tests/compounding.test.d.ts.map +1 -0
  33. package/dist/tests/compounding.test.js +51 -0
  34. package/dist/tests/compounding.test.js.map +1 -0
  35. package/dist/tests/cwd-changed.test.d.ts +2 -0
  36. package/dist/tests/cwd-changed.test.d.ts.map +1 -0
  37. package/dist/tests/cwd-changed.test.js +62 -0
  38. package/dist/tests/cwd-changed.test.js.map +1 -0
  39. package/dist/tests/decision.test.d.ts +2 -0
  40. package/dist/tests/decision.test.d.ts.map +1 -0
  41. package/dist/tests/decision.test.js +61 -0
  42. package/dist/tests/decision.test.js.map +1 -0
  43. package/dist/tests/dedup.test.d.ts +2 -0
  44. package/dist/tests/dedup.test.d.ts.map +1 -0
  45. package/dist/tests/dedup.test.js +74 -0
  46. package/dist/tests/dedup.test.js.map +1 -0
  47. package/dist/tests/dont-repeat.test.d.ts +2 -0
  48. package/dist/tests/dont-repeat.test.d.ts.map +1 -0
  49. package/dist/tests/dont-repeat.test.js +100 -0
  50. package/dist/tests/dont-repeat.test.js.map +1 -0
  51. package/dist/tests/e2e-pipeline.test.d.ts +2 -0
  52. package/dist/tests/e2e-pipeline.test.d.ts.map +1 -0
  53. package/dist/tests/e2e-pipeline.test.js +220 -0
  54. package/dist/tests/e2e-pipeline.test.js.map +1 -0
  55. package/dist/tests/evolve.test.d.ts +2 -0
  56. package/dist/tests/evolve.test.d.ts.map +1 -0
  57. package/dist/tests/evolve.test.js +105 -0
  58. package/dist/tests/evolve.test.js.map +1 -0
  59. package/dist/tests/explore.test.d.ts +2 -0
  60. package/dist/tests/explore.test.d.ts.map +1 -0
  61. package/dist/tests/explore.test.js +146 -0
  62. package/dist/tests/explore.test.js.map +1 -0
  63. package/dist/tests/frontmatter.test.d.ts +2 -0
  64. package/dist/tests/frontmatter.test.d.ts.map +1 -0
  65. package/dist/tests/frontmatter.test.js +90 -0
  66. package/dist/tests/frontmatter.test.js.map +1 -0
  67. package/dist/tests/fts5.test.d.ts +2 -0
  68. package/dist/tests/fts5.test.d.ts.map +1 -0
  69. package/dist/tests/fts5.test.js +95 -0
  70. package/dist/tests/fts5.test.js.map +1 -0
  71. package/dist/tests/global-layer.test.d.ts +2 -0
  72. package/dist/tests/global-layer.test.d.ts.map +1 -0
  73. package/dist/tests/global-layer.test.js +152 -0
  74. package/dist/tests/global-layer.test.js.map +1 -0
  75. package/dist/tests/helpers/db.d.ts +20 -0
  76. package/dist/tests/helpers/db.d.ts.map +1 -0
  77. package/dist/tests/helpers/db.js +46 -0
  78. package/dist/tests/helpers/db.js.map +1 -0
  79. package/dist/tests/hook-smoke.test.d.ts +2 -0
  80. package/dist/tests/hook-smoke.test.d.ts.map +1 -0
  81. package/dist/tests/hook-smoke.test.js +58 -0
  82. package/dist/tests/hook-smoke.test.js.map +1 -0
  83. package/dist/tests/init.test.d.ts +2 -0
  84. package/dist/tests/init.test.d.ts.map +1 -0
  85. package/dist/tests/init.test.js +109 -0
  86. package/dist/tests/init.test.js.map +1 -0
  87. package/dist/tests/log.test.d.ts +2 -0
  88. package/dist/tests/log.test.d.ts.map +1 -0
  89. package/dist/tests/log.test.js +68 -0
  90. package/dist/tests/log.test.js.map +1 -0
  91. package/dist/tests/post-read.test.d.ts +2 -0
  92. package/dist/tests/post-read.test.d.ts.map +1 -0
  93. package/dist/tests/post-read.test.js +69 -0
  94. package/dist/tests/post-read.test.js.map +1 -0
  95. package/dist/tests/quality-populate.test.d.ts +2 -0
  96. package/dist/tests/quality-populate.test.d.ts.map +1 -0
  97. package/dist/tests/quality-populate.test.js +85 -0
  98. package/dist/tests/quality-populate.test.js.map +1 -0
  99. package/dist/tests/read-guard.test.d.ts +2 -0
  100. package/dist/tests/read-guard.test.d.ts.map +1 -0
  101. package/dist/tests/read-guard.test.js +69 -0
  102. package/dist/tests/read-guard.test.js.map +1 -0
  103. package/dist/tests/reflect.test.d.ts +2 -0
  104. package/dist/tests/reflect.test.d.ts.map +1 -0
  105. package/dist/tests/reflect.test.js +122 -0
  106. package/dist/tests/reflect.test.js.map +1 -0
  107. package/dist/tests/schemas.test.d.ts +2 -0
  108. package/dist/tests/schemas.test.d.ts.map +1 -0
  109. package/dist/tests/schemas.test.js +87 -0
  110. package/dist/tests/schemas.test.js.map +1 -0
  111. package/dist/tests/search-hook.test.d.ts +2 -0
  112. package/dist/tests/search-hook.test.d.ts.map +1 -0
  113. package/dist/tests/search-hook.test.js +108 -0
  114. package/dist/tests/search-hook.test.js.map +1 -0
  115. package/dist/tests/session-focus.test.d.ts +2 -0
  116. package/dist/tests/session-focus.test.d.ts.map +1 -0
  117. package/dist/tests/session-focus.test.js +71 -0
  118. package/dist/tests/session-focus.test.js.map +1 -0
  119. package/dist/tests/uninstall.test.d.ts +2 -0
  120. package/dist/tests/uninstall.test.d.ts.map +1 -0
  121. package/dist/tests/uninstall.test.js +98 -0
  122. package/dist/tests/uninstall.test.js.map +1 -0
  123. package/dist/tests/upgrade.test.d.ts +2 -0
  124. package/dist/tests/upgrade.test.d.ts.map +1 -0
  125. package/dist/tests/upgrade.test.js +91 -0
  126. package/dist/tests/upgrade.test.js.map +1 -0
  127. package/hooks/lib/mindlore-common.cjs +66 -5
  128. package/hooks/lib/types.d.ts +56 -0
  129. package/hooks/mindlore-cwd-changed.cjs +57 -0
  130. package/hooks/mindlore-dont-repeat.cjs +222 -0
  131. package/hooks/mindlore-fts5-sync.cjs +6 -9
  132. package/hooks/mindlore-index.cjs +3 -3
  133. package/hooks/mindlore-post-read.cjs +97 -0
  134. package/hooks/mindlore-read-guard.cjs +27 -4
  135. package/hooks/mindlore-search.cjs +73 -52
  136. package/hooks/mindlore-session-end.cjs +43 -1
  137. package/hooks/mindlore-session-focus.cjs +14 -0
  138. package/package.json +21 -8
  139. package/plugin.json +24 -1
  140. package/skills/mindlore-decide/SKILL.md +8 -0
  141. package/skills/mindlore-evolve/SKILL.md +81 -0
  142. package/skills/mindlore-explore/SKILL.md +84 -0
  143. package/skills/mindlore-health/SKILL.md +8 -0
  144. package/skills/mindlore-ingest/SKILL.md +19 -4
  145. package/skills/mindlore-log/SKILL.md +30 -13
  146. package/skills/mindlore-query/SKILL.md +8 -0
  147. package/templates/SCHEMA.md +15 -2
  148. package/scripts/init.cjs +0 -448
  149. package/scripts/lib/constants.cjs +0 -49
  150. package/scripts/mindlore-fts5-index.cjs +0 -112
  151. package/scripts/mindlore-fts5-search.cjs +0 -119
  152. package/scripts/mindlore-health-check.cjs +0 -389
  153. package/scripts/uninstall.cjs +0 -186
@@ -0,0 +1,85 @@
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 db_1 = require("./helpers/db");
8
+ const TEST_DIR = path_1.default.join(__dirname, '..', '.test-quality-populate');
9
+ const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
10
+ let db;
11
+ beforeEach(() => {
12
+ (0, db_1.setupTestDir)(TEST_DIR, ['sources', 'raw']);
13
+ db = (0, db_1.createTestDb)(DB_PATH);
14
+ });
15
+ afterEach(() => {
16
+ db.close();
17
+ (0, db_1.teardownTestDir)(TEST_DIR);
18
+ });
19
+ describe('Quality populate — storage and retrieval', () => {
20
+ test('high quality stored and retrieved correctly', () => {
21
+ (0, db_1.insertFts)(db, {
22
+ path: path_1.default.join(TEST_DIR, 'sources', 'anthropic-docs.md'),
23
+ slug: 'anthropic-docs',
24
+ type: 'source',
25
+ title: 'Anthropic Claude API Docs',
26
+ content: '# Claude API\n\nOfficial documentation from docs.anthropic.com',
27
+ quality: 'high',
28
+ });
29
+ const row = db.prepare('SELECT quality FROM mindlore_fts WHERE slug = ?').get('anthropic-docs');
30
+ expect(row.quality).toBe('high');
31
+ });
32
+ test('medium quality stored and retrieved correctly', () => {
33
+ (0, db_1.insertFts)(db, {
34
+ path: path_1.default.join(TEST_DIR, 'sources', 'blog-post.md'),
35
+ slug: 'blog-post',
36
+ type: 'source',
37
+ content: '# React Patterns\n\nSome thoughts on React patterns.',
38
+ quality: 'medium',
39
+ });
40
+ const row = db.prepare('SELECT quality FROM mindlore_fts WHERE slug = ?').get('blog-post');
41
+ expect(row.quality).toBe('medium');
42
+ });
43
+ test('low quality stored and retrieved correctly', () => {
44
+ (0, db_1.insertFts)(db, {
45
+ path: path_1.default.join(TEST_DIR, 'raw', 'quick-paste.md'),
46
+ slug: 'quick-paste',
47
+ type: 'raw',
48
+ content: 'some random text pasted quickly',
49
+ quality: 'low',
50
+ });
51
+ const row = db.prepare('SELECT quality FROM mindlore_fts WHERE slug = ?').get('quick-paste');
52
+ expect(row.quality).toBe('low');
53
+ });
54
+ test('NULL quality records are queryable via FTS5', () => {
55
+ (0, db_1.insertFts)(db, {
56
+ path: path_1.default.join(TEST_DIR, 'sources', 'no-quality.md'),
57
+ slug: 'no-quality',
58
+ type: 'source',
59
+ content: '# Test\n\nContent without quality assignment.',
60
+ });
61
+ const row = db.prepare('SELECT quality FROM mindlore_fts WHERE slug = ?').get('no-quality');
62
+ expect(row.quality).toBeNull();
63
+ const results = db.prepare("SELECT slug FROM mindlore_fts WHERE mindlore_fts MATCH 'quality'").all();
64
+ expect(results.length).toBeGreaterThan(0);
65
+ });
66
+ test('all three quality values coexist in same DB', () => {
67
+ for (const q of ['high', 'medium', 'low', null]) {
68
+ (0, db_1.insertFts)(db, {
69
+ path: path_1.default.join(TEST_DIR, 'sources', `quality-${q}.md`),
70
+ slug: `quality-${q}`,
71
+ type: 'source',
72
+ content: `Test content for ${q}`,
73
+ quality: q,
74
+ });
75
+ }
76
+ const rows = db.prepare('SELECT slug, quality FROM mindlore_fts WHERE slug LIKE ?').all('quality-%');
77
+ expect(rows).toHaveLength(4);
78
+ const qualities = rows.map(r => r.quality);
79
+ expect(qualities).toContain('high');
80
+ expect(qualities).toContain('medium');
81
+ expect(qualities).toContain('low');
82
+ expect(qualities).toContain(null);
83
+ });
84
+ });
85
+ //# sourceMappingURL=quality-populate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-populate.test.js","sourceRoot":"","sources":["../../tests/quality-populate.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AAExB,qCAAsF;AAEtF,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;AACtE,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAEnD,IAAI,EAAqB,CAAC;AAE1B,UAAU,CAAC,GAAG,EAAE;IACd,IAAA,iBAAY,EAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3C,EAAE,GAAG,IAAA,iBAAY,EAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,IAAA,oBAAe,EAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,IAAA,cAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,mBAAmB,CAAC;YACzD,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,2BAA2B;YAClC,OAAO,EAAE,gEAAgE;YACzE,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAwB,CAAC;QACvH,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,IAAA,cAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,cAAc,CAAC;YACpD,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sDAAsD;YAC/D,OAAO,EAAE,QAAQ;SAClB,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,WAAW,CAAwB,CAAC;QAClH,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACtD,IAAA,cAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,gBAAgB,CAAC;YAClD,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,iCAAiC;YAC1C,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,aAAa,CAAwB,CAAC;QACpH,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,IAAA,cAAS,EAAC,EAAE,EAAE;YACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,eAAe,CAAC;YACrD,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,+CAA+C;SACzD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,YAAY,CAA+B,CAAC;QAC1H,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;QAE/B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,EAAE,CAAC;QACrG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACvD,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;YAChD,IAAA,cAAS,EAAC,EAAE,EAAE;gBACZ,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;gBACvD,IAAI,EAAE,WAAW,CAAC,EAAE;gBACpB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,oBAAoB,CAAC,EAAE;gBAChC,OAAO,EAAE,CAAC;aACX,CAAC,CAAC;QACL,CAAC;QAED,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC,GAAG,CAAC,WAAW,CAAoD,CAAC;QACxJ,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACtC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=read-guard.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-guard.test.d.ts","sourceRoot":"","sources":["../../tests/read-guard.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
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 child_process_1 = require("child_process");
9
+ const db_js_1 = require("./helpers/db.js");
10
+ const PROJECT_DIR = path_1.default.join(__dirname, '..', '.test-project-readguard');
11
+ const TEST_DIR = path_1.default.join(PROJECT_DIR, '.mindlore');
12
+ const HOOK_PATH = path_1.default.join(__dirname, '..', 'hooks', 'mindlore-read-guard.cjs');
13
+ beforeEach(() => {
14
+ (0, db_js_1.setupTestDir)(TEST_DIR, ['diary']);
15
+ fs_1.default.writeFileSync(path_1.default.join(TEST_DIR, 'INDEX.md'), '# Index\n', 'utf8');
16
+ fs_1.default.writeFileSync(path_1.default.join(PROJECT_DIR, 'README.md'), '# Test\n', 'utf8');
17
+ });
18
+ afterEach(() => {
19
+ (0, db_js_1.teardownTestDir)(PROJECT_DIR);
20
+ });
21
+ function runGuard(input) {
22
+ try {
23
+ const result = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
24
+ input,
25
+ encoding: 'utf8',
26
+ timeout: 5000,
27
+ cwd: PROJECT_DIR,
28
+ env: { ...process.env },
29
+ });
30
+ return { stdout: result.trim(), exitCode: 0 };
31
+ }
32
+ catch (err) {
33
+ const e = err;
34
+ return {
35
+ stdout: (e.stdout ?? '').trim(),
36
+ stderr: (e.stderr ?? '').trim(),
37
+ exitCode: e.status ?? 0,
38
+ };
39
+ }
40
+ }
41
+ describe('Read Guard Hook', () => {
42
+ test('should not warn on first read', () => {
43
+ const input = JSON.stringify({ file_path: path_1.default.join(PROJECT_DIR, 'README.md') });
44
+ const { stdout } = runGuard(input);
45
+ expect(stdout).toBe('');
46
+ });
47
+ test('should create _session-reads.json on first read', () => {
48
+ const input = JSON.stringify({ file_path: path_1.default.join(PROJECT_DIR, 'README.md') });
49
+ runGuard(input);
50
+ const readsPath = path_1.default.join(TEST_DIR, 'diary', '_session-reads.json');
51
+ expect(fs_1.default.existsSync(readsPath)).toBe(true);
52
+ });
53
+ test('should skip files inside .mindlore/', () => {
54
+ const input = JSON.stringify({ file_path: path_1.default.join(TEST_DIR, 'INDEX.md') });
55
+ runGuard(input);
56
+ const readsPath = path_1.default.join(TEST_DIR, 'diary', '_session-reads.json');
57
+ if (fs_1.default.existsSync(readsPath)) {
58
+ const reads = JSON.parse(fs_1.default.readFileSync(readsPath, 'utf8'));
59
+ const keys = Object.keys(reads);
60
+ const mindloreKeys = keys.filter((k) => k.includes('.mindlore'));
61
+ expect(mindloreKeys).toHaveLength(0);
62
+ }
63
+ });
64
+ test('should handle empty input gracefully', () => {
65
+ const { exitCode } = runGuard('');
66
+ expect(exitCode).toBe(0);
67
+ });
68
+ });
69
+ //# sourceMappingURL=read-guard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-guard.test.js","sourceRoot":"","sources":["../../tests/read-guard.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reflect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.test.d.ts","sourceRoot":"","sources":["../../tests/reflect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,122 @@
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 db_1 = require("./helpers/db");
9
+ const TEST_DIR = path_1.default.join(__dirname, '..', '.test-reflect');
10
+ const DIARY_DIR = path_1.default.join(TEST_DIR, 'diary');
11
+ const LEARNINGS_DIR = path_1.default.join(TEST_DIR, 'learnings');
12
+ function writeDelta(slug, date, files, opts) {
13
+ const frontmatter = [
14
+ '---',
15
+ `slug: ${slug}`,
16
+ 'type: diary',
17
+ `date: ${date}`,
18
+ ...(opts?.archived ? ['archived: true'] : []),
19
+ '---',
20
+ ];
21
+ const content = [
22
+ ...frontmatter,
23
+ '',
24
+ `# Session Delta — ${slug}`,
25
+ '',
26
+ '## Changed Files',
27
+ ...files.map(f => `- ${f}`),
28
+ ].join('\n');
29
+ fs_1.default.writeFileSync(path_1.default.join(DIARY_DIR, `${slug}.md`), content);
30
+ }
31
+ beforeEach(() => {
32
+ (0, db_1.setupTestDir)(TEST_DIR, ['diary', 'learnings']);
33
+ });
34
+ afterEach(() => {
35
+ (0, db_1.teardownTestDir)(TEST_DIR);
36
+ });
37
+ describe('Reflect — diary scanning and pattern extraction', () => {
38
+ test('diary deltas are readable and parseable', () => {
39
+ writeDelta('delta-2026-04-10-1400', '2026-04-10', ['tests/fts5.test.ts', 'scripts/lib/constants.ts']);
40
+ writeDelta('delta-2026-04-11-0900', '2026-04-11', ['tests/dedup.test.ts', 'scripts/lib/constants.ts']);
41
+ const deltas = fs_1.default.readdirSync(DIARY_DIR)
42
+ .filter(f => f.startsWith('delta-') && f.endsWith('.md'))
43
+ .sort();
44
+ expect(deltas).toHaveLength(2);
45
+ for (const d of deltas) {
46
+ const content = fs_1.default.readFileSync(path_1.default.join(DIARY_DIR, d), 'utf8');
47
+ expect(content).toContain('type: diary');
48
+ expect(content).toContain('## Changed Files');
49
+ }
50
+ });
51
+ test('recurring patterns are detectable across deltas', () => {
52
+ writeDelta('delta-2026-04-10-1000', '2026-04-10', ['scripts/lib/constants.ts', 'tests/fts5.test.ts']);
53
+ writeDelta('delta-2026-04-11-1000', '2026-04-11', ['scripts/lib/constants.ts', 'hooks/mindlore-search.cjs']);
54
+ writeDelta('delta-2026-04-12-1000', '2026-04-12', ['scripts/lib/constants.ts', 'tests/dedup.test.ts']);
55
+ const fileCounts = {};
56
+ const deltaFiles = fs_1.default.readdirSync(DIARY_DIR).filter(f => f.startsWith('delta-'));
57
+ for (const d of deltaFiles) {
58
+ const content = fs_1.default.readFileSync(path_1.default.join(DIARY_DIR, d), 'utf8');
59
+ const changedSection = content.split('## Changed Files')[1] || '';
60
+ for (const line of changedSection.split('\n').filter(l => l.startsWith('- '))) {
61
+ const file = line.replace('- ', '').trim();
62
+ fileCounts[file] = (fileCounts[file] || 0) + 1;
63
+ }
64
+ }
65
+ expect(fileCounts['scripts/lib/constants.ts']).toBe(3);
66
+ });
67
+ test('learnings are written with correct frontmatter format', () => {
68
+ const learning = [
69
+ '---',
70
+ 'type: learning',
71
+ 'slug: testing-patterns',
72
+ 'title: Testing Patterns',
73
+ 'tags: testing, jest',
74
+ '---',
75
+ '',
76
+ '# Testing Patterns',
77
+ '',
78
+ '- YAPMA: Test icinde sleep kullanma — deterministic timer mock kullan',
79
+ '- BEST PRACTICE: Her test kendi temp dizinini olusturup temizlesin',
80
+ ].join('\n');
81
+ fs_1.default.writeFileSync(path_1.default.join(LEARNINGS_DIR, 'testing-patterns.md'), learning);
82
+ const content = fs_1.default.readFileSync(path_1.default.join(LEARNINGS_DIR, 'testing-patterns.md'), 'utf8');
83
+ expect(content).toContain('type: learning');
84
+ expect(content).toContain('YAPMA:');
85
+ expect(content).toContain('BEST PRACTICE:');
86
+ });
87
+ test('archived deltas are excluded from reflect scan', () => {
88
+ writeDelta('delta-2026-04-08-1000', '2026-04-08', ['old-file.ts'], { archived: true });
89
+ writeDelta('delta-2026-04-09-1000', '2026-04-09', ['active-file.ts']);
90
+ const deltas = fs_1.default.readdirSync(DIARY_DIR)
91
+ .filter(f => f.startsWith('delta-') && f.endsWith('.md'))
92
+ .filter(f => !fs_1.default.readFileSync(path_1.default.join(DIARY_DIR, f), 'utf8').includes('archived: true'));
93
+ expect(deltas).toHaveLength(1);
94
+ expect(deltas[0]).toContain('04-09');
95
+ });
96
+ test('learnings append to existing topic file without overwriting', () => {
97
+ const initial = [
98
+ '---',
99
+ 'type: learning',
100
+ 'slug: git-workflow',
101
+ 'title: Git Workflow',
102
+ '---',
103
+ '',
104
+ '# Git Workflow',
105
+ '',
106
+ '- BEST PRACTICE: Atomic commits — bir degisiklik, bir commit',
107
+ ].join('\n');
108
+ fs_1.default.writeFileSync(path_1.default.join(LEARNINGS_DIR, 'git-workflow.md'), initial);
109
+ fs_1.default.appendFileSync(path_1.default.join(LEARNINGS_DIR, 'git-workflow.md'), '\n- YAPMA: Force push to main — her zaman feature branch kullan\n');
110
+ const content = fs_1.default.readFileSync(path_1.default.join(LEARNINGS_DIR, 'git-workflow.md'), 'utf8');
111
+ expect(content).toContain('Atomic commits');
112
+ expect(content).toContain('Force push');
113
+ const ruleCount = (content.match(/^- (YAPMA|BEST PRACTICE|KRITIK):/gm) || []).length;
114
+ expect(ruleCount).toBe(2);
115
+ });
116
+ test('empty diary directory returns no deltas', () => {
117
+ const deltas = fs_1.default.readdirSync(DIARY_DIR)
118
+ .filter(f => f.startsWith('delta-') && f.endsWith('.md'));
119
+ expect(deltas).toHaveLength(0);
120
+ });
121
+ });
122
+ //# sourceMappingURL=reflect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflect.test.js","sourceRoot":"","sources":["../../tests/reflect.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.d.ts","sourceRoot":"","sources":["../../tests/schemas.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schemas_1 = require("../scripts/lib/schemas");
4
+ describe('Zod frontmatter schemas', () => {
5
+ test('all 9 types have schemas defined', () => {
6
+ const types = ['raw', 'source', 'domain', 'analysis', 'diary', 'decision', 'insight', 'connection', 'learning'];
7
+ for (const t of types) {
8
+ expect(schemas_1.FRONTMATTER_SCHEMAS[t]).toBeDefined();
9
+ }
10
+ });
11
+ test('valid source frontmatter passes', () => {
12
+ const result = (0, schemas_1.validateFrontmatter)({
13
+ type: 'source',
14
+ slug: 'react-hooks',
15
+ title: 'React Hooks Guide',
16
+ quality: 'high',
17
+ tags: 'react, hooks',
18
+ });
19
+ expect(result.valid).toBe(true);
20
+ expect(result.errors).toHaveLength(0);
21
+ });
22
+ test('missing type field fails', () => {
23
+ const result = (0, schemas_1.validateFrontmatter)({ slug: 'test' });
24
+ expect(result.valid).toBe(false);
25
+ expect(result.errors[0]).toContain('type');
26
+ });
27
+ test('unknown type fails', () => {
28
+ const result = (0, schemas_1.validateFrontmatter)({ type: 'unknown', slug: 'test' });
29
+ expect(result.valid).toBe(false);
30
+ expect(result.errors[0]).toContain('unknown');
31
+ });
32
+ test('source missing slug fails', () => {
33
+ const result = (0, schemas_1.validateFrontmatter)({ type: 'source' });
34
+ expect(result.valid).toBe(false);
35
+ });
36
+ test('invalid quality enum fails', () => {
37
+ const result = (0, schemas_1.validateFrontmatter)({
38
+ type: 'source',
39
+ slug: 'test',
40
+ quality: 'excellent',
41
+ });
42
+ expect(result.valid).toBe(false);
43
+ });
44
+ test('valid diary frontmatter passes', () => {
45
+ const result = (0, schemas_1.validateFrontmatter)({
46
+ type: 'diary',
47
+ slug: 'delta-2026-04-12',
48
+ date: '2026-04-12',
49
+ });
50
+ expect(result.valid).toBe(true);
51
+ });
52
+ test('valid connection frontmatter passes', () => {
53
+ const result = (0, schemas_1.validateFrontmatter)({
54
+ type: 'connection',
55
+ slug: 'conn-a-b',
56
+ strength: 'medium',
57
+ sources: ['source-a.md', 'source-b.md'],
58
+ });
59
+ expect(result.valid).toBe(true);
60
+ });
61
+ test('valid decision with supersedes passes', () => {
62
+ const result = (0, schemas_1.validateFrontmatter)({
63
+ type: 'decision',
64
+ slug: 'dec-002',
65
+ status: 'active',
66
+ supersedes: 'dec-001',
67
+ });
68
+ expect(result.valid).toBe(true);
69
+ });
70
+ test('tags as array passes', () => {
71
+ const result = (0, schemas_1.validateFrontmatter)({
72
+ type: 'raw',
73
+ slug: 'test-raw',
74
+ tags: ['tag1', 'tag2'],
75
+ });
76
+ expect(result.valid).toBe(true);
77
+ });
78
+ test('tags as string passes', () => {
79
+ const result = (0, schemas_1.validateFrontmatter)({
80
+ type: 'raw',
81
+ slug: 'test-raw',
82
+ tags: 'tag1, tag2',
83
+ });
84
+ expect(result.valid).toBe(true);
85
+ });
86
+ });
87
+ //# sourceMappingURL=schemas.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.test.js","sourceRoot":"","sources":["../../tests/schemas.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-hook.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-hook.test.d.ts","sourceRoot":"","sources":["../../tests/search-hook.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,108 @@
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 better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
+ const db_js_1 = require("./helpers/db.js");
9
+ const TEST_DIR = path_1.default.join(__dirname, '..', '.test-mindlore-search');
10
+ const DB_PATH = path_1.default.join(TEST_DIR, 'mindlore.db');
11
+ beforeEach(() => {
12
+ (0, db_js_1.setupTestDir)(TEST_DIR, ['sources', 'domains']);
13
+ const db = (0, db_js_1.createTestDb)(DB_PATH);
14
+ (0, db_js_1.insertFts)(db, { path: path_1.default.join(TEST_DIR, 'sources', 'react-hooks.md'), slug: 'react-hooks', description: 'useEffect cleanup patterns for memory leak prevention', type: 'source', category: 'sources', title: 'React Hooks Guide', content: '---\nslug: react-hooks\ntype: source\n---\n# React Hooks Guide\n\nuseEffect cleanup patterns for memory leak prevention.', tags: '', quality: null });
15
+ (0, db_js_1.insertFts)(db, { path: path_1.default.join(TEST_DIR, 'sources', 'typescript-generics.md'), slug: 'typescript-generics', description: 'Advanced generic patterns for type-safe APIs', type: 'source', category: 'sources', title: 'TypeScript Generics', content: '---\nslug: typescript-generics\ntype: source\n---\n# TypeScript Generics\n\nAdvanced generic patterns for type-safe APIs.', tags: '', quality: null });
16
+ (0, db_js_1.insertFts)(db, { path: path_1.default.join(TEST_DIR, 'domains', 'security.md'), slug: 'security', description: 'SSH hardening firewall rules audit checks', type: 'domain', category: 'domains', title: 'Security', content: '---\nslug: security\ntype: domain\n---\n# Security\n\nSSH hardening, firewall rules, audit checks.', tags: '', quality: null });
17
+ db.close();
18
+ });
19
+ afterEach(() => {
20
+ (0, db_js_1.teardownTestDir)(TEST_DIR);
21
+ });
22
+ describe('Search Hook — Keyword Extraction', () => {
23
+ // Inline the extractKeywords logic for testing
24
+ function extractKeywords(text) {
25
+ const stopWords = new Set([
26
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being',
27
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could',
28
+ 'should', 'may', 'might', 'can', 'shall', 'to', 'of', 'in', 'for',
29
+ 'on', 'with', 'at', 'by', 'from', 'as', 'into', 'about', 'between',
30
+ 'through', 'after', 'before', 'above', 'below', 'up', 'down', 'out',
31
+ 'and', 'but', 'or', 'nor', 'not', 'so', 'yet', 'both', 'either',
32
+ 'neither', 'each', 'every', 'all', 'any', 'few', 'more', 'most',
33
+ 'other', 'some', 'such', 'no', 'only', 'own', 'same', 'than', 'too',
34
+ 'very', 'just', 'also', 'now', 'then', 'here', 'there', 'when',
35
+ 'where', 'why', 'how', 'what', 'which', 'who', 'whom', 'this',
36
+ 'that', 'these', 'those', 'it', 'its', 'my', 'your', 'his', 'her',
37
+ 'our', 'their', 'me', 'him', 'us', 'them', 'i', 'you', 'he', 'she',
38
+ 'we', 'they', 'bu', 'su', 'bir', 'de', 'da', 've', 'ile', 'icin',
39
+ 'var', 'mi', 'ne', 'nasil', 'nedir', 'evet', 'hayir',
40
+ ]);
41
+ return text
42
+ .toLowerCase()
43
+ .replace(/[^a-z0-9\u00e7\u011f\u0131\u00f6\u015f\u00fc\s-]/g, ' ')
44
+ .split(/\s+/)
45
+ .filter((w) => w.length >= 3 && !stopWords.has(w))
46
+ .filter((v, i, a) => a.indexOf(v) === i)
47
+ .slice(0, 5);
48
+ }
49
+ test('should extract meaningful keywords from prompt', () => {
50
+ const keywords = extractKeywords('How do React hooks handle cleanup?');
51
+ expect(keywords).toContain('react');
52
+ expect(keywords).toContain('hooks');
53
+ expect(keywords).toContain('cleanup');
54
+ expect(keywords).not.toContain('how');
55
+ expect(keywords).not.toContain('do');
56
+ });
57
+ test('should handle Turkish stop words', () => {
58
+ const keywords = extractKeywords('bu proje nasil calisir ve ne yapar');
59
+ expect(keywords).toContain('proje');
60
+ expect(keywords).toContain('calisir');
61
+ expect(keywords).toContain('yapar');
62
+ expect(keywords).not.toContain('nasil');
63
+ expect(keywords).not.toContain('bu');
64
+ });
65
+ test('should limit to 5 keywords', () => {
66
+ const keywords = extractKeywords('react hooks typescript generics security firewall audit ssh hardening');
67
+ expect(keywords.length).toBeLessThanOrEqual(5);
68
+ });
69
+ test('should deduplicate keywords', () => {
70
+ const keywords = extractKeywords('hooks hooks hooks different word');
71
+ const hookCount = keywords.filter((k) => k === 'hooks').length;
72
+ expect(hookCount).toBe(1);
73
+ });
74
+ });
75
+ describe('Search Hook — FTS5 Query', () => {
76
+ function queryFts(query) {
77
+ const db = new better_sqlite3_1.default(DB_PATH, { readonly: true });
78
+ try {
79
+ return db
80
+ .prepare(`SELECT path, rank FROM mindlore_fts
81
+ WHERE mindlore_fts MATCH ?
82
+ ORDER BY rank LIMIT 3`)
83
+ .all(query);
84
+ }
85
+ finally {
86
+ db.close();
87
+ }
88
+ }
89
+ test('should find matching documents via FTS5', () => {
90
+ const results = queryFts('react hooks');
91
+ expect(results.length).toBeGreaterThan(0);
92
+ expect(results[0]?.path).toContain('react-hooks');
93
+ });
94
+ test('should return empty for non-matching query', () => {
95
+ const results = queryFts('kubernetes docker');
96
+ expect(results).toHaveLength(0);
97
+ });
98
+ test('should rank more relevant documents higher', () => {
99
+ const results = queryFts('security');
100
+ expect(results.length).toBeGreaterThan(0);
101
+ expect(results[0]?.path).toContain('security');
102
+ });
103
+ test('should handle OR queries across multiple keywords', () => {
104
+ const results = queryFts('react OR typescript');
105
+ expect(results.length).toBe(2);
106
+ });
107
+ });
108
+ //# sourceMappingURL=search-hook.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-hook.test.js","sourceRoot":"","sources":["../../tests/search-hook.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-focus.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-focus.test.d.ts","sourceRoot":"","sources":["../../tests/session-focus.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
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 child_process_1 = require("child_process");
9
+ const TEST_DIR = path_1.default.join(__dirname, '..', '.test-mindlore-session-focus');
10
+ const HOOK_PATH = path_1.default.join(__dirname, '..', 'hooks', 'mindlore-session-focus.cjs');
11
+ function createMindloreDir() {
12
+ const mindloreDir = path_1.default.join(TEST_DIR, '.mindlore');
13
+ fs_1.default.mkdirSync(path_1.default.join(mindloreDir, 'diary'), { recursive: true });
14
+ fs_1.default.writeFileSync(path_1.default.join(mindloreDir, 'INDEX.md'), '# Mindlore Index\n\n## Stats\n2 source, 1 analysis, 3 total\n');
15
+ return mindloreDir;
16
+ }
17
+ function createDelta(mindloreDir, name, content) {
18
+ fs_1.default.writeFileSync(path_1.default.join(mindloreDir, 'diary', name), content);
19
+ }
20
+ beforeEach(() => {
21
+ fs_1.default.mkdirSync(TEST_DIR, { recursive: true });
22
+ });
23
+ afterEach(() => {
24
+ fs_1.default.rmSync(TEST_DIR, { recursive: true, force: true });
25
+ });
26
+ describe('Session Focus Hook', () => {
27
+ test('should inject INDEX.md content when .mindlore/ exists', () => {
28
+ createMindloreDir();
29
+ const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
30
+ cwd: TEST_DIR,
31
+ encoding: 'utf8',
32
+ timeout: 5000,
33
+ });
34
+ expect(output).toContain('[Mindlore INDEX]');
35
+ expect(output).toContain('2 source, 1 analysis, 3 total');
36
+ });
37
+ test('should inject latest delta when diary has entries', () => {
38
+ const mindloreDir = createMindloreDir();
39
+ createDelta(mindloreDir, 'delta-2026-04-09-1200.md', '# Old Delta\n\nOld session.');
40
+ createDelta(mindloreDir, 'delta-2026-04-10-0900.md', '# Latest Delta\n\nLatest session.');
41
+ const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
42
+ cwd: TEST_DIR,
43
+ encoding: 'utf8',
44
+ timeout: 5000,
45
+ });
46
+ expect(output).toContain('[Mindlore Delta: delta-2026-04-10-0900.md]');
47
+ expect(output).toContain('Latest session');
48
+ expect(output).not.toContain('Old session');
49
+ });
50
+ test('should produce no output when .mindlore/ does not exist', () => {
51
+ const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
52
+ cwd: TEST_DIR,
53
+ encoding: 'utf8',
54
+ timeout: 5000,
55
+ });
56
+ expect(output).toBe('');
57
+ });
58
+ test('should handle missing diary directory gracefully', () => {
59
+ const mindloreDir = path_1.default.join(TEST_DIR, '.mindlore');
60
+ fs_1.default.mkdirSync(mindloreDir, { recursive: true });
61
+ fs_1.default.writeFileSync(path_1.default.join(mindloreDir, 'INDEX.md'), '# Empty Index\n');
62
+ const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
63
+ cwd: TEST_DIR,
64
+ encoding: 'utf8',
65
+ timeout: 5000,
66
+ });
67
+ expect(output).toContain('[Mindlore INDEX]');
68
+ expect(output).not.toContain('[Mindlore Delta');
69
+ });
70
+ });
71
+ //# sourceMappingURL=session-focus.test.js.map