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.
Files changed (120) hide show
  1. package/README.md +30 -3
  2. package/dist/scripts/bundle-hooks.d.ts +2 -0
  3. package/dist/scripts/bundle-hooks.d.ts.map +1 -0
  4. package/dist/scripts/bundle-hooks.js +70 -0
  5. package/dist/scripts/bundle-hooks.js.map +1 -0
  6. package/dist/scripts/init.js +0 -3
  7. package/dist/scripts/init.js.map +1 -1
  8. package/dist/scripts/lib/all-migrations.d.ts.map +1 -1
  9. package/dist/scripts/lib/all-migrations.js +3 -0
  10. package/dist/scripts/lib/all-migrations.js.map +1 -1
  11. package/dist/scripts/lib/constants.d.ts +7 -2
  12. package/dist/scripts/lib/constants.d.ts.map +1 -1
  13. package/dist/scripts/lib/constants.js +17 -22
  14. package/dist/scripts/lib/constants.js.map +1 -1
  15. package/dist/scripts/lib/mcp-tools.d.ts.map +1 -1
  16. package/dist/scripts/lib/mcp-tools.js +63 -78
  17. package/dist/scripts/lib/mcp-tools.js.map +1 -1
  18. package/dist/scripts/lib/migrations-v072.d.ts +3 -0
  19. package/dist/scripts/lib/migrations-v072.d.ts.map +1 -0
  20. package/dist/scripts/lib/migrations-v072.js +25 -0
  21. package/dist/scripts/lib/migrations-v072.js.map +1 -0
  22. package/dist/scripts/lib/relation-helpers.d.ts +15 -0
  23. package/dist/scripts/lib/relation-helpers.d.ts.map +1 -0
  24. package/dist/scripts/lib/relation-helpers.js +30 -0
  25. package/dist/scripts/lib/relation-helpers.js.map +1 -0
  26. package/dist/scripts/lib/tool-adapters/get-adapter.d.ts +21 -0
  27. package/dist/scripts/lib/tool-adapters/get-adapter.d.ts.map +1 -0
  28. package/dist/scripts/lib/tool-adapters/get-adapter.js +51 -0
  29. package/dist/scripts/lib/tool-adapters/get-adapter.js.map +1 -0
  30. package/dist/scripts/lib/tool-adapters/relate-adapter.d.ts +34 -0
  31. package/dist/scripts/lib/tool-adapters/relate-adapter.d.ts.map +1 -0
  32. package/dist/scripts/lib/tool-adapters/relate-adapter.js +43 -0
  33. package/dist/scripts/lib/tool-adapters/relate-adapter.js.map +1 -0
  34. package/dist/scripts/lib/tool-adapters/search-adapter.d.ts +5 -0
  35. package/dist/scripts/lib/tool-adapters/search-adapter.d.ts.map +1 -1
  36. package/dist/scripts/lib/tool-adapters/search-adapter.js +37 -0
  37. package/dist/scripts/lib/tool-adapters/search-adapter.js.map +1 -1
  38. package/dist/scripts/mcp-server.js +1 -1
  39. package/dist/scripts/mcp-server.js.map +1 -1
  40. package/dist/tests/dont-repeat-dedup.test.d.ts +2 -0
  41. package/dist/tests/dont-repeat-dedup.test.d.ts.map +1 -0
  42. package/dist/tests/dont-repeat-dedup.test.js +93 -0
  43. package/dist/tests/dont-repeat-dedup.test.js.map +1 -0
  44. package/dist/tests/e2e-kg-pipeline.test.d.ts +2 -0
  45. package/dist/tests/e2e-kg-pipeline.test.d.ts.map +1 -0
  46. package/dist/tests/e2e-kg-pipeline.test.js +59 -0
  47. package/dist/tests/e2e-kg-pipeline.test.js.map +1 -0
  48. package/dist/tests/helpers/db.d.ts.map +1 -1
  49. package/dist/tests/helpers/db.js +2 -1
  50. package/dist/tests/helpers/db.js.map +1 -1
  51. package/dist/tests/hook-smoke.test.js +1 -1
  52. package/dist/tests/hook-smoke.test.js.map +1 -1
  53. package/dist/tests/mcp-get-tool.test.d.ts +2 -0
  54. package/dist/tests/mcp-get-tool.test.d.ts.map +1 -0
  55. package/dist/tests/mcp-get-tool.test.js +93 -0
  56. package/dist/tests/mcp-get-tool.test.js.map +1 -0
  57. package/dist/tests/mcp-relate-tool.test.d.ts +2 -0
  58. package/dist/tests/mcp-relate-tool.test.d.ts.map +1 -0
  59. package/dist/tests/mcp-relate-tool.test.js +85 -0
  60. package/dist/tests/mcp-relate-tool.test.js.map +1 -0
  61. package/dist/tests/mcp-server.test.js +3 -1
  62. package/dist/tests/mcp-server.test.js.map +1 -1
  63. package/dist/tests/mcp-tools.test.js +20 -0
  64. package/dist/tests/mcp-tools.test.js.map +1 -1
  65. package/dist/tests/memory-relate.test.d.ts +2 -0
  66. package/dist/tests/memory-relate.test.d.ts.map +1 -0
  67. package/dist/tests/memory-relate.test.js +70 -0
  68. package/dist/tests/memory-relate.test.js.map +1 -0
  69. package/dist/tests/migrations-v063.test.js +1 -1
  70. package/dist/tests/migrations-v072.test.d.ts +2 -0
  71. package/dist/tests/migrations-v072.test.d.ts.map +1 -0
  72. package/dist/tests/migrations-v072.test.js +74 -0
  73. package/dist/tests/migrations-v072.test.js.map +1 -0
  74. package/dist/tests/plugin-cache-regression.test.d.ts +2 -0
  75. package/dist/tests/plugin-cache-regression.test.d.ts.map +1 -0
  76. package/dist/tests/plugin-cache-regression.test.js +19 -0
  77. package/dist/tests/plugin-cache-regression.test.js.map +1 -0
  78. package/dist/tests/search-hook.test.js +1 -1
  79. package/dist/tests/search-hook.test.js.map +1 -1
  80. package/hooks/cc-memory-bulk-sync.cjs +606 -0
  81. package/hooks/cc-session-sync.cjs +856 -0
  82. package/hooks/hooks.json +149 -0
  83. package/hooks/lib/mindlore-common.cjs +2 -2
  84. package/hooks/lib/secure-io.cjs +17 -0
  85. package/hooks/mindlore-cwd-changed.cjs +19 -34
  86. package/hooks/mindlore-decision-detector.cjs +40 -31
  87. package/hooks/mindlore-dont-repeat.cjs +75 -115
  88. package/hooks/mindlore-fts5-sync.cjs +15 -44
  89. package/hooks/mindlore-index.cjs +100 -101
  90. package/hooks/mindlore-model-router.cjs +20 -32
  91. package/hooks/mindlore-post-compact.cjs +26 -42
  92. package/hooks/mindlore-post-read.cjs +35 -60
  93. package/hooks/mindlore-pre-compact.cjs +55 -73
  94. package/hooks/mindlore-read-guard.cjs +28 -51
  95. package/hooks/mindlore-research-guard.cjs +63 -101
  96. package/hooks/mindlore-search.cjs +1156 -93
  97. package/hooks/mindlore-session-end.cjs +155 -276
  98. package/hooks/mindlore-session-focus.cjs +672 -110
  99. package/hooks/src/lib/constants.cjs +15 -0
  100. package/hooks/src/lib/mindlore-common.cjs +975 -0
  101. package/hooks/src/lib/mindlore-common.d.cts +72 -0
  102. package/hooks/src/lib/secure-io.cjs +17 -0
  103. package/hooks/src/lib/types.d.ts +58 -0
  104. package/hooks/src/mindlore-cwd-changed.cjs +57 -0
  105. package/hooks/src/mindlore-decision-detector.cjs +54 -0
  106. package/hooks/src/mindlore-dont-repeat.cjs +243 -0
  107. package/hooks/src/mindlore-fts5-sync.cjs +98 -0
  108. package/hooks/src/mindlore-index.cjs +230 -0
  109. package/hooks/src/mindlore-model-router.cjs +54 -0
  110. package/hooks/src/mindlore-post-compact.cjs +69 -0
  111. package/hooks/src/mindlore-post-read.cjs +106 -0
  112. package/hooks/src/mindlore-pre-compact.cjs +154 -0
  113. package/hooks/src/mindlore-read-guard.cjs +105 -0
  114. package/hooks/src/mindlore-research-guard.cjs +176 -0
  115. package/hooks/src/mindlore-search.cjs +200 -0
  116. package/hooks/src/mindlore-session-end.cjs +511 -0
  117. package/hooks/src/mindlore-session-focus.cjs +256 -0
  118. package/package.json +8 -3
  119. package/plugin.json +5 -4
  120. package/templates/config.json +1 -1
