mindlore 0.3.2 → 0.3.4
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.
- package/README.md +50 -24
- package/SCHEMA.md +9 -11
- package/dist/scripts/init.d.ts +4 -2
- package/dist/scripts/init.d.ts.map +1 -1
- package/dist/scripts/init.js +67 -59
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/constants.d.ts +10 -5
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +18 -20
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/obsidian-helpers.d.ts +25 -0
- package/dist/scripts/lib/obsidian-helpers.d.ts.map +1 -0
- package/dist/scripts/lib/obsidian-helpers.js +88 -0
- package/dist/scripts/lib/obsidian-helpers.js.map +1 -0
- package/dist/scripts/mindlore-backup.d.ts +12 -0
- package/dist/scripts/mindlore-backup.d.ts.map +1 -0
- package/dist/scripts/mindlore-backup.js +218 -0
- package/dist/scripts/mindlore-backup.js.map +1 -0
- package/dist/scripts/mindlore-fts5-index.js +3 -2
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-fts5-search.d.ts +3 -2
- package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -1
- package/dist/scripts/mindlore-fts5-search.js +38 -50
- package/dist/scripts/mindlore-fts5-search.js.map +1 -1
- package/dist/scripts/mindlore-health-check.js +4 -4
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/scripts/mindlore-obsidian.d.ts +11 -0
- package/dist/scripts/mindlore-obsidian.d.ts.map +1 -0
- package/dist/scripts/mindlore-obsidian.js +182 -0
- package/dist/scripts/mindlore-obsidian.js.map +1 -0
- package/dist/scripts/quality-populate.js +1 -3
- package/dist/scripts/quality-populate.js.map +1 -1
- package/dist/scripts/uninstall.d.ts +4 -3
- package/dist/scripts/uninstall.d.ts.map +1 -1
- package/dist/scripts/uninstall.js +10 -29
- package/dist/scripts/uninstall.js.map +1 -1
- package/dist/tests/backup.test.d.ts +2 -0
- package/dist/tests/backup.test.d.ts.map +1 -0
- package/dist/tests/backup.test.js +105 -0
- package/dist/tests/backup.test.js.map +1 -0
- package/dist/tests/cwd-changed.test.js +6 -5
- package/dist/tests/cwd-changed.test.js.map +1 -1
- package/dist/tests/decision.test.js +1 -1
- package/dist/tests/decision.test.js.map +1 -1
- package/dist/tests/global-layer.test.js +22 -39
- package/dist/tests/global-layer.test.js.map +1 -1
- package/dist/tests/helpers/db.d.ts +1 -0
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/init.test.js +22 -0
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/model-router.test.js +2 -1
- package/dist/tests/model-router.test.js.map +1 -1
- package/dist/tests/obsidian.test.d.ts +2 -0
- package/dist/tests/obsidian.test.d.ts.map +1 -0
- package/dist/tests/obsidian.test.js +138 -0
- package/dist/tests/obsidian.test.js.map +1 -0
- package/dist/tests/post-read.test.js +2 -1
- package/dist/tests/post-read.test.js.map +1 -1
- package/dist/tests/project-namespace.test.d.ts +2 -0
- package/dist/tests/project-namespace.test.d.ts.map +1 -0
- package/dist/tests/project-namespace.test.js +151 -0
- package/dist/tests/project-namespace.test.js.map +1 -0
- package/dist/tests/read-guard.test.js +5 -4
- package/dist/tests/read-guard.test.js.map +1 -1
- package/dist/tests/session-focus.test.js +50 -0
- package/dist/tests/session-focus.test.js.map +1 -1
- package/hooks/lib/mindlore-common.cjs +38 -29
- package/hooks/lib/types.d.ts +2 -0
- package/hooks/mindlore-cwd-changed.cjs +1 -1
- package/hooks/mindlore-dont-repeat.cjs +2 -2
- package/hooks/mindlore-fts5-sync.cjs +4 -3
- package/hooks/mindlore-index.cjs +2 -2
- package/hooks/mindlore-post-read.cjs +2 -2
- package/hooks/mindlore-read-guard.cjs +2 -2
- package/hooks/mindlore-search.cjs +0 -2
- package/hooks/mindlore-session-end.cjs +5 -2
- package/hooks/mindlore-session-focus.cjs +22 -7
- package/package.json +1 -1
- package/templates/SCHEMA.md +9 -11
- package/templates/config.json +4 -1
|
@@ -0,0 +1,151 @@
|
|
|
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 better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
9
|
+
const db_1 = require("./helpers/db");
|
|
10
|
+
const TEST_DIR = path_1.default.join(__dirname, '..', '.test-project-namespace');
|
|
11
|
+
const commonPath = path_1.default.resolve(__dirname, '..', 'hooks', 'lib', 'mindlore-common.cjs');
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
(0, db_1.setupTestDir)(TEST_DIR);
|
|
14
|
+
delete require.cache[require.resolve(commonPath)];
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
delete require.cache[require.resolve(commonPath)];
|
|
18
|
+
(0, db_1.teardownTestDir)(TEST_DIR);
|
|
19
|
+
});
|
|
20
|
+
// ── getProjectName ────────────────────────────────────────────────────
|
|
21
|
+
describe('getProjectName', () => {
|
|
22
|
+
test('returns basename of current working directory', () => {
|
|
23
|
+
const fakeProject = path_1.default.join(TEST_DIR, 'my-cool-project');
|
|
24
|
+
fs_1.default.mkdirSync(fakeProject, { recursive: true });
|
|
25
|
+
const originalCwd = process.cwd();
|
|
26
|
+
process.chdir(fakeProject);
|
|
27
|
+
try {
|
|
28
|
+
const { getProjectName } = require(commonPath);
|
|
29
|
+
expect(getProjectName()).toBe('my-cool-project');
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
process.chdir(originalCwd);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
test('reflects cwd change between calls', () => {
|
|
36
|
+
const projectA = path_1.default.join(TEST_DIR, 'project-alpha');
|
|
37
|
+
const projectB = path_1.default.join(TEST_DIR, 'project-beta');
|
|
38
|
+
fs_1.default.mkdirSync(projectA, { recursive: true });
|
|
39
|
+
fs_1.default.mkdirSync(projectB, { recursive: true });
|
|
40
|
+
const originalCwd = process.cwd();
|
|
41
|
+
try {
|
|
42
|
+
process.chdir(projectA);
|
|
43
|
+
delete require.cache[require.resolve(commonPath)];
|
|
44
|
+
expect(require(commonPath).getProjectName()).toBe('project-alpha');
|
|
45
|
+
process.chdir(projectB);
|
|
46
|
+
delete require.cache[require.resolve(commonPath)];
|
|
47
|
+
expect(require(commonPath).getProjectName()).toBe('project-beta');
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
process.chdir(originalCwd);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
// ── project column in FTS5 ────────────────────────────────────────────
|
|
55
|
+
describe('project column — insertFtsRow', () => {
|
|
56
|
+
test('stores project value in FTS5 row', () => {
|
|
57
|
+
const dbPath = path_1.default.join(TEST_DIR, 'store.db');
|
|
58
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
59
|
+
(0, db_1.insertFts)(db, {
|
|
60
|
+
path: '/fake/sources/entry.md',
|
|
61
|
+
slug: 'entry',
|
|
62
|
+
title: 'Entry Doc',
|
|
63
|
+
content: 'some content here',
|
|
64
|
+
project: 'my-project',
|
|
65
|
+
});
|
|
66
|
+
const row = db
|
|
67
|
+
.prepare('SELECT project FROM mindlore_fts WHERE path = ?')
|
|
68
|
+
.get('/fake/sources/entry.md');
|
|
69
|
+
db.close();
|
|
70
|
+
expect(row?.project).toBe('my-project');
|
|
71
|
+
});
|
|
72
|
+
test('stores null project when not provided', () => {
|
|
73
|
+
const dbPath = path_1.default.join(TEST_DIR, 'null-project.db');
|
|
74
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
75
|
+
(0, db_1.insertFts)(db, {
|
|
76
|
+
path: '/fake/sources/legacy.md',
|
|
77
|
+
slug: 'legacy',
|
|
78
|
+
content: 'legacy data',
|
|
79
|
+
});
|
|
80
|
+
const row = db
|
|
81
|
+
.prepare('SELECT project FROM mindlore_fts WHERE path = ?')
|
|
82
|
+
.get('/fake/sources/legacy.md');
|
|
83
|
+
db.close();
|
|
84
|
+
expect(row?.project).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
// ── project filter in FTS5 queries ───────────────────────────────────
|
|
88
|
+
describe('project column — FTS5 filtering', () => {
|
|
89
|
+
test('project filter returns only matching project rows', () => {
|
|
90
|
+
const dbPath = path_1.default.join(TEST_DIR, 'filter.db');
|
|
91
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
92
|
+
(0, db_1.insertFts)(db, { path: '/alpha/doc.md', slug: 'alpha-doc', title: 'Alpha Doc', content: 'shared keyword findme', project: 'project-alpha' });
|
|
93
|
+
(0, db_1.insertFts)(db, { path: '/beta/doc.md', slug: 'beta-doc', title: 'Beta Doc', content: 'shared keyword findme', project: 'project-beta' });
|
|
94
|
+
const alphaRows = db
|
|
95
|
+
.prepare('SELECT path FROM mindlore_fts WHERE mindlore_fts MATCH ? AND project = ?')
|
|
96
|
+
.all('shared keyword findme', 'project-alpha');
|
|
97
|
+
const betaRows = db
|
|
98
|
+
.prepare('SELECT path FROM mindlore_fts WHERE mindlore_fts MATCH ? AND project = ?')
|
|
99
|
+
.all('shared keyword findme', 'project-beta');
|
|
100
|
+
db.close();
|
|
101
|
+
expect(alphaRows).toHaveLength(1);
|
|
102
|
+
expect(alphaRows[0]?.path).toBe('/alpha/doc.md');
|
|
103
|
+
expect(betaRows).toHaveLength(1);
|
|
104
|
+
expect(betaRows[0]?.path).toBe('/beta/doc.md');
|
|
105
|
+
});
|
|
106
|
+
test('unfiltered query returns rows from all projects', () => {
|
|
107
|
+
const dbPath = path_1.default.join(TEST_DIR, 'unfiltered.db');
|
|
108
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
109
|
+
(0, db_1.insertFts)(db, { path: '/p1/doc.md', slug: 'p1', content: 'unique term omnisearch', project: 'project-one' });
|
|
110
|
+
(0, db_1.insertFts)(db, { path: '/p2/doc.md', slug: 'p2', content: 'unique term omnisearch', project: 'project-two' });
|
|
111
|
+
(0, db_1.insertFts)(db, { path: '/p3/doc.md', slug: 'p3', content: 'unique term omnisearch', project: null });
|
|
112
|
+
const rows = db
|
|
113
|
+
.prepare('SELECT path FROM mindlore_fts WHERE mindlore_fts MATCH ?')
|
|
114
|
+
.all('unique term omnisearch');
|
|
115
|
+
db.close();
|
|
116
|
+
expect(rows).toHaveLength(3);
|
|
117
|
+
});
|
|
118
|
+
test('project filter returns empty when no rows match project', () => {
|
|
119
|
+
const dbPath = path_1.default.join(TEST_DIR, 'nomatch.db');
|
|
120
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
121
|
+
(0, db_1.insertFts)(db, { path: '/alpha/doc.md', slug: 'alpha', content: 'some content findme', project: 'project-alpha' });
|
|
122
|
+
const rows = db
|
|
123
|
+
.prepare('SELECT path FROM mindlore_fts WHERE mindlore_fts MATCH ? AND project = ?')
|
|
124
|
+
.all('some content findme', 'project-other');
|
|
125
|
+
db.close();
|
|
126
|
+
expect(rows).toHaveLength(0);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
// ── detectSchemaVersion ───────────────────────────────────────────────
|
|
130
|
+
describe('detectSchemaVersion', () => {
|
|
131
|
+
test('returns 11 for 11-column FTS5 DB (SQL_FTS_CREATE)', () => {
|
|
132
|
+
const dbPath = path_1.default.join(TEST_DIR, 'v11.db');
|
|
133
|
+
const db = (0, db_1.createTestDb)(dbPath);
|
|
134
|
+
db.close();
|
|
135
|
+
const { detectSchemaVersion, openDatabase } = require(commonPath);
|
|
136
|
+
const openDb = openDatabase(dbPath);
|
|
137
|
+
const version = detectSchemaVersion(openDb);
|
|
138
|
+
openDb.close();
|
|
139
|
+
expect(version).toBe(11);
|
|
140
|
+
});
|
|
141
|
+
test('returns 2 (legacy fallback) for DB without mindlore_fts table', () => {
|
|
142
|
+
const dbPath = path_1.default.join(TEST_DIR, 'empty.db');
|
|
143
|
+
new better_sqlite3_1.default(dbPath).close();
|
|
144
|
+
const { detectSchemaVersion, openDatabase } = require(commonPath);
|
|
145
|
+
const openDb = openDatabase(dbPath);
|
|
146
|
+
const version = detectSchemaVersion(openDb);
|
|
147
|
+
openDb.close();
|
|
148
|
+
expect(version).toBe(2);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=project-namespace.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-namespace.test.js","sourceRoot":"","sources":["../../tests/project-namespace.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ const db_js_1 = require("./helpers/db.js");
|
|
|
10
10
|
const PROJECT_DIR = path_1.default.join(__dirname, '..', '.test-project-readguard');
|
|
11
11
|
const TEST_DIR = path_1.default.join(PROJECT_DIR, '.mindlore');
|
|
12
12
|
const HOOK_PATH = path_1.default.join(__dirname, '..', 'hooks', 'mindlore-read-guard.cjs');
|
|
13
|
+
const PROJECT_NAME = path_1.default.basename(PROJECT_DIR);
|
|
13
14
|
beforeEach(() => {
|
|
14
15
|
(0, db_js_1.setupTestDir)(TEST_DIR, ['diary']);
|
|
15
16
|
fs_1.default.writeFileSync(path_1.default.join(TEST_DIR, 'INDEX.md'), '# Index\n', 'utf8');
|
|
@@ -25,7 +26,7 @@ function runGuard(input) {
|
|
|
25
26
|
encoding: 'utf8',
|
|
26
27
|
timeout: 5000,
|
|
27
28
|
cwd: PROJECT_DIR,
|
|
28
|
-
env: { ...process.env },
|
|
29
|
+
env: { ...process.env, MINDLORE_HOME: TEST_DIR },
|
|
29
30
|
});
|
|
30
31
|
return { stdout: result.trim(), exitCode: 0 };
|
|
31
32
|
}
|
|
@@ -44,16 +45,16 @@ describe('Read Guard Hook', () => {
|
|
|
44
45
|
const { stdout } = runGuard(input);
|
|
45
46
|
expect(stdout).toBe('');
|
|
46
47
|
});
|
|
47
|
-
test('should create _session-reads
|
|
48
|
+
test('should create project-namespaced _session-reads file on first read', () => {
|
|
48
49
|
const input = JSON.stringify({ file_path: path_1.default.join(PROJECT_DIR, 'README.md') });
|
|
49
50
|
runGuard(input);
|
|
50
|
-
const readsPath = path_1.default.join(TEST_DIR, 'diary',
|
|
51
|
+
const readsPath = path_1.default.join(TEST_DIR, 'diary', `_session-reads-${PROJECT_NAME}.json`);
|
|
51
52
|
expect(fs_1.default.existsSync(readsPath)).toBe(true);
|
|
52
53
|
});
|
|
53
54
|
test('should skip files inside .mindlore/', () => {
|
|
54
55
|
const input = JSON.stringify({ file_path: path_1.default.join(TEST_DIR, 'INDEX.md') });
|
|
55
56
|
runGuard(input);
|
|
56
|
-
const readsPath = path_1.default.join(TEST_DIR, 'diary',
|
|
57
|
+
const readsPath = path_1.default.join(TEST_DIR, 'diary', `_session-reads-${PROJECT_NAME}.json`);
|
|
57
58
|
if (fs_1.default.existsSync(readsPath)) {
|
|
58
59
|
const reads = JSON.parse(fs_1.default.readFileSync(readsPath, 'utf8'));
|
|
59
60
|
const keys = Object.keys(reads);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-guard.test.js","sourceRoot":"","sources":["../../tests/read-guard.test.ts"],"names":[],"mappings":";;;;;AAAA,gDAAwB;AACxB,4CAAoB;AACpB,iDAAyC;AACzC,2CAAgE;AAEhE,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,yBAAyB,CAAC,CAAC;AAC1E,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AACrD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,yBAAyB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"read-guard.test.js","sourceRoot":"","sources":["../../tests/read-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,6 +30,7 @@ describe('Session Focus Hook', () => {
|
|
|
30
30
|
cwd: TEST_DIR,
|
|
31
31
|
encoding: 'utf8',
|
|
32
32
|
timeout: 5000,
|
|
33
|
+
env: { ...process.env, MINDLORE_HOME: path_1.default.join(TEST_DIR, '.mindlore') },
|
|
33
34
|
});
|
|
34
35
|
expect(output).toContain('[Mindlore INDEX]');
|
|
35
36
|
expect(output).toContain('2 source, 1 analysis, 3 total');
|
|
@@ -42,19 +43,67 @@ describe('Session Focus Hook', () => {
|
|
|
42
43
|
cwd: TEST_DIR,
|
|
43
44
|
encoding: 'utf8',
|
|
44
45
|
timeout: 5000,
|
|
46
|
+
env: { ...process.env, MINDLORE_HOME: path_1.default.join(TEST_DIR, '.mindlore') },
|
|
45
47
|
});
|
|
46
48
|
expect(output).toContain('[Mindlore Delta: delta-2026-04-10-0900.md]');
|
|
47
49
|
expect(output).toContain('Latest session');
|
|
48
50
|
expect(output).not.toContain('Old session');
|
|
49
51
|
});
|
|
50
52
|
test('should produce no output when .mindlore/ does not exist', () => {
|
|
53
|
+
const nonExistent = path_1.default.join(TEST_DIR, 'no-mindlore');
|
|
51
54
|
const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
|
|
52
55
|
cwd: TEST_DIR,
|
|
53
56
|
encoding: 'utf8',
|
|
54
57
|
timeout: 5000,
|
|
58
|
+
env: { ...process.env, MINDLORE_HOME: nonExistent },
|
|
55
59
|
});
|
|
56
60
|
expect(output).toBe('');
|
|
57
61
|
});
|
|
62
|
+
test('should not inject reflect warning when diary entries below threshold', () => {
|
|
63
|
+
const mindloreDir = createMindloreDir();
|
|
64
|
+
// Create 4 deltas (below default threshold of 5)
|
|
65
|
+
for (let i = 1; i <= 4; i++) {
|
|
66
|
+
createDelta(mindloreDir, `delta-2026-04-0${i}-1200.md`, `# Delta ${i}\n`);
|
|
67
|
+
}
|
|
68
|
+
const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
|
|
69
|
+
cwd: TEST_DIR,
|
|
70
|
+
encoding: 'utf8',
|
|
71
|
+
timeout: 5000,
|
|
72
|
+
env: { ...process.env, MINDLORE_HOME: path_1.default.join(TEST_DIR, '.mindlore') },
|
|
73
|
+
});
|
|
74
|
+
expect(output).not.toContain('diary entry birikti');
|
|
75
|
+
});
|
|
76
|
+
test('should inject reflect warning when diary entries reach threshold', () => {
|
|
77
|
+
const mindloreDir = createMindloreDir();
|
|
78
|
+
// Create 6 deltas (above default threshold of 5)
|
|
79
|
+
for (let i = 1; i <= 6; i++) {
|
|
80
|
+
createDelta(mindloreDir, `delta-2026-04-0${i}-1200.md`, `# Delta ${i}\n`);
|
|
81
|
+
}
|
|
82
|
+
const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
|
|
83
|
+
cwd: TEST_DIR,
|
|
84
|
+
encoding: 'utf8',
|
|
85
|
+
timeout: 5000,
|
|
86
|
+
env: { ...process.env, MINDLORE_HOME: path_1.default.join(TEST_DIR, '.mindlore') },
|
|
87
|
+
});
|
|
88
|
+
expect(output).toContain('6 diary entry birikti');
|
|
89
|
+
expect(output).toContain('/mindlore-log reflect');
|
|
90
|
+
});
|
|
91
|
+
test('should respect custom reflect threshold from config.json', () => {
|
|
92
|
+
const mindloreDir = createMindloreDir();
|
|
93
|
+
// Set custom threshold to 3
|
|
94
|
+
fs_1.default.writeFileSync(path_1.default.join(mindloreDir, 'config.json'), JSON.stringify({ version: '0.3.3', reflect: { threshold: 3 } }));
|
|
95
|
+
// Create 3 deltas (exactly at threshold)
|
|
96
|
+
for (let i = 1; i <= 3; i++) {
|
|
97
|
+
createDelta(mindloreDir, `delta-2026-04-0${i}-1200.md`, `# Delta ${i}\n`);
|
|
98
|
+
}
|
|
99
|
+
const output = (0, child_process_1.execSync)(`node "${HOOK_PATH}"`, {
|
|
100
|
+
cwd: TEST_DIR,
|
|
101
|
+
encoding: 'utf8',
|
|
102
|
+
timeout: 5000,
|
|
103
|
+
env: { ...process.env, MINDLORE_HOME: path_1.default.join(TEST_DIR, '.mindlore') },
|
|
104
|
+
});
|
|
105
|
+
expect(output).toContain('3 diary entry birikti');
|
|
106
|
+
});
|
|
58
107
|
test('should handle missing diary directory gracefully', () => {
|
|
59
108
|
const mindloreDir = path_1.default.join(TEST_DIR, '.mindlore');
|
|
60
109
|
fs_1.default.mkdirSync(mindloreDir, { recursive: true });
|
|
@@ -63,6 +112,7 @@ describe('Session Focus Hook', () => {
|
|
|
63
112
|
cwd: TEST_DIR,
|
|
64
113
|
encoding: 'utf8',
|
|
65
114
|
timeout: 5000,
|
|
115
|
+
env: { ...process.env, MINDLORE_HOME: mindloreDir },
|
|
66
116
|
});
|
|
67
117
|
expect(output).toContain('[Mindlore INDEX]');
|
|
68
118
|
expect(output).not.toContain('[Mindlore Delta');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-focus.test.js","sourceRoot":"","sources":["../../tests/session-focus.test.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,iDAAyC;AAEzC,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,8BAA8B,CAAC,CAAC;AAC5E,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,4BAA4B,CAAC,CAAC;AAEpF,SAAS,iBAAiB;IACxB,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrD,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnE,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAClC,+DAA+D,CAChE,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,WAAmB,EAAE,IAAY,EAAE,OAAe;IACrE,YAAE,CAAC,aAAa,CACd,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EACrC,OAAO,CACR,CAAC;AACJ,CAAC;AAED,UAAU,CAAC,GAAG,EAAE;IACd,YAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,YAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,iBAAiB,EAAE,CAAC;QAEpB,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,SAAS,SAAS,GAAG,EAAE;YAC7C,GAAG,EAAE,QAAQ;YACb,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"session-focus.test.js","sourceRoot":"","sources":["../../tests/session-focus.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,47 +17,49 @@ const SKIP_FILES = new Set(['INDEX.md', 'SCHEMA.md', 'log.md']);
|
|
|
17
17
|
/**
|
|
18
18
|
* Compute global .mindlore/ path at call time.
|
|
19
19
|
* Separate function so os.homedir() is evaluated lazily (testable).
|
|
20
|
+
* MINDLORE_HOME env var overrides for testing and custom installs.
|
|
20
21
|
*/
|
|
21
22
|
function globalDir() {
|
|
23
|
+
if (process.env.MINDLORE_HOME) return process.env.MINDLORE_HOME;
|
|
22
24
|
return path.join(os.homedir(), MINDLORE_DIR);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
// Convenience export — snapshot at load time for simple references.
|
|
26
28
|
const GLOBAL_MINDLORE_DIR = globalDir();
|
|
27
29
|
|
|
30
|
+
/**
|
|
31
|
+
* v0.3.3 Global-First: always returns global ~/.mindlore/ if it exists.
|
|
32
|
+
*/
|
|
28
33
|
function findMindloreDir() {
|
|
29
|
-
const projectDir = path.join(process.cwd(), MINDLORE_DIR);
|
|
30
|
-
if (fs.existsSync(projectDir)) return projectDir;
|
|
31
|
-
|
|
32
34
|
const gDir = globalDir();
|
|
33
35
|
if (fs.existsSync(gDir)) return gDir;
|
|
34
|
-
|
|
35
36
|
return null;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
* Always returns
|
|
40
|
-
*
|
|
40
|
+
* Always returns the global ~/.mindlore/ path.
|
|
41
|
+
* v0.3.3: project scope removed — single global directory.
|
|
41
42
|
*/
|
|
42
43
|
function getActiveMindloreDir() {
|
|
43
|
-
const projectDir = path.join(process.cwd(), MINDLORE_DIR);
|
|
44
|
-
if (fs.existsSync(projectDir)) return projectDir;
|
|
45
44
|
return globalDir();
|
|
46
45
|
}
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
|
-
* Return
|
|
50
|
-
*
|
|
48
|
+
* Return the single global mindlore DB path.
|
|
49
|
+
* v0.3.3: multi-DB layered search removed — single global DB with project column.
|
|
51
50
|
*/
|
|
52
51
|
function getAllDbs() {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (fs.existsSync(projectDb)) dbs.push(projectDb);
|
|
58
|
-
if (fs.existsSync(gDb) && gDb !== projectDb) dbs.push(gDb);
|
|
52
|
+
const dbPath = path.join(globalDir(), DB_NAME);
|
|
53
|
+
if (fs.existsSync(dbPath)) return [dbPath];
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Get current project name from CWD basename.
|
|
59
|
+
* Used as the `project` column value in FTS5.
|
|
60
|
+
*/
|
|
61
|
+
function getProjectName() {
|
|
62
|
+
return path.basename(process.cwd());
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
function getLatestDelta(diaryDir) {
|
|
@@ -135,10 +137,10 @@ function extractFtsMetadata(meta, body, filePath, baseDir) {
|
|
|
135
137
|
* Shared SQL constants to prevent drift across indexing paths.
|
|
136
138
|
*/
|
|
137
139
|
const SQL_FTS_CREATE =
|
|
138
|
-
"CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts USING fts5(path UNINDEXED, slug, description, type UNINDEXED, category, title, content, tags, quality UNINDEXED, date_captured UNINDEXED, tokenize='porter unicode61')";
|
|
140
|
+
"CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts USING fts5(path UNINDEXED, slug, description, type UNINDEXED, category, title, content, tags, quality UNINDEXED, date_captured UNINDEXED, project UNINDEXED, tokenize='porter unicode61')";
|
|
139
141
|
|
|
140
142
|
const SQL_FTS_INSERT =
|
|
141
|
-
'INSERT INTO mindlore_fts (path, slug, description, type, category, title, content, tags, quality, date_captured) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
|
143
|
+
'INSERT INTO mindlore_fts (path, slug, description, type, category, title, content, tags, quality, date_captured, project) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
|
142
144
|
|
|
143
145
|
/**
|
|
144
146
|
* Insert a row into FTS5 using an object parameter (replaces positional args).
|
|
@@ -156,6 +158,7 @@ function insertFtsRow(db, entry) {
|
|
|
156
158
|
entry.tags || '',
|
|
157
159
|
entry.quality || null,
|
|
158
160
|
entry.dateCaptured || null,
|
|
161
|
+
entry.project || null,
|
|
159
162
|
);
|
|
160
163
|
}
|
|
161
164
|
|
|
@@ -255,18 +258,23 @@ function readConfig(mindloreDir) {
|
|
|
255
258
|
*/
|
|
256
259
|
function detectSchemaVersion(db) {
|
|
257
260
|
try {
|
|
258
|
-
db.prepare('SELECT tags, quality, date_captured FROM mindlore_fts LIMIT 0').run();
|
|
259
|
-
return
|
|
260
|
-
} catch (
|
|
261
|
+
db.prepare('SELECT tags, quality, date_captured, project FROM mindlore_fts LIMIT 0').run();
|
|
262
|
+
return 11;
|
|
263
|
+
} catch (_err11) {
|
|
261
264
|
try {
|
|
262
|
-
db.prepare('SELECT tags, quality FROM mindlore_fts LIMIT 0').run();
|
|
263
|
-
return
|
|
264
|
-
} catch (
|
|
265
|
+
db.prepare('SELECT tags, quality, date_captured FROM mindlore_fts LIMIT 0').run();
|
|
266
|
+
return 10;
|
|
267
|
+
} catch (_err10) {
|
|
265
268
|
try {
|
|
266
|
-
db.prepare('SELECT
|
|
267
|
-
return
|
|
268
|
-
} catch (
|
|
269
|
-
|
|
269
|
+
db.prepare('SELECT tags, quality FROM mindlore_fts LIMIT 0').run();
|
|
270
|
+
return 9;
|
|
271
|
+
} catch (_err9) {
|
|
272
|
+
try {
|
|
273
|
+
db.prepare('SELECT slug, description, category, title FROM mindlore_fts LIMIT 0').run();
|
|
274
|
+
return 7;
|
|
275
|
+
} catch (_err7) {
|
|
276
|
+
return 2;
|
|
277
|
+
}
|
|
270
278
|
}
|
|
271
279
|
}
|
|
272
280
|
}
|
|
@@ -302,5 +310,6 @@ module.exports = {
|
|
|
302
310
|
getAllMdFiles,
|
|
303
311
|
readConfig,
|
|
304
312
|
detectSchemaVersion,
|
|
313
|
+
getProjectName,
|
|
305
314
|
DEFAULT_MODELS,
|
|
306
315
|
};
|
package/hooks/lib/types.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export interface FtsEntry {
|
|
|
25
25
|
tags?: string;
|
|
26
26
|
quality?: string | null;
|
|
27
27
|
dateCaptured?: string | null;
|
|
28
|
+
project?: string | null;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export interface ParsedFrontmatter {
|
|
@@ -53,4 +54,5 @@ export interface MindloreCommon {
|
|
|
53
54
|
getAllMdFiles(dir: string, skip?: Set<string>): string[];
|
|
54
55
|
SQL_FTS_CREATE: string;
|
|
55
56
|
SQL_FTS_INSERT: string;
|
|
57
|
+
getProjectName(): string;
|
|
56
58
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* CwdChanged has NO inject to Claude — stdout is swallowed, stderr shown to user.
|
|
9
9
|
*
|
|
10
10
|
* Side effects:
|
|
11
|
-
* 1. Detect scope (
|
|
11
|
+
* 1. Detect scope (global ~/.mindlore/ or none)
|
|
12
12
|
* 2. Write scope state to .mindlore/diary/_scope.json for session-focus to read
|
|
13
13
|
* 3. Show user-facing message via stderr
|
|
14
14
|
*/
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
const fs = require('fs');
|
|
19
19
|
const path = require('path');
|
|
20
20
|
const os = require('os');
|
|
21
|
-
const { findMindloreDir } = require('./lib/mindlore-common.cjs');
|
|
21
|
+
const { findMindloreDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* File-persisted pattern cache — survives across process invocations.
|
|
@@ -167,7 +167,7 @@ function main() {
|
|
|
167
167
|
|
|
168
168
|
// Load patterns from all sources (file-persisted mtime cache)
|
|
169
169
|
const mindloreDir = findMindloreDir();
|
|
170
|
-
const cachePath = mindloreDir ? path.join(mindloreDir, 'diary',
|
|
170
|
+
const cachePath = mindloreDir ? path.join(mindloreDir, 'diary', `_pattern-cache-${getProjectName()}.json`) : null;
|
|
171
171
|
const cache = readCache(cachePath);
|
|
172
172
|
const allPatterns = [];
|
|
173
173
|
const cwd = process.cwd();
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
16
|
+
const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
function main() {
|
|
19
19
|
const filePath = readHookStdin(['path', 'file_path']);
|
|
@@ -25,7 +25,7 @@ function main() {
|
|
|
25
25
|
// This hook is for bulk changes (git pull, manual batch edits).
|
|
26
26
|
if (filePath.endsWith('.md')) return;
|
|
27
27
|
|
|
28
|
-
const baseDir =
|
|
28
|
+
const baseDir = getActiveMindloreDir();
|
|
29
29
|
if (!fs.existsSync(baseDir)) return;
|
|
30
30
|
|
|
31
31
|
const dbPath = path.join(baseDir, DB_NAME);
|
|
@@ -50,6 +50,7 @@ function main() {
|
|
|
50
50
|
const now = new Date().toISOString();
|
|
51
51
|
|
|
52
52
|
try {
|
|
53
|
+
const project = getProjectName();
|
|
53
54
|
const transaction = db.transaction(() => {
|
|
54
55
|
for (const file of mdFiles) {
|
|
55
56
|
const content = fs.readFileSync(file, 'utf8').replace(/\r\n/g, '\n');
|
|
@@ -61,7 +62,7 @@ function main() {
|
|
|
61
62
|
const { meta, body } = parseFrontmatter(content);
|
|
62
63
|
const { slug, description, type, category, title, tags, quality, dateCaptured } = extractFtsMetadata(meta, body, file, baseDir);
|
|
63
64
|
deleteFts.run(file);
|
|
64
|
-
insertFtsRow(db, { path: file, slug, description, type, category, title, content: body, tags, quality, dateCaptured });
|
|
65
|
+
insertFtsRow(db, { path: file, slug, description, type, category, title, content: body, tags, quality, dateCaptured, project });
|
|
65
66
|
upsertHash.run(file, hash, now);
|
|
66
67
|
}
|
|
67
68
|
});
|
package/hooks/mindlore-index.cjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
-
const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
13
|
+
const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
function main() {
|
|
16
16
|
const filePath = readHookStdin(['path', 'file_path']);
|
|
@@ -62,7 +62,7 @@ function main() {
|
|
|
62
62
|
|
|
63
63
|
// Update FTS5
|
|
64
64
|
db.prepare('DELETE FROM mindlore_fts WHERE path = ?').run(filePath);
|
|
65
|
-
insertFtsRow(db, { path: filePath, slug, description, type, category, title, content: body, tags, quality, dateCaptured });
|
|
65
|
+
insertFtsRow(db, { path: filePath, slug, description, type, category, title, content: body, tags, quality, dateCaptured, project: getProjectName() });
|
|
66
66
|
|
|
67
67
|
// Update hash
|
|
68
68
|
db.prepare(
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const { findMindloreDir } = require('./lib/mindlore-common.cjs');
|
|
16
|
+
const { findMindloreDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
const CODE_EXTS = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.rs', '.go', '.java', '.c', '.cpp', '.h', '.css', '.scss', '.sql', '.sh', '.yaml', '.yml', '.json', '.toml', '.xml', '.cjs', '.mjs']);
|
|
19
19
|
const PROSE_EXTS = new Set(['.md', '.txt', '.rst', '.adoc']);
|
|
@@ -67,7 +67,7 @@ function main() {
|
|
|
67
67
|
|
|
68
68
|
// Update _session-reads.json with token info
|
|
69
69
|
const diaryDir = path.join(baseDir, 'diary');
|
|
70
|
-
const readsPath = path.join(diaryDir,
|
|
70
|
+
const readsPath = path.join(diaryDir, `_session-reads-${getProjectName()}.json`);
|
|
71
71
|
let reads = {};
|
|
72
72
|
if (fs.existsSync(readsPath)) {
|
|
73
73
|
try { reads = JSON.parse(fs.readFileSync(readsPath, 'utf8')); } catch { reads = {}; }
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { findMindloreDir, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
17
|
+
const { findMindloreDir, readHookStdin, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
18
18
|
|
|
19
19
|
function main() {
|
|
20
20
|
const baseDir = findMindloreDir();
|
|
@@ -35,7 +35,7 @@ function main() {
|
|
|
35
35
|
fs.mkdirSync(diaryDir, { recursive: true });
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const readsPath = path.join(diaryDir,
|
|
38
|
+
const readsPath = path.join(diaryDir, `_session-reads-${getProjectName()}.json`);
|
|
39
39
|
let reads = {};
|
|
40
40
|
if (fs.existsSync(readsPath)) {
|
|
41
41
|
try {
|
|
@@ -117,8 +117,6 @@ function main() {
|
|
|
117
117
|
const Database = requireDatabase();
|
|
118
118
|
if (!Database) return;
|
|
119
119
|
|
|
120
|
-
// Layered search: project DB first, global DB second
|
|
121
|
-
// Project results appear first in output (higher priority)
|
|
122
120
|
const allScores = [];
|
|
123
121
|
for (const dbPath of dbPaths) {
|
|
124
122
|
allScores.push(...searchDb(dbPath, keywords, Database));
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const { execSync } = require('child_process');
|
|
15
|
-
const { findMindloreDir, globalDir } = require('./lib/mindlore-common.cjs');
|
|
15
|
+
const { findMindloreDir, globalDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
16
16
|
|
|
17
17
|
function formatDate(date) {
|
|
18
18
|
const y = date.getFullYear();
|
|
@@ -50,7 +50,7 @@ function getRecentCommits() {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function getSessionReads(baseDir) {
|
|
53
|
-
const readsPath = path.join(baseDir, 'diary',
|
|
53
|
+
const readsPath = path.join(baseDir, 'diary', `_session-reads-${getProjectName()}.json`);
|
|
54
54
|
if (!fs.existsSync(readsPath)) return null;
|
|
55
55
|
try {
|
|
56
56
|
const data = JSON.parse(fs.readFileSync(readsPath, 'utf8'));
|
|
@@ -85,11 +85,14 @@ function main() {
|
|
|
85
85
|
const changedFiles = getRecentGitChanges();
|
|
86
86
|
const reads = getSessionReads(baseDir);
|
|
87
87
|
|
|
88
|
+
const project = getProjectName();
|
|
89
|
+
|
|
88
90
|
const sections = [
|
|
89
91
|
'---',
|
|
90
92
|
`slug: delta-${dateStr}`,
|
|
91
93
|
'type: diary',
|
|
92
94
|
`date: ${now.toISOString().slice(0, 10)}`,
|
|
95
|
+
`project: ${project}`,
|
|
93
96
|
'---',
|
|
94
97
|
'',
|
|
95
98
|
`# Session Delta — ${dateStr}`,
|