mindlore 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -2
- package/dist/scripts/fetch-raw.d.ts +2 -0
- package/dist/scripts/fetch-raw.d.ts.map +1 -0
- package/dist/scripts/fetch-raw.js +124 -0
- package/dist/scripts/fetch-raw.js.map +1 -0
- package/dist/scripts/lib/constants.d.ts +2 -0
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +13 -4
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/db-helpers.d.ts +12 -2
- package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
- package/dist/scripts/lib/db-helpers.js +36 -0
- package/dist/scripts/lib/db-helpers.js.map +1 -1
- package/dist/scripts/lib/hybrid-search.d.ts +0 -2
- package/dist/scripts/lib/hybrid-search.d.ts.map +1 -1
- package/dist/scripts/lib/hybrid-search.js +7 -1
- package/dist/scripts/lib/hybrid-search.js.map +1 -1
- package/dist/scripts/lib/migrations-v052.d.ts +3 -0
- package/dist/scripts/lib/migrations-v052.d.ts.map +1 -0
- package/dist/scripts/lib/migrations-v052.js +23 -0
- package/dist/scripts/lib/migrations-v052.js.map +1 -0
- package/dist/scripts/lib/skeleton.d.ts +2 -0
- package/dist/scripts/lib/skeleton.d.ts.map +1 -0
- package/dist/scripts/lib/skeleton.js +99 -0
- package/dist/scripts/lib/skeleton.js.map +1 -0
- package/dist/scripts/lib/skill-memory.d.ts +13 -0
- package/dist/scripts/lib/skill-memory.d.ts.map +1 -0
- package/dist/scripts/lib/skill-memory.js +94 -0
- package/dist/scripts/lib/skill-memory.js.map +1 -0
- package/dist/scripts/mindlore-fts5-index.js +2 -1
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-health-check.d.ts +1 -1
- package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
- package/dist/scripts/mindlore-health-check.js +110 -142
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/tests/catch-up.test.d.ts +2 -0
- package/dist/tests/catch-up.test.d.ts.map +1 -0
- package/dist/tests/catch-up.test.js +88 -0
- package/dist/tests/catch-up.test.js.map +1 -0
- package/dist/tests/episode-file.test.js +9 -6
- package/dist/tests/episode-file.test.js.map +1 -1
- package/dist/tests/fetch-raw.test.d.ts +2 -0
- package/dist/tests/fetch-raw.test.d.ts.map +1 -0
- package/dist/tests/fetch-raw.test.js +43 -0
- package/dist/tests/fetch-raw.test.js.map +1 -0
- package/dist/tests/resolve-hook-common.test.d.ts +2 -0
- package/dist/tests/resolve-hook-common.test.d.ts.map +1 -0
- package/dist/tests/resolve-hook-common.test.js +30 -0
- package/dist/tests/resolve-hook-common.test.js.map +1 -0
- package/dist/tests/search-offload.test.d.ts +2 -0
- package/dist/tests/search-offload.test.d.ts.map +1 -0
- package/dist/tests/search-offload.test.js +34 -0
- package/dist/tests/search-offload.test.js.map +1 -0
- package/dist/tests/skeleton.test.d.ts +2 -0
- package/dist/tests/skeleton.test.d.ts.map +1 -0
- package/dist/tests/skeleton.test.js +116 -0
- package/dist/tests/skeleton.test.js.map +1 -0
- package/dist/tests/skill-memory-api.test.d.ts +2 -0
- package/dist/tests/skill-memory-api.test.d.ts.map +1 -0
- package/dist/tests/skill-memory-api.test.js +62 -0
- package/dist/tests/skill-memory-api.test.js.map +1 -0
- package/dist/tests/skill-memory.test.d.ts +2 -0
- package/dist/tests/skill-memory.test.d.ts.map +1 -0
- package/dist/tests/skill-memory.test.js +67 -0
- package/dist/tests/skill-memory.test.js.map +1 -0
- package/dist/tests/wiki-lint.test.d.ts +2 -0
- package/dist/tests/wiki-lint.test.d.ts.map +1 -0
- package/dist/tests/wiki-lint.test.js +47 -0
- package/dist/tests/wiki-lint.test.js.map +1 -0
- package/hooks/lib/mindlore-common.cjs +24 -5
- package/hooks/mindlore-cwd-changed.cjs +2 -2
- package/hooks/mindlore-decision-detector.cjs +2 -2
- package/hooks/mindlore-dont-repeat.cjs +2 -2
- package/hooks/mindlore-fts5-sync.cjs +2 -2
- package/hooks/mindlore-index.cjs +60 -2
- package/hooks/mindlore-model-router.cjs +2 -2
- package/hooks/mindlore-post-compact.cjs +2 -2
- package/hooks/mindlore-post-read.cjs +2 -2
- package/hooks/mindlore-pre-compact.cjs +2 -2
- package/hooks/mindlore-read-guard.cjs +15 -3
- package/hooks/mindlore-research-guard.cjs +2 -2
- package/hooks/mindlore-search.cjs +20 -2
- package/hooks/mindlore-session-end.cjs +1 -1
- package/package.json +3 -2
- package/plugin.json +29 -2
- package/skills/mindlore-diary/SKILL.md +76 -0
- package/skills/mindlore-ingest/SKILL.md +41 -49
- package/skills/mindlore-log/SKILL.md +3 -143
- package/skills/mindlore-reflect/SKILL.md +104 -0
- package/templates/config.json +1 -1
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const os_1 = __importDefault(require("os"));
|
|
9
|
+
const mindlore_health_check_js_1 = require("../scripts/mindlore-health-check.js");
|
|
10
|
+
describe('wiki lint (contradiction detection)', () => {
|
|
11
|
+
let tmpDir;
|
|
12
|
+
let sourcesDir;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'mindlore-wikilint-'));
|
|
15
|
+
sourcesDir = path_1.default.join(tmpDir, 'sources');
|
|
16
|
+
fs_1.default.mkdirSync(sourcesDir, { recursive: true });
|
|
17
|
+
});
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
20
|
+
});
|
|
21
|
+
it('detects conflicting numeric claims with same tag', () => {
|
|
22
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'a.md'), '---\nslug: a\ntype: source\ntags: [fts5]\n---\nFTS5 has 10 columns.', 'utf8');
|
|
23
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'b.md'), '---\nslug: b\ntype: source\ntags: [fts5]\n---\nFTS5 uses 9 columns.', 'utf8');
|
|
24
|
+
const warnings = (0, mindlore_health_check_js_1.detectWikiContradictions)(tmpDir);
|
|
25
|
+
expect(warnings.length).toBeGreaterThan(0);
|
|
26
|
+
expect(warnings[0]).toMatch(/conflicting values/);
|
|
27
|
+
expect(warnings[0]).toMatch(/10.*9|9.*10/);
|
|
28
|
+
});
|
|
29
|
+
it('no contradiction when values match', () => {
|
|
30
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'a.md'), '---\nslug: a\ntype: source\ntags: [fts5]\n---\nFTS5 has 11 columns.', 'utf8');
|
|
31
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'b.md'), '---\nslug: b\ntype: source\ntags: [fts5]\n---\nFTS5 uses 11 columns.', 'utf8');
|
|
32
|
+
const warnings = (0, mindlore_health_check_js_1.detectWikiContradictions)(tmpDir);
|
|
33
|
+
expect(warnings.length).toBe(0);
|
|
34
|
+
});
|
|
35
|
+
it('ignores files with no tags', () => {
|
|
36
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'a.md'), '---\nslug: a\ntype: source\n---\nFTS5 has 10 columns.', 'utf8');
|
|
37
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'b.md'), '---\nslug: b\ntype: source\n---\nFTS5 uses 9 columns.', 'utf8');
|
|
38
|
+
const warnings = (0, mindlore_health_check_js_1.detectWikiContradictions)(tmpDir);
|
|
39
|
+
expect(warnings.length).toBe(0);
|
|
40
|
+
});
|
|
41
|
+
it('no false positive when only one file has a tag', () => {
|
|
42
|
+
fs_1.default.writeFileSync(path_1.default.join(sourcesDir, 'a.md'), '---\nslug: a\ntype: source\ntags: [fts5]\n---\nFTS5 has 10 columns.', 'utf8');
|
|
43
|
+
const warnings = (0, mindlore_health_check_js_1.detectWikiContradictions)(tmpDir);
|
|
44
|
+
expect(warnings.length).toBe(0);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=wiki-lint.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiki-lint.test.js","sourceRoot":"","sources":["../../tests/wiki-lint.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -310,7 +310,7 @@ CREATE TABLE IF NOT EXISTS episodes (
|
|
|
310
310
|
/**
|
|
311
311
|
* Valid episode kinds. CO-EVOLUTION: mirrors EPISODE_KINDS in scripts/lib/episodes.ts
|
|
312
312
|
*/
|
|
313
|
-
// ~
|
|
313
|
+
// ~625 tokens context budget for multi-session inject (~4 chars/token)
|
|
314
314
|
const MULTI_SESSION_TOKEN_CAP_CHARS = 2500;
|
|
315
315
|
|
|
316
316
|
const EPISODE_KINDS_CJS = ['session', 'decision', 'event', 'preference', 'learning', 'friction', 'discovery', 'nomination'];
|
|
@@ -554,7 +554,7 @@ const STOP_WORDS = new Set([
|
|
|
554
554
|
'evet', 'hayir', 'tamam', 'ok', 'oldu', 'olur', 'dur',
|
|
555
555
|
'simdi', 'sonra', 'once', 'hemen', 'biraz',
|
|
556
556
|
'lan', 'ya', 'ki', 'abi', 'hadi', 'hey', 'selam',
|
|
557
|
-
'olarak', 'olan', 'gibi', 'kadar', 'daha', 'cok',
|
|
557
|
+
'olarak', 'olan', 'gibi', 'kadar', 'daha', 'cok',
|
|
558
558
|
'bunu', 'buna', 'icinde', 'uzerinde', 'arasinda',
|
|
559
559
|
'sonucu', 'tarafindan', 'zaten', 'gayet',
|
|
560
560
|
'acaba', 'nedir', 'midir', 'mudur',
|
|
@@ -590,8 +590,15 @@ function sanitizeKeyword(kw) {
|
|
|
590
590
|
return clean.length >= 2 ? `"${clean}"` : null;
|
|
591
591
|
}
|
|
592
592
|
|
|
593
|
-
//
|
|
594
|
-
const SHARED_EXPORT_DIRS =
|
|
593
|
+
// Derive from compiled constants — single source of truth
|
|
594
|
+
const SHARED_EXPORT_DIRS = (() => {
|
|
595
|
+
try {
|
|
596
|
+
const { DIRECTORIES } = require('../../dist/scripts/lib/constants.js');
|
|
597
|
+
return [...DIRECTORIES, 'memory'];
|
|
598
|
+
} catch {
|
|
599
|
+
return ['raw', 'sources', 'domains', 'analyses', 'insights', 'connections', 'learnings', 'diary', 'decisions', 'memory'];
|
|
600
|
+
}
|
|
601
|
+
})();
|
|
595
602
|
|
|
596
603
|
function resolveWin32Bin(name) {
|
|
597
604
|
if (process.platform === 'win32') {
|
|
@@ -604,6 +611,16 @@ function resolveWin32Bin(name) {
|
|
|
604
611
|
return name;
|
|
605
612
|
}
|
|
606
613
|
|
|
614
|
+
// Import from compiled TS — single source of truth
|
|
615
|
+
const extractSkeleton = (() => {
|
|
616
|
+
try {
|
|
617
|
+
return require('../../dist/scripts/lib/skeleton.js').extractSkeleton;
|
|
618
|
+
} catch {
|
|
619
|
+
// Fallback: identity function if dist not built
|
|
620
|
+
return (content) => content;
|
|
621
|
+
}
|
|
622
|
+
})();
|
|
623
|
+
|
|
607
624
|
module.exports = {
|
|
608
625
|
MINDLORE_DIR,
|
|
609
626
|
GLOBAL_MINDLORE_DIR,
|
|
@@ -656,6 +673,8 @@ module.exports = {
|
|
|
656
673
|
// Shared helpers (v0.5.1)
|
|
657
674
|
SHARED_EXPORT_DIRS,
|
|
658
675
|
resolveWin32Bin,
|
|
676
|
+
// Skeleton compression (v0.5.2)
|
|
677
|
+
extractSkeleton,
|
|
659
678
|
};
|
|
660
679
|
|
|
661
680
|
/**
|
|
@@ -712,7 +731,7 @@ function hookLog(hook, level, message) {
|
|
|
712
731
|
msg: message,
|
|
713
732
|
pid: process.pid,
|
|
714
733
|
});
|
|
715
|
-
// Rotate if file exceeds threshold
|
|
734
|
+
// Rotate if file exceeds threshold (at most once per hook — each runs as separate process)
|
|
716
735
|
try {
|
|
717
736
|
const stat = fs.statSync(logFile);
|
|
718
737
|
if (stat.size > HOOK_LOG_MAX_BYTES) {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const path = require('path');
|
|
18
|
-
const { findMindloreDir, globalDir } = require('./lib/mindlore-common.cjs');
|
|
18
|
+
const { findMindloreDir, globalDir, hookLog } = require('./lib/mindlore-common.cjs');
|
|
19
19
|
|
|
20
20
|
function main() {
|
|
21
21
|
const cwd = process.cwd();
|
|
@@ -54,4 +54,4 @@ function main() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
main();
|
|
57
|
+
try { main(); } catch (err) { hookLog('cwd-changed', 'error', err?.message ?? String(err)); }
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* Does NOT block (exit 0) — advisory only.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const { findMindloreDir, readHookStdin } = require('./lib/mindlore-common.cjs');
|
|
12
|
+
const { findMindloreDir, readHookStdin, hookLog } = require('./lib/mindlore-common.cjs');
|
|
13
13
|
|
|
14
14
|
const SIGNALS_TR = [
|
|
15
15
|
'karar verdik', 'karar verildi', 'kararlastirdik', 'kararlaştırdık',
|
|
@@ -48,4 +48,4 @@ function main() {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
main();
|
|
51
|
+
try { main(); } catch (err) { hookLog('decision-detector', 'error', err?.message ?? String(err)); }
|
|
@@ -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, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
21
|
+
const { findMindloreDir, getProjectName, hookLog } = require('./lib/mindlore-common.cjs');
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* File-persisted pattern cache — survives across process invocations.
|
|
@@ -219,4 +219,4 @@ function main() {
|
|
|
219
219
|
});
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
main();
|
|
222
|
+
try { main(); } catch (err) { hookLog('dont-repeat', 'error', err?.message ?? String(err)); }
|
|
@@ -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, getActiveMindloreDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
16
|
+
const { MINDLORE_DIR, DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName, hookLog } = require('./lib/mindlore-common.cjs');
|
|
17
17
|
|
|
18
18
|
function main() {
|
|
19
19
|
const filePath = readHookStdin(['path', 'file_path']);
|
|
@@ -75,4 +75,4 @@ function main() {
|
|
|
75
75
|
// process.stdout.write kaldırıldı (kimse görmüyor)
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
main();
|
|
78
|
+
try { main(); } catch (err) { hookLog('fts5-sync', 'error', err?.message ?? String(err)); }
|
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, getProjectName, globalDir } = require('./lib/mindlore-common.cjs');
|
|
13
|
+
const { MINDLORE_DIR, DB_NAME, SKIP_FILES, sha256, openDatabase, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getProjectName, globalDir, hookLog } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
function main() {
|
|
16
16
|
const filePath = readHookStdin(['path', 'file_path']);
|
|
@@ -32,7 +32,6 @@ function main() {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const fileName = path.basename(filePath);
|
|
35
|
-
if (SKIP_FILES.has(fileName)) return;
|
|
36
35
|
|
|
37
36
|
// Find the .mindlore dir from the file path
|
|
38
37
|
const mindloreIdx = filePath.indexOf(MINDLORE_DIR);
|
|
@@ -41,6 +40,14 @@ function main() {
|
|
|
41
40
|
|
|
42
41
|
if (!fs.existsSync(dbPath)) return;
|
|
43
42
|
|
|
43
|
+
// Catch-up scan: when INDEX.md or log.md triggers, index recently-modified files
|
|
44
|
+
if (['INDEX.md', 'log.md'].includes(fileName)) {
|
|
45
|
+
catchUpScan(baseDir, dbPath);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (SKIP_FILES.has(fileName)) return;
|
|
50
|
+
|
|
44
51
|
if (!fs.existsSync(filePath)) {
|
|
45
52
|
// File was deleted — remove from index
|
|
46
53
|
const db = openDatabase(dbPath);
|
|
@@ -160,4 +167,55 @@ function indexCcMemory(filePath) {
|
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
169
|
|
|
170
|
+
function catchUpScan(baseDir, dbPath) {
|
|
171
|
+
const CATCH_UP_DIRS = ['raw', 'sources', 'analyses', 'diary'];
|
|
172
|
+
const fiveMinAgo = Date.now() - 5 * 60 * 1000;
|
|
173
|
+
|
|
174
|
+
const db = openDatabase(dbPath);
|
|
175
|
+
if (!db) return;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
let indexed = 0;
|
|
179
|
+
for (const dir of CATCH_UP_DIRS) {
|
|
180
|
+
const dirPath = path.join(baseDir, dir);
|
|
181
|
+
if (!fs.existsSync(dirPath)) continue;
|
|
182
|
+
|
|
183
|
+
const files = fs.readdirSync(dirPath).filter(f => f.endsWith('.md'));
|
|
184
|
+
for (const file of files) {
|
|
185
|
+
const filePath = path.join(dirPath, file);
|
|
186
|
+
const stat = fs.statSync(filePath);
|
|
187
|
+
if (stat.mtimeMs < fiveMinAgo) continue;
|
|
188
|
+
|
|
189
|
+
const content = fs.readFileSync(filePath, 'utf8').replace(/\r\n/g, '\n');
|
|
190
|
+
const hash = sha256(content);
|
|
191
|
+
|
|
192
|
+
const existing = db.prepare('SELECT content_hash FROM file_hashes WHERE path = ?').get(filePath);
|
|
193
|
+
if (existing && existing.content_hash === hash) continue;
|
|
194
|
+
|
|
195
|
+
const { meta, body } = parseFrontmatter(content);
|
|
196
|
+
const ftsData = extractFtsMetadata(meta, body, filePath, baseDir);
|
|
197
|
+
|
|
198
|
+
const update = db.transaction(() => {
|
|
199
|
+
db.prepare('DELETE FROM mindlore_fts WHERE path = ?').run(filePath);
|
|
200
|
+
insertFtsRow(db, { path: filePath, ...ftsData, project: getProjectName() });
|
|
201
|
+
db.prepare(
|
|
202
|
+
`INSERT INTO file_hashes (path, content_hash, last_indexed)
|
|
203
|
+
VALUES (?, ?, ?)
|
|
204
|
+
ON CONFLICT(path) DO UPDATE SET
|
|
205
|
+
content_hash = excluded.content_hash,
|
|
206
|
+
last_indexed = excluded.last_indexed`
|
|
207
|
+
).run(filePath, hash, new Date().toISOString());
|
|
208
|
+
});
|
|
209
|
+
update();
|
|
210
|
+
indexed++;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (indexed > 0) {
|
|
214
|
+
hookLog(`catch-up: ${indexed} file(s) indexed`);
|
|
215
|
+
}
|
|
216
|
+
} finally {
|
|
217
|
+
db.close();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
163
221
|
main();
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const fs = require('fs');
|
|
9
|
-
const { findMindloreDir, readConfig, DEFAULT_MODELS } = require('./lib/mindlore-common.cjs');
|
|
9
|
+
const { findMindloreDir, readConfig, DEFAULT_MODELS, hookLog } = require('./lib/mindlore-common.cjs');
|
|
10
10
|
|
|
11
11
|
const SKILL_KEYS = Object.keys(DEFAULT_MODELS).filter((k) => k !== 'default');
|
|
12
12
|
const MARKER_REGEX = new RegExp(`\\[mindlore:(${SKILL_KEYS.join('|')})\\]`);
|
|
@@ -51,4 +51,4 @@ function main() {
|
|
|
51
51
|
process.stdout.write(JSON.stringify(output));
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
main();
|
|
54
|
+
try { main(); } catch (err) { hookLog('model-router', 'error', err?.message ?? String(err)); }
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { findMindloreDir, getLatestDelta } = require('./lib/mindlore-common.cjs');
|
|
17
|
+
const { findMindloreDir, getLatestDelta, hookLog } = require('./lib/mindlore-common.cjs');
|
|
18
18
|
|
|
19
19
|
function main() {
|
|
20
20
|
const baseDir = findMindloreDir();
|
|
@@ -43,4 +43,4 @@ function main() {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
main();
|
|
46
|
+
try { main(); } catch (err) { hookLog('post-compact', 'error', err?.message ?? String(err)); }
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
const fs = require('fs');
|
|
15
15
|
const path = require('path');
|
|
16
|
-
const { findMindloreDir, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
16
|
+
const { findMindloreDir, getProjectName, hookLog } = 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']);
|
|
@@ -103,4 +103,4 @@ function main() {
|
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
main();
|
|
106
|
+
try { main(); } catch (err) { hookLog('post-read', 'error', err?.message ?? String(err)); }
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
const fs = require('fs');
|
|
13
13
|
const path = require('path');
|
|
14
|
-
const { findMindloreDir } = require('./lib/mindlore-common.cjs');
|
|
14
|
+
const { findMindloreDir, hookLog } = require('./lib/mindlore-common.cjs');
|
|
15
15
|
|
|
16
16
|
function main() {
|
|
17
17
|
const baseDir = findMindloreDir();
|
|
@@ -45,4 +45,4 @@ function main() {
|
|
|
45
45
|
process.stdout.write('[Mindlore: pre-compact FTS5 flush complete]\n');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
main();
|
|
48
|
+
try { main(); } catch (err) { hookLog('pre-compact', 'error', err?.message ?? String(err)); }
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { findMindloreDir, readHookStdin, getProjectName } = require('./lib/mindlore-common.cjs');
|
|
17
|
+
const { findMindloreDir, readHookStdin, getProjectName, hookLog, extractSkeleton } = require('./lib/mindlore-common.cjs');
|
|
18
18
|
|
|
19
19
|
function main() {
|
|
20
20
|
const baseDir = findMindloreDir();
|
|
@@ -81,13 +81,25 @@ function main() {
|
|
|
81
81
|
// Warn on 2nd read (exit 0 = allow but warn)
|
|
82
82
|
if (count > 1) {
|
|
83
83
|
const totalWaste = tokens > 0 ? ` Toplam tekrar: ~${tokens * (count - 1)} token.` : '';
|
|
84
|
+
let skeletonSection = '';
|
|
85
|
+
try {
|
|
86
|
+
const ext = path.extname(filePath).slice(1);
|
|
87
|
+
const fileContent = fs.readFileSync(filePath, 'utf8');
|
|
88
|
+
if (fileContent.length < 500_000) {
|
|
89
|
+
const skeleton = extractSkeleton(fileContent, ext);
|
|
90
|
+
if (skeleton !== fileContent) {
|
|
91
|
+
const truncated = skeleton.length > 2000 ? skeleton.slice(0, 2000) + '\n...[truncated]' : skeleton;
|
|
92
|
+
skeletonSection = '\n\n' + truncated;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} catch (_e) { /* unreadable/binary — skip */ }
|
|
84
96
|
process.stdout.write(JSON.stringify({
|
|
85
97
|
hookSpecificOutput: {
|
|
86
98
|
hookEventName: 'PreToolUse',
|
|
87
|
-
additionalContext: `[Mindlore: ${basename}${tokenInfo} bu session'da ${count}. kez okunuyor.${totalWaste} Bir sonraki okuma engellenecek — Edit gerekiyorsa simdi yap.]`
|
|
99
|
+
additionalContext: `[Mindlore: ${basename}${tokenInfo} bu session'da ${count}. kez okunuyor.${totalWaste} Bir sonraki okuma engellenecek — Edit gerekiyorsa simdi yap.]${skeletonSection}`
|
|
88
100
|
}
|
|
89
101
|
}));
|
|
90
102
|
}
|
|
91
103
|
}
|
|
92
104
|
|
|
93
|
-
main();
|
|
105
|
+
try { main(); } catch (err) { hookLog('read-guard', 'error', err?.message ?? String(err)); }
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { getAllDbs, requireDatabase, extractKeywords, sanitizeKeyword } = require('./lib/mindlore-common.cjs');
|
|
17
|
+
const { getAllDbs, requireDatabase, extractKeywords, sanitizeKeyword, hookLog } = require('./lib/mindlore-common.cjs');
|
|
18
18
|
|
|
19
19
|
// Keywords that signal a research/web-search intent in agent prompts
|
|
20
20
|
// Note: entries with dots/stars are regex patterns, rest are literals
|
|
@@ -141,4 +141,4 @@ function main() {
|
|
|
141
141
|
process.stdout.write(JSON.stringify(output));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
main();
|
|
144
|
+
try { main(); } catch (err) { hookLog('research-guard', 'error', err?.message ?? String(err)); }
|
|
@@ -154,7 +154,7 @@ function main() {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
// Sort: most keyword hits first, then best rank
|
|
157
|
-
allScores.sort((a, b) => b.hits - a.hits || a.
|
|
157
|
+
allScores.sort((a, b) => b.hits - a.hits || a.rank - b.rank);
|
|
158
158
|
|
|
159
159
|
// Deduplicate by full path (project version wins — appears first in sort)
|
|
160
160
|
const seen = new Set();
|
|
@@ -225,7 +225,25 @@ function main() {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
if (output.length > 0) {
|
|
228
|
-
|
|
228
|
+
let outputStr = output.join('\n\n') + '\n';
|
|
229
|
+
|
|
230
|
+
const OFFLOAD_THRESHOLD = 10240; // 10KB
|
|
231
|
+
if (outputStr.length > OFFLOAD_THRESHOLD) {
|
|
232
|
+
const baseDir = path.dirname(dbPaths[0]);
|
|
233
|
+
const tmpDir = path.join(baseDir, 'tmp');
|
|
234
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
235
|
+
const fileName = `search-${Date.now()}.md`;
|
|
236
|
+
const filePath = path.join(tmpDir, fileName);
|
|
237
|
+
fs.writeFileSync(filePath, outputStr, 'utf8');
|
|
238
|
+
|
|
239
|
+
const summary = outputStr.slice(0, 500).replace(/\n/g, ' ').trim();
|
|
240
|
+
outputStr = `[Mindlore Search: ${outputStr.length} chars offloaded to ${filePath}]\n` +
|
|
241
|
+
`Summary: ${summary}...\n` +
|
|
242
|
+
`[Read full results: ${filePath}]`;
|
|
243
|
+
hookLog('search', 'info', 'offloaded to tmp/ (' + outputStr.length + ' chars)');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
process.stdout.write(outputStr);
|
|
229
247
|
}
|
|
230
248
|
}
|
|
231
249
|
|
|
@@ -291,7 +291,7 @@ function writeEpisodeFile(baseDir, project, commits, changedFiles, reads) {
|
|
|
291
291
|
const projDir = path.join(baseDir, 'diary', project || 'unknown');
|
|
292
292
|
if (!fs.existsSync(projDir)) fs.mkdirSync(projDir, { recursive: true });
|
|
293
293
|
|
|
294
|
-
const now = new Date();
|
|
294
|
+
const now = process.env.MINDLORE_EPISODE_TS ? new Date(process.env.MINDLORE_EPISODE_TS) : new Date();
|
|
295
295
|
const ts = formatDate(now);
|
|
296
296
|
const filePath = path.join(projDir, `episode-${ts}.md`);
|
|
297
297
|
if (fs.existsSync(filePath)) return; // idempotent
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindlore",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "AI-native knowledge system for Claude Code",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"health": "node dist/scripts/mindlore-health-check.js",
|
|
18
18
|
"index": "node dist/scripts/mindlore-fts5-index.js",
|
|
19
19
|
"search": "node dist/scripts/mindlore-fts5-search.js",
|
|
20
|
-
"quality": "node dist/scripts/quality-populate.js"
|
|
20
|
+
"quality": "node dist/scripts/quality-populate.js",
|
|
21
|
+
"fetch-raw": "node dist/scripts/fetch-raw.js"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
|
23
24
|
"claude-code",
|
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.5.
|
|
4
|
+
"version": "0.5.2",
|
|
5
5
|
"skills": [
|
|
6
6
|
{
|
|
7
7
|
"name": "mindlore-ingest",
|
|
@@ -21,7 +21,17 @@
|
|
|
21
21
|
{
|
|
22
22
|
"name": "mindlore-log",
|
|
23
23
|
"path": "skills/mindlore-log/SKILL.md",
|
|
24
|
-
"description": "Session logging
|
|
24
|
+
"description": "Session logging and wiki updates. Modes: log (manual diary entry), status (recent sessions summary with trends), save (structured delta + log.md append + domain wiki update). For diary analysis use /mindlore-diary; for pattern extraction use /mindlore-reflect."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "mindlore-diary",
|
|
28
|
+
"path": "skills/mindlore-diary/SKILL.md",
|
|
29
|
+
"description": "LLM-powered session analysis: decisions, discoveries, frictions, learnings. Promotes episodes to semantic knowledge with 3-tier confidence. Reads/writes skill_memory for continuity."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "mindlore-reflect",
|
|
33
|
+
"path": "skills/mindlore-reflect/SKILL.md",
|
|
34
|
+
"description": "Pattern extraction from episodes: recurring decisions, frictions, discoveries. 3-tier confidence (Note/Learning/Nomination), nomination pipeline with approval flow, CLAUDE.md update proposals."
|
|
25
35
|
},
|
|
26
36
|
{
|
|
27
37
|
"name": "mindlore-decide",
|
|
@@ -39,6 +49,23 @@
|
|
|
39
49
|
"description": "Discover unexpected connections between knowledge sources — undirected exploration mode. Cross-references domains, sources, analyses, and episodes to find non-obvious relationships. Identifies: shared entities across sources, pattern convergence between domains, episodic evidence supporting or contradicting domain claims. Default scope: project + global (--scope project|global|all)."
|
|
40
50
|
}
|
|
41
51
|
],
|
|
52
|
+
"agents": [
|
|
53
|
+
{
|
|
54
|
+
"name": "mindlore-assistant",
|
|
55
|
+
"path": "agents/mindlore-assistant.md",
|
|
56
|
+
"description": "Knowledge base Q&A with hybrid search and citations"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "mindlore-researcher",
|
|
60
|
+
"path": "agents/mindlore-researcher.md",
|
|
61
|
+
"description": "Independent web research with source comparison"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "mindlore-librarian",
|
|
65
|
+
"path": "agents/mindlore-librarian.md",
|
|
66
|
+
"description": "Periodic maintenance, stale detection, health trends"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
42
69
|
"hooks": [
|
|
43
70
|
{
|
|
44
71
|
"event": "SessionStart",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mindlore-diary
|
|
3
|
+
description: LLM-powered session analysis — decisions, discoveries, frictions, learnings. Promotes episodes to semantic knowledge.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /mindlore-diary
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Determine target using `getActiveMindloreDir()` logic:
|
|
11
|
+
- If CWD has `.mindlore/` -> project scope
|
|
12
|
+
- Otherwise -> global `~/.mindlore/`
|
|
13
|
+
|
|
14
|
+
## Trigger
|
|
15
|
+
|
|
16
|
+
`/mindlore-diary` or `/mindlore-log diary`
|
|
17
|
+
|
|
18
|
+
## On Start — Read skill_memory
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
node dist/scripts/lib/skill-memory.js get mindlore-diary last_diary_date
|
|
22
|
+
```
|
|
23
|
+
If last_diary_date is today, warn: "Diary already ran today. Continue anyway?"
|
|
24
|
+
|
|
25
|
+
## Flow
|
|
26
|
+
|
|
27
|
+
1. Read active episodes: `WHERE status = 'active' AND source IN ('hook', 'diary')`
|
|
28
|
+
2. Filter by time: default last 24h, or `--days N` flag
|
|
29
|
+
3. Present summary: "Found N episodes spanning DATE1 to DATE2"
|
|
30
|
+
4. LLM analyzes episodes for semantic patterns:
|
|
31
|
+
- **Decisions:** choices made, alternatives considered
|
|
32
|
+
- **Discoveries:** new insights, broken assumptions
|
|
33
|
+
- **Frictions:** recurring blockers, errors, slowdowns
|
|
34
|
+
- **Learnings:** techniques that worked, patterns validated
|
|
35
|
+
- **Preferences:** user workflow preferences detected
|
|
36
|
+
- **Events:** notable milestones, completions
|
|
37
|
+
|
|
38
|
+
5. For each detected item, create enriched episode:
|
|
39
|
+
```sql
|
|
40
|
+
INSERT INTO episodes (summary, body, kind, source, status, project, created_at)
|
|
41
|
+
VALUES (?, ?, ?, 'diary', 'active', ?, ?)
|
|
42
|
+
```
|
|
43
|
+
Where kind = 'decision' | 'discovery' | 'friction' | 'learning' | 'preference' | 'event'
|
|
44
|
+
|
|
45
|
+
6. Output structured report:
|
|
46
|
+
```
|
|
47
|
+
-- Diary Raporu ({date}, {N} episode analiz edildi) --
|
|
48
|
+
|
|
49
|
+
Decisions ({count}):
|
|
50
|
+
- {summary}
|
|
51
|
+
|
|
52
|
+
Discoveries ({count}):
|
|
53
|
+
- {summary}
|
|
54
|
+
|
|
55
|
+
Frictions ({count}):
|
|
56
|
+
- {summary}
|
|
57
|
+
|
|
58
|
+
Learnings ({count}):
|
|
59
|
+
- {summary}
|
|
60
|
+
|
|
61
|
+
{M} yeni episode olusturuldu.
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## On End — Write skill_memory
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
node dist/scripts/lib/skill-memory.js set mindlore-diary last_diary_date "$(date -I)"
|
|
68
|
+
node dist/scripts/lib/skill-memory.js set mindlore-diary last_episode_count "{N}"
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Rules
|
|
72
|
+
|
|
73
|
+
- NEVER create episodes without user seeing the analysis first
|
|
74
|
+
- Each episode must have proper `kind` field — don't default everything to 'event'
|
|
75
|
+
- Group related items — don't create 5 episodes for the same friction
|
|
76
|
+
- Append to `log.md`: `| {date} | diary | {N} episodes created |`
|