@@ -1,256 +1,818 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
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
- * mindlore-session-focus — SessionStart hook
6
- *
7
- * Injects last delta file content + INDEX.md into session context.
8
- * Fires once at session start via stdout additionalContext.
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
- const fs = require('fs');
12
- const path = require('path');
13
- const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry, withTimeoutDb, listSnapshots, isCorruptionError, recoverCorruptDb, getNominationCounts } = require('./lib/mindlore-common.cjs');
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('\n');
604
+ const lines = match[2].trim().split("\n");
19
605
  if (lines.length <= keepCount) return content;
20
- const kept = lines.slice(0, keepCount).join('\n');
21
- return content.replace(match[2].trim(), kept + `\n- ...ve ${lines.length - keepCount} ${label} daha`);
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, 'commit');
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, 'dosya');
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(db,
623
+ const rawCount = withTimeoutDb(
624
+ db,
41
625
  "SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL",
42
- [], { mode: 'get' });
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 \`/mindlore-maintain consolidate\` ile birleştirmeyi düşün.`;
632
+ consolidationMsg = `[Mindlore] ${cnt} raw episode birikti \u2014 \`/mindlore-maintain consolidate\` ile birle\u015Ftirmeyi d\xFC\u015F\xFCn.`;
47
633
  }
48
- } catch (_err) { /* consolidation_status column may not exist yet */ }
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() - (30 * 24 * 60 * 60 * 1000)).toISOString();
55
- const row = withTimeoutDb(db, 'SELECT COUNT(*) as cnt FROM file_hashes WHERE last_indexed < ?', [thirtyDaysAgo], { mode: 'get' });
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 \`/mindlore-evolve\` dusun]`;
644
+ return `[Mindlore: ${staleCount} dosya 30+ gundur guncellenmemis \u2014 \`/mindlore-evolve\` dusun]`;
59
645
  }
