mindlore 0.1.0 → 0.2.1
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 +13 -5
- package/SCHEMA.md +60 -4
- package/dist/scripts/init.d.ts +10 -0
- package/dist/scripts/init.d.ts.map +1 -0
- package/dist/scripts/init.js +375 -0
- package/dist/scripts/init.js.map +1 -0
- package/dist/scripts/lib/constants.d.ts +29 -0
- package/dist/scripts/lib/constants.d.ts.map +1 -0
- package/dist/scripts/lib/constants.js +58 -0
- package/dist/scripts/lib/constants.js.map +1 -0
- package/dist/scripts/mindlore-fts5-index.d.ts +9 -0
- package/dist/scripts/mindlore-fts5-index.d.ts.map +1 -0
- package/dist/scripts/mindlore-fts5-index.js +89 -0
- package/dist/scripts/mindlore-fts5-index.js.map +1 -0
- package/dist/scripts/mindlore-fts5-search.d.ts +10 -0
- package/dist/scripts/mindlore-fts5-search.d.ts.map +1 -0
- package/dist/scripts/mindlore-fts5-search.js +108 -0
- package/dist/scripts/mindlore-fts5-search.js.map +1 -0
- package/dist/scripts/mindlore-health-check.d.ts +10 -0
- package/dist/scripts/mindlore-health-check.d.ts.map +1 -0
- package/dist/scripts/mindlore-health-check.js +337 -0
- package/dist/scripts/mindlore-health-check.js.map +1 -0
- package/dist/scripts/uninstall.d.ts +10 -0
- package/dist/scripts/uninstall.d.ts.map +1 -0
- package/dist/scripts/uninstall.js +143 -0
- package/dist/scripts/uninstall.js.map +1 -0
- package/dist/tests/compounding.test.d.ts +8 -0
- package/dist/tests/compounding.test.d.ts.map +1 -0
- package/dist/tests/compounding.test.js +51 -0
- package/dist/tests/compounding.test.js.map +1 -0
- package/dist/tests/decision.test.d.ts +2 -0
- package/dist/tests/decision.test.d.ts.map +1 -0
- package/dist/tests/decision.test.js +61 -0
- package/dist/tests/decision.test.js.map +1 -0
- package/dist/tests/dedup.test.d.ts +2 -0
- package/dist/tests/dedup.test.d.ts.map +1 -0
- package/dist/tests/dedup.test.js +74 -0
- package/dist/tests/dedup.test.js.map +1 -0
- package/dist/tests/frontmatter.test.d.ts +2 -0
- package/dist/tests/frontmatter.test.d.ts.map +1 -0
- package/dist/tests/frontmatter.test.js +90 -0
- package/dist/tests/frontmatter.test.js.map +1 -0
- package/dist/tests/fts5.test.d.ts +2 -0
- package/dist/tests/fts5.test.d.ts.map +1 -0
- package/dist/tests/fts5.test.js +95 -0
- package/dist/tests/fts5.test.js.map +1 -0
- package/dist/tests/helpers/db.d.ts +7 -0
- package/dist/tests/helpers/db.d.ts.map +1 -0
- package/dist/tests/helpers/db.js +46 -0
- package/dist/tests/helpers/db.js.map +1 -0
- package/dist/tests/hook-smoke.test.d.ts +2 -0
- package/dist/tests/hook-smoke.test.d.ts.map +1 -0
- package/dist/tests/hook-smoke.test.js +58 -0
- package/dist/tests/hook-smoke.test.js.map +1 -0
- package/dist/tests/init.test.d.ts +2 -0
- package/dist/tests/init.test.d.ts.map +1 -0
- package/dist/tests/init.test.js +85 -0
- package/dist/tests/init.test.js.map +1 -0
- package/dist/tests/log.test.d.ts +2 -0
- package/dist/tests/log.test.d.ts.map +1 -0
- package/dist/tests/log.test.js +68 -0
- package/dist/tests/log.test.js.map +1 -0
- package/dist/tests/read-guard.test.d.ts +2 -0
- package/dist/tests/read-guard.test.d.ts.map +1 -0
- package/dist/tests/read-guard.test.js +69 -0
- package/dist/tests/read-guard.test.js.map +1 -0
- package/dist/tests/search-hook.test.d.ts +2 -0
- package/dist/tests/search-hook.test.d.ts.map +1 -0
- package/dist/tests/search-hook.test.js +108 -0
- package/dist/tests/search-hook.test.js.map +1 -0
- package/dist/tests/session-focus.test.d.ts +2 -0
- package/dist/tests/session-focus.test.d.ts.map +1 -0
- package/dist/tests/session-focus.test.js +71 -0
- package/dist/tests/session-focus.test.js.map +1 -0
- package/dist/tests/uninstall.test.d.ts +2 -0
- package/dist/tests/uninstall.test.d.ts.map +1 -0
- package/dist/tests/uninstall.test.js +98 -0
- package/dist/tests/uninstall.test.js.map +1 -0
- package/hooks/lib/mindlore-common.cjs +36 -2
- package/hooks/mindlore-decision-detector.cjs +51 -0
- package/hooks/mindlore-fts5-sync.cjs +4 -18
- package/hooks/mindlore-index.cjs +4 -18
- package/hooks/mindlore-read-guard.cjs +62 -0
- package/hooks/mindlore-search.cjs +5 -18
- package/hooks/mindlore-session-end.cjs +74 -8
- package/package.json +19 -7
- package/plugin.json +26 -2
- package/skills/mindlore-decide/SKILL.md +71 -0
- package/skills/mindlore-ingest/SKILL.md +13 -2
- package/skills/mindlore-log/SKILL.md +79 -0
- package/skills/mindlore-query/SKILL.md +125 -0
- package/templates/SCHEMA.md +60 -4
- package/scripts/init.cjs +0 -450
- package/scripts/lib/constants.cjs +0 -49
- package/scripts/mindlore-fts5-index.cjs +0 -112
- package/scripts/mindlore-fts5-search.cjs +0 -119
- package/scripts/mindlore-health-check.cjs +0 -336
- package/scripts/uninstall.cjs +0 -186
|
@@ -0,0 +1,98 @@
|
|
|
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 TEST_DIR = path_1.default.join(__dirname, '..', '.test-mindlore-uninstall');
|
|
9
|
+
const MOCK_HOME = path_1.default.join(TEST_DIR, 'home');
|
|
10
|
+
const MOCK_PROJECT = path_1.default.join(TEST_DIR, 'project');
|
|
11
|
+
function setupMockEnvironment() {
|
|
12
|
+
const claudeDir = path_1.default.join(MOCK_HOME, '.claude');
|
|
13
|
+
const skillsDir = path_1.default.join(claudeDir, 'skills');
|
|
14
|
+
fs_1.default.mkdirSync(path_1.default.join(skillsDir, 'mindlore-ingest'), { recursive: true });
|
|
15
|
+
fs_1.default.mkdirSync(path_1.default.join(skillsDir, 'mindlore-health'), { recursive: true });
|
|
16
|
+
fs_1.default.mkdirSync(path_1.default.join(skillsDir, 'other-skill'), { recursive: true });
|
|
17
|
+
fs_1.default.writeFileSync(path_1.default.join(skillsDir, 'mindlore-ingest', 'SKILL.md'), '# Ingest');
|
|
18
|
+
fs_1.default.writeFileSync(path_1.default.join(skillsDir, 'mindlore-health', 'SKILL.md'), '# Health');
|
|
19
|
+
fs_1.default.writeFileSync(path_1.default.join(skillsDir, 'other-skill', 'SKILL.md'), '# Other');
|
|
20
|
+
const settings = {
|
|
21
|
+
hooks: {
|
|
22
|
+
SessionStart: [
|
|
23
|
+
{ hooks: [{ type: 'command', command: 'node some-other-hook.cjs' }] },
|
|
24
|
+
{ hooks: [{ type: 'command', command: 'node mindlore-session-focus.cjs' }] },
|
|
25
|
+
],
|
|
26
|
+
UserPromptSubmit: [
|
|
27
|
+
{ hooks: [{ type: 'command', command: 'node mindlore-search.cjs' }] },
|
|
28
|
+
],
|
|
29
|
+
SessionEnd: [
|
|
30
|
+
{ hooks: [{ type: 'command', command: 'node mindlore-session-end.cjs' }] },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
fs_1.default.writeFileSync(path_1.default.join(claudeDir, 'settings.json'), JSON.stringify(settings, null, 2));
|
|
35
|
+
const projectClaude = path_1.default.join(MOCK_PROJECT, '.claude');
|
|
36
|
+
const projectMindlore = path_1.default.join(MOCK_PROJECT, '.mindlore');
|
|
37
|
+
fs_1.default.mkdirSync(path_1.default.join(projectMindlore, 'sources'), { recursive: true });
|
|
38
|
+
fs_1.default.mkdirSync(projectClaude, { recursive: true });
|
|
39
|
+
fs_1.default.writeFileSync(path_1.default.join(projectMindlore, 'INDEX.md'), '# Mindlore Index');
|
|
40
|
+
fs_1.default.writeFileSync(path_1.default.join(projectClaude, 'settings.json'), JSON.stringify({ projectDocFiles: ['.mindlore/SCHEMA.md', 'other.md'] }));
|
|
41
|
+
}
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
fs_1.default.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
44
|
+
setupMockEnvironment();
|
|
45
|
+
});
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
fs_1.default.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
48
|
+
});
|
|
49
|
+
describe('Uninstall Logic', () => {
|
|
50
|
+
test('should remove mindlore hooks but keep other hooks', () => {
|
|
51
|
+
const settingsPath = path_1.default.join(MOCK_HOME, '.claude', 'settings.json');
|
|
52
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, 'utf8'));
|
|
53
|
+
for (const event of Object.keys(settings.hooks)) {
|
|
54
|
+
settings.hooks[event] = (settings.hooks[event] ?? []).filter((entry) => {
|
|
55
|
+
const hooks = entry.hooks ?? [];
|
|
56
|
+
return !hooks.some((h) => (h.command ?? '').includes('mindlore-'));
|
|
57
|
+
});
|
|
58
|
+
if (settings.hooks[event].length === 0) {
|
|
59
|
+
delete settings.hooks[event];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
expect(settings.hooks['SessionStart']).toHaveLength(1);
|
|
63
|
+
expect(settings.hooks['SessionStart'][0].hooks[0].command).toContain('some-other-hook');
|
|
64
|
+
expect(settings.hooks['UserPromptSubmit']).toBeUndefined();
|
|
65
|
+
expect(settings.hooks['SessionEnd']).toBeUndefined();
|
|
66
|
+
});
|
|
67
|
+
test('should remove mindlore skills but keep other skills', () => {
|
|
68
|
+
const skillsDir = path_1.default.join(MOCK_HOME, '.claude', 'skills');
|
|
69
|
+
const before = fs_1.default.readdirSync(skillsDir);
|
|
70
|
+
expect(before).toContain('mindlore-ingest');
|
|
71
|
+
expect(before).toContain('mindlore-health');
|
|
72
|
+
expect(before).toContain('other-skill');
|
|
73
|
+
const mindloreSkills = before.filter((d) => d.startsWith('mindlore-'));
|
|
74
|
+
for (const skill of mindloreSkills) {
|
|
75
|
+
fs_1.default.rmSync(path_1.default.join(skillsDir, skill), { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
const after = fs_1.default.readdirSync(skillsDir);
|
|
78
|
+
expect(after).not.toContain('mindlore-ingest');
|
|
79
|
+
expect(after).not.toContain('mindlore-health');
|
|
80
|
+
expect(after).toContain('other-skill');
|
|
81
|
+
});
|
|
82
|
+
test('should remove SCHEMA.md from projectDocFiles but keep others', () => {
|
|
83
|
+
const settingsPath = path_1.default.join(MOCK_PROJECT, '.claude', 'settings.json');
|
|
84
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, 'utf8'));
|
|
85
|
+
expect(settings.projectDocFiles).toContain('.mindlore/SCHEMA.md');
|
|
86
|
+
expect(settings.projectDocFiles).toContain('other.md');
|
|
87
|
+
settings.projectDocFiles = settings.projectDocFiles.filter((p) => !p.includes('mindlore'));
|
|
88
|
+
expect(settings.projectDocFiles).not.toContain('.mindlore/SCHEMA.md');
|
|
89
|
+
expect(settings.projectDocFiles).toContain('other.md');
|
|
90
|
+
});
|
|
91
|
+
test('should remove .mindlore/ with --all flag', () => {
|
|
92
|
+
const mindloreDir = path_1.default.join(MOCK_PROJECT, '.mindlore');
|
|
93
|
+
expect(fs_1.default.existsSync(mindloreDir)).toBe(true);
|
|
94
|
+
fs_1.default.rmSync(mindloreDir, { recursive: true, force: true });
|
|
95
|
+
expect(fs_1.default.existsSync(mindloreDir)).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=uninstall.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.test.js","sourceRoot":"","sources":["../../tests/uninstall.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,14 +86,22 @@ function extractFtsMetadata(meta, body, filePath, baseDir) {
|
|
|
86
86
|
const headingMatch = body.match(/^#\s+(.+)/m);
|
|
87
87
|
title = headingMatch ? headingMatch[1].trim() : path.basename(filePath, '.md');
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
let tags = '';
|
|
90
|
+
if (meta.tags) {
|
|
91
|
+
tags = Array.isArray(meta.tags) ? meta.tags.join(', ') : String(meta.tags);
|
|
92
|
+
}
|
|
93
|
+
const quality = meta.quality !== undefined && meta.quality !== null ? meta.quality : null;
|
|
94
|
+
return { slug, description, type, category, title, tags, quality };
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
/**
|
|
93
98
|
* Shared SQL constants to prevent drift across indexing paths.
|
|
94
99
|
*/
|
|
100
|
+
const SQL_FTS_CREATE =
|
|
101
|
+
"CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts USING fts5(path UNINDEXED, slug, description, type UNINDEXED, category, title, content, tags, quality UNINDEXED, tokenize='porter unicode61')";
|
|
102
|
+
|
|
95
103
|
const SQL_FTS_INSERT =
|
|
96
|
-
'INSERT INTO mindlore_fts (path, slug, description, type, category, title, content) VALUES (?, ?, ?, ?, ?, ?, ?)';
|
|
104
|
+
'INSERT INTO mindlore_fts (path, slug, description, type, category, title, content, tags, quality) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
|
97
105
|
|
|
98
106
|
/**
|
|
99
107
|
* Extract headings (h1-h3) from markdown content.
|
|
@@ -145,6 +153,30 @@ function getAllMdFiles(dir, skip) {
|
|
|
145
153
|
return results;
|
|
146
154
|
}
|
|
147
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Read CC hook stdin and parse JSON envelope.
|
|
158
|
+
* Returns the value of the first matching field, or raw text as fallback.
|
|
159
|
+
* @param {string[]} fields - Priority-ordered field names to extract
|
|
160
|
+
*/
|
|
161
|
+
function readHookStdin(fields) {
|
|
162
|
+
let input = '';
|
|
163
|
+
try {
|
|
164
|
+
input = fs.readFileSync(0, 'utf8').trim();
|
|
165
|
+
} catch (_err) {
|
|
166
|
+
return '';
|
|
167
|
+
}
|
|
168
|
+
if (!input) return '';
|
|
169
|
+
try {
|
|
170
|
+
const parsed = JSON.parse(input);
|
|
171
|
+
for (const f of fields) {
|
|
172
|
+
if (parsed[f]) return parsed[f];
|
|
173
|
+
}
|
|
174
|
+
} catch (_err) {
|
|
175
|
+
// plain text
|
|
176
|
+
}
|
|
177
|
+
return input;
|
|
178
|
+
}
|
|
179
|
+
|
|
148
180
|
module.exports = {
|
|
149
181
|
MINDLORE_DIR,
|
|
150
182
|
DB_NAME,
|
|
@@ -154,6 +186,8 @@ module.exports = {
|
|
|
154
186
|
sha256,
|
|
155
187
|
parseFrontmatter,
|
|
156
188
|
extractFtsMetadata,
|
|
189
|
+
readHookStdin,
|
|
190
|
+
SQL_FTS_CREATE,
|
|
157
191
|
SQL_FTS_INSERT,
|
|
158
192
|
extractHeadings,
|
|
159
193
|
requireDatabase,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mindlore-decision-detector — UserPromptSubmit hook
|
|
6
|
+
*
|
|
7
|
+
* Detects decision signals in user messages (TR + EN).
|
|
8
|
+
* Outputs a suggestion to record the decision via /mindlore-decide.
|
|
9
|
+
* Does NOT block (exit 0) — advisory only.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { findMindloreDir, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
13
|
+
|
|
14
|
+
const SIGNALS_TR = [
|
|
15
|
+
'karar verdik', 'karar verildi', 'kararlastirdik', 'kararlaştırdık',
|
|
16
|
+
'şunu seçtik', 'sunu sectik', 'bunu yapmayalım', 'bunu yapmayalim',
|
|
17
|
+
'yerine', 'tercih ettik', 'onaylandi', 'onaylandı', 'kesinleşti', 'kesinlesti',
|
|
18
|
+
'vazgeçtik', 'vazgectik', 'iptal ettik',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const SIGNALS_EN = [
|
|
22
|
+
'decided', 'decision made', "let's go with", 'lets go with',
|
|
23
|
+
"we'll use", 'well use', 'approved', 'settled on',
|
|
24
|
+
'going with', 'chosen', 'finalized', 'rejected',
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
function detectDecision(text) {
|
|
28
|
+
const lower = text.toLowerCase();
|
|
29
|
+
for (const signal of SIGNALS_TR) {
|
|
30
|
+
if (lower.includes(signal)) return signal;
|
|
31
|
+
}
|
|
32
|
+
for (const signal of SIGNALS_EN) {
|
|
33
|
+
if (lower.includes(signal)) return signal;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function main() {
|
|
39
|
+
const baseDir = findMindloreDir();
|
|
40
|
+
if (!baseDir) return;
|
|
41
|
+
|
|
42
|
+
const userText = readHookStdin(['prompt', 'content', 'message']);
|
|
43
|
+
if (!userText || userText.length < 10) return;
|
|
44
|
+
|
|
45
|
+
const signal = detectDecision(userText);
|
|
46
|
+
if (signal) {
|
|
47
|
+
process.stdout.write(`[Mindlore: Karar sinyali tespit edildi ("${signal}") — /mindlore-decide record ile kaydetmek ister misin?]\n`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
main();
|
|
@@ -13,24 +13,10 @@
|
|
|
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, SQL_FTS_INSERT } = require('./lib/mindlore-common.cjs');
|
|
16
|
+
const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, SQL_FTS_INSERT, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
function main() {
|
|
19
|
-
|
|
20
|
-
let input = '';
|
|
21
|
-
try {
|
|
22
|
-
input = fs.readFileSync(0, 'utf8').trim();
|
|
23
|
-
} catch (_err) {
|
|
24
|
-
// No stdin — skip
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let filePath = '';
|
|
28
|
-
try {
|
|
29
|
-
const parsed = JSON.parse(input);
|
|
30
|
-
filePath = parsed.path || parsed.file_path || '';
|
|
31
|
-
} catch (_err) {
|
|
32
|
-
filePath = input;
|
|
33
|
-
}
|
|
19
|
+
const filePath = readHookStdin(['path', 'file_path']);
|
|
34
20
|
|
|
35
21
|
// Only trigger on .mindlore/ changes (empty filePath = skip)
|
|
36
22
|
if (!filePath || !filePath.includes(MINDLORE_DIR)) return;
|
|
@@ -74,9 +60,9 @@ function main() {
|
|
|
74
60
|
if (existing && existing.content_hash === hash) continue;
|
|
75
61
|
|
|
76
62
|
const { meta, body } = parseFrontmatter(content);
|
|
77
|
-
const { slug, description, type, category, title } = extractFtsMetadata(meta, body, file, baseDir);
|
|
63
|
+
const { slug, description, type, category, title, tags, quality } = extractFtsMetadata(meta, body, file, baseDir);
|
|
78
64
|
deleteFts.run(file);
|
|
79
|
-
insertFts.run(file, slug, description, type, category, title, body);
|
|
65
|
+
insertFts.run(file, slug, description, type, category, title, body, tags, quality);
|
|
80
66
|
upsertHash.run(file, hash, now);
|
|
81
67
|
synced++;
|
|
82
68
|
}
|
package/hooks/mindlore-index.cjs
CHANGED
|
@@ -10,24 +10,10 @@
|
|
|
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, SQL_FTS_INSERT } = require('./lib/mindlore-common.cjs');
|
|
13
|
+
const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, SQL_FTS_INSERT, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
function main() {
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
input = fs.readFileSync(0, 'utf8').trim();
|
|
19
|
-
} catch (_err) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
let filePath = '';
|
|
24
|
-
try {
|
|
25
|
-
const parsed = JSON.parse(input);
|
|
26
|
-
filePath = parsed.path || parsed.file_path || '';
|
|
27
|
-
} catch (_err) {
|
|
28
|
-
filePath = input;
|
|
29
|
-
}
|
|
30
|
-
|
|
16
|
+
const filePath = readHookStdin(['path', 'file_path']);
|
|
31
17
|
if (!filePath) return;
|
|
32
18
|
|
|
33
19
|
// Only process .md files inside .mindlore/
|
|
@@ -72,11 +58,11 @@ function main() {
|
|
|
72
58
|
|
|
73
59
|
// Parse frontmatter for rich FTS5 columns
|
|
74
60
|
const { meta, body } = parseFrontmatter(content);
|
|
75
|
-
const { slug, description, type, category, title } = extractFtsMetadata(meta, body, filePath, baseDir);
|
|
61
|
+
const { slug, description, type, category, title, tags, quality } = extractFtsMetadata(meta, body, filePath, baseDir);
|
|
76
62
|
|
|
77
63
|
// Update FTS5
|
|
78
64
|
db.prepare('DELETE FROM mindlore_fts WHERE path = ?').run(filePath);
|
|
79
|
-
db.prepare(SQL_FTS_INSERT).run(filePath, slug, description, type, category, title, body);
|
|
65
|
+
db.prepare(SQL_FTS_INSERT).run(filePath, slug, description, type, category, title, body, tags, quality);
|
|
80
66
|
|
|
81
67
|
// Update hash
|
|
82
68
|
db.prepare(
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* mindlore-read-guard — PreToolUse hook (if: "Read")
|
|
6
|
+
*
|
|
7
|
+
* OpenWolf repeated-read pattern: detects files read multiple times
|
|
8
|
+
* in the same session and emits a soft warning.
|
|
9
|
+
* Does NOT block (exit 0) — advisory only.
|
|
10
|
+
*
|
|
11
|
+
* Storage: .mindlore/diary/_session-reads.json
|
|
12
|
+
* Cleanup: session-end hook writes stats to delta then deletes the file.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { findMindloreDir, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
18
|
+
|
|
19
|
+
function main() {
|
|
20
|
+
const baseDir = findMindloreDir();
|
|
21
|
+
if (!baseDir) return;
|
|
22
|
+
|
|
23
|
+
const filePath = readHookStdin(['file_path', 'path']);
|
|
24
|
+
if (!filePath) return;
|
|
25
|
+
|
|
26
|
+
// Only track CWD-relative files, skip .mindlore/ internals
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
const resolved = path.resolve(filePath);
|
|
29
|
+
if (!resolved.startsWith(cwd)) return;
|
|
30
|
+
if (resolved.startsWith(path.resolve(baseDir))) return;
|
|
31
|
+
|
|
32
|
+
// Load or create session reads tracker
|
|
33
|
+
const diaryDir = path.join(baseDir, 'diary');
|
|
34
|
+
if (!fs.existsSync(diaryDir)) {
|
|
35
|
+
fs.mkdirSync(diaryDir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const readsPath = path.join(diaryDir, '_session-reads.json');
|
|
39
|
+
let reads = {};
|
|
40
|
+
if (fs.existsSync(readsPath)) {
|
|
41
|
+
try {
|
|
42
|
+
reads = JSON.parse(fs.readFileSync(readsPath, 'utf8'));
|
|
43
|
+
} catch (_err) {
|
|
44
|
+
reads = {};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const normalizedPath = path.resolve(filePath);
|
|
49
|
+
const count = (reads[normalizedPath] || 0) + 1;
|
|
50
|
+
reads[normalizedPath] = count;
|
|
51
|
+
|
|
52
|
+
// Write updated reads
|
|
53
|
+
fs.writeFileSync(readsPath, JSON.stringify(reads, null, 2), 'utf8');
|
|
54
|
+
|
|
55
|
+
// Warn on repeated reads (2nd+ time)
|
|
56
|
+
if (count > 1) {
|
|
57
|
+
const basename = path.basename(filePath);
|
|
58
|
+
process.stdout.write(`[Mindlore: ${basename} bu session'da ${count}. kez okunuyor. Değişiklik yoksa tekrar okumayı atlayabilirsin.]\n`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
main();
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
-
const { findMindloreDir, DB_NAME, requireDatabase, extractHeadings } = require('./lib/mindlore-common.cjs');
|
|
13
|
+
const { findMindloreDir, DB_NAME, requireDatabase, extractHeadings, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
const MAX_RESULTS = 3;
|
|
16
16
|
const MIN_QUERY_WORDS = 3;
|
|
@@ -60,21 +60,7 @@ function extractKeywords(text) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
function main() {
|
|
63
|
-
|
|
64
|
-
try {
|
|
65
|
-
input = fs.readFileSync(0, 'utf8');
|
|
66
|
-
} catch (_err) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
let userMessage = '';
|
|
71
|
-
try {
|
|
72
|
-
const parsed = JSON.parse(input);
|
|
73
|
-
userMessage = parsed.prompt || parsed.content || parsed.message || parsed.query || input;
|
|
74
|
-
} catch (_err) {
|
|
75
|
-
userMessage = input;
|
|
76
|
-
}
|
|
77
|
-
|
|
63
|
+
const userMessage = readHookStdin(['prompt', 'content', 'message', 'query']);
|
|
78
64
|
if (!userMessage || userMessage.length < MIN_QUERY_WORDS) return;
|
|
79
65
|
|
|
80
66
|
const baseDir = findMindloreDir();
|
|
@@ -127,7 +113,7 @@ function main() {
|
|
|
127
113
|
|
|
128
114
|
// Build rich inject output
|
|
129
115
|
const metaStmt = db.prepare(
|
|
130
|
-
'SELECT slug, description, category, title FROM mindlore_fts WHERE path = ?'
|
|
116
|
+
'SELECT slug, description, category, title, tags FROM mindlore_fts WHERE path = ?'
|
|
131
117
|
);
|
|
132
118
|
|
|
133
119
|
const output = [];
|
|
@@ -146,8 +132,9 @@ function main() {
|
|
|
146
132
|
const description = meta.description || '';
|
|
147
133
|
|
|
148
134
|
const headingStr = headings.length > 0 ? `\nBasliklar: ${headings.join(', ')}` : '';
|
|
135
|
+
const tagsStr = meta.tags ? `\nTags: ${meta.tags}` : '';
|
|
149
136
|
output.push(
|
|
150
|
-
`[Mindlore: ${category}/${title}] ${description}\nDosya: ${relativePath}${headingStr}`
|
|
137
|
+
`[Mindlore: ${category}/${title}] ${description}\nDosya: ${relativePath}${tagsStr}${headingStr}`
|
|
151
138
|
);
|
|
152
139
|
}
|
|
153
140
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
|
+
const { execSync } = require('child_process');
|
|
14
15
|
const { findMindloreDir } = require('./lib/mindlore-common.cjs');
|
|
15
16
|
|
|
16
17
|
function formatDate(date) {
|
|
@@ -22,6 +23,47 @@ function formatDate(date) {
|
|
|
22
23
|
return `${y}-${m}-${d}-${h}${min}`;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
function getRecentGitChanges() {
|
|
27
|
+
try {
|
|
28
|
+
const raw = execSync('git diff --name-only HEAD~5..HEAD 2>/dev/null', {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
timeout: 5000,
|
|
31
|
+
}).trim();
|
|
32
|
+
if (!raw) return [];
|
|
33
|
+
return raw.split('\n').filter(Boolean).slice(0, 20);
|
|
34
|
+
} catch (_err) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getRecentCommits() {
|
|
40
|
+
try {
|
|
41
|
+
const raw = execSync('git log --oneline -5 2>/dev/null', {
|
|
42
|
+
encoding: 'utf8',
|
|
43
|
+
timeout: 5000,
|
|
44
|
+
}).trim();
|
|
45
|
+
if (!raw) return [];
|
|
46
|
+
return raw.split('\n').filter(Boolean);
|
|
47
|
+
} catch (_err) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getSessionReads(baseDir) {
|
|
53
|
+
const readsPath = path.join(baseDir, 'diary', '_session-reads.json');
|
|
54
|
+
if (!fs.existsSync(readsPath)) return null;
|
|
55
|
+
try {
|
|
56
|
+
const data = JSON.parse(fs.readFileSync(readsPath, 'utf8'));
|
|
57
|
+
const count = Object.keys(data).length;
|
|
58
|
+
const repeats = Object.values(data).filter((v) => v > 1).length;
|
|
59
|
+
// Clean up session file
|
|
60
|
+
fs.unlinkSync(readsPath);
|
|
61
|
+
return { count, repeats };
|
|
62
|
+
} catch (_err) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
25
67
|
function main() {
|
|
26
68
|
const baseDir = findMindloreDir();
|
|
27
69
|
if (!baseDir) return;
|
|
@@ -38,7 +80,12 @@ function main() {
|
|
|
38
80
|
// Don't overwrite existing delta (idempotent)
|
|
39
81
|
if (fs.existsSync(deltaPath)) return;
|
|
40
82
|
|
|
41
|
-
|
|
83
|
+
// Gather structured data
|
|
84
|
+
const commits = getRecentCommits();
|
|
85
|
+
const changedFiles = getRecentGitChanges();
|
|
86
|
+
const reads = getSessionReads(baseDir);
|
|
87
|
+
|
|
88
|
+
const sections = [
|
|
42
89
|
'---',
|
|
43
90
|
`slug: delta-${dateStr}`,
|
|
44
91
|
'type: diary',
|
|
@@ -48,14 +95,33 @@ function main() {
|
|
|
48
95
|
`# Session Delta — ${dateStr}`,
|
|
49
96
|
'',
|
|
50
97
|
`Session ended: ${now.toISOString()}`,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// Commits section
|
|
101
|
+
sections.push('', '## Commits');
|
|
102
|
+
if (commits.length > 0) {
|
|
103
|
+
for (const c of commits) sections.push(`- ${c}`);
|
|
104
|
+
} else {
|
|
105
|
+
sections.push('- _(no commits)_');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Changed files section
|
|
109
|
+
sections.push('', '## Changed Files');
|
|
110
|
+
if (changedFiles.length > 0) {
|
|
111
|
+
for (const f of changedFiles) sections.push(`- ${f}`);
|
|
112
|
+
} else {
|
|
113
|
+
sections.push('- _(no file changes)_');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Read stats (from read-guard, if active)
|
|
117
|
+
if (reads) {
|
|
118
|
+
sections.push('', '## Read Stats');
|
|
119
|
+
sections.push(`- ${reads.count} files read, ${reads.repeats} repeated reads`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
sections.push('');
|
|
57
123
|
|
|
58
|
-
fs.writeFileSync(deltaPath,
|
|
124
|
+
fs.writeFileSync(deltaPath, sections.join('\n'), 'utf8');
|
|
59
125
|
|
|
60
126
|
// Append to log.md
|
|
61
127
|
const logPath = path.join(baseDir, 'log.md');
|
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindlore",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "AI-native knowledge system for Claude Code",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
7
|
-
"mindlore": "scripts/init.
|
|
7
|
+
"mindlore": "dist/scripts/init.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
12
|
+
"pretest": "npm run build",
|
|
10
13
|
"test": "jest --config jest.config.cjs",
|
|
11
14
|
"lint": "eslint -c eslint.config.cjs scripts/ hooks/ tests/",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
+
"typecheck": "tsc --noEmit",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"health": "node dist/scripts/mindlore-health-check.js",
|
|
18
|
+
"index": "node dist/scripts/mindlore-fts5-index.js",
|
|
19
|
+
"search": "node dist/scripts/mindlore-fts5-search.js"
|
|
15
20
|
},
|
|
16
21
|
"keywords": [
|
|
17
22
|
"claude-code",
|
|
@@ -40,12 +45,19 @@
|
|
|
40
45
|
"better-sqlite3": "^11.0.0"
|
|
41
46
|
},
|
|
42
47
|
"devDependencies": {
|
|
48
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
49
|
+
"@types/jest": "^30.0.0",
|
|
50
|
+
"@types/node": "^25.6.0",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
52
|
+
"@typescript-eslint/parser": "^8.58.1",
|
|
43
53
|
"eslint": "^9.0.0",
|
|
54
|
+
"globals": "^15.0.0",
|
|
44
55
|
"jest": "^29.7.0",
|
|
45
|
-
"
|
|
56
|
+
"ts-jest": "^29.4.9",
|
|
57
|
+
"typescript": "^6.0.2"
|
|
46
58
|
},
|
|
47
59
|
"files": [
|
|
48
|
-
"
|
|
60
|
+
"dist/",
|
|
49
61
|
"hooks/",
|
|
50
62
|
"skills/",
|
|
51
63
|
"templates/",
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindlore",
|
|
3
3
|
"description": "AI-native knowledge system for Claude Code. Persistent, searchable, evolving knowledge base with FTS5.",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"skills": [
|
|
6
6
|
{
|
|
7
7
|
"name": "mindlore-ingest",
|
|
@@ -11,7 +11,22 @@
|
|
|
11
11
|
{
|
|
12
12
|
"name": "mindlore-health",
|
|
13
13
|
"path": "skills/mindlore-health/SKILL.md",
|
|
14
|
-
"description": "Run
|
|
14
|
+
"description": "Run 18-point structural health check on .mindlore/ knowledge base"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "mindlore-query",
|
|
18
|
+
"path": "skills/mindlore-query/SKILL.md",
|
|
19
|
+
"description": "Search, ask, stats, brief — compounding knowledge pipeline"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "mindlore-log",
|
|
23
|
+
"path": "skills/mindlore-log/SKILL.md",
|
|
24
|
+
"description": "Session logging, pattern extraction, wiki updates"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "mindlore-decide",
|
|
28
|
+
"path": "skills/mindlore-decide/SKILL.md",
|
|
29
|
+
"description": "Record and list decisions with context, alternatives, rationale"
|
|
15
30
|
}
|
|
16
31
|
],
|
|
17
32
|
"hooks": [
|
|
@@ -23,6 +38,10 @@
|
|
|
23
38
|
"event": "UserPromptSubmit",
|
|
24
39
|
"script": "hooks/mindlore-search.cjs"
|
|
25
40
|
},
|
|
41
|
+
{
|
|
42
|
+
"event": "UserPromptSubmit",
|
|
43
|
+
"script": "hooks/mindlore-decision-detector.cjs"
|
|
44
|
+
},
|
|
26
45
|
{
|
|
27
46
|
"event": "FileChanged",
|
|
28
47
|
"script": "hooks/mindlore-index.cjs"
|
|
@@ -42,6 +61,11 @@
|
|
|
42
61
|
{
|
|
43
62
|
"event": "PostCompact",
|
|
44
63
|
"script": "hooks/mindlore-post-compact.cjs"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"event": "PreToolUse",
|
|
67
|
+
"script": "hooks/mindlore-read-guard.cjs",
|
|
68
|
+
"if": "Read"
|
|
45
69
|
}
|
|
46
70
|
]
|
|
47
71
|
}
|