mindlore 0.7.0 → 0.7.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 +30 -3
- package/dist/scripts/bundle-hooks.d.ts +2 -0
- package/dist/scripts/bundle-hooks.d.ts.map +1 -0
- package/dist/scripts/bundle-hooks.js +70 -0
- package/dist/scripts/bundle-hooks.js.map +1 -0
- package/dist/scripts/init.js +0 -3
- package/dist/scripts/init.js.map +1 -1
- package/dist/scripts/lib/all-migrations.d.ts.map +1 -1
- package/dist/scripts/lib/all-migrations.js +3 -0
- package/dist/scripts/lib/all-migrations.js.map +1 -1
- package/dist/scripts/lib/constants.d.ts +7 -2
- package/dist/scripts/lib/constants.d.ts.map +1 -1
- package/dist/scripts/lib/constants.js +17 -22
- package/dist/scripts/lib/constants.js.map +1 -1
- package/dist/scripts/lib/mcp-tools.d.ts.map +1 -1
- package/dist/scripts/lib/mcp-tools.js +63 -78
- package/dist/scripts/lib/mcp-tools.js.map +1 -1
- package/dist/scripts/lib/migrations-v072.d.ts +3 -0
- package/dist/scripts/lib/migrations-v072.d.ts.map +1 -0
- package/dist/scripts/lib/migrations-v072.js +25 -0
- package/dist/scripts/lib/migrations-v072.js.map +1 -0
- package/dist/scripts/lib/relation-helpers.d.ts +15 -0
- package/dist/scripts/lib/relation-helpers.d.ts.map +1 -0
- package/dist/scripts/lib/relation-helpers.js +30 -0
- package/dist/scripts/lib/relation-helpers.js.map +1 -0
- package/dist/scripts/lib/tool-adapters/get-adapter.d.ts +21 -0
- package/dist/scripts/lib/tool-adapters/get-adapter.d.ts.map +1 -0
- package/dist/scripts/lib/tool-adapters/get-adapter.js +51 -0
- package/dist/scripts/lib/tool-adapters/get-adapter.js.map +1 -0
- package/dist/scripts/lib/tool-adapters/relate-adapter.d.ts +34 -0
- package/dist/scripts/lib/tool-adapters/relate-adapter.d.ts.map +1 -0
- package/dist/scripts/lib/tool-adapters/relate-adapter.js +43 -0
- package/dist/scripts/lib/tool-adapters/relate-adapter.js.map +1 -0
- package/dist/scripts/lib/tool-adapters/search-adapter.d.ts +5 -0
- package/dist/scripts/lib/tool-adapters/search-adapter.d.ts.map +1 -1
- package/dist/scripts/lib/tool-adapters/search-adapter.js +37 -0
- package/dist/scripts/lib/tool-adapters/search-adapter.js.map +1 -1
- package/dist/scripts/mcp-server.js +1 -1
- package/dist/scripts/mcp-server.js.map +1 -1
- package/dist/tests/dont-repeat-dedup.test.d.ts +2 -0
- package/dist/tests/dont-repeat-dedup.test.d.ts.map +1 -0
- package/dist/tests/dont-repeat-dedup.test.js +93 -0
- package/dist/tests/dont-repeat-dedup.test.js.map +1 -0
- package/dist/tests/e2e-kg-pipeline.test.d.ts +2 -0
- package/dist/tests/e2e-kg-pipeline.test.d.ts.map +1 -0
- package/dist/tests/e2e-kg-pipeline.test.js +59 -0
- package/dist/tests/e2e-kg-pipeline.test.js.map +1 -0
- package/dist/tests/helpers/db.d.ts.map +1 -1
- package/dist/tests/helpers/db.js +2 -1
- package/dist/tests/helpers/db.js.map +1 -1
- package/dist/tests/hook-smoke.test.js +1 -1
- package/dist/tests/hook-smoke.test.js.map +1 -1
- package/dist/tests/mcp-get-tool.test.d.ts +2 -0
- package/dist/tests/mcp-get-tool.test.d.ts.map +1 -0
- package/dist/tests/mcp-get-tool.test.js +93 -0
- package/dist/tests/mcp-get-tool.test.js.map +1 -0
- package/dist/tests/mcp-relate-tool.test.d.ts +2 -0
- package/dist/tests/mcp-relate-tool.test.d.ts.map +1 -0
- package/dist/tests/mcp-relate-tool.test.js +85 -0
- package/dist/tests/mcp-relate-tool.test.js.map +1 -0
- package/dist/tests/mcp-server.test.js +3 -1
- package/dist/tests/mcp-server.test.js.map +1 -1
- package/dist/tests/mcp-tools.test.js +20 -0
- package/dist/tests/mcp-tools.test.js.map +1 -1
- package/dist/tests/memory-relate.test.d.ts +2 -0
- package/dist/tests/memory-relate.test.d.ts.map +1 -0
- package/dist/tests/memory-relate.test.js +70 -0
- package/dist/tests/memory-relate.test.js.map +1 -0
- package/dist/tests/migrations-v063.test.js +1 -1
- package/dist/tests/migrations-v072.test.d.ts +2 -0
- package/dist/tests/migrations-v072.test.d.ts.map +1 -0
- package/dist/tests/migrations-v072.test.js +74 -0
- package/dist/tests/migrations-v072.test.js.map +1 -0
- package/dist/tests/plugin-cache-regression.test.d.ts +2 -0
- package/dist/tests/plugin-cache-regression.test.d.ts.map +1 -0
- package/dist/tests/plugin-cache-regression.test.js +19 -0
- package/dist/tests/plugin-cache-regression.test.js.map +1 -0
- package/dist/tests/search-hook.test.js +1 -1
- package/dist/tests/search-hook.test.js.map +1 -1
- package/hooks/cc-memory-bulk-sync.cjs +606 -0
- package/hooks/cc-session-sync.cjs +856 -0
- package/hooks/hooks.json +149 -0
- package/hooks/lib/mindlore-common.cjs +2 -2
- package/hooks/lib/secure-io.cjs +17 -0
- package/hooks/mindlore-cwd-changed.cjs +19 -34
- package/hooks/mindlore-decision-detector.cjs +40 -31
- package/hooks/mindlore-dont-repeat.cjs +75 -115
- package/hooks/mindlore-fts5-sync.cjs +15 -44
- package/hooks/mindlore-index.cjs +100 -101
- package/hooks/mindlore-model-router.cjs +20 -32
- package/hooks/mindlore-post-compact.cjs +26 -42
- package/hooks/mindlore-post-read.cjs +35 -60
- package/hooks/mindlore-pre-compact.cjs +55 -73
- package/hooks/mindlore-read-guard.cjs +28 -51
- package/hooks/mindlore-research-guard.cjs +63 -101
- package/hooks/mindlore-search.cjs +1156 -93
- package/hooks/mindlore-session-end.cjs +155 -276
- package/hooks/mindlore-session-focus.cjs +672 -110
- package/hooks/src/lib/constants.cjs +15 -0
- package/hooks/src/lib/mindlore-common.cjs +975 -0
- package/hooks/src/lib/mindlore-common.d.cts +72 -0
- package/hooks/src/lib/secure-io.cjs +17 -0
- package/hooks/src/lib/types.d.ts +58 -0
- package/hooks/src/mindlore-cwd-changed.cjs +57 -0
- package/hooks/src/mindlore-decision-detector.cjs +54 -0
- package/hooks/src/mindlore-dont-repeat.cjs +243 -0
- package/hooks/src/mindlore-fts5-sync.cjs +98 -0
- package/hooks/src/mindlore-index.cjs +230 -0
- package/hooks/src/mindlore-model-router.cjs +54 -0
- package/hooks/src/mindlore-post-compact.cjs +69 -0
- package/hooks/src/mindlore-post-read.cjs +106 -0
- package/hooks/src/mindlore-pre-compact.cjs +154 -0
- package/hooks/src/mindlore-read-guard.cjs +105 -0
- package/hooks/src/mindlore-research-guard.cjs +176 -0
- package/hooks/src/mindlore-search.cjs +200 -0
- package/hooks/src/mindlore-session-end.cjs +511 -0
- package/hooks/src/mindlore-session-focus.cjs +256 -0
- package/package.json +8 -3
- package/plugin.json +5 -4
- package/templates/config.json +1 -1
|
@@ -1,256 +1,818 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
5
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
6
|
+
};
|
|
3
7
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
// dist/scripts/lib/session-payload.js
|
|
9
|
+
var require_session_payload = __commonJS({
|
|
10
|
+
"dist/scripts/lib/session-payload.js"(exports2) {
|
|
11
|
+
"use strict";
|
|
12
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
13
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
16
|
+
exports2.buildSessionPayload = buildSessionPayload;
|
|
17
|
+
var fs_1 = __importDefault(require("fs"));
|
|
18
|
+
var path_1 = __importDefault(require("path"));
|
|
19
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
20
|
+
var CHARS_PER_TOKEN = 4;
|
|
21
|
+
function estimateTokens(text) {
|
|
22
|
+
return Math.ceil(text.length / CHARS_PER_TOKEN);
|
|
23
|
+
}
|
|
24
|
+
function buildSessionSummary(baseDir, latestDeltaContent) {
|
|
25
|
+
if (latestDeltaContent) {
|
|
26
|
+
const lines2 = latestDeltaContent.split("\n").filter((l) => l.startsWith("- ") || l.startsWith("# "));
|
|
27
|
+
return lines2.slice(0, 10).join("\n") || "No previous session data.";
|
|
28
|
+
}
|
|
29
|
+
const diaryDir = path_1.default.join(baseDir, "diary");
|
|
30
|
+
if (!fs_1.default.existsSync(diaryDir))
|
|
31
|
+
return "No previous session data.";
|
|
32
|
+
const deltas = fs_1.default.readdirSync(diaryDir).filter((f) => f.startsWith("delta-")).sort();
|
|
33
|
+
if (deltas.length === 0)
|
|
34
|
+
return "No previous session data.";
|
|
35
|
+
const latestFile = deltas[deltas.length - 1] ?? "";
|
|
36
|
+
const latest = fs_1.default.readFileSync(path_1.default.join(diaryDir, latestFile), "utf8");
|
|
37
|
+
const lines = latest.split("\n").filter((l) => l.startsWith("- ") || l.startsWith("# "));
|
|
38
|
+
return lines.slice(0, 10).join("\n");
|
|
39
|
+
}
|
|
40
|
+
function buildEpisodeSections(db, project, sessionId) {
|
|
41
|
+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3).toISOString();
|
|
42
|
+
const dedupClause = sessionId ? "AND rowid NOT IN (SELECT episode_id FROM episode_inject_log WHERE session_id = ?)" : "";
|
|
43
|
+
const query = `SELECT rowid, kind, summary, created_at FROM episodes
|
|
44
|
+
WHERE status = 'active' AND project = ?
|
|
45
|
+
AND kind IN ('decision', 'friction', 'learning')
|
|
46
|
+
AND created_at >= ?
|
|
47
|
+
${dedupClause}
|
|
48
|
+
ORDER BY kind, created_at DESC`;
|
|
49
|
+
const params = sessionId ? [project, sevenDaysAgo, sessionId] : [project, sevenDaysAgo];
|
|
50
|
+
const rawRows = db.prepare(query).all(...params);
|
|
51
|
+
const rows = rawRows;
|
|
52
|
+
if (sessionId && rows.length > 0) {
|
|
53
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
54
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO episode_inject_log (session_id, episode_id, injected_at) VALUES (?, ?, ?)`);
|
|
55
|
+
db.transaction(() => {
|
|
56
|
+
for (const row of rows) {
|
|
57
|
+
insert.run(sessionId, row.rowid, now);
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
}
|
|
61
|
+
const grouped = { decision: [], friction: [], learning: [] };
|
|
62
|
+
for (const row of rows) {
|
|
63
|
+
const kind = row.kind;
|
|
64
|
+
if (kind === "decision" || kind === "friction" || kind === "learning") {
|
|
65
|
+
grouped[kind].push(row);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const fmt = (items, limit) => items.slice(0, limit).map((r) => `- ${r.summary} (${r.created_at.slice(0, 10)})`).join("\n");
|
|
69
|
+
return {
|
|
70
|
+
decisions: grouped.decision.length > 0 ? fmt(grouped.decision, 5) : "No recent decisions.",
|
|
71
|
+
friction: grouped.friction.length > 0 ? fmt(grouped.friction, 3) : "No active friction points.",
|
|
72
|
+
learnings: grouped.learning.length > 0 ? fmt(grouped.learning, 5) : "No recent learnings."
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function buildSessionPayload(opts) {
|
|
76
|
+
const { db, baseDir, project, tokenBudget = 2e3, latestDeltaContent, sessionId } = opts;
|
|
77
|
+
const sections = [];
|
|
78
|
+
const summary = buildSessionSummary(baseDir, latestDeltaContent);
|
|
79
|
+
sections.push({ label: "Session", content: summary, tokens: estimateTokens(summary) });
|
|
80
|
+
const episodes = buildEpisodeSections(db, project, sessionId);
|
|
81
|
+
sections.push({ label: "Decisions", content: episodes.decisions, tokens: estimateTokens(episodes.decisions) });
|
|
82
|
+
sections.push({ label: "Friction", content: episodes.friction, tokens: estimateTokens(episodes.friction) });
|
|
83
|
+
sections.push({ label: "Learnings", content: episodes.learnings, tokens: estimateTokens(episodes.learnings) });
|
|
84
|
+
try {
|
|
85
|
+
const summaries = db.prepare(`SELECT session_summary, created_at FROM episodes
|
|
86
|
+
WHERE kind = 'session-summary' AND project = ? AND session_summary IS NOT NULL
|
|
87
|
+
ORDER BY created_at DESC LIMIT 3`).all(project);
|
|
88
|
+
if (summaries.length > 0) {
|
|
89
|
+
const content = summaries.map((s) => `- ${s.created_at.slice(0, 16)}: ${s.session_summary}`).join("\n");
|
|
90
|
+
sections.push({ label: "Past Sessions", content: `# Son Sessionlar
|
|
91
|
+
${content}`, tokens: estimateTokens(content) });
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
let totalTokens = sections.reduce((sum, s) => sum + s.tokens, 0);
|
|
96
|
+
while (totalTokens > tokenBudget && sections.length > 1) {
|
|
97
|
+
const removed = sections.pop();
|
|
98
|
+
if (!removed)
|
|
99
|
+
break;
|
|
100
|
+
totalTokens -= removed.tokens;
|
|
101
|
+
}
|
|
102
|
+
const allContent = sections.map((s) => s.content).join("|");
|
|
103
|
+
const contentHash = crypto_1.default.createHash("md5").update(allContent).digest("hex").slice(0, 8);
|
|
104
|
+
return { sections, totalTokens, contentHash };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// dist/scripts/lib/migrations-v051.js
|
|
110
|
+
var require_migrations_v051 = __commonJS({
|
|
111
|
+
"dist/scripts/lib/migrations-v051.js"(exports2) {
|
|
112
|
+
"use strict";
|
|
113
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
114
|
+
exports2.V051_MIGRATIONS = void 0;
|
|
115
|
+
exports2.V051_MIGRATIONS = [
|
|
116
|
+
{
|
|
117
|
+
version: 2,
|
|
118
|
+
name: "add_source_type_and_project_scope",
|
|
119
|
+
up: (db) => {
|
|
120
|
+
const cols = db.pragma("table_info(file_hashes)");
|
|
121
|
+
const colNames = new Set(cols.map((c) => c.name));
|
|
122
|
+
if (!colNames.has("source_type")) {
|
|
123
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN source_type TEXT DEFAULT 'mindlore'");
|
|
124
|
+
}
|
|
125
|
+
if (!colNames.has("project_scope")) {
|
|
126
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN project_scope TEXT");
|
|
127
|
+
}
|
|
128
|
+
if (!colNames.has("content_hash")) {
|
|
129
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN content_hash TEXT");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// dist/scripts/lib/migrations.js
|
|
138
|
+
var require_migrations = __commonJS({
|
|
139
|
+
"dist/scripts/lib/migrations.js"(exports2) {
|
|
140
|
+
"use strict";
|
|
141
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
142
|
+
exports2.V051_MIGRATIONS = exports2.V050_MIGRATIONS = void 0;
|
|
143
|
+
exports2.V050_MIGRATIONS = [
|
|
144
|
+
{
|
|
145
|
+
version: 1,
|
|
146
|
+
name: "add_vec_table_and_timestamps",
|
|
147
|
+
up: (db) => {
|
|
148
|
+
const cols = db.pragma("table_info(file_hashes)");
|
|
149
|
+
const colNames = new Set(cols.map((c) => c.name));
|
|
150
|
+
if (!colNames.has("created_at")) {
|
|
151
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN created_at TEXT");
|
|
152
|
+
}
|
|
153
|
+
if (!colNames.has("updated_at")) {
|
|
154
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN updated_at TEXT");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
];
|
|
159
|
+
var migrations_v051_js_1 = require_migrations_v051();
|
|
160
|
+
Object.defineProperty(exports2, "V051_MIGRATIONS", { enumerable: true, get: function() {
|
|
161
|
+
return migrations_v051_js_1.V051_MIGRATIONS;
|
|
162
|
+
} });
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// dist/scripts/lib/migrations-v052.js
|
|
167
|
+
var require_migrations_v052 = __commonJS({
|
|
168
|
+
"dist/scripts/lib/migrations-v052.js"(exports2) {
|
|
169
|
+
"use strict";
|
|
170
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
171
|
+
exports2.V052_MIGRATIONS = void 0;
|
|
172
|
+
exports2.V052_MIGRATIONS = [
|
|
173
|
+
{
|
|
174
|
+
version: 3,
|
|
175
|
+
name: "add_skill_memory_table",
|
|
176
|
+
up: (db) => {
|
|
177
|
+
db.exec(`
|
|
178
|
+
CREATE TABLE IF NOT EXISTS skill_memory (
|
|
179
|
+
id INTEGER PRIMARY KEY,
|
|
180
|
+
skill_name TEXT NOT NULL,
|
|
181
|
+
key TEXT NOT NULL,
|
|
182
|
+
value TEXT NOT NULL,
|
|
183
|
+
updated_at TEXT NOT NULL,
|
|
184
|
+
access_count INTEGER DEFAULT 0,
|
|
185
|
+
UNIQUE(skill_name, key)
|
|
186
|
+
)
|
|
187
|
+
`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
});
|
|
10
193
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
194
|
+
// dist/scripts/lib/migrations-v053.js
|
|
195
|
+
var require_migrations_v053 = __commonJS({
|
|
196
|
+
"dist/scripts/lib/migrations-v053.js"(exports2) {
|
|
197
|
+
"use strict";
|
|
198
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
199
|
+
exports2.V053_MIGRATIONS = void 0;
|
|
200
|
+
exports2.V053_MIGRATIONS = [
|
|
201
|
+
{
|
|
202
|
+
version: 4,
|
|
203
|
+
name: "add_recall_telemetry_and_decay",
|
|
204
|
+
up: (db) => {
|
|
205
|
+
const cols = db.pragma("table_info(file_hashes)");
|
|
206
|
+
const colNames = new Set(cols.map((c) => c.name));
|
|
207
|
+
if (!colNames.has("recall_count")) {
|
|
208
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN recall_count INTEGER DEFAULT 0");
|
|
209
|
+
}
|
|
210
|
+
if (!colNames.has("last_recalled_at")) {
|
|
211
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN last_recalled_at TEXT");
|
|
212
|
+
}
|
|
213
|
+
if (!colNames.has("archived_at")) {
|
|
214
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN archived_at TEXT");
|
|
215
|
+
}
|
|
216
|
+
if (!colNames.has("importance")) {
|
|
217
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN importance REAL DEFAULT 1.0");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
version: 5,
|
|
223
|
+
name: "add_episode_consolidation",
|
|
224
|
+
up: (db) => {
|
|
225
|
+
const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='episodes'").get();
|
|
226
|
+
if (!table)
|
|
227
|
+
return;
|
|
228
|
+
const cols = db.pragma("table_info(episodes)");
|
|
229
|
+
const colNames = new Set(cols.map((c) => c.name));
|
|
230
|
+
if (!colNames.has("consolidation_status")) {
|
|
231
|
+
db.exec("ALTER TABLE episodes ADD COLUMN consolidation_status TEXT DEFAULT 'raw'");
|
|
232
|
+
}
|
|
233
|
+
if (!colNames.has("consolidated_into")) {
|
|
234
|
+
db.exec("ALTER TABLE episodes ADD COLUMN consolidated_into TEXT");
|
|
235
|
+
}
|
|
236
|
+
if (!colNames.has("decay_score")) {
|
|
237
|
+
db.exec("ALTER TABLE episodes ADD COLUMN decay_score REAL");
|
|
238
|
+
}
|
|
239
|
+
if (!colNames.has("last_decay_calc")) {
|
|
240
|
+
db.exec("ALTER TABLE episodes ADD COLUMN last_decay_calc TEXT");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
];
|
|
245
|
+
}
|
|
246
|
+
});
|
|
14
247
|
|
|
248
|
+
// dist/scripts/lib/migrations-v061.js
|
|
249
|
+
var require_migrations_v061 = __commonJS({
|
|
250
|
+
"dist/scripts/lib/migrations-v061.js"(exports2) {
|
|
251
|
+
"use strict";
|
|
252
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
253
|
+
exports2.V061_MIGRATIONS = void 0;
|
|
254
|
+
exports2.V061_MIGRATIONS = [
|
|
255
|
+
{
|
|
256
|
+
version: 6,
|
|
257
|
+
name: "cleanup_project_category",
|
|
258
|
+
up: (db) => {
|
|
259
|
+
db.exec(`
|
|
260
|
+
UPDATE mindlore_fts SET project = 'unknown'
|
|
261
|
+
WHERE project LIKE '.mindlore%' OR project LIKE 'C--%'
|
|
262
|
+
`);
|
|
263
|
+
db.exec(`
|
|
264
|
+
UPDATE mindlore_fts SET category = 'cc-subagent'
|
|
265
|
+
WHERE category IN ('subagent', 'cc_subagent')
|
|
266
|
+
`);
|
|
267
|
+
db.exec(`
|
|
268
|
+
UPDATE mindlore_fts SET category = 'cc-session'
|
|
269
|
+
WHERE category IN ('session', 'cc_session')
|
|
270
|
+
`);
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
version: 7,
|
|
275
|
+
name: "split_fts_sessions",
|
|
276
|
+
up: (db) => {
|
|
277
|
+
db.exec(`
|
|
278
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts_sessions USING fts5(
|
|
279
|
+
path, slug, description, type, category, title, content, tags,
|
|
280
|
+
quality, date_captured, project
|
|
281
|
+
)
|
|
282
|
+
`);
|
|
283
|
+
db.exec("BEGIN");
|
|
284
|
+
try {
|
|
285
|
+
db.exec(`
|
|
286
|
+
INSERT INTO mindlore_fts_sessions (path, slug, description, type, category, title, content, tags, quality, date_captured, project)
|
|
287
|
+
SELECT path, slug, description, type, category, title, content, tags, quality, date_captured, project
|
|
288
|
+
FROM mindlore_fts
|
|
289
|
+
WHERE category IN ('cc-subagent', 'cc-session')
|
|
290
|
+
`);
|
|
291
|
+
db.exec(`
|
|
292
|
+
DELETE FROM mindlore_fts WHERE category IN ('cc-subagent', 'cc-session')
|
|
293
|
+
`);
|
|
294
|
+
db.exec("COMMIT");
|
|
295
|
+
} catch (err) {
|
|
296
|
+
db.exec("ROLLBACK");
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
299
|
+
const cols = db.pragma("table_info(file_hashes)");
|
|
300
|
+
if (!cols.some((c) => c.name === "table_target")) {
|
|
301
|
+
db.exec("ALTER TABLE file_hashes ADD COLUMN table_target TEXT DEFAULT 'mindlore_fts'");
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
];
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
// dist/scripts/lib/migrations-v062.js
|
|
310
|
+
var require_migrations_v062 = __commonJS({
|
|
311
|
+
"dist/scripts/lib/migrations-v062.js"(exports2) {
|
|
312
|
+
"use strict";
|
|
313
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
314
|
+
exports2.V062_MIGRATIONS = void 0;
|
|
315
|
+
exports2.V062_MIGRATIONS = [
|
|
316
|
+
{
|
|
317
|
+
version: 8,
|
|
318
|
+
name: "raw_metadata_table",
|
|
319
|
+
up: (db) => {
|
|
320
|
+
db.exec(`
|
|
321
|
+
CREATE TABLE IF NOT EXISTS raw_metadata (
|
|
322
|
+
path TEXT PRIMARY KEY,
|
|
323
|
+
title TEXT,
|
|
324
|
+
url TEXT,
|
|
325
|
+
date_captured TEXT,
|
|
326
|
+
headings TEXT,
|
|
327
|
+
file_size INTEGER,
|
|
328
|
+
line_count INTEGER,
|
|
329
|
+
extracted_at TEXT NOT NULL
|
|
330
|
+
)
|
|
331
|
+
`);
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
version: 9,
|
|
336
|
+
name: "episodes_session_summary",
|
|
337
|
+
up: (db) => {
|
|
338
|
+
const cols = db.pragma("table_info(episodes)");
|
|
339
|
+
if (!cols.some((c) => c.name === "session_summary")) {
|
|
340
|
+
db.exec("ALTER TABLE episodes ADD COLUMN session_summary TEXT");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
];
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
// dist/scripts/lib/migrations-v063.js
|
|
349
|
+
var require_migrations_v063 = __commonJS({
|
|
350
|
+
"dist/scripts/lib/migrations-v063.js"(exports2) {
|
|
351
|
+
"use strict";
|
|
352
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
353
|
+
exports2.V063_MIGRATIONS = exports2.SQL_SEARCH_THROTTLE_CREATE = exports2.SQL_SEARCH_CACHE_CREATE = exports2.SQL_VOCABULARY_CREATE = exports2.SQL_FTS_TRIGRAM_CREATE = void 0;
|
|
354
|
+
exports2.SQL_FTS_TRIGRAM_CREATE = "CREATE VIRTUAL TABLE IF NOT EXISTS mindlore_fts_trigram USING fts5(path UNINDEXED, slug, description, type UNINDEXED, category, title, content, tags, quality UNINDEXED, date_captured UNINDEXED, project UNINDEXED, tokenize='trigram')";
|
|
355
|
+
exports2.SQL_VOCABULARY_CREATE = "CREATE TABLE IF NOT EXISTS vocabulary (word TEXT PRIMARY KEY) WITHOUT ROWID";
|
|
356
|
+
exports2.SQL_SEARCH_CACHE_CREATE = "CREATE TABLE IF NOT EXISTS search_cache (query_hash TEXT PRIMARY KEY, results_json TEXT NOT NULL, expires_at TEXT NOT NULL)";
|
|
357
|
+
exports2.SQL_SEARCH_THROTTLE_CREATE = "CREATE TABLE IF NOT EXISTS search_throttle (session_id TEXT PRIMARY KEY, call_count INTEGER NOT NULL DEFAULT 0, last_call TEXT NOT NULL)";
|
|
358
|
+
exports2.V063_MIGRATIONS = [
|
|
359
|
+
{
|
|
360
|
+
version: 10,
|
|
361
|
+
name: "fts_trigram_table",
|
|
362
|
+
up: (db) => {
|
|
363
|
+
db.exec(exports2.SQL_FTS_TRIGRAM_CREATE);
|
|
364
|
+
const porterCount = db.prepare("SELECT COUNT(*) as c FROM mindlore_fts").get().c;
|
|
365
|
+
if (porterCount > 0) {
|
|
366
|
+
db.exec(`
|
|
367
|
+
INSERT INTO mindlore_fts_trigram(path, slug, description, type, category, title, content, tags, quality, date_captured, project)
|
|
368
|
+
SELECT path, slug, description, type, category, title, content, tags, quality, date_captured, project
|
|
369
|
+
FROM mindlore_fts
|
|
370
|
+
`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
version: 11,
|
|
376
|
+
name: "vocabulary_table",
|
|
377
|
+
up: (db) => {
|
|
378
|
+
db.exec(exports2.SQL_VOCABULARY_CREATE);
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
version: 12,
|
|
383
|
+
name: "chunks_table",
|
|
384
|
+
up: (db) => {
|
|
385
|
+
db.exec(`
|
|
386
|
+
CREATE TABLE IF NOT EXISTS chunks (
|
|
387
|
+
id INTEGER PRIMARY KEY,
|
|
388
|
+
source_path TEXT NOT NULL,
|
|
389
|
+
chunk_index INTEGER NOT NULL,
|
|
390
|
+
heading TEXT,
|
|
391
|
+
breadcrumb TEXT,
|
|
392
|
+
char_count INTEGER,
|
|
393
|
+
UNIQUE(source_path, chunk_index)
|
|
394
|
+
)
|
|
395
|
+
`);
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
version: 13,
|
|
400
|
+
name: "search_cache_tables",
|
|
401
|
+
up: (db) => {
|
|
402
|
+
db.exec(exports2.SQL_SEARCH_CACHE_CREATE);
|
|
403
|
+
db.exec(exports2.SQL_SEARCH_THROTTLE_CREATE);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
];
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// dist/scripts/lib/migrations-v066.js
|
|
411
|
+
var require_migrations_v066 = __commonJS({
|
|
412
|
+
"dist/scripts/lib/migrations-v066.js"(exports2) {
|
|
413
|
+
"use strict";
|
|
414
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
415
|
+
exports2.V066_MIGRATIONS = exports2.SQL_EPISODE_INJECT_LOG_CREATE = void 0;
|
|
416
|
+
exports2.SQL_EPISODE_INJECT_LOG_CREATE = "CREATE TABLE IF NOT EXISTS episode_inject_log (session_id TEXT NOT NULL, episode_id TEXT NOT NULL, injected_at TEXT NOT NULL, PRIMARY KEY (session_id, episode_id))";
|
|
417
|
+
exports2.V066_MIGRATIONS = [
|
|
418
|
+
{
|
|
419
|
+
version: 14,
|
|
420
|
+
name: "episode_inject_log",
|
|
421
|
+
up: (db) => {
|
|
422
|
+
db.exec(exports2.SQL_EPISODE_INJECT_LOG_CREATE);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
];
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// dist/scripts/lib/migrations-v067.js
|
|
430
|
+
var require_migrations_v067 = __commonJS({
|
|
431
|
+
"dist/scripts/lib/migrations-v067.js"(exports2) {
|
|
432
|
+
"use strict";
|
|
433
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
434
|
+
exports2.V067_MIGRATIONS = void 0;
|
|
435
|
+
exports2.cleanupExpiredInjectLog = cleanupExpiredInjectLog;
|
|
436
|
+
var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
437
|
+
function cleanupExpiredInjectLog(db, ttlMs = THIRTY_DAYS_MS) {
|
|
438
|
+
const cutoff = new Date(Date.now() - ttlMs).toISOString();
|
|
439
|
+
const result = db.prepare("DELETE FROM episode_inject_log WHERE injected_at < ?").run(cutoff);
|
|
440
|
+
return result.changes;
|
|
441
|
+
}
|
|
442
|
+
exports2.V067_MIGRATIONS = [
|
|
443
|
+
{
|
|
444
|
+
version: 15,
|
|
445
|
+
name: "episodes_graduation_columns",
|
|
446
|
+
up: (db) => {
|
|
447
|
+
db.exec("ALTER TABLE episodes ADD COLUMN graduated_at TEXT");
|
|
448
|
+
db.exec("ALTER TABLE episodes ADD COLUMN rejected_at TEXT");
|
|
449
|
+
db.exec("ALTER TABLE episodes ADD COLUMN rejection_reason TEXT");
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
version: 16,
|
|
454
|
+
name: "episode_inject_log_integer_fix",
|
|
455
|
+
up: (db) => {
|
|
456
|
+
db.exec(`
|
|
457
|
+
CREATE TABLE episode_inject_log_new (
|
|
458
|
+
session_id TEXT NOT NULL,
|
|
459
|
+
episode_id INTEGER NOT NULL,
|
|
460
|
+
injected_at TEXT NOT NULL,
|
|
461
|
+
PRIMARY KEY (session_id, episode_id)
|
|
462
|
+
)
|
|
463
|
+
`);
|
|
464
|
+
db.exec(`
|
|
465
|
+
INSERT INTO episode_inject_log_new (session_id, episode_id, injected_at)
|
|
466
|
+
SELECT session_id, CAST(episode_id AS INTEGER), injected_at
|
|
467
|
+
FROM episode_inject_log
|
|
468
|
+
`);
|
|
469
|
+
db.exec("DROP TABLE episode_inject_log");
|
|
470
|
+
db.exec("ALTER TABLE episode_inject_log_new RENAME TO episode_inject_log");
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
version: 17,
|
|
475
|
+
name: "episode_inject_log_ttl",
|
|
476
|
+
up: (db) => {
|
|
477
|
+
cleanupExpiredInjectLog(db);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
];
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// dist/scripts/lib/migrations-v068.js
|
|
485
|
+
var require_migrations_v068 = __commonJS({
|
|
486
|
+
"dist/scripts/lib/migrations-v068.js"(exports2) {
|
|
487
|
+
"use strict";
|
|
488
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
489
|
+
exports2.V068_MIGRATIONS = void 0;
|
|
490
|
+
exports2.V068_MIGRATIONS = [
|
|
491
|
+
{
|
|
492
|
+
version: 18,
|
|
493
|
+
name: "inject_log_injected_at_index",
|
|
494
|
+
up: (db) => {
|
|
495
|
+
db.exec("CREATE INDEX IF NOT EXISTS idx_inject_log_injected_at ON episode_inject_log(injected_at)");
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
version: 19,
|
|
500
|
+
name: "drop_dead_vec_tables",
|
|
501
|
+
up: (db) => {
|
|
502
|
+
const shadowTables = [
|
|
503
|
+
"documents_vec_info",
|
|
504
|
+
"documents_vec_chunks",
|
|
505
|
+
"documents_vec_rowids",
|
|
506
|
+
"documents_vec_vector_chunks00",
|
|
507
|
+
"documents_vec_metadatachunks00",
|
|
508
|
+
"documents_vec_metadatatext00",
|
|
509
|
+
"documents_vec_auxiliary"
|
|
510
|
+
];
|
|
511
|
+
for (const table of shadowTables) {
|
|
512
|
+
db.exec(`DROP TABLE IF EXISTS "${table}"`);
|
|
513
|
+
}
|
|
514
|
+
try {
|
|
515
|
+
db.exec("DROP TABLE IF EXISTS documents_vec");
|
|
516
|
+
} catch {
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
];
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
// dist/scripts/lib/migrations-v072.js
|
|
525
|
+
var require_migrations_v072 = __commonJS({
|
|
526
|
+
"dist/scripts/lib/migrations-v072.js"(exports2) {
|
|
527
|
+
"use strict";
|
|
528
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
529
|
+
exports2.V072_MIGRATIONS = void 0;
|
|
530
|
+
exports2.V072_MIGRATIONS = [
|
|
531
|
+
{
|
|
532
|
+
version: 20,
|
|
533
|
+
name: "create_mindlore_relations",
|
|
534
|
+
up: (db) => {
|
|
535
|
+
db.exec(`
|
|
536
|
+
CREATE TABLE IF NOT EXISTS mindlore_relations (
|
|
537
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
538
|
+
source_a TEXT NOT NULL,
|
|
539
|
+
source_b TEXT NOT NULL,
|
|
540
|
+
relation_type TEXT NOT NULL CHECK(relation_type IN ('cites', 'extends', 'contradicts', 'supersedes')),
|
|
541
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
542
|
+
UNIQUE(source_a, source_b, relation_type)
|
|
543
|
+
);
|
|
544
|
+
CREATE INDEX IF NOT EXISTS idx_relations_source_a ON mindlore_relations(source_a);
|
|
545
|
+
CREATE INDEX IF NOT EXISTS idx_relations_source_b ON mindlore_relations(source_b);
|
|
546
|
+
CREATE INDEX IF NOT EXISTS idx_relations_type ON mindlore_relations(relation_type);
|
|
547
|
+
`);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
];
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// dist/scripts/lib/all-migrations.js
|
|
555
|
+
var require_all_migrations = __commonJS({
|
|
556
|
+
"dist/scripts/lib/all-migrations.js"(exports2) {
|
|
557
|
+
"use strict";
|
|
558
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
559
|
+
exports2.EXPECTED_SCHEMA_VERSION = exports2.INIT_MIGRATIONS = exports2.FTS_DB_MIGRATIONS = exports2.ALL_MIGRATIONS = void 0;
|
|
560
|
+
var migrations_js_1 = require_migrations();
|
|
561
|
+
var migrations_v052_js_1 = require_migrations_v052();
|
|
562
|
+
var migrations_v053_js_1 = require_migrations_v053();
|
|
563
|
+
var migrations_v061_js_1 = require_migrations_v061();
|
|
564
|
+
var migrations_v062_js_1 = require_migrations_v062();
|
|
565
|
+
var migrations_v063_js_1 = require_migrations_v063();
|
|
566
|
+
var migrations_v066_js_1 = require_migrations_v066();
|
|
567
|
+
var migrations_v067_js_1 = require_migrations_v067();
|
|
568
|
+
var migrations_v068_js_1 = require_migrations_v068();
|
|
569
|
+
var migrations_v072_js_1 = require_migrations_v072();
|
|
570
|
+
exports2.ALL_MIGRATIONS = [
|
|
571
|
+
...migrations_js_1.V050_MIGRATIONS,
|
|
572
|
+
...migrations_js_1.V051_MIGRATIONS,
|
|
573
|
+
...migrations_v052_js_1.V052_MIGRATIONS,
|
|
574
|
+
...migrations_v053_js_1.V053_MIGRATIONS,
|
|
575
|
+
...migrations_v061_js_1.V061_MIGRATIONS,
|
|
576
|
+
...migrations_v062_js_1.V062_MIGRATIONS,
|
|
577
|
+
...migrations_v063_js_1.V063_MIGRATIONS,
|
|
578
|
+
...migrations_v066_js_1.V066_MIGRATIONS,
|
|
579
|
+
...migrations_v067_js_1.V067_MIGRATIONS,
|
|
580
|
+
...migrations_v068_js_1.V068_MIGRATIONS,
|
|
581
|
+
...migrations_v072_js_1.V072_MIGRATIONS
|
|
582
|
+
];
|
|
583
|
+
var EPISODES_DEPENDENT = /* @__PURE__ */ new Set([9, 14, 15, 16, 17, 18]);
|
|
584
|
+
exports2.FTS_DB_MIGRATIONS = exports2.ALL_MIGRATIONS.filter((m) => !EPISODES_DEPENDENT.has(m.version));
|
|
585
|
+
exports2.INIT_MIGRATIONS = [
|
|
586
|
+
...migrations_v062_js_1.V062_MIGRATIONS,
|
|
587
|
+
...migrations_v063_js_1.V063_MIGRATIONS,
|
|
588
|
+
...migrations_v066_js_1.V066_MIGRATIONS,
|
|
589
|
+
...migrations_v067_js_1.V067_MIGRATIONS,
|
|
590
|
+
...migrations_v068_js_1.V068_MIGRATIONS,
|
|
591
|
+
...migrations_v072_js_1.V072_MIGRATIONS
|
|
592
|
+
];
|
|
593
|
+
exports2.EXPECTED_SCHEMA_VERSION = Math.max(...exports2.ALL_MIGRATIONS.map((m) => m.version));
|
|
594
|
+
}
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
// hooks/src/mindlore-session-focus.cjs
|
|
598
|
+
var fs = require("fs");
|
|
599
|
+
var path = require("path");
|
|
600
|
+
var { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry, withTimeoutDb, listSnapshots, isCorruptionError, recoverCorruptDb, getNominationCounts } = require("./lib/mindlore-common.cjs");
|
|
15
601
|
function truncateSection(content, sectionRegex, keepCount, label) {
|
|
16
602
|
const match = content.match(sectionRegex);
|
|
17
603
|
if (!match) return content;
|
|
18
|
-
const lines = match[2].trim().split(
|
|
604
|
+
const lines = match[2].trim().split("\n");
|
|
19
605
|
if (lines.length <= keepCount) return content;
|
|
20
|
-
const kept = lines.slice(0, keepCount).join(
|
|
21
|
-
return content.replace(match[2].trim(), kept +
|
|
606
|
+
const kept = lines.slice(0, keepCount).join("\n");
|
|
607
|
+
return content.replace(match[2].trim(), kept + `
|
|
608
|
+
- ...ve ${lines.length - keepCount} ${label} daha`);
|
|
22
609
|
}
|
|
23
|
-
|
|
24
610
|
function truncateCommits(content) {
|
|
25
|
-
return truncateSection(content, /(## Commits\n)((?:- [^\n]+\n?)+)/, 5,
|
|
611
|
+
return truncateSection(content, /(## Commits\n)((?:- [^\n]+\n?)+)/, 5, "commit");
|
|
26
612
|
}
|
|
27
|
-
|
|
28
613
|
function truncateChangedFiles(content) {
|
|
29
|
-
return truncateSection(content, /(## Changed Files\n)((?:- [^\n]+\n?)+)/, 10,
|
|
614
|
+
return truncateSection(content, /(## Changed Files\n)((?:- [^\n]+\n?)+)/, 10, "dosya");
|
|
30
615
|
}
|
|
31
|
-
|
|
32
616
|
function tryOpenDb(dbPath) {
|
|
33
617
|
return openDatabase(dbPath, { readonly: true });
|
|
34
618
|
}
|
|
35
|
-
|
|
36
619
|
function getEpisodeStats(db, config, project) {
|
|
37
620
|
const chains = querySupersededChains(db, { project, days: 7, limit: 5 });
|
|
38
621
|
let consolidationMsg = null;
|
|
39
622
|
try {
|
|
40
|
-
const rawCount = withTimeoutDb(
|
|
623
|
+
const rawCount = withTimeoutDb(
|
|
624
|
+
db,
|
|
41
625
|
"SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL",
|
|
42
|
-
[],
|
|
626
|
+
[],
|
|
627
|
+
{ mode: "get" }
|
|
628
|
+
);
|
|
43
629
|
const cnt = rawCount?.cnt ?? 0;
|
|
44
630
|
const consolThreshold = config?.consolidation?.threshold ?? 50;
|
|
45
631
|
if (cnt >= consolThreshold) {
|
|
46
|
-
consolidationMsg = `[Mindlore] ${cnt} raw episode birikti
|
|
632
|
+
consolidationMsg = `[Mindlore] ${cnt} raw episode birikti \u2014 \`/mindlore-maintain consolidate\` ile birle\u015Ftirmeyi d\xFC\u015F\xFCn.`;
|
|
47
633
|
}
|
|
48
|
-
} catch (_err) {
|
|
634
|
+
} catch (_err) {
|
|
635
|
+
}
|
|
49
636
|
return { chains, consolidationMsg };
|
|
50
637
|
}
|
|
51
|
-
|
|
52
638
|
function checkStaleContent(db) {
|
|
53
639
|
try {
|
|
54
|
-
const thirtyDaysAgo = new Date(Date.now() -
|
|
55
|
-
const row = withTimeoutDb(db,
|
|
640
|
+
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3).toISOString();
|
|
641
|
+
const row = withTimeoutDb(db, "SELECT COUNT(*) as cnt FROM file_hashes WHERE last_indexed < ?", [thirtyDaysAgo], { mode: "get" });
|
|
56
642
|
const staleCount = row?.cnt ?? 0;
|
|
57
643
|
if (staleCount > 3) {
|
|
58
|
-
return `[Mindlore: ${staleCount} dosya 30+ gundur guncellenmemis
|
|
644
|
+
return `[Mindlore: ${staleCount} dosya 30+ gundur guncellenmemis \u2014 \`/mindlore-evolve\` dusun]`;
|
|
59
645
|
}
|
|
60
|
-
} catch (_staleErr) {
|
|
646
|
+
} catch (_staleErr) {
|
|
647
|
+
}
|
|
61
648
|
return null;
|
|
62
649
|
}
|
|
63
|
-
|
|
64
650
|
function loadDbContent({ db, baseDir, config, output, timings, latestDeltaContent, sessionId }) {
|
|
65
651
|
const project = path.basename(process.cwd());
|
|
66
|
-
// Session payload: Session summary, Decisions, Friction, Learnings
|
|
67
652
|
const tPayload = Date.now();
|
|
68
653
|
try {
|
|
69
|
-
const { buildSessionPayload } =
|
|
70
|
-
const payloadBudget = config?.tokenBudget?.sessionInject ??
|
|
654
|
+
const { buildSessionPayload } = require_session_payload();
|
|
655
|
+
const payloadBudget = config?.tokenBudget?.sessionInject ?? 2e3;
|
|
71
656
|
const payload = buildSessionPayload({ db, baseDir, project, tokenBudget: payloadBudget, latestDeltaContent, sessionId });
|
|
72
657
|
for (const section of payload.sections) {
|
|
73
|
-
output.push(`[Mindlore ${section.label}]
|
|
658
|
+
output.push(`[Mindlore ${section.label}]
|
|
659
|
+
${section.content}`);
|
|
74
660
|
}
|
|
75
661
|
} catch (_payloadErr) {
|
|
76
|
-
// Session payload is optional — don't break session start
|
|
77
662
|
}
|
|
78
663
|
timings.db_payload = Date.now() - tPayload;
|
|
79
|
-
|
|
80
|
-
// Supersedes chain display + episode consolidation reminder
|
|
81
664
|
const tSuperseded = Date.now();
|
|
82
665
|
if (hasEpisodesTable(db)) {
|
|
83
666
|
const { chains, consolidationMsg } = getEpisodeStats(db, config, project);
|
|
84
667
|
if (chains.length > 0) {
|
|
85
|
-
output.push(`[Mindlore Supersedes]
|
|
668
|
+
output.push(`[Mindlore Supersedes]
|
|
669
|
+
${formatSupersededChains(chains)}`);
|
|
86
670
|
}
|
|
87
671
|
if (consolidationMsg) {
|
|
88
672
|
output.push(consolidationMsg);
|
|
89
673
|
}
|
|
90
674
|
}
|
|
91
675
|
timings.db_episodes = Date.now() - tSuperseded;
|
|
92
|
-
|
|
93
|
-
// Stale content check
|
|
94
676
|
const tStale = Date.now();
|
|
95
677
|
const staleMsg = checkStaleContent(db);
|
|
96
678
|
if (staleMsg) {
|
|
97
679
|
output.push(staleMsg);
|
|
98
680
|
}
|
|
99
681
|
timings.db_stale = Date.now() - tStale;
|
|
100
|
-
|
|
101
|
-
// Auto reflect trigger (Q1) + Graduated lesson count (Q3)
|
|
102
682
|
try {
|
|
103
683
|
const counts = getNominationCounts(db, project);
|
|
104
684
|
if (counts.staged >= (config?.graduation?.reflectThreshold ?? 5)) {
|
|
105
|
-
output.push(`[Mindlore] ${counts.staged} bekleyen nomination var
|
|
685
|
+
output.push(`[Mindlore] ${counts.staged} bekleyen nomination var \u2014 \`/mindlore-reflect\` \xE7al\u0131\u015Ft\u0131r`);
|
|
106
686
|
}
|
|
107
687
|
if (counts.graduated > 0) {
|
|
108
688
|
output.push(`[Mindlore Graduation] ${counts.graduated} lesson mezun oldu`);
|
|
109
689
|
}
|
|
110
|
-
} catch (_reflectErr) {
|
|
690
|
+
} catch (_reflectErr) {
|
|
691
|
+
}
|
|
111
692
|
}
|
|
112
|
-
|
|
113
693
|
function main() {
|
|
114
694
|
const t0 = Date.now();
|
|
115
695
|
const baseDir = findMindloreDir();
|
|
116
|
-
if (!baseDir) return;
|
|
117
|
-
|
|
118
|
-
// Read session_id from stdin (Claude Code passes { session_id } to SessionStart hooks)
|
|
696
|
+
if (!baseDir) return;
|
|
119
697
|
let sessionId;
|
|
120
698
|
try {
|
|
121
|
-
const stdinData = JSON.parse(fs.readFileSync(0,
|
|
122
|
-
sessionId = stdinData.session_id ||
|
|
123
|
-
} catch {
|
|
124
|
-
|
|
699
|
+
const stdinData = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
|
|
700
|
+
sessionId = stdinData.session_id || void 0;
|
|
701
|
+
} catch {
|
|
702
|
+
sessionId = void 0;
|
|
703
|
+
}
|
|
125
704
|
const output = [];
|
|
126
705
|
const config = readConfig(baseDir);
|
|
127
706
|
const timings = {};
|
|
128
707
|
let sourceChars = 0;
|
|
129
|
-
|
|
130
|
-
// Inject INDEX.md
|
|
131
708
|
const tIndex = Date.now();
|
|
132
|
-
const indexPath = path.join(baseDir,
|
|
709
|
+
const indexPath = path.join(baseDir, "INDEX.md");
|
|
133
710
|
if (fs.existsSync(indexPath)) {
|
|
134
|
-
const content = fs.readFileSync(indexPath,
|
|
711
|
+
const content = fs.readFileSync(indexPath, "utf8").trim();
|
|
135
712
|
sourceChars += content.length;
|
|
136
|
-
output.push(`[Mindlore INDEX]
|
|
713
|
+
output.push(`[Mindlore INDEX]
|
|
714
|
+
${content}`);
|
|
137
715
|
}
|
|
138
716
|
timings.index_read = Date.now() - tIndex;
|
|
139
|
-
|
|
140
|
-
// Inject latest delta + reflect trigger (single readdirSync)
|
|
141
717
|
const tDiary = Date.now();
|
|
142
|
-
const diaryDir = path.join(baseDir,
|
|
143
|
-
let latestDeltaContent =
|
|
718
|
+
const diaryDir = path.join(baseDir, "diary");
|
|
719
|
+
let latestDeltaContent = void 0;
|
|
144
720
|
if (fs.existsSync(diaryDir)) {
|
|
145
721
|
try {
|
|
146
|
-
const diaryFiles = listSnapshots(diaryDir).filter(f => f.startsWith(
|
|
147
|
-
|
|
722
|
+
const diaryFiles = listSnapshots(diaryDir).filter((f) => f.startsWith("delta-"));
|
|
148
723
|
if (diaryFiles.length > 0) {
|
|
149
724
|
const latestName = diaryFiles[diaryFiles.length - 1];
|
|
150
725
|
const latestPath = path.join(diaryDir, latestName);
|
|
151
|
-
const deltaContent = fs.readFileSync(latestPath,
|
|
726
|
+
const deltaContent = fs.readFileSync(latestPath, "utf8").trim();
|
|
152
727
|
sourceChars += deltaContent.length;
|
|
153
728
|
latestDeltaContent = deltaContent;
|
|
154
729
|
const { meta } = parseFrontmatter(deltaContent);
|
|
155
730
|
const deltaProject = meta.project || null;
|
|
156
731
|
const currentProject = getProjectName();
|
|
157
732
|
if (!deltaProject || deltaProject.toLowerCase() === currentProject.toLowerCase()) {
|
|
158
|
-
output.push(`[Mindlore Delta: ${latestName}]
|
|
733
|
+
output.push(`[Mindlore Delta: ${latestName}]
|
|
734
|
+
${truncateChangedFiles(truncateCommits(deltaContent))}`);
|
|
159
735
|
}
|
|
160
736
|
}
|
|
161
|
-
|
|
162
|
-
// Reflect trigger
|
|
163
737
|
const threshold = config?.reflect?.threshold ?? 5;
|
|
164
738
|
if (diaryFiles.length >= threshold) {
|
|
165
|
-
output.push(`[Mindlore] ${diaryFiles.length} diary entry birikti
|
|
739
|
+
output.push(`[Mindlore] ${diaryFiles.length} diary entry birikti \u2014 \`/mindlore-log reflect\` calistirmayi dusun.`);
|
|
166
740
|
}
|
|
167
|
-
} catch (_err) {
|
|
741
|
+
} catch (_err) {
|
|
742
|
+
}
|
|
168
743
|
}
|
|
169
744
|
timings.diary_walk = Date.now() - tDiary;
|
|
170
|
-
|
|
171
|
-
// Version check: compare .version (installed) vs .pkg-version (package)
|
|
172
745
|
const tVersion = Date.now();
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
const pkgVersionPath = path.join(baseDir, '.pkg-version');
|
|
746
|
+
const versionPath = path.join(baseDir, ".version");
|
|
747
|
+
const pkgVersionPath = path.join(baseDir, ".pkg-version");
|
|
176
748
|
try {
|
|
177
749
|
if (fs.existsSync(versionPath) && fs.existsSync(pkgVersionPath)) {
|
|
178
|
-
const installed = fs.readFileSync(versionPath,
|
|
179
|
-
const pkgVersion = fs.readFileSync(pkgVersionPath,
|
|
750
|
+
const installed = fs.readFileSync(versionPath, "utf8").trim();
|
|
751
|
+
const pkgVersion = fs.readFileSync(pkgVersionPath, "utf8").trim();
|
|
180
752
|
if (pkgVersion && pkgVersion !== installed) {
|
|
181
|
-
output.push(`[Mindlore: Guncelleme mevcut (${installed}
|
|
753
|
+
output.push(`[Mindlore: Guncelleme mevcut (${installed} \u2192 ${pkgVersion}). \`npx mindlore init\` calistirin.]`);
|
|
182
754
|
}
|
|
183
755
|
}
|
|
184
|
-
} catch (_err) {
|
|
756
|
+
} catch (_err) {
|
|
757
|
+
}
|
|
185
758
|
timings.version_check = Date.now() - tVersion;
|
|
186
|
-
|
|
187
|
-
// v0.5.4: Consolidated session payload (replaces scattered episodes/activity/alerts injection)
|
|
188
759
|
const tDb = Date.now();
|
|
189
760
|
const outputLenBeforeDb = output.reduce((s, o) => s + o.length, 0);
|
|
190
761
|
try {
|
|
191
|
-
const dbPath = path.join(baseDir,
|
|
762
|
+
const dbPath = path.join(baseDir, "mindlore.db");
|
|
192
763
|
const tDbOpen = Date.now();
|
|
193
764
|
const db = tryOpenDb(dbPath);
|
|
194
765
|
timings.db_open = Date.now() - tDbOpen;
|
|
195
766
|
timings.db_integrity = 0;
|
|
196
|
-
|
|
197
767
|
if (db) {
|
|
198
768
|
try {
|
|
199
|
-
// Schema version check: warn if DB is behind expected version
|
|
200
769
|
const tSchema = Date.now();
|
|
201
770
|
try {
|
|
202
|
-
const { EXPECTED_SCHEMA_VERSION } =
|
|
203
|
-
const row = db.prepare(
|
|
771
|
+
const { EXPECTED_SCHEMA_VERSION } = require_all_migrations();
|
|
772
|
+
const row = db.prepare("SELECT MAX(version) as v FROM schema_versions").get();
|
|
204
773
|
const current = row?.v ?? 0;
|
|
205
774
|
if (current < EXPECTED_SCHEMA_VERSION) {
|
|
206
|
-
output.push(`[Mindlore: schema
|
|
775
|
+
output.push(`[Mindlore: schema g\xFCncel de\u011Fil (v${current} \u2192 v${EXPECTED_SCHEMA_VERSION}). \`npx mindlore upgrade\` \xE7al\u0131\u015Ft\u0131r.]`);
|
|
207
776
|
}
|
|
208
|
-
} catch (_schemaErr) {
|
|
777
|
+
} catch (_schemaErr) {
|
|
778
|
+
}
|
|
209
779
|
timings.schema_check = Date.now() - tSchema;
|
|
210
|
-
|
|
211
780
|
loadDbContent({ db, baseDir, config, output, timings, latestDeltaContent, sessionId });
|
|
212
781
|
} catch (err) {
|
|
213
782
|
if (isCorruptionError(err)) {
|
|
214
|
-
recoverCorruptDb(db, dbPath,
|
|
783
|
+
recoverCorruptDb(db, dbPath, "session-focus");
|
|
215
784
|
}
|
|
216
785
|
} finally {
|
|
217
|
-
try {
|
|
786
|
+
try {
|
|
787
|
+
db.close();
|
|
788
|
+
} catch {
|
|
789
|
+
}
|
|
218
790
|
}
|
|
219
791
|
}
|
|
220
|
-
} catch (_err) {
|
|
792
|
+
} catch (_err) {
|
|
793
|
+
}
|
|
221
794
|
const outputLenAfterDb = output.reduce((s, o) => s + o.length, 0);
|
|
222
|
-
sourceChars +=
|
|
795
|
+
sourceChars += outputLenAfterDb - outputLenBeforeDb;
|
|
223
796
|
timings.db_total = Date.now() - tDb;
|
|
224
|
-
|
|
225
797
|
timings.total = Date.now() - t0;
|
|
226
|
-
hookLog(
|
|
227
|
-
|
|
228
|
-
// Token budget for session inject
|
|
229
|
-
// Defaults match DEFAULT_TOKEN_BUDGET in scripts/lib/constants.ts
|
|
798
|
+
hookLog("session-focus", "info", `timings: ${JSON.stringify(timings)}`);
|
|
230
799
|
const budgetConfig = config?.tokenBudget ?? {};
|
|
231
|
-
const maxInjectChars = (budgetConfig.sessionInject ||
|
|
232
|
-
|
|
233
|
-
let joined = output.join('\n\n');
|
|
800
|
+
const maxInjectChars = (budgetConfig.sessionInject || 2e3) * 4;
|
|
801
|
+
let joined = output.join("\n\n");
|
|
234
802
|
if (joined.length > maxInjectChars) {
|
|
235
|
-
joined = joined.slice(0, maxInjectChars) +
|
|
803
|
+
joined = joined.slice(0, maxInjectChars) + "\n[...truncated by token budget]";
|
|
236
804
|
}
|
|
237
|
-
|
|
238
|
-
// v0.6.1: Daemon auto-start removed (daemon deprecated — MCP Server in v0.7)
|
|
239
|
-
|
|
240
805
|
if (joined.length > 0) {
|
|
241
|
-
process.stdout.write(joined +
|
|
806
|
+
process.stdout.write(joined + "\n");
|
|
242
807
|
}
|
|
243
|
-
|
|
244
808
|
const inject_tokens = Math.ceil(joined.length / 4);
|
|
245
809
|
const source_tokens = Math.ceil(sourceChars / 4);
|
|
246
810
|
return { inject_tokens, source_tokens };
|
|
247
811
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
hookLog('mindlore-session-focus', 'error', err?.message ?? String(err));
|
|
812
|
+
withTelemetry("mindlore-session-focus", main).catch((err) => {
|
|
813
|
+
hookLog("mindlore-session-focus", "error", err?.message ?? String(err));
|
|
251
814
|
process.exit(0);
|
|
252
815
|
});
|
|
253
|
-
|
|
254
|
-
if (typeof module !== 'undefined') {
|
|
816
|
+
if (typeof module !== "undefined") {
|
|
255
817
|
module.exports = { truncateCommits, truncateChangedFiles, getEpisodeStats, checkStaleContent };
|
|
256
818
|
}
|