60
- } catch (_staleErr) { /* file_hashes may not exist */ }
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 } = require('../dist/scripts/lib/session-payload.js');
70
- const payloadBudget = config?.tokenBudget?.sessionInject ?? 2000;
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}]\n${section.content}`);
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]\n${formatSupersededChains(chains)}`);
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 \`/mindlore-reflect\` çalıştır`);
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) { /* graduation not available */ }
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; // No .mindlore/ found, silently skip
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, 'utf8') || '{}');
122
- sessionId = stdinData.session_id || undefined;
123
- } catch { sessionId = undefined; }
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, 'INDEX.md');
709
+ const indexPath = path.join(baseDir, "INDEX.md");
133
710
  if (fs.existsSync(indexPath)) {
134
- const content = fs.readFileSync(indexPath, 'utf8').trim();
711
+ const content = fs.readFileSync(indexPath, "utf8").trim();
135
712
  sourceChars += content.length;
136
- output.push(`[Mindlore INDEX]\n${content}`);
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, 'diary');
143
- let latestDeltaContent = undefined;
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('delta-'));
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, 'utf8').trim();
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}]\n${truncateChangedFiles(truncateCommits(deltaContent))}`);
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 \`/mindlore-log reflect\` calistirmayi dusun.`);
739
+ output.push(`[Mindlore] ${diaryFiles.length} diary entry birikti \u2014 \`/mindlore-log reflect\` calistirmayi dusun.`);
166
740
  }
167
- } catch (_err) { /* skip */ }
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
- // Both are flat strings written by init — no JSON parse needed on session start
174
- const versionPath = path.join(baseDir, '.version');
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, 'utf8').trim();
179
- const pkgVersion = fs.readFileSync(pkgVersionPath, 'utf8').trim();
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} ${pkgVersion}). \`npx mindlore init\` calistirin.]`);
753
+ output.push(`[Mindlore: Guncelleme mevcut (${installed} \u2192 ${pkgVersion}). \`npx mindlore init\` calistirin.]`);
182
754
  }
183
755
  }
184
- } catch (_err) { /* skip */ }
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, 'mindlore.db');
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 } = require('../dist/scripts/lib/all-migrations.js');
203
- const row = db.prepare('SELECT MAX(version) as v FROM schema_versions').get();
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 güncel değil (v${current} v${EXPECTED_SCHEMA_VERSION}). \`npx mindlore upgrade\` çalıştır.]`);
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) { /* schema_versions may not exist yet */ }
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, 'session-focus');
783
+ recoverCorruptDb(db, dbPath, "session-focus");
215
784
  }
216
785
  } finally {
217
- try { db.close(); } catch { /* already closed by recovery */ }
786
+ try {
787
+ db.close();
788
+ } catch {
789
+ }
218
790
  }
219
791
  }
220
- } catch (_err) { /* graceful skip */ }
792
+ } catch (_err) {
793
+ }
221
794
  const outputLenAfterDb = output.reduce((s, o) => s + o.length, 0);
222
- sourceChars += (outputLenAfterDb - outputLenBeforeDb);
795
+ sourceChars += outputLenAfterDb - outputLenBeforeDb;
223
796
  timings.db_total = Date.now() - tDb;
224
-
225
797
  timings.total = Date.now() - t0;
226
- hookLog('session-focus', 'info', `timings: ${JSON.stringify(timings)}`);
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 || 2000) * 4;
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) + '\n[...truncated by token budget]';
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 + '\n');
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
- withTelemetry('mindlore-session-focus', main).catch(err => {
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
  }