mindlore 0.7.6 → 0.7.7

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 (148) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/README.md +3 -1
  4. package/dist/scripts/bundle-hooks.js +5 -1
  5. package/dist/scripts/bundle-hooks.js.map +1 -1
  6. package/dist/scripts/init.js +49 -10
  7. package/dist/scripts/init.js.map +1 -1
  8. package/dist/scripts/lib/constants.d.ts +8 -0
  9. package/dist/scripts/lib/constants.d.ts.map +1 -1
  10. package/dist/scripts/lib/constants.js +9 -1
  11. package/dist/scripts/lib/constants.js.map +1 -1
  12. package/dist/scripts/lib/db-helpers.d.ts +6 -0
  13. package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
  14. package/dist/scripts/lib/db-helpers.js +6 -0
  15. package/dist/scripts/lib/db-helpers.js.map +1 -1
  16. package/dist/scripts/lib/read-guard-core.d.ts +21 -0
  17. package/dist/scripts/lib/read-guard-core.d.ts.map +1 -0
  18. package/dist/scripts/lib/read-guard-core.js +40 -0
  19. package/dist/scripts/lib/read-guard-core.js.map +1 -0
  20. package/dist/scripts/lib/search-cache.d.ts +1 -7
  21. package/dist/scripts/lib/search-cache.d.ts.map +1 -1
  22. package/dist/scripts/lib/search-cache.js +3 -25
  23. package/dist/scripts/lib/search-cache.js.map +1 -1
  24. package/dist/scripts/lib/search-throttle.d.ts +10 -0
  25. package/dist/scripts/lib/search-throttle.d.ts.map +1 -0
  26. package/dist/scripts/lib/search-throttle.js +32 -0
  27. package/dist/scripts/lib/search-throttle.js.map +1 -0
  28. package/dist/scripts/lib/settings-cleanup.d.ts.map +1 -1
  29. package/dist/scripts/lib/settings-cleanup.js +2 -1
  30. package/dist/scripts/lib/settings-cleanup.js.map +1 -1
  31. package/dist/scripts/lib/setup-wizard.d.ts +13 -0
  32. package/dist/scripts/lib/setup-wizard.d.ts.map +1 -0
  33. package/dist/scripts/lib/setup-wizard.js +51 -0
  34. package/dist/scripts/lib/setup-wizard.js.map +1 -0
  35. package/dist/scripts/lib/tool-adapters/decide-adapter.d.ts.map +1 -1
  36. package/dist/scripts/lib/tool-adapters/decide-adapter.js +3 -3
  37. package/dist/scripts/lib/tool-adapters/decide-adapter.js.map +1 -1
  38. package/dist/scripts/lib/tool-adapters/get-adapter.d.ts.map +1 -1
  39. package/dist/scripts/lib/tool-adapters/get-adapter.js +10 -2
  40. package/dist/scripts/lib/tool-adapters/get-adapter.js.map +1 -1
  41. package/dist/scripts/lib/tool-adapters/ingest-adapter.d.ts.map +1 -1
  42. package/dist/scripts/lib/tool-adapters/ingest-adapter.js +3 -3
  43. package/dist/scripts/lib/tool-adapters/ingest-adapter.js.map +1 -1
  44. package/dist/scripts/lib/transcript-token-estimator.d.ts +8 -0
  45. package/dist/scripts/lib/transcript-token-estimator.d.ts.map +1 -0
  46. package/dist/scripts/lib/transcript-token-estimator.js +164 -0
  47. package/dist/scripts/lib/transcript-token-estimator.js.map +1 -0
  48. package/dist/scripts/maintain-cleanup.d.ts.map +1 -1
  49. package/dist/scripts/maintain-cleanup.js +2 -1
  50. package/dist/scripts/maintain-cleanup.js.map +1 -1
  51. package/dist/scripts/mcp-server.js +3 -3
  52. package/dist/scripts/mcp-server.js.map +1 -1
  53. package/dist/scripts/mindlore-backup.d.ts.map +1 -1
  54. package/dist/scripts/mindlore-backup.js +3 -2
  55. package/dist/scripts/mindlore-backup.js.map +1 -1
  56. package/dist/scripts/mindlore-clean-cache.d.ts +4 -1
  57. package/dist/scripts/mindlore-clean-cache.d.ts.map +1 -1
  58. package/dist/scripts/mindlore-clean-cache.js +47 -20
  59. package/dist/scripts/mindlore-clean-cache.js.map +1 -1
  60. package/dist/scripts/mindlore-doctor.d.ts +4 -0
  61. package/dist/scripts/mindlore-doctor.d.ts.map +1 -1
  62. package/dist/scripts/mindlore-doctor.js +9 -1
  63. package/dist/scripts/mindlore-doctor.js.map +1 -1
  64. package/dist/scripts/mindlore-health-check.d.ts +7 -0
  65. package/dist/scripts/mindlore-health-check.d.ts.map +1 -1
  66. package/dist/scripts/mindlore-health-check.js +57 -4
  67. package/dist/scripts/mindlore-health-check.js.map +1 -1
  68. package/dist/scripts/mindlore-learnings.d.ts +6 -0
  69. package/dist/scripts/mindlore-learnings.d.ts.map +1 -0
  70. package/dist/scripts/mindlore-learnings.js +106 -0
  71. package/dist/scripts/mindlore-learnings.js.map +1 -0
  72. package/dist/scripts/mindlore-obsidian.js +6 -5
  73. package/dist/scripts/mindlore-obsidian.js.map +1 -1
  74. package/dist/scripts/quality-populate.js +2 -1
  75. package/dist/scripts/quality-populate.js.map +1 -1
  76. package/dist/scripts/uninstall.js +2 -1
  77. package/dist/scripts/uninstall.js.map +1 -1
  78. package/dist/tests/clean-cache-eperm.test.d.ts +2 -0
  79. package/dist/tests/clean-cache-eperm.test.d.ts.map +1 -0
  80. package/dist/tests/clean-cache-eperm.test.js +74 -0
  81. package/dist/tests/clean-cache-eperm.test.js.map +1 -0
  82. package/dist/tests/doctor.test.js +18 -0
  83. package/dist/tests/doctor.test.js.map +1 -1
  84. package/dist/tests/health-check.test.d.ts +2 -0
  85. package/dist/tests/health-check.test.d.ts.map +1 -0
  86. package/dist/tests/health-check.test.js +61 -0
  87. package/dist/tests/health-check.test.js.map +1 -0
  88. package/dist/tests/helpers/db.d.ts +7 -2
  89. package/dist/tests/helpers/db.d.ts.map +1 -1
  90. package/dist/tests/helpers/db.js +16 -14
  91. package/dist/tests/helpers/db.js.map +1 -1
  92. package/dist/tests/mindlore-ingest-extraction.test.d.ts +2 -0
  93. package/dist/tests/mindlore-ingest-extraction.test.d.ts.map +1 -0
  94. package/dist/tests/mindlore-ingest-extraction.test.js +48 -0
  95. package/dist/tests/mindlore-ingest-extraction.test.js.map +1 -0
  96. package/dist/tests/mindlore-learnings.test.d.ts +2 -0
  97. package/dist/tests/mindlore-learnings.test.d.ts.map +1 -0
  98. package/dist/tests/mindlore-learnings.test.js +63 -0
  99. package/dist/tests/mindlore-learnings.test.js.map +1 -0
  100. package/dist/tests/read-guard-perf.test.d.ts +2 -0
  101. package/dist/tests/read-guard-perf.test.d.ts.map +1 -0
  102. package/dist/tests/read-guard-perf.test.js +31 -0
  103. package/dist/tests/read-guard-perf.test.js.map +1 -0
  104. package/dist/tests/reflect-trigger.test.js +8 -1
  105. package/dist/tests/reflect-trigger.test.js.map +1 -1
  106. package/dist/tests/search-cache.test.js +0 -35
  107. package/dist/tests/search-cache.test.js.map +1 -1
  108. package/dist/tests/search-throttle.test.d.ts +2 -0
  109. package/dist/tests/search-throttle.test.d.ts.map +1 -0
  110. package/dist/tests/search-throttle.test.js +53 -0
  111. package/dist/tests/search-throttle.test.js.map +1 -0
  112. package/dist/tests/session-focus-reflect-nudge.test.js +3 -3
  113. package/dist/tests/session-focus-reflect-nudge.test.js.map +1 -1
  114. package/dist/tests/setup-wizard.test.d.ts +2 -0
  115. package/dist/tests/setup-wizard.test.d.ts.map +1 -0
  116. package/dist/tests/setup-wizard.test.js +35 -0
  117. package/dist/tests/setup-wizard.test.js.map +1 -0
  118. package/dist/tests/transcript-token-estimator.test.d.ts +2 -0
  119. package/dist/tests/transcript-token-estimator.test.d.ts.map +1 -0
  120. package/dist/tests/transcript-token-estimator.test.js +122 -0
  121. package/dist/tests/transcript-token-estimator.test.js.map +1 -0
  122. package/hooks/cc-memory-bulk-sync.cjs +9 -1
  123. package/hooks/cc-session-sync.cjs +9 -1
  124. package/hooks/lib/learnings-loader.cjs +21 -11
  125. package/hooks/lib/reflect-trigger.cjs +6 -3
  126. package/hooks/mindlore-cwd-changed.cjs +4 -5
  127. package/hooks/mindlore-dont-repeat.cjs +2 -1
  128. package/hooks/mindlore-post-read.cjs +2 -1
  129. package/hooks/mindlore-pre-compact.cjs +3 -2
  130. package/hooks/mindlore-read-guard.cjs +62 -35
  131. package/hooks/mindlore-search.cjs +231 -31
  132. package/hooks/mindlore-session-end.cjs +6 -8
  133. package/hooks/mindlore-session-focus.cjs +472 -23
  134. package/hooks/src/mindlore-cwd-changed.cjs +4 -5
  135. package/hooks/src/mindlore-dont-repeat.cjs +2 -1
  136. package/hooks/src/mindlore-post-read.cjs +2 -1
  137. package/hooks/src/mindlore-pre-compact.cjs +3 -2
  138. package/hooks/src/mindlore-read-guard.cjs +15 -55
  139. package/hooks/src/mindlore-search.cjs +39 -10
  140. package/hooks/src/mindlore-session-end.cjs +6 -8
  141. package/hooks/src/mindlore-session-focus.cjs +29 -21
  142. package/mcp-server.cjs +41 -25
  143. package/package.json +1 -1
  144. package/plugin.json +6 -1
  145. package/skills/mindlore-ingest/SKILL.md +21 -0
  146. package/skills/mindlore-learnings/SKILL.md +30 -0
  147. package/start.cjs +1 -1
  148. package/templates/config.json +1 -1
