mindlore 0.5.3 → 0.5.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 +5 -5
- package/dist/scripts/fetch-raw.js +14 -7
- package/dist/scripts/fetch-raw.js.map +1 -1
- package/dist/scripts/init.js +38 -1
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/backfill.d.ts +9 -0
- package/dist/scripts/lib/backfill.d.ts.map +1 -0
- package/dist/scripts/lib/backfill.js +74 -0
- package/dist/scripts/lib/backfill.js.map +1 -0
- package/dist/scripts/lib/constants.d.ts +1 -1
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +2 -0
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/contradiction.d.ts +7 -0
- package/dist/scripts/lib/contradiction.d.ts.map +1 -0
- package/dist/scripts/lib/contradiction.js +205 -0
- package/dist/scripts/lib/contradiction.js.map +1 -0
- package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
- package/dist/scripts/lib/db-helpers.js +7 -1
- package/dist/scripts/lib/db-helpers.js.map +1 -1
- package/dist/scripts/lib/decay.d.ts +7 -2
- package/dist/scripts/lib/decay.d.ts.map +1 -1
- package/dist/scripts/lib/decay.js +28 -5
- package/dist/scripts/lib/decay.js.map +1 -1
- package/dist/scripts/lib/git-snapshot.d.ts +3 -0
- package/dist/scripts/lib/git-snapshot.d.ts.map +1 -0
- package/dist/scripts/lib/git-snapshot.js +38 -0
- package/dist/scripts/lib/git-snapshot.js.map +1 -0
- package/dist/scripts/lib/session-payload.d.ts +19 -0
- package/dist/scripts/lib/session-payload.d.ts.map +1 -0
- package/dist/scripts/lib/session-payload.js +85 -0
- package/dist/scripts/lib/session-payload.js.map +1 -0
- package/dist/scripts/mindlore-fts5-index.js +18 -6
- package/dist/scripts/mindlore-fts5-index.js.map +1 -1
- package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
- package/dist/scripts/mindlore-health-check.js +12 -0
- package/dist/scripts/mindlore-health-check.js.map +1 -1
- package/dist/tests/backfill.test.d.ts +2 -0
- package/dist/tests/backfill.test.d.ts.map +1 -0
- package/dist/tests/backfill.test.js +127 -0
- package/dist/tests/backfill.test.js.map +1 -0
- package/dist/tests/contradiction-extended.test.d.ts +2 -0
- package/dist/tests/contradiction-extended.test.d.ts.map +1 -0
- package/dist/tests/contradiction-extended.test.js +182 -0
- package/dist/tests/contradiction-extended.test.js.map +1 -0
- package/dist/tests/decay.test.js +51 -0
- package/dist/tests/decay.test.js.map +1 -1
- package/dist/tests/fts5.test.js +181 -0
- package/dist/tests/fts5.test.js.map +1 -1
- package/dist/tests/git-snapshot.test.js +53 -10
- package/dist/tests/git-snapshot.test.js.map +1 -1
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js +3 -1
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/init.test.js +36 -3
- package/dist/tests/init.test.js.map +1 -1
- package/dist/tests/research-guard-scope.test.d.ts +2 -0
- package/dist/tests/research-guard-scope.test.d.ts.map +1 -0
- package/dist/tests/research-guard-scope.test.js +154 -0
- package/dist/tests/research-guard-scope.test.js.map +1 -0
- package/dist/tests/research-guard.test.js +60 -0
- package/dist/tests/research-guard.test.js.map +1 -1
- package/dist/tests/search-hook.test.js +37 -0
- package/dist/tests/search-hook.test.js.map +1 -1
- package/dist/tests/session-focus.test.js +86 -0
- package/dist/tests/session-focus.test.js.map +1 -1
- package/dist/tests/session-payload.test.d.ts +5 -0
- package/dist/tests/session-payload.test.d.ts.map +1 -0
- package/dist/tests/session-payload.test.js +135 -0
- package/dist/tests/session-payload.test.js.map +1 -0
- package/hooks/lib/mindlore-common.cjs +13 -7
- package/hooks/mindlore-research-guard.cjs +25 -2
- package/hooks/mindlore-search.cjs +20 -16
- package/hooks/mindlore-session-end.cjs +35 -0
- package/hooks/mindlore-session-focus.cjs +24 -35
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/templates/config.json +11 -9
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* session-payload tests — 4-section builder with token budget + cache-lock.
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const db_js_1 = require("./helpers/db.js");
|
|
12
|
+
const session_payload_js_1 = require("../scripts/lib/session-payload.js");
|
|
13
|
+
let env;
|
|
14
|
+
let db;
|
|
15
|
+
let baseDir;
|
|
16
|
+
const PROJECT = 'test-project';
|
|
17
|
+
function insertEpisode(kind, summary, opts = {}) {
|
|
18
|
+
const id = `ep-${Math.random().toString(36).slice(2, 10)}`;
|
|
19
|
+
db.prepare(`INSERT INTO episodes (id, kind, scope, project, summary, status, created_at)
|
|
20
|
+
VALUES (?, ?, 'project', ?, ?, ?, ?)`).run(id, kind, opts.project ?? PROJECT, summary, opts.status ?? 'active', opts.created_at ?? new Date().toISOString());
|
|
21
|
+
}
|
|
22
|
+
function writeDelta(filename, content) {
|
|
23
|
+
const diaryDir = path_1.default.join(baseDir, 'diary');
|
|
24
|
+
fs_1.default.mkdirSync(diaryDir, { recursive: true });
|
|
25
|
+
fs_1.default.writeFileSync(path_1.default.join(diaryDir, filename), content, 'utf8');
|
|
26
|
+
}
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
env = (0, db_js_1.createEpisodesTestEnv)('session-payload');
|
|
29
|
+
db = env.db;
|
|
30
|
+
baseDir = env.tmpDir;
|
|
31
|
+
(0, session_payload_js_1.resetCache)();
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
(0, db_js_1.destroyEpisodesTestEnv)(env);
|
|
35
|
+
});
|
|
36
|
+
describe('buildSessionPayload', () => {
|
|
37
|
+
test('produces 4 sections for a full DB', () => {
|
|
38
|
+
writeDelta('delta-2026-04-19.md', '# Session\n- Did X\n- Did Y');
|
|
39
|
+
insertEpisode('decision', 'Use TypeScript for all scripts');
|
|
40
|
+
insertEpisode('friction', 'CI pipeline is slow');
|
|
41
|
+
insertEpisode('learning', 'Always build before test');
|
|
42
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
43
|
+
expect(payload.sections).toHaveLength(4);
|
|
44
|
+
expect(payload.sections[0].label).toBe('Session');
|
|
45
|
+
expect(payload.sections[1].label).toBe('Decisions');
|
|
46
|
+
expect(payload.sections[2].label).toBe('Friction');
|
|
47
|
+
expect(payload.sections[3].label).toBe('Learnings');
|
|
48
|
+
expect(payload.totalTokens).toBeGreaterThan(0);
|
|
49
|
+
expect(payload.skipInjection).toBe(false);
|
|
50
|
+
expect(payload.contentHash).toMatch(/^[0-9a-f]{8}$/);
|
|
51
|
+
});
|
|
52
|
+
test('trims sections from end when over budget', () => {
|
|
53
|
+
writeDelta('delta-2026-04-19.md', '# Session\n- Short');
|
|
54
|
+
insertEpisode('decision', 'Short decision');
|
|
55
|
+
insertEpisode('friction', 'Short friction');
|
|
56
|
+
insertEpisode('learning', 'Short learning');
|
|
57
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT, 20);
|
|
58
|
+
expect(payload.sections.length).toBeLessThan(4);
|
|
59
|
+
expect(payload.sections[0].label).toBe('Session');
|
|
60
|
+
expect(payload.totalTokens).toBeLessThanOrEqual(20);
|
|
61
|
+
});
|
|
62
|
+
test('trim order: Learnings dropped first, then Friction, then Decisions', () => {
|
|
63
|
+
writeDelta('delta-2026-04-19.md', '# Session\n- Work');
|
|
64
|
+
insertEpisode('decision', 'Dec');
|
|
65
|
+
insertEpisode('friction', 'Fric');
|
|
66
|
+
insertEpisode('learning', 'Learn');
|
|
67
|
+
const full = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT, 99999);
|
|
68
|
+
const sessionTokens = full.sections[0].tokens;
|
|
69
|
+
const decisionTokens = full.sections[1].tokens;
|
|
70
|
+
(0, session_payload_js_1.resetCache)();
|
|
71
|
+
const budgetFor2 = sessionTokens + decisionTokens + 1;
|
|
72
|
+
const trimmed = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT, budgetFor2);
|
|
73
|
+
expect(trimmed.sections.map(s => s.label)).toEqual(['Session', 'Decisions']);
|
|
74
|
+
});
|
|
75
|
+
test('skips injection when content unchanged (cache-lock)', () => {
|
|
76
|
+
writeDelta('delta-2026-04-19.md', '# Session\n- Same content');
|
|
77
|
+
insertEpisode('decision', 'Same decision');
|
|
78
|
+
const first = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
79
|
+
expect(first.skipInjection).toBe(false);
|
|
80
|
+
const second = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
81
|
+
expect(second.skipInjection).toBe(true);
|
|
82
|
+
expect(second.contentHash).toBe(first.contentHash);
|
|
83
|
+
});
|
|
84
|
+
test('handles empty DB gracefully', () => {
|
|
85
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
86
|
+
expect(payload.sections).toHaveLength(4);
|
|
87
|
+
expect(payload.sections[0].content).toContain('No previous session data');
|
|
88
|
+
expect(payload.sections[1].content).toContain('No recent decisions');
|
|
89
|
+
expect(payload.sections[2].content).toContain('No active friction');
|
|
90
|
+
expect(payload.sections[3].content).toContain('No recent learnings');
|
|
91
|
+
expect(payload.skipInjection).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
test('handles missing diary directory', () => {
|
|
94
|
+
insertEpisode('decision', 'A decision');
|
|
95
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
96
|
+
expect(payload.sections[0].label).toBe('Session');
|
|
97
|
+
expect(payload.sections[0].content).toContain('No previous session data');
|
|
98
|
+
expect(payload.sections).toHaveLength(4);
|
|
99
|
+
});
|
|
100
|
+
test('token estimation is reasonable', () => {
|
|
101
|
+
const text = 'abcd'; // 4 chars = 1 token
|
|
102
|
+
writeDelta('delta-2026-04-19.md', `# H\n- ${text}`);
|
|
103
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
104
|
+
for (const section of payload.sections) {
|
|
105
|
+
const expectedTokens = Math.ceil(section.content.length / 4);
|
|
106
|
+
expect(section.tokens).toBe(expectedTokens);
|
|
107
|
+
}
|
|
108
|
+
const expectedTotal = payload.sections.reduce((s, sec) => s + sec.tokens, 0);
|
|
109
|
+
expect(payload.totalTokens).toBe(expectedTotal);
|
|
110
|
+
});
|
|
111
|
+
test('reads latest delta file when multiple exist', () => {
|
|
112
|
+
writeDelta('delta-2026-04-18.md', '# Old\n- Old stuff');
|
|
113
|
+
writeDelta('delta-2026-04-19.md', '# Latest\n- Latest stuff');
|
|
114
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
115
|
+
expect(payload.sections[0].content).toContain('Latest stuff');
|
|
116
|
+
expect(payload.sections[0].content).not.toContain('Old stuff');
|
|
117
|
+
});
|
|
118
|
+
test('only returns episodes for matching project', () => {
|
|
119
|
+
insertEpisode('decision', 'My project decision', { project: PROJECT });
|
|
120
|
+
insertEpisode('decision', 'Other project decision', { project: 'other-project' });
|
|
121
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT);
|
|
122
|
+
expect(payload.sections[1].content).toContain('My project decision');
|
|
123
|
+
expect(payload.sections[1].content).not.toContain('Other project decision');
|
|
124
|
+
});
|
|
125
|
+
test('Session section is always kept even when over budget', () => {
|
|
126
|
+
writeDelta('delta-2026-04-19.md', '# Session\n- Important context');
|
|
127
|
+
insertEpisode('decision', 'Dec');
|
|
128
|
+
insertEpisode('friction', 'Fric');
|
|
129
|
+
insertEpisode('learning', 'Learn');
|
|
130
|
+
const payload = (0, session_payload_js_1.buildSessionPayload)(db, baseDir, PROJECT, 1);
|
|
131
|
+
expect(payload.sections).toHaveLength(1);
|
|
132
|
+
expect(payload.sections[0].label).toBe('Session');
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=session-payload.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-payload.test.js","sourceRoot":"","sources":["../../tests/session-payload.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -186,14 +186,20 @@ function requireDatabase() {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
function openDatabase(dbPath, opts) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
db
|
|
189
|
+
try {
|
|
190
|
+
const Database = requireDatabase();
|
|
191
|
+
if (!Database) return null;
|
|
192
|
+
if (!fs.existsSync(dbPath)) return null;
|
|
193
|
+
const readonly = opts?.readonly ?? false;
|
|
194
|
+
const db = new Database(dbPath, { readonly });
|
|
195
|
+
if (!readonly) {
|
|
196
|
+
db.pragma('journal_mode = WAL');
|
|
197
|
+
db.pragma('busy_timeout = 5000');
|
|
198
|
+
}
|
|
199
|
+
return db;
|
|
200
|
+
} catch (_err) {
|
|
201
|
+
return null;
|
|
195
202
|
}
|
|
196
|
-
return db;
|
|
197
203
|
}
|
|
198
204
|
|
|
199
205
|
function getAllMdFiles(dir, skip) {
|
|
@@ -103,13 +103,36 @@ function main() {
|
|
|
103
103
|
if (toolName !== 'Agent') return;
|
|
104
104
|
|
|
105
105
|
const toolInput = input.tool_input || {};
|
|
106
|
+
|
|
107
|
+
// Only block agents with web access — let local-only agents pass
|
|
108
|
+
const WEB_CAPABLE_TYPES = ['researcher', 'general-purpose'];
|
|
109
|
+
const LOCAL_ONLY_TYPES = [
|
|
110
|
+
'Explore', 'coder', 'code-reviewer', 'Plan',
|
|
111
|
+
'bug-analyzer', 'security-reviewer', 'contrarian',
|
|
112
|
+
'scope-guardian', 'quality-gate', 'test-runner',
|
|
113
|
+
];
|
|
114
|
+
const subagentType = toolInput.subagent_type || '';
|
|
115
|
+
const description = (toolInput.description || '').toLowerCase();
|
|
116
|
+
|
|
117
|
+
// Known local-only agent → always pass
|
|
118
|
+
if (LOCAL_ONLY_TYPES.includes(subagentType)) return;
|
|
119
|
+
|
|
120
|
+
// Known web-capable agent → continue to FTS5 check
|
|
121
|
+
// Unknown or empty subagent_type → check description for research intent
|
|
122
|
+
if (subagentType && !WEB_CAPABLE_TYPES.includes(subagentType)) return;
|
|
123
|
+
|
|
124
|
+
// If no subagent_type, check description for web research intent (reuse RESEARCH_REGEX)
|
|
125
|
+
if (!subagentType && !RESEARCH_REGEX.test(description)) return;
|
|
126
|
+
|
|
106
127
|
const prompt = (toolInput.prompt || '') + ' ' + (toolInput.description || '');
|
|
107
128
|
|
|
108
129
|
// Skip mindlore internal operations and explicit overrides
|
|
109
130
|
if (EXCLUDE_REGEX.test(prompt)) return;
|
|
110
131
|
|
|
111
|
-
//
|
|
112
|
-
|
|
132
|
+
// If subagent_type is a known research type, skip prompt-level regex check
|
|
133
|
+
// Otherwise require research signals in the prompt text
|
|
134
|
+
const isKnownResearchType = WEB_CAPABLE_TYPES.includes(subagentType);
|
|
135
|
+
if (!isKnownResearchType && !RESEARCH_REGEX.test(prompt)) return;
|
|
113
136
|
|
|
114
137
|
const keywords = extractKeywords(prompt, 10);
|
|
115
138
|
if (keywords.length < 2) return;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
-
const { getAllDbs,
|
|
13
|
+
const { getAllDbs, openDatabase, extractHeadings, readHookStdin, extractKeywords, sanitizeKeyword, readConfig, loadSqliteVecCjs, hasVecTableCjs, hookLog, incrementRecallCount } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
const MAX_RESULTS = 3;
|
|
16
16
|
const MIN_QUERY_WORDS = 3;
|
|
@@ -26,12 +26,16 @@ try {
|
|
|
26
26
|
/**
|
|
27
27
|
* Search a single DB and return scored results with their baseDir.
|
|
28
28
|
*/
|
|
29
|
-
function searchDb(dbPath, keywords
|
|
29
|
+
function searchDb(dbPath, keywords) {
|
|
30
30
|
const baseDir = path.dirname(dbPath);
|
|
31
|
-
const db =
|
|
31
|
+
const db = openDatabase(dbPath, { readonly: true });
|
|
32
|
+
if (!db) return [];
|
|
32
33
|
const results = [];
|
|
33
34
|
|
|
34
35
|
// v0.5.0: Try hybrid search with synonym expansion (no embedding — hooks are sync)
|
|
36
|
+
if (!hybridSearchMod) {
|
|
37
|
+
hookLog('search', 'info', 'No hybridSearchMod — FTS5-only mode');
|
|
38
|
+
}
|
|
35
39
|
if (hybridSearchMod && loadSqliteVecCjs(db) && hasVecTableCjs(db)) {
|
|
36
40
|
try {
|
|
37
41
|
const config = readConfig(baseDir);
|
|
@@ -75,8 +79,8 @@ function searchDb(dbPath, keywords, Database) {
|
|
|
75
79
|
db.close();
|
|
76
80
|
return results;
|
|
77
81
|
}
|
|
78
|
-
} catch (
|
|
79
|
-
|
|
82
|
+
} catch (hybridErr) {
|
|
83
|
+
hookLog('search', 'warn', `Hybrid search fallback to FTS5: ${hybridErr?.message || hybridErr}`);
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
86
|
|
|
@@ -145,12 +149,9 @@ function main() {
|
|
|
145
149
|
const keywords = extractKeywords(userMessage);
|
|
146
150
|
if (keywords.length < MIN_QUERY_WORDS) return;
|
|
147
151
|
|
|
148
|
-
const Database = requireDatabase();
|
|
149
|
-
if (!Database) return;
|
|
150
|
-
|
|
151
152
|
const allScores = [];
|
|
152
153
|
for (const dbPath of dbPaths) {
|
|
153
|
-
allScores.push(...searchDb(dbPath, keywords
|
|
154
|
+
allScores.push(...searchDb(dbPath, keywords));
|
|
154
155
|
}
|
|
155
156
|
|
|
156
157
|
// Sort: most keyword hits first, then best rank
|
|
@@ -171,12 +172,14 @@ function main() {
|
|
|
171
172
|
if (relevant.length === 0) return;
|
|
172
173
|
|
|
173
174
|
try {
|
|
174
|
-
const db =
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
175
|
+
const db = openDatabase(dbPaths[0]);
|
|
176
|
+
if (db) {
|
|
177
|
+
const txn = db.transaction(() => {
|
|
178
|
+
for (const r of relevant) incrementRecallCount(db, r.path);
|
|
179
|
+
});
|
|
180
|
+
txn();
|
|
181
|
+
db.close();
|
|
182
|
+
}
|
|
180
183
|
} catch (_e) { /* graceful — never block search output */ }
|
|
181
184
|
|
|
182
185
|
// Populate headings only for final results (avoid reading extra files)
|
|
@@ -222,7 +225,8 @@ function main() {
|
|
|
222
225
|
if (relevant.length < MAX_RESULTS) {
|
|
223
226
|
for (const dbPath of dbPaths) {
|
|
224
227
|
try {
|
|
225
|
-
const db =
|
|
228
|
+
const db = openDatabase(dbPath, { readonly: true });
|
|
229
|
+
if (!db) continue;
|
|
226
230
|
const episodeResults = searchEpisodesFts(db, keywords);
|
|
227
231
|
db.close();
|
|
228
232
|
if (episodeResults.length > 0) {
|
|
@@ -46,6 +46,41 @@ if (process.argv.includes('--worker')) {
|
|
|
46
46
|
await safeRunAsync(() => writeBareEpisode(baseDir, project, commits, changedFiles, reads), 'episode');
|
|
47
47
|
await safeRunAsync(() => writeEpisodeFile(baseDir, project, commits, changedFiles, reads), 'episode-file');
|
|
48
48
|
|
|
49
|
+
// CC memory bulk sync — synchronous with timeout
|
|
50
|
+
await safeRunAsync(async () => {
|
|
51
|
+
const syncScript = path.join(__dirname, '..', 'dist', 'scripts', 'cc-memory-bulk-sync.js');
|
|
52
|
+
if (fs.existsSync(syncScript)) {
|
|
53
|
+
const nodeExe = resolveWin32Bin('node') || process.execPath;
|
|
54
|
+
const { execFileSync } = require('child_process');
|
|
55
|
+
try {
|
|
56
|
+
execFileSync(nodeExe, [syncScript, '--auto'], {
|
|
57
|
+
timeout: 10000,
|
|
58
|
+
env: { ...process.env, MINDLORE_HOME: baseDir },
|
|
59
|
+
});
|
|
60
|
+
hookLog('session-end', 'info', 'CC memory sync completed');
|
|
61
|
+
} catch (syncErr) {
|
|
62
|
+
hookLog('session-end', 'warn', `CC memory sync failed: ${syncErr?.message || syncErr}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, 'cc-memory-sync');
|
|
66
|
+
|
|
67
|
+
// Embed trigger — detached, fire-and-forget
|
|
68
|
+
await safeRunAsync(async () => {
|
|
69
|
+
const indexScript = path.join(__dirname, '..', 'dist', 'scripts', 'mindlore-fts5-index.js');
|
|
70
|
+
if (fs.existsSync(indexScript)) {
|
|
71
|
+
const nodeExe = resolveWin32Bin('node') || process.execPath;
|
|
72
|
+
const { spawn: spawnChild } = require('child_process');
|
|
73
|
+
const embedProc = spawnChild(nodeExe, [indexScript, '--embed'], {
|
|
74
|
+
detached: true,
|
|
75
|
+
stdio: 'ignore',
|
|
76
|
+
windowsHide: true,
|
|
77
|
+
env: { ...process.env, MINDLORE_HOME: baseDir },
|
|
78
|
+
});
|
|
79
|
+
embedProc.unref();
|
|
80
|
+
hookLog('session-end', 'info', 'embed subprocess spawned, pid=' + embedProc.pid);
|
|
81
|
+
}
|
|
82
|
+
}, 'embed-trigger');
|
|
83
|
+
|
|
49
84
|
// Obsidian + git-sync are independent — run in parallel
|
|
50
85
|
await Promise.allSettled([
|
|
51
86
|
safeRunAsync(() => syncObsidian(baseDir), 'obsidian'),
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
-
const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable,
|
|
13
|
+
const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, getAllMdFiles, hookLog, getProjectName, parseFrontmatter } = require('./lib/mindlore-common.cjs');
|
|
14
14
|
|
|
15
15
|
function main() {
|
|
16
16
|
const baseDir = findMindloreDir();
|
|
@@ -32,13 +32,17 @@ function main() {
|
|
|
32
32
|
try {
|
|
33
33
|
const diaryFiles = fs.readdirSync(diaryDir).filter(f => f.startsWith('delta-') && f.endsWith('.md'));
|
|
34
34
|
|
|
35
|
-
// Latest delta
|
|
36
35
|
if (diaryFiles.length > 0) {
|
|
37
36
|
const sorted = [...diaryFiles].sort();
|
|
38
37
|
const latestName = sorted[sorted.length - 1];
|
|
39
38
|
const latestPath = path.join(diaryDir, latestName);
|
|
40
39
|
const deltaContent = fs.readFileSync(latestPath, 'utf8').trim();
|
|
41
|
-
|
|
40
|
+
const { meta } = parseFrontmatter(deltaContent);
|
|
41
|
+
const deltaProject = meta.project || null;
|
|
42
|
+
const currentProject = getProjectName();
|
|
43
|
+
if (!deltaProject || deltaProject.toLowerCase() === currentProject.toLowerCase()) {
|
|
44
|
+
output.push(`[Mindlore Delta: ${latestName}]\n${deltaContent}`);
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
// Reflect trigger
|
|
@@ -63,43 +67,37 @@ function main() {
|
|
|
63
67
|
}
|
|
64
68
|
} catch (_err) { /* skip */ }
|
|
65
69
|
|
|
66
|
-
// v0.4
|
|
70
|
+
// v0.5.4: Consolidated session payload (replaces scattered episodes/activity/alerts injection)
|
|
67
71
|
try {
|
|
68
72
|
const dbPath = path.join(baseDir, 'mindlore.db');
|
|
69
73
|
const db = openDatabase(dbPath, { readonly: true });
|
|
70
74
|
if (db) {
|
|
71
75
|
try {
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
// Session payload: Session summary, Decisions, Friction, Learnings
|
|
77
|
+
try {
|
|
78
|
+
const { buildSessionPayload } = require('../dist/scripts/lib/session-payload.js');
|
|
74
79
|
const project = path.basename(process.cwd());
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const summary = String(ep.summary || '').slice(0, 100);
|
|
81
|
-
return `- [${date}] ${ep.kind}: ${summary}`;
|
|
82
|
-
});
|
|
83
|
-
output.push(`[Mindlore Episodes]\n${lines.join('\n')}`);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// v0.4.1: Enriched multi-session episodes
|
|
87
|
-
const multiDays = config?.session_focus?.multi_session_days ?? 3;
|
|
88
|
-
const enriched = queryMultiSessionEpisodes(db, { project, days: multiDays, limit: 20 });
|
|
89
|
-
if (enriched.length > 0) {
|
|
90
|
-
const formatted = formatMultiSessionEpisodes(enriched);
|
|
91
|
-
if (formatted) {
|
|
92
|
-
output.push(`[Mindlore Recent Activity]\n${formatted}`);
|
|
80
|
+
const payloadBudget = config?.tokenBudget?.sessionInject ?? 2000;
|
|
81
|
+
const payload = buildSessionPayload(db, baseDir, project, payloadBudget);
|
|
82
|
+
if (!payload.skipInjection) {
|
|
83
|
+
for (const section of payload.sections) {
|
|
84
|
+
output.push(`[Mindlore ${section.label}]\n${section.content}`);
|
|
93
85
|
}
|
|
94
86
|
}
|
|
87
|
+
} catch (_payloadErr) {
|
|
88
|
+
// Session payload is optional — don't break session start
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// v0.4.1: Supersedes chain display (kept — not covered by session-payload)
|
|
92
|
+
if (hasEpisodesTable(db)) {
|
|
93
|
+
const project = path.basename(process.cwd());
|
|
95
94
|
|
|
96
|
-
// v0.4.1: Supersedes chain display
|
|
97
95
|
const chains = querySupersededChains(db, { project, days: 7, limit: 5 });
|
|
98
96
|
if (chains.length > 0) {
|
|
99
97
|
output.push(`[Mindlore Supersedes]\n${formatSupersededChains(chains)}`);
|
|
100
98
|
}
|
|
101
99
|
|
|
102
|
-
// v0.5.3: Episode consolidation reminder
|
|
100
|
+
// v0.5.3: Episode consolidation reminder (kept — threshold-based reminder)
|
|
103
101
|
try {
|
|
104
102
|
const rawCount = db.prepare(
|
|
105
103
|
"SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL"
|
|
@@ -129,15 +127,6 @@ function main() {
|
|
|
129
127
|
}
|
|
130
128
|
} catch (_healthErr) { /* skip */ }
|
|
131
129
|
|
|
132
|
-
// Check for recent hook errors — inject warnings into CC context
|
|
133
|
-
try {
|
|
134
|
-
const errors = getRecentHookErrors();
|
|
135
|
-
if (errors.length > 0) {
|
|
136
|
-
const lines = errors.map(e => `- [${e.ts.slice(0, 19)}] **${e.hook}** (${e.level}): ${e.msg}`);
|
|
137
|
-
output.push(`[Mindlore Hook Alerts]\n${lines.join('\n')}`);
|
|
138
|
-
}
|
|
139
|
-
} catch (_hookLogErr) { /* skip */ }
|
|
140
|
-
|
|
141
130
|
hookLog('session-focus', 'info', 'session started');
|
|
142
131
|
|
|
143
132
|
// Token budget for session inject
|
package/package.json
CHANGED
package/plugin.json
CHANGED
package/templates/config.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.5.
|
|
2
|
+
"version": "0.5.4",
|
|
3
3
|
"models": {
|
|
4
4
|
"ingest": "haiku",
|
|
5
5
|
"evolve": "sonnet",
|
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
"max_episodes": 3,
|
|
14
14
|
"multi_session_days": 3
|
|
15
15
|
},
|
|
16
|
-
"synonyms": {
|
|
17
|
-
"auth": ["authentication", "login", "kimlik doğrulama"],
|
|
18
|
-
"güvenlik": ["security", "hardening", "sertleştirme"],
|
|
19
|
-
"db": ["database", "veritabanı", "sqlite"],
|
|
20
|
-
"api": ["endpoint", "rest", "graphql"],
|
|
21
|
-
"ui": ["frontend", "arayüz", "interface"],
|
|
22
|
-
"test": ["testing", "jest", "unit test"]
|
|
23
|
-
},
|
|
16
|
+
"synonyms": {},
|
|
24
17
|
"hybrid": {
|
|
25
18
|
"enabled": true,
|
|
26
19
|
"ftsWeight": 0.4,
|
|
@@ -38,5 +31,14 @@
|
|
|
38
31
|
},
|
|
39
32
|
"consolidation": {
|
|
40
33
|
"threshold": 50
|
|
34
|
+
},
|
|
35
|
+
"backup": {
|
|
36
|
+
"autoOnSessionEnd": false,
|
|
37
|
+
"remote": null
|
|
38
|
+
},
|
|
39
|
+
"reminders": {
|
|
40
|
+
"diaryReflectThreshold": 10,
|
|
41
|
+
"consolidationThreshold": 50,
|
|
42
|
+
"evolveIntervalDays": 30
|
|
41
43
|
}
|
|
42
44
|
}
|