@@ -34,7 +34,7 @@ var require_constants = __commonJS({
34
34
  return mod && mod.__esModule ? mod : { "default": mod };
35
35
  };
36
36
  Object.defineProperty(exports2, "__esModule", { value: true });
37
- exports2.CONSOLIDATION_THRESHOLD = exports2.STALE_THRESHOLD = exports2.DECAY_HALF_LIFE_DAYS = exports2.DEFAULT_TOKEN_BUDGET = exports2.TELEMETRY_FILE_ROTATE_BYTES = exports2.TELEMETRY_OUTPUT_MAX_BYTES = exports2.TELEMETRY_FILENAME = exports2.CC_MEMORY_BOOST = exports2.CC_SUBAGENT_CATEGORY = exports2.CC_SESSION_CATEGORY = exports2.CC_MEMORY_CATEGORY = exports2.CC_MEMORY_DIR = exports2.CC_MEMORY_PATH_MARKER = exports2.CC_PLUGIN_CACHE_DIR = exports2.TYPE_TO_DIR = exports2.PRIORITY_CASE = exports2.RELATED_OVERFETCH = exports2.MAX_RELATED_SOURCES = exports2.RELATION_PRIORITY = exports2.SYMMETRIC_TYPES = exports2.RELATION_TYPES = exports2.QUALITY_HEURISTICS = exports2.QUALITY_VALUES = exports2.FRONTMATTER_TYPES = exports2.FTS5_COLUMNS = exports2.STOP_WORDS = exports2.TURKISH_WORD_RE = exports2.STOP_WORDS_MIN_LENGTH = exports2.SESSION_CATEGORIES = exports2.CATEGORIES = exports2.SCHEMA_VERSION = exports2.DEFAULT_MODELS = exports2.CONFIG_FILE = exports2.MCP_BUSY_TIMEOUT_MS = exports2.DB_BUSY_TIMEOUT_MS = exports2.SKIP_FILES = exports2.DIRECTORIES = exports2.DB_NAME = exports2.GLOBAL_MINDLORE_DIR = exports2.MINDLORE_DIR = exports2.KNOWN_HOOK_EVENTS = void 0;
37
+ exports2.CACHE_STALE_AGE_MS = exports2.NUDGE_COOLDOWN_HOURS = exports2.REFLECT_THRESHOLD_DAYS = exports2.LEARNINGS_TOTAL_CHAR_BUDGET = exports2.LEARNINGS_MAX_LINES_PER_LESSON = exports2.LEARNINGS_MAX_LESSONS = exports2.CONSOLIDATION_THRESHOLD = exports2.STALE_THRESHOLD = exports2.DECAY_HALF_LIFE_DAYS = exports2.DEFAULT_TOKEN_BUDGET = exports2.TELEMETRY_FILE_ROTATE_BYTES = exports2.TELEMETRY_OUTPUT_MAX_BYTES = exports2.TELEMETRY_FILENAME = exports2.CC_MEMORY_BOOST = exports2.CC_SUBAGENT_CATEGORY = exports2.CC_SESSION_CATEGORY = exports2.CC_MEMORY_CATEGORY = exports2.CC_MEMORY_DIR = exports2.CC_MEMORY_PATH_MARKER = exports2.CC_PLUGIN_CACHE_DIR = exports2.SLUG_OPTIONAL_TYPES = exports2.NESTED_DIR_TYPES = exports2.TYPE_TO_DIR = exports2.PRIORITY_CASE = exports2.RELATED_OVERFETCH = exports2.MAX_RELATED_SOURCES = exports2.RELATION_PRIORITY = exports2.SYMMETRIC_TYPES = exports2.RELATION_TYPES = exports2.QUALITY_HEURISTICS = exports2.QUALITY_VALUES = exports2.FRONTMATTER_TYPES = exports2.FTS5_COLUMNS = exports2.STOP_WORDS = exports2.TURKISH_WORD_RE = exports2.STOP_WORDS_MIN_LENGTH = exports2.SESSION_CATEGORIES = exports2.CATEGORIES = exports2.SCHEMA_VERSION = exports2.DEFAULT_MODELS = exports2.CONFIG_FILE = exports2.MCP_BUSY_TIMEOUT_MS = exports2.DB_BUSY_TIMEOUT_MS = exports2.SKIP_FILES = exports2.DIRECTORIES = exports2.DB_NAME = exports2.GLOBAL_MINDLORE_DIR = exports2.MINDLORE_DIR = exports2.KNOWN_HOOK_EVENTS = void 0;
38
38
  exports2.isKnownHookEvent = isKnownHookEvent;
39
39
  exports2.isSessionCategory = isSessionCategory;
40
40
  exports2.fixVersionTokens = fixVersionTokens;
@@ -355,6 +355,8 @@ var require_constants = __commonJS({
355
355
  reference: "memory",
356
356
  note: "memory"
357
357
  };
358
+ exports2.NESTED_DIR_TYPES = /* @__PURE__ */ new Set(["raw"]);
359
+ exports2.SLUG_OPTIONAL_TYPES = /* @__PURE__ */ new Set(["raw", "compaction-snapshot"]);
358
360
  exports2.CC_PLUGIN_CACHE_DIR = path_12.default.join(os_12.default.homedir(), ".claude", "plugins", "cache");
359
361
  exports2.CC_MEMORY_PATH_MARKER = path_12.default.join(".claude", "projects");
360
362
  exports2.CC_MEMORY_DIR = "memory";
@@ -426,6 +428,12 @@ var require_constants = __commonJS({
426
428
  exports2.DECAY_HALF_LIFE_DAYS = 30;
427
429
  exports2.STALE_THRESHOLD = 0.3;
428
430
  exports2.CONSOLIDATION_THRESHOLD = 50;
431
+ exports2.LEARNINGS_MAX_LESSONS = 10;
432
+ exports2.LEARNINGS_MAX_LINES_PER_LESSON = 5;
433
+ exports2.LEARNINGS_TOTAL_CHAR_BUDGET = 6e3;
434
+ exports2.REFLECT_THRESHOLD_DAYS = 7;
435
+ exports2.NUDGE_COOLDOWN_HOURS = 24;
436
+ exports2.CACHE_STALE_AGE_MS = 24 * 3600 * 1e3;
429
437
  }
430
438
  });
431
439
 
@@ -1,22 +1,32 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { parseFrontmatter, hookLog } = require('./mindlore-common.cjs');
4
-
5
- const MAX_LESSONS = 10;
6
- const MAX_LINES_PER_LESSON = 5;
7
- const TOTAL_CHAR_BUDGET = 6000;
4
+ const { LEARNINGS_MAX_LESSONS, LEARNINGS_MAX_LINES_PER_LESSON, LEARNINGS_TOTAL_CHAR_BUDGET } = require('../../dist/scripts/lib/constants.js');
8
5
 
9
6
  function summarizeLesson(body, relPath) {
10
7
  const lines = body.split('\n');
11
8
  const h2Idx = lines.findIndex(l => l.startsWith('## '));
12
9
  const start = h2Idx >= 0 ? h2Idx : 0;
13
- const slice = lines.slice(start, start + MAX_LINES_PER_LESSON).join('\n');
14
- const rest = lines.slice(start + MAX_LINES_PER_LESSON).length > 0
10
+ const slice = lines.slice(start, start + LEARNINGS_MAX_LINES_PER_LESSON).join('\n');
11
+ const rest = lines.slice(start + LEARNINGS_MAX_LINES_PER_LESSON).length > 0
15
12
  ? `\n… (full: ${relPath})`
16
13
  : '';
17
14
  return slice + rest;
18
15
  }
19
16
 
17
+ function readProjectField(filePath) {
18
+ const buf = Buffer.alloc(512);
19
+ const fd = fs.openSync(filePath, 'r');
20
+ try {
21
+ const n = fs.readSync(fd, buf, 0, 512, 0);
22
+ const head = buf.subarray(0, n).toString('utf8');
23
+ const m = head.match(/^project:\s*(.+)$/m);
24
+ return m ? m[1].trim() : undefined;
25
+ } finally {
26
+ fs.closeSync(fd);
27
+ }
28
+ }
29
+
20
30
  function loadLearningsBlock(mindloreDir, currentProject) {
21
31
  const learningsDir = path.join(mindloreDir, 'learnings');
22
32
  if (!fs.existsSync(learningsDir)) return '';
@@ -37,15 +47,15 @@ function loadLearningsBlock(mindloreDir, currentProject) {
37
47
 
38
48
  const candidates = [];
39
49
  for (const s of stats) {
40
- if (candidates.length >= MAX_LESSONS) break;
50
+ if (candidates.length >= LEARNINGS_MAX_LESSONS) break;
51
+ const project = readProjectField(s.abs) || 'global';
52
+ if (project !== 'global' && project !== currentProject) continue;
41
53
  let raw;
42
54
  try { raw = fs.readFileSync(s.abs, 'utf8'); } catch (err) {
43
55
  hookLog('learnings-loader', 'warn', `read skipped ${s.file}: ${err.message}`);
44
56
  continue;
45
57
  }
46
- const { meta, body } = parseFrontmatter(raw);
47
- const project = meta.project || 'global';
48
- if (project !== 'global' && project !== currentProject) continue;
58
+ const { body } = parseFrontmatter(raw);
49
59
  candidates.push({
50
60
  relPath: `.mindlore/learnings/${s.file}`,
51
61
  body,
@@ -59,7 +69,7 @@ function loadLearningsBlock(mindloreDir, currentProject) {
59
69
  let count = 0;
60
70
  for (const c of candidates) {
61
71
  const piece = summarizeLesson(c.body, c.relPath) + '\n\n';
62
- if (used + piece.length > TOTAL_CHAR_BUDGET && count > 0) break;
72
+ if (used + piece.length > LEARNINGS_TOTAL_CHAR_BUDGET && count > 0) break;
63
73
  block += piece;
64
74
  used += piece.length;
65
75
  count++;
@@ -1,5 +1,4 @@
1
- const REFLECT_THRESHOLD_DAYS = 7;
2
- const NUDGE_COOLDOWN_HOURS = 24;
1
+ const { REFLECT_THRESHOLD_DAYS, NUDGE_COOLDOWN_HOURS } = require('../../dist/scripts/lib/constants.js');
3
2
 
4
3
  function isValidDate(iso) {
5
4
  if (!iso) return false;
@@ -26,4 +25,8 @@ function shouldNudgeReflect(lastReflectIso, lastNudgeIso, now = new Date()) {
26
25
  return true;
27
26
  }
28
27
 
29
- module.exports = { shouldNudgeReflect, REFLECT_THRESHOLD_DAYS, NUDGE_COOLDOWN_HOURS };
28
+ function buildNudgeMessage(params) {
29
+ return `[Mindlore] Son reflect'inden ${params.daysSince} gün geçti. ${params.episodeCount} episode + ${params.diaryCount} diary birikti — \`/mindlore-reflect\` ile pattern özetle.`;
30
+ }
31
+
32
+ module.exports = { shouldNudgeReflect, buildNudgeMessage, REFLECT_THRESHOLD_DAYS, NUDGE_COOLDOWN_HOURS };
@@ -5,15 +5,14 @@
5
5
  var fs = require("fs");
6
6
  var path = require("path");
7
7
  var { findMindloreDir, globalDir, hookLog, withTelemetry } = require("./lib/mindlore-common.cjs");
8
+ var { safeMkdir, safeWriteFile } = require("./lib/secure-io.cjs");
8
9
  function main() {
9
10
  const cwd = process.cwd();
10
11
  const activeDir = findMindloreDir();
11
12
  const scope = !activeDir ? "none" : activeDir.startsWith(globalDir()) ? "global" : "project";
12
13
  if (activeDir) {
13
14
  const diaryDir = path.join(activeDir, "diary");
14
- if (!fs.existsSync(diaryDir)) {
15
- fs.mkdirSync(diaryDir, { recursive: true });
16
- }
15
+ safeMkdir(diaryDir);
17
16
  const scopePath = path.join(diaryDir, "_scope.json");
18
17
  if (fs.existsSync(scopePath)) {
19
18
  try {
@@ -22,12 +21,12 @@ function main() {
22
21
  } catch (_err) {
23
22
  }
24
23
  }
25
- fs.writeFileSync(scopePath, JSON.stringify({
24
+ safeWriteFile(scopePath, JSON.stringify({
26
25
  scope,
27
26
  dir: activeDir,
28
27
  cwd,
29
28
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
30
- }, null, 2), "utf8");
29
+ }, null, 2));
31
30
  }
32
31
  if (scope === "none") {
33
32
  process.stderr.write(`[Mindlore] Bu projede mindlore kurulu degil. npx mindlore init calistirin.
@@ -6,6 +6,7 @@ var fs = require("fs");
6
6
  var path = require("path");
7
7
  var os = require("os");
8
8
  var { findMindloreDir, getProjectName, hookLog, withTelemetrySync } = require("./lib/mindlore-common.cjs");
9
+ var { safeWriteFile } = require("./lib/secure-io.cjs");
9
10
  var cacheDirty = false;
10
11
  function readCache(cachePath) {
11
12
  if (!cachePath) return {};
@@ -18,7 +19,7 @@ function readCache(cachePath) {
18
19
  function writeCache(cachePath, cache) {
19
20
  if (!cachePath || !cacheDirty) return;
20
21
  try {
21
- fs.writeFileSync(cachePath, JSON.stringify(cache), "utf8");
22
+ safeWriteFile(cachePath, JSON.stringify(cache));
22
23
  } catch (_err) {
23
24
  }
24
25
  }
@@ -5,6 +5,7 @@
5
5
  var fs = require("fs");
6
6
  var path = require("path");
7
7
  var { findMindloreDir, getProjectName, hookLog, withTelemetry } = require("./lib/mindlore-common.cjs");
8
+ var { safeWriteFile } = require("./lib/secure-io.cjs");
8
9
  var CODE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".py", ".rs", ".go", ".java", ".c", ".cpp", ".h", ".css", ".scss", ".sql", ".sh", ".yaml", ".yml", ".json", ".toml", ".xml", ".cjs", ".mjs"]);
9
10
  var PROSE_EXTS = /* @__PURE__ */ new Set([".md", ".txt", ".rst", ".adoc"]);
10
11
  function estimateTokens(charCount, ext) {
@@ -63,7 +64,7 @@ function main() {
63
64
  } else {
64
65
  reads[key] = { count: 1, tokens, chars: charCount };
65
66
  }
66
- fs.writeFileSync(readsPath, JSON.stringify(reads, null, 2), "utf8");
67
+ safeWriteFile(readsPath, JSON.stringify(reads, null, 2));
67
68
  const basename = path.basename(filePath);
68
69
  process.stdout.write(JSON.stringify({
69
70
  hookSpecificOutput: {
@@ -5,6 +5,7 @@
5
5
  var fs = require("fs");
6
6
  var path = require("path");
7
7
  var { findMindloreDir, openDatabase, hookLog, withTelemetry, listSnapshots } = require("./lib/mindlore-common.cjs");
8
+ var { safeWriteFile } = require("./lib/secure-io.cjs");
8
9
  function collectRecentEpisodes(baseDir) {
9
10
  try {
10
11
  const dbPath = path.join(baseDir, "mindlore.db");
@@ -93,7 +94,7 @@ function main() {
93
94
  `Pre-compact snapshot at ${iso}.`,
94
95
  `Working directory: ${process.cwd()}`
95
96
  ].join("\n");
96
- fs.writeFileSync(episodePath, content, "utf8");
97
+ safeWriteFile(episodePath, content);
97
98
  } catch (_err) {
98
99
  }
99
100
  const logPath = path.join(baseDir, "log.md");
@@ -119,7 +120,7 @@ function main() {
119
120
  "",
120
121
  ...sections
121
122
  ].join("\n");
122
- fs.writeFileSync(path.join(diaryDir, `compaction-snapshot-${ts}.md`), snapshotContent);
123
+ safeWriteFile(path.join(diaryDir, `compaction-snapshot-${ts}.md`), snapshotContent);
123
124
  }
124
125
  const snapshots = listSnapshots(diaryDir).filter((f) => f.startsWith("compaction-"));
125
126
  while (snapshots.length > 5) {
@@ -1,10 +1,59 @@
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
+ };
7
+
8
+ // dist/scripts/lib/read-guard-core.js
9
+ var require_read_guard_core = __commonJS({
10
+ "dist/scripts/lib/read-guard-core.js"(exports2) {
11
+ "use strict";
12
+ Object.defineProperty(exports2, "__esModule", { value: true });
13
+ exports2.runReadGuard = runReadGuard2;
14
+ function runReadGuard2(input, existingReads) {
15
+ const normalizedPath = input.filePath;
16
+ const existing = existingReads[normalizedPath];
17
+ let count;
18
+ let tokens;
19
+ if (typeof existing === "number") {
20
+ count = existing + 1;
21
+ tokens = 0;
22
+ } else if (existing && typeof existing === "object") {
23
+ count = (existing.count || 0) + 1;
24
+ tokens = existing.tokens || 0;
25
+ } else {
26
+ count = 1;
27
+ tokens = 0;
28
+ }
29
+ const updatedReadsEntry = { count, tokens, chars: 0 };
30
+ existingReads[normalizedPath] = updatedReadsEntry;
31
+ if (count >= 3) {
32
+ const totalWaste = tokens > 0 ? ` Toplam israf: ~${tokens * (count - 1)} token.` : "";
33
+ return {
34
+ block: true,
35
+ warning: `[Mindlore BLOCK] ${input.basename} bu session'da ${count}. kez okunuyor.${totalWaste} Edit icin gerekiyorsa once degisikligini yap, sonra tekrar oku. Analiz icin ctx_execute_file kullan.`,
36
+ updatedReadsEntry
37
+ };
38
+ }
39
+ if (count > 1) {
40
+ const totalWaste = tokens > 0 ? ` Toplam tekrar: ~${tokens * (count - 1)} token.` : "";
41
+ return {
42
+ additionalContext: `[Mindlore: ${input.basename} bu session'da ${count}. kez okunuyor.${totalWaste} Bir sonraki okuma engellenecek \u2014 Edit gerekiyorsa simdi yap.]`,
43
+ updatedReadsEntry
44
+ };
45
+ }
46
+ return { updatedReadsEntry };
47
+ }
48
+ }
49
+ });
3
50
 
4
51
  // hooks/src/mindlore-read-guard.cjs
5
52
  var fs = require("fs");
6
53
  var path = require("path");
7
54
  var { findMindloreDir, readHookStdin, getProjectName, hookLog, extractSkeleton, withTelemetrySync } = require("./lib/mindlore-common.cjs");
55
+ var { safeMkdir, safeWriteFile } = require("./lib/secure-io.cjs");
56
+ var { runReadGuard } = require_read_guard_core();
8
57
  function main() {
9
58
  const baseDir = findMindloreDir();
10
59
  if (!baseDir) return;
@@ -15,45 +64,23 @@ function main() {
15
64
  if (!resolved.startsWith(cwd)) return;
16
65
  if (resolved.startsWith(path.resolve(baseDir))) return;
17
66
  const diaryDir = path.join(baseDir, "diary");
18
- if (!fs.existsSync(diaryDir)) {
19
- fs.mkdirSync(diaryDir, { recursive: true });
20
- }
67
+ safeMkdir(diaryDir);
21
68
  const readsPath = path.join(diaryDir, `_session-reads-${getProjectName()}.json`);
22
69
  let reads = {};
23
- if (fs.existsSync(readsPath)) {
24
- try {
25
- reads = JSON.parse(fs.readFileSync(readsPath, "utf8"));
26
- } catch (_err) {
27
- reads = {};
28
- }
29
- }
30
- const normalizedPath = path.resolve(filePath);
31
- const existing = reads[normalizedPath];
32
- let count, tokens;
33
- if (typeof existing === "number") {
34
- count = existing + 1;
35
- tokens = 0;
36
- reads[normalizedPath] = { count, tokens: 0, chars: 0 };
37
- } else if (existing && typeof existing === "object") {
38
- count = (existing.count || 0) + 1;
39
- tokens = existing.tokens || 0;
40
- existing.count = count;
41
- reads[normalizedPath] = existing;
42
- } else {
43
- count = 1;
44
- tokens = 0;
45
- reads[normalizedPath] = { count, tokens: 0, chars: 0 };
70
+ try {
71
+ reads = JSON.parse(fs.readFileSync(readsPath, "utf8"));
72
+ } catch (err) {
73
+ if (err.code !== "ENOENT") hookLog("read-guard", "warn", `read error: ${err.message}`);
74
+ reads = {};
46
75
  }
47
- fs.writeFileSync(readsPath, JSON.stringify(reads, null, 2), "utf8");
48
- const basename = path.basename(filePath);
49
- const tokenInfo = tokens > 0 ? ` (~${tokens} token)` : "";
50
- if (count >= 3) {
51
- const totalWaste = tokens > 0 ? ` Toplam israf: ~${tokens * (count - 1)} token.` : "";
52
- process.stderr.write(`[Mindlore BLOCK] ${basename}${tokenInfo} bu session'da ${count}. kez okunuyor.${totalWaste} Edit icin gerekiyorsa once degisikligini yap, sonra tekrar oku. Analiz icin ctx_execute_file kullan.`);
76
+ const decision = runReadGuard({ filePath: resolved, basename: path.basename(filePath) }, reads);
77
+ reads[resolved] = decision.updatedReadsEntry;
78
+ safeWriteFile(readsPath, JSON.stringify(reads, null, 2));
79
+ if (decision.block) {
80
+ process.stderr.write(decision.warning);
53
81
  process.exit(2);
54
82
  }
55
- if (count > 1) {
56
- const totalWaste = tokens > 0 ? ` Toplam tekrar: ~${tokens * (count - 1)} token.` : "";
83
+ if (decision.additionalContext) {
57
84
  let skeletonSection = "";
58
85
  try {
59
86
  const ext = path.extname(filePath).slice(1);
@@ -70,7 +97,7 @@ function main() {
70
97
  process.stdout.write(JSON.stringify({
71
98
  hookSpecificOutput: {
72
99
  hookEventName: "PreToolUse",
73
- additionalContext: `[Mindlore: ${basename}${tokenInfo} bu session'da ${count}. kez okunuyor.${totalWaste} Bir sonraki okuma engellenecek \u2014 Edit gerekiyorsa simdi yap.]${skeletonSection}`
100
+ additionalContext: decision.additionalContext + skeletonSection
74
101
  }
75
102
  }));
76
103
  }