mindlore 0.7.3 → 0.7.5

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 (197) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +18 -0
  4. package/dist/scripts/bundle-hooks.js +3 -4
  5. package/dist/scripts/bundle-hooks.js.map +1 -1
  6. package/dist/scripts/init.js +74 -20
  7. package/dist/scripts/init.js.map +1 -1
  8. package/dist/scripts/lib/constants.d.ts +21 -1
  9. package/dist/scripts/lib/constants.d.ts.map +1 -1
  10. package/dist/scripts/lib/constants.js +33 -7
  11. package/dist/scripts/lib/constants.js.map +1 -1
  12. package/dist/scripts/lib/db-helpers.d.ts +1 -0
  13. package/dist/scripts/lib/db-helpers.d.ts.map +1 -1
  14. package/dist/scripts/lib/db-helpers.js +37 -0
  15. package/dist/scripts/lib/db-helpers.js.map +1 -1
  16. package/dist/scripts/lib/detect-plugin.js +1 -1
  17. package/dist/scripts/lib/detect-plugin.js.map +1 -1
  18. package/dist/scripts/lib/episodes.d.ts +1 -1
  19. package/dist/scripts/lib/episodes.d.ts.map +1 -1
  20. package/dist/scripts/lib/episodes.js +1 -1
  21. package/dist/scripts/lib/episodes.js.map +1 -1
  22. package/dist/scripts/lib/hook-helpers.d.ts +8 -0
  23. package/dist/scripts/lib/hook-helpers.d.ts.map +1 -0
  24. package/dist/scripts/lib/hook-helpers.js +27 -0
  25. package/dist/scripts/lib/hook-helpers.js.map +1 -0
  26. package/dist/scripts/lib/mcp-namespace.d.ts.map +1 -1
  27. package/dist/scripts/lib/mcp-namespace.js +0 -5
  28. package/dist/scripts/lib/mcp-namespace.js.map +1 -1
  29. package/dist/scripts/lib/mcp-tools.d.ts.map +1 -1
  30. package/dist/scripts/lib/mcp-tools.js +3 -19
  31. package/dist/scripts/lib/mcp-tools.js.map +1 -1
  32. package/dist/scripts/lib/relation-helpers.js +1 -1
  33. package/dist/scripts/lib/relation-helpers.js.map +1 -1
  34. package/dist/scripts/lib/session-payload.d.ts.map +1 -1
  35. package/dist/scripts/lib/session-payload.js +7 -21
  36. package/dist/scripts/lib/session-payload.js.map +1 -1
  37. package/dist/scripts/lib/settings-cleanup.d.ts.map +1 -1
  38. package/dist/scripts/lib/settings-cleanup.js +2 -2
  39. package/dist/scripts/lib/settings-cleanup.js.map +1 -1
  40. package/dist/scripts/lib/skill-runner.d.ts +3 -0
  41. package/dist/scripts/lib/skill-runner.d.ts.map +1 -0
  42. package/dist/scripts/lib/skill-runner.js +78 -0
  43. package/dist/scripts/lib/skill-runner.js.map +1 -0
  44. package/dist/scripts/lib/telemetry-scan.d.ts +19 -0
  45. package/dist/scripts/lib/telemetry-scan.d.ts.map +1 -0
  46. package/dist/scripts/lib/telemetry-scan.js +42 -0
  47. package/dist/scripts/lib/telemetry-scan.js.map +1 -0
  48. package/dist/scripts/lib/tool-adapters/decide-adapter.d.ts +1 -1
  49. package/dist/scripts/lib/tool-adapters/decide-adapter.d.ts.map +1 -1
  50. package/dist/scripts/lib/tool-adapters/decide-adapter.js +5 -0
  51. package/dist/scripts/lib/tool-adapters/decide-adapter.js.map +1 -1
  52. package/dist/scripts/mindlore-clean-cache.d.ts +3 -0
  53. package/dist/scripts/mindlore-clean-cache.d.ts.map +1 -0
  54. package/dist/scripts/mindlore-clean-cache.js +65 -0
  55. package/dist/scripts/mindlore-clean-cache.js.map +1 -0
  56. package/dist/scripts/mindlore-doctor.d.ts +3 -0
  57. package/dist/scripts/mindlore-doctor.d.ts.map +1 -1
  58. package/dist/scripts/mindlore-doctor.js +84 -15
  59. package/dist/scripts/mindlore-doctor.js.map +1 -1
  60. package/dist/scripts/mindlore-health-check.js +2 -2
  61. package/dist/scripts/mindlore-health-check.js.map +1 -1
  62. package/dist/scripts/mindlore-perf.d.ts +3 -1
  63. package/dist/scripts/mindlore-perf.d.ts.map +1 -1
  64. package/dist/scripts/mindlore-perf.js +13 -6
  65. package/dist/scripts/mindlore-perf.js.map +1 -1
  66. package/dist/scripts/reflect-failure-scan.d.ts +3 -0
  67. package/dist/scripts/reflect-failure-scan.d.ts.map +1 -0
  68. package/dist/scripts/reflect-failure-scan.js +41 -0
  69. package/dist/scripts/reflect-failure-scan.js.map +1 -0
  70. package/dist/tests/clean-cache.test.d.ts +2 -0
  71. package/dist/tests/clean-cache.test.d.ts.map +1 -0
  72. package/dist/tests/clean-cache.test.js +59 -0
  73. package/dist/tests/clean-cache.test.js.map +1 -0
  74. package/dist/tests/db-helpers-vec.test.d.ts +2 -0
  75. package/dist/tests/db-helpers-vec.test.d.ts.map +1 -0
  76. package/dist/tests/db-helpers-vec.test.js +32 -0
  77. package/dist/tests/db-helpers-vec.test.js.map +1 -0
  78. package/dist/tests/db-helpers.test.d.ts +2 -0
  79. package/dist/tests/db-helpers.test.d.ts.map +1 -0
  80. package/dist/tests/db-helpers.test.js +30 -0
  81. package/dist/tests/db-helpers.test.js.map +1 -0
  82. package/dist/tests/diary.test.js +3 -3
  83. package/dist/tests/diary.test.js.map +1 -1
  84. package/dist/tests/doctor.test.js +39 -0
  85. package/dist/tests/doctor.test.js.map +1 -1
  86. package/dist/tests/dont-repeat-dedup.test.js +13 -1
  87. package/dist/tests/dont-repeat-dedup.test.js.map +1 -1
  88. package/dist/tests/episodes-inject.test.js +5 -5
  89. package/dist/tests/episodes-inject.test.js.map +1 -1
  90. package/dist/tests/fts5-sync.test.js +11 -117
  91. package/dist/tests/fts5-sync.test.js.map +1 -1
  92. package/dist/tests/hook-helpers.test.d.ts +2 -0
  93. package/dist/tests/hook-helpers.test.d.ts.map +1 -0
  94. package/dist/tests/hook-helpers.test.js +44 -0
  95. package/dist/tests/hook-helpers.test.js.map +1 -0
  96. package/dist/tests/init-spawn-cleanup.test.d.ts +2 -0
  97. package/dist/tests/init-spawn-cleanup.test.d.ts.map +1 -0
  98. package/dist/tests/init-spawn-cleanup.test.js +21 -0
  99. package/dist/tests/init-spawn-cleanup.test.js.map +1 -0
  100. package/dist/tests/install-matrix.test.js +39 -0
  101. package/dist/tests/install-matrix.test.js.map +1 -1
  102. package/dist/tests/latency-budget.test.d.ts +2 -0
  103. package/dist/tests/latency-budget.test.d.ts.map +1 -0
  104. package/dist/tests/latency-budget.test.js +37 -0
  105. package/dist/tests/latency-budget.test.js.map +1 -0
  106. package/dist/tests/learnings-loader.test.d.ts +2 -0
  107. package/dist/tests/learnings-loader.test.d.ts.map +1 -0
  108. package/dist/tests/learnings-loader.test.js +64 -0
  109. package/dist/tests/learnings-loader.test.js.map +1 -0
  110. package/dist/tests/mcp-namespace.test.d.ts +2 -0
  111. package/dist/tests/mcp-namespace.test.d.ts.map +1 -0
  112. package/dist/tests/mcp-namespace.test.js +41 -0
  113. package/dist/tests/mcp-namespace.test.js.map +1 -0
  114. package/dist/tests/mindlore-home-env.test.d.ts +2 -0
  115. package/dist/tests/mindlore-home-env.test.d.ts.map +1 -0
  116. package/dist/tests/mindlore-home-env.test.js +33 -0
  117. package/dist/tests/mindlore-home-env.test.js.map +1 -0
  118. package/dist/tests/no-hardcoded-cache.test.d.ts +2 -0
  119. package/dist/tests/no-hardcoded-cache.test.d.ts.map +1 -0
  120. package/dist/tests/no-hardcoded-cache.test.js +40 -0
  121. package/dist/tests/no-hardcoded-cache.test.js.map +1 -0
  122. package/dist/tests/nomination.test.js +1 -1
  123. package/dist/tests/nomination.test.js.map +1 -1
  124. package/dist/tests/reflect-failure-scan.test.d.ts +2 -0
  125. package/dist/tests/reflect-failure-scan.test.d.ts.map +1 -0
  126. package/dist/tests/reflect-failure-scan.test.js +49 -0
  127. package/dist/tests/reflect-failure-scan.test.js.map +1 -0
  128. package/dist/tests/reflect-trigger.test.d.ts +2 -0
  129. package/dist/tests/reflect-trigger.test.d.ts.map +1 -0
  130. package/dist/tests/reflect-trigger.test.js +31 -0
  131. package/dist/tests/reflect-trigger.test.js.map +1 -0
  132. package/dist/tests/session-focus-episode-counter.test.d.ts +2 -0
  133. package/dist/tests/session-focus-episode-counter.test.d.ts.map +1 -0
  134. package/dist/tests/session-focus-episode-counter.test.js +41 -0
  135. package/dist/tests/session-focus-episode-counter.test.js.map +1 -0
  136. package/dist/tests/session-focus-learnings-inject.test.d.ts +2 -0
  137. package/dist/tests/session-focus-learnings-inject.test.d.ts.map +1 -0
  138. package/dist/tests/session-focus-learnings-inject.test.js +29 -0
  139. package/dist/tests/session-focus-learnings-inject.test.js.map +1 -0
  140. package/dist/tests/session-focus-nomination-inject.test.d.ts +2 -0
  141. package/dist/tests/session-focus-nomination-inject.test.d.ts.map +1 -0
  142. package/dist/tests/session-focus-nomination-inject.test.js +50 -0
  143. package/dist/tests/session-focus-nomination-inject.test.js.map +1 -0
  144. package/dist/tests/session-focus-reflect-nudge.test.d.ts +2 -0
  145. package/dist/tests/session-focus-reflect-nudge.test.d.ts.map +1 -0
  146. package/dist/tests/session-focus-reflect-nudge.test.js +62 -0
  147. package/dist/tests/session-focus-reflect-nudge.test.js.map +1 -0
  148. package/dist/tests/session-payload.test.js +19 -17
  149. package/dist/tests/session-payload.test.js.map +1 -1
  150. package/dist/tests/skill-md-uses-runner.test.d.ts +2 -0
  151. package/dist/tests/skill-md-uses-runner.test.d.ts.map +1 -0
  152. package/dist/tests/skill-md-uses-runner.test.js +31 -0
  153. package/dist/tests/skill-md-uses-runner.test.js.map +1 -0
  154. package/dist/tests/skill-runner-failure-e2e.test.d.ts +10 -0
  155. package/dist/tests/skill-runner-failure-e2e.test.d.ts.map +1 -0
  156. package/dist/tests/skill-runner-failure-e2e.test.js +64 -0
  157. package/dist/tests/skill-runner-failure-e2e.test.js.map +1 -0
  158. package/dist/tests/skill-runner.test.d.ts +2 -0
  159. package/dist/tests/skill-runner.test.d.ts.map +1 -0
  160. package/dist/tests/skill-runner.test.js +55 -0
  161. package/dist/tests/skill-runner.test.js.map +1 -0
  162. package/dist/tests/sync-scripts.test.d.ts +2 -0
  163. package/dist/tests/sync-scripts.test.d.ts.map +1 -0
  164. package/dist/tests/sync-scripts.test.js +26 -0
  165. package/dist/tests/sync-scripts.test.js.map +1 -0
  166. package/dist/tests/telemetry-perf.test.js +9 -8
  167. package/dist/tests/telemetry-perf.test.js.map +1 -1
  168. package/dist/tests/telemetry-scan.test.d.ts +2 -0
  169. package/dist/tests/telemetry-scan.test.d.ts.map +1 -0
  170. package/dist/tests/telemetry-scan.test.js +32 -0
  171. package/dist/tests/telemetry-scan.test.js.map +1 -0
  172. package/hooks/cc-memory-bulk-sync.cjs +20 -5
  173. package/hooks/cc-session-sync.cjs +20 -5
  174. package/hooks/lib/constants.cjs +1 -1
  175. package/hooks/lib/learnings-loader.cjs +70 -0
  176. package/hooks/lib/mindlore-common.cjs +46 -8
  177. package/hooks/lib/reflect-trigger.cjs +29 -0
  178. package/hooks/lib/sync-scripts.cjs +12 -0
  179. package/hooks/mindlore-fts5-sync.cjs +5 -1
  180. package/hooks/mindlore-search.cjs +116 -14
  181. package/hooks/mindlore-session-focus.cjs +81 -27
  182. package/hooks/src/lib/mindlore-common.cjs +5 -0
  183. package/hooks/src/mindlore-fts5-sync.cjs +7 -4
  184. package/hooks/src/mindlore-search.cjs +19 -11
  185. package/hooks/src/mindlore-session-focus.cjs +48 -6
  186. package/package.json +5 -3
  187. package/plugin.json +1 -1
  188. package/skills/mindlore-decide/SKILL.md +1 -1
  189. package/skills/mindlore-diary/SKILL.md +4 -4
  190. package/skills/mindlore-evolve/SKILL.md +2 -2
  191. package/skills/mindlore-health/SKILL.md +2 -2
  192. package/skills/mindlore-ingest/SKILL.md +7 -7
  193. package/skills/mindlore-log/SKILL.md +1 -1
  194. package/skills/mindlore-maintain/SKILL.md +2 -2
  195. package/skills/mindlore-query/SKILL.md +1 -1
  196. package/skills/mindlore-reflect/SKILL.md +30 -16
  197. package/templates/config.json +1 -1
@@ -5,6 +5,38 @@ var __commonJS = (cb, mod) => function __require() {
5
5
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
6
6
  };
7
7
 
8
+ // hooks/lib/reflect-trigger.cjs
9
+ var require_reflect_trigger = __commonJS({
10
+ "hooks/lib/reflect-trigger.cjs"(exports2, module2) {
11
+ "use strict";
12
+ var REFLECT_THRESHOLD_DAYS = 7;
13
+ var NUDGE_COOLDOWN_HOURS = 24;
14
+ function isValidDate(iso) {
15
+ if (!iso) return false;
16
+ const d = new Date(iso);
17
+ return !isNaN(d.getTime());
18
+ }
19
+ function shouldNudgeReflect2(lastReflectIso, lastNudgeIso, now = /* @__PURE__ */ new Date()) {
20
+ let needsReflect;
21
+ if (!lastReflectIso) {
22
+ needsReflect = true;
23
+ } else if (!isValidDate(lastReflectIso)) {
24
+ return false;
25
+ } else {
26
+ const daysSince = (now.getTime() - new Date(lastReflectIso).getTime()) / 864e5;
27
+ needsReflect = daysSince >= REFLECT_THRESHOLD_DAYS;
28
+ }
29
+ if (!needsReflect) return false;
30
+ if (lastNudgeIso && isValidDate(lastNudgeIso)) {
31
+ const hoursSinceNudge = (now.getTime() - new Date(lastNudgeIso).getTime()) / 36e5;
32
+ if (hoursSinceNudge < NUDGE_COOLDOWN_HOURS) return false;
33
+ }
34
+ return true;
35
+ }
36
+ module2.exports = { shouldNudgeReflect: shouldNudgeReflect2, REFLECT_THRESHOLD_DAYS, NUDGE_COOLDOWN_HOURS };
37
+ }
38
+ });
39
+
8
40
  // dist/scripts/lib/session-payload.js
9
41
  var require_session_payload = __commonJS({
10
42
  "dist/scripts/lib/session-payload.js"(exports2) {
@@ -14,35 +46,23 @@ var require_session_payload = __commonJS({
14
46
  };
15
47
  Object.defineProperty(exports2, "__esModule", { value: true });
16
48
  exports2.buildSessionPayload = buildSessionPayload;
17
- var fs_1 = __importDefault(require("fs"));
18
- var path_1 = __importDefault(require("path"));
19
49
  var crypto_1 = __importDefault(require("crypto"));
20
50
  var CHARS_PER_TOKEN = 4;
21
51
  function estimateTokens(text) {
22
52
  return Math.ceil(text.length / CHARS_PER_TOKEN);
23
53
  }
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))
54
+ function buildSessionSummary(_baseDir, latestDeltaContent) {
55
+ if (!latestDeltaContent)
31
56
  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");
57
+ const lines = latestDeltaContent.split("\n").filter((l) => l.startsWith("- ") || l.startsWith("# "));
58
+ return lines.slice(0, 10).join("\n") || "No previous session data.";
39
59
  }
40
60
  function buildEpisodeSections(db, project, sessionId) {
41
61
  const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3).toISOString();
42
62
  const dedupClause = sessionId ? "AND rowid NOT IN (SELECT episode_id FROM episode_inject_log WHERE session_id = ?)" : "";
43
63
  const query = `SELECT rowid, kind, summary, created_at FROM episodes
44
64
  WHERE status = 'active' AND project = ?
45
- AND kind IN ('decision', 'friction', 'learning')
65
+ AND kind IN ('decision', 'friction')
46
66
  AND created_at >= ?
47
67
  ${dedupClause}
48
68
  ORDER BY kind, created_at DESC`;
@@ -58,18 +78,17 @@ var require_session_payload = __commonJS({
58
78
  }
59
79
  })();
60
80
  }
61
- const grouped = { decision: [], friction: [], learning: [] };
81
+ const grouped = { decision: [], friction: [] };
62
82
  for (const row of rows) {
63
83
  const kind = row.kind;
64
- if (kind === "decision" || kind === "friction" || kind === "learning") {
84
+ if (kind === "decision" || kind === "friction") {
65
85
  grouped[kind].push(row);
66
86
  }
67
87
  }
68
88
  const fmt = (items, limit) => items.slice(0, limit).map((r) => `- ${r.summary} (${r.created_at.slice(0, 10)})`).join("\n");
69
89
  return {
70
90
  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."
91
+ friction: grouped.friction.length > 0 ? fmt(grouped.friction, 3) : "No active friction points."
73
92
  };
74
93
  }
75
94
  function buildSessionPayload(opts) {
@@ -80,7 +99,6 @@ var require_session_payload = __commonJS({
80
99
  const episodes = buildEpisodeSections(db, project, sessionId);
81
100
  sections.push({ label: "Decisions", content: episodes.decisions, tokens: estimateTokens(episodes.decisions) });
82
101
  sections.push({ label: "Friction", content: episodes.friction, tokens: estimateTokens(episodes.friction) });
83
- sections.push({ label: "Learnings", content: episodes.learnings, tokens: estimateTokens(episodes.learnings) });
84
102
  try {
85
103
  const summaries = db.prepare(`SELECT session_summary, created_at FROM episodes
86
104
  WHERE kind = 'session-summary' AND project = ? AND session_summary IS NOT NULL
@@ -597,7 +615,9 @@ var require_all_migrations = __commonJS({
597
615
  // hooks/src/mindlore-session-focus.cjs
598
616
  var fs = require("fs");
599
617
  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");
618
+ var { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry, withTimeoutDb, listSnapshots, isCorruptionError, recoverCorruptDb, getNominationCounts, resolveMindloreHome } = require("./lib/mindlore-common.cjs");
619
+ var { loadLearningsBlock } = require("./lib/learnings-loader.cjs");
620
+ var { shouldNudgeReflect } = require_reflect_trigger();
601
621
  function truncateSection(content, sectionRegex, keepCount, label) {
602
622
  const match = content.match(sectionRegex);
603
623
  if (!match) return content;
@@ -614,7 +634,7 @@ function truncateChangedFiles(content) {
614
634
  return truncateSection(content, /(## Changed Files\n)((?:- [^\n]+\n?)+)/, 10, "dosya");
615
635
  }
616
636
  function tryOpenDb(dbPath) {
617
- return openDatabase(dbPath, { readonly: true });
637
+ return openDatabase(dbPath, { readonly: false }) || openDatabase(dbPath, { readonly: true });
618
638
  }
619
639
  function getEpisodeStats(db, config, project) {
620
640
  const chains = querySupersededChains(db, { project, days: 7, limit: 5 });
@@ -622,8 +642,11 @@ function getEpisodeStats(db, config, project) {
622
642
  try {
623
643
  const rawCount = withTimeoutDb(
624
644
  db,
625
- "SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL",
626
- [],
645
+ `SELECT COUNT(*) as cnt FROM episodes
646
+ WHERE (consolidation_status = 'raw' OR consolidation_status IS NULL)
647
+ AND kind IN ('learning','discovery','friction','decision','nomination')
648
+ AND project = ?`,
649
+ [project],
627
650
  { mode: "get" }
628
651
  );
629
652
  const cnt = rawCount?.cnt ?? 0;
@@ -681,6 +704,9 @@ ${formatSupersededChains(chains)}`);
681
704
  timings.db_stale = Date.now() - tStale;
682
705
  try {
683
706
  const counts = getNominationCounts(db, project);
707
+ if (counts.staged > 0) {
708
+ output.push(`[Mindlore Nomination] ${counts.staged} karar bekliyor \u2014 /mindlore-reflect ile onayla`);
709
+ }
684
710
  if (counts.staged >= (config?.graduation?.reflectThreshold ?? 5)) {
685
711
  output.push(`[Mindlore] ${counts.staged} bekleyen nomination var \u2014 \`/mindlore-reflect\` \xE7al\u0131\u015Ft\u0131r`);
686
712
  }
@@ -725,11 +751,11 @@ ${content}`);
725
751
  const latestPath = path.join(diaryDir, latestName);
726
752
  const deltaContent = fs.readFileSync(latestPath, "utf8").trim();
727
753
  sourceChars += deltaContent.length;
728
- latestDeltaContent = deltaContent;
729
754
  const { meta } = parseFrontmatter(deltaContent);
730
755
  const deltaProject = meta.project || null;
731
756
  const currentProject = getProjectName();
732
757
  if (!deltaProject || deltaProject.toLowerCase() === currentProject.toLowerCase()) {
758
+ latestDeltaContent = deltaContent;
733
759
  output.push(`[Mindlore Delta: ${latestName}]
734
760
  ${truncateChangedFiles(truncateCommits(deltaContent))}`);
735
761
  }
@@ -778,6 +804,24 @@ ${truncateChangedFiles(truncateCommits(deltaContent))}`);
778
804
  }
779
805
  timings.schema_check = Date.now() - tSchema;
780
806
  loadDbContent({ db, baseDir, config, output, timings, latestDeltaContent, sessionId });
807
+ try {
808
+ const reflectRow = db.prepare(
809
+ "SELECT value FROM skill_memory WHERE skill_name = 'mindlore-reflect' AND key = 'last_reflect_date'"
810
+ ).get();
811
+ const nudgeRow = db.prepare(
812
+ "SELECT value FROM skill_memory WHERE skill_name = 'mindlore-reflect' AND key = 'last_nudge_date'"
813
+ ).get();
814
+ if (shouldNudgeReflect(reflectRow?.value ?? null, nudgeRow?.value ?? null, /* @__PURE__ */ new Date())) {
815
+ output.push("[Mindlore] 7+ g\xFCn reflect yap\u0131lmad\u0131 \u2014 `/mindlore-reflect` \xE7al\u0131\u015Ft\u0131r");
816
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
817
+ db.prepare(`
818
+ INSERT INTO skill_memory (skill_name, key, value, updated_at)
819
+ VALUES ('mindlore-reflect', 'last_nudge_date', ?, ?)
820
+ ON CONFLICT(skill_name, key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
821
+ `).run(nowIso, nowIso);
822
+ }
823
+ } catch (_err) {
824
+ }
781
825
  } catch (err) {
782
826
  if (isCorruptionError(err)) {
783
827
  recoverCorruptDb(db, dbPath, "session-focus");
@@ -794,6 +838,16 @@ ${truncateChangedFiles(truncateCommits(deltaContent))}`);
794
838
  const outputLenAfterDb = output.reduce((s, o) => s + o.length, 0);
795
839
  sourceChars += outputLenAfterDb - outputLenBeforeDb;
796
840
  timings.db_total = Date.now() - tDb;
841
+ try {
842
+ const mindloreDir = resolveMindloreHome();
843
+ const project = getProjectName();
844
+ const learningsBlock = loadLearningsBlock(mindloreDir, project);
845
+ if (learningsBlock) {
846
+ output.push(learningsBlock);
847
+ sourceChars += learningsBlock.length;
848
+ }
849
+ } catch (_err) {
850
+ }
797
851
  timings.total = Date.now() - t0;
798
852
  hookLog("session-focus", "info", `timings: ${JSON.stringify(timings)}`);
799
853
  const budgetConfig = config?.tokenBudget ?? {};
@@ -26,6 +26,10 @@ function globalDir() {
26
26
  return path.join(os.homedir(), MINDLORE_DIR);
27
27
  }
28
28
 
29
+ function resolveMindloreHome() {
30
+ return globalDir();
31
+ }
32
+
29
33
  // Convenience export — snapshot at load time for simple references.
30
34
  const GLOBAL_MINDLORE_DIR = globalDir();
31
35
 
@@ -773,6 +777,7 @@ module.exports = {
773
777
  MINDLORE_DIR,
774
778
  GLOBAL_MINDLORE_DIR,
775
779
  globalDir,
780
+ resolveMindloreHome,
776
781
  DB_NAME,
777
782
  SKIP_FILES,
778
783
  findMindloreDir,
@@ -15,17 +15,18 @@ const fs = require('fs');
15
15
  const path = require('path');
16
16
  const { DB_NAME, sha256, openDatabase, getAllMdFiles, parseFrontmatter, extractFtsMetadata, insertFtsRow, readHookStdin, getActiveMindloreDir, getProjectName, resolveProject, hookLog, withTelemetry, SQL_FTS_SESSIONS_INSERT, isSessionCategory, isInsideMindloreDir } = require('./lib/mindlore-common.cjs');
17
17
 
18
+ function shouldIndexFile(filePath) {
19
+ return !!(filePath && filePath.endsWith('.md'));
20
+ }
21
+
18
22
  function main() {
19
23
  const filePath = readHookStdin(['path', 'file_path']);
20
24
 
21
25
  if (!filePath) return;
26
+ if (!shouldIndexFile(filePath)) return;
22
27
  const resolved = path.resolve(filePath);
23
28
  if (!isInsideMindloreDir(resolved)) return;
24
29
 
25
- // Skip if this is a single .md file change — mindlore-index.cjs handles those.
26
- // This hook is for bulk changes (git pull, manual batch edits).
27
- if (filePath.endsWith('.md')) return;
28
-
29
30
  const baseDir = getActiveMindloreDir();
30
31
  if (!fs.existsSync(baseDir)) return;
31
32
 
@@ -92,6 +93,8 @@ function main() {
92
93
 
93
94
  }
94
95
 
96
+ module.exports = { shouldIndexFile };
97
+
95
98
  withTelemetry('mindlore-fts5-sync', main).catch(err => {
96
99
  hookLog('mindlore-fts5-sync', 'error', err?.message ?? String(err));
97
100
  process.exit(0);
@@ -11,7 +11,7 @@
11
11
 
12
12
  const fs = require('fs');
13
13
  const path = require('path');
14
- const { getAllDbs, openDatabase, extractHeadings, readHookStdin, readConfig, hookLog, incrementRecallCount, withTelemetry } = require('./lib/mindlore-common.cjs');
14
+ const { getAllDbs, openDatabase, extractHeadings, readConfig, hookLog, incrementRecallCount, withTelemetry } = require('./lib/mindlore-common.cjs');
15
15
 
16
16
  const MAX_RESULTS = 3;
17
17
  const MIN_QUERY_WORDS = 3;
@@ -30,9 +30,23 @@ try {
30
30
  // search-cache not built yet
31
31
  }
32
32
 
33
+ function parseStdin() {
34
+ try {
35
+ const raw = fs.readFileSync(0, 'utf8').trim();
36
+ if (!raw) return { userMessage: '', sessionId: 'unknown' };
37
+ const parsed = JSON.parse(raw);
38
+ const userMessage = parsed.prompt || parsed.content || parsed.message || parsed.query || raw;
39
+ const sessionId = parsed.session_id || 'unknown';
40
+ return { userMessage, sessionId };
41
+ } catch (_err) {
42
+ return { userMessage: '', sessionId: 'unknown' };
43
+ }
44
+ }
45
+
33
46
  function main() {
34
- const userMessage = readHookStdin(['prompt', 'content', 'message', 'query']);
47
+ const { userMessage, sessionId } = parseStdin();
35
48
  if (!userMessage || userMessage.length < MIN_QUERY_WORDS) return;
49
+ let searchMs = 0;
36
50
 
37
51
  const dbPaths = getAllDbs();
38
52
  if (dbPaths.length === 0) return;
@@ -46,15 +60,6 @@ function main() {
46
60
  const config = readConfig(path.dirname(dbPaths[0]));
47
61
  const synonyms = (config && config.synonyms) ? config.synonyms : {};
48
62
 
49
- // Read session_id from stdin for throttling
50
- let sessionId;
51
- try {
52
- const stdinData = JSON.parse(process.env.CLAUDE_HOOK_STDIN || '{}');
53
- sessionId = stdinData.session_id || 'unknown';
54
- } catch (_) {
55
- sessionId = 'unknown';
56
- }
57
-
58
63
  const allResults = [];
59
64
  for (const dbPath of dbPaths) {
60
65
  const db = openDatabase(dbPath);
@@ -82,11 +87,13 @@ function main() {
82
87
  }
83
88
  }
84
89
 
90
+ const t0 = Date.now();
85
91
  const results = searchEngineMod.search(db, userMessage, {
86
92
  project,
87
93
  maxResults: effectiveMax,
88
94
  synonyms,
89
95
  });
96
+ searchMs += Date.now() - t0;
90
97
 
91
98
  if (cache) cache.set(userMessage, results);
92
99
 
@@ -192,6 +199,7 @@ function main() {
192
199
 
193
200
  process.stdout.write(outputStr);
194
201
  }
202
+ return { search_ms: searchMs, result_count: relevant.length };
195
203
  }
196
204
 
197
205
  withTelemetry('mindlore-search', main).catch(err => {
@@ -10,7 +10,9 @@
10
10
 
11
11
  const fs = require('fs');
12
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');
13
+ const { findMindloreDir, readConfig, openDatabase, hasEpisodesTable, querySupersededChains, formatSupersededChains, hookLog, getProjectName, parseFrontmatter, withTelemetry, withTimeoutDb, listSnapshots, isCorruptionError, recoverCorruptDb, getNominationCounts, resolveMindloreHome } = require('./lib/mindlore-common.cjs');
14
+ const { loadLearningsBlock } = require('./lib/learnings-loader.cjs');
15
+ const { shouldNudgeReflect } = require('../lib/reflect-trigger.cjs');
14
16
 
15
17
  function truncateSection(content, sectionRegex, keepCount, label) {
16
18
  const match = content.match(sectionRegex);
@@ -30,7 +32,7 @@ function truncateChangedFiles(content) {
30
32
  }
31
33
 
32
34
  function tryOpenDb(dbPath) {
33
- return openDatabase(dbPath, { readonly: true });
35
+ return openDatabase(dbPath, { readonly: false }) || openDatabase(dbPath, { readonly: true });
34
36
  }
35
37
 
36
38
  function getEpisodeStats(db, config, project) {
@@ -38,8 +40,11 @@ function getEpisodeStats(db, config, project) {
38
40
  let consolidationMsg = null;
39
41
  try {
40
42
  const rawCount = withTimeoutDb(db,
41
- "SELECT COUNT(*) as cnt FROM episodes WHERE consolidation_status = 'raw' OR consolidation_status IS NULL",
42
- [], { mode: 'get' });
43
+ `SELECT COUNT(*) as cnt FROM episodes
44
+ WHERE (consolidation_status = 'raw' OR consolidation_status IS NULL)
45
+ AND kind IN ('learning','discovery','friction','decision','nomination')
46
+ AND project = ?`,
47
+ [project], { mode: 'get' });
43
48
  const cnt = rawCount?.cnt ?? 0;
44
49
  const consolThreshold = config?.consolidation?.threshold ?? 50;
45
50
  if (cnt >= consolThreshold) {
@@ -63,7 +68,7 @@ function checkStaleContent(db) {
63
68
 
64
69
  function loadDbContent({ db, baseDir, config, output, timings, latestDeltaContent, sessionId }) {
65
70
  const project = path.basename(process.cwd());
66
- // Session payload: Session summary, Decisions, Friction, Learnings
71
+ // Session payload: Session summary, Decisions, Friction (Learnings via file-based loadLearningsBlock)
67
72
  const tPayload = Date.now();
68
73
  try {
69
74
  const { buildSessionPayload } = require('../dist/scripts/lib/session-payload.js');
@@ -101,6 +106,9 @@ function loadDbContent({ db, baseDir, config, output, timings, latestDeltaConten
101
106
  // Auto reflect trigger (Q1) + Graduated lesson count (Q3)
102
107
  try {
103
108
  const counts = getNominationCounts(db, project);
109
+ if (counts.staged > 0) {
110
+ output.push(`[Mindlore Nomination] ${counts.staged} karar bekliyor — /mindlore-reflect ile onayla`);
111
+ }
104
112
  if (counts.staged >= (config?.graduation?.reflectThreshold ?? 5)) {
105
113
  output.push(`[Mindlore] ${counts.staged} bekleyen nomination var — \`/mindlore-reflect\` çalıştır`);
106
114
  }
@@ -150,11 +158,11 @@ function main() {
150
158
  const latestPath = path.join(diaryDir, latestName);
151
159
  const deltaContent = fs.readFileSync(latestPath, 'utf8').trim();
152
160
  sourceChars += deltaContent.length;
153
- latestDeltaContent = deltaContent;
154
161
  const { meta } = parseFrontmatter(deltaContent);
155
162
  const deltaProject = meta.project || null;
156
163
  const currentProject = getProjectName();
157
164
  if (!deltaProject || deltaProject.toLowerCase() === currentProject.toLowerCase()) {
165
+ latestDeltaContent = deltaContent;
158
166
  output.push(`[Mindlore Delta: ${latestName}]\n${truncateChangedFiles(truncateCommits(deltaContent))}`);
159
167
  }
160
168
  }
@@ -209,6 +217,27 @@ function main() {
209
217
  timings.schema_check = Date.now() - tSchema;
210
218
 
211
219
  loadDbContent({ db, baseDir, config, output, timings, latestDeltaContent, sessionId });
220
+
221
+ // Auto-reflect nudge (7-day threshold + 24h cooldown)
222
+ try {
223
+ const reflectRow = db.prepare(
224
+ "SELECT value FROM skill_memory WHERE skill_name = 'mindlore-reflect' AND key = 'last_reflect_date'"
225
+ ).get();
226
+ const nudgeRow = db.prepare(
227
+ "SELECT value FROM skill_memory WHERE skill_name = 'mindlore-reflect' AND key = 'last_nudge_date'"
228
+ ).get();
229
+ if (shouldNudgeReflect(reflectRow?.value ?? null, nudgeRow?.value ?? null, new Date())) {
230
+ output.push('[Mindlore] 7+ gün reflect yapılmadı — `/mindlore-reflect` çalıştır');
231
+ const nowIso = new Date().toISOString();
232
+ db.prepare(`
233
+ INSERT INTO skill_memory (skill_name, key, value, updated_at)
234
+ VALUES ('mindlore-reflect', 'last_nudge_date', ?, ?)
235
+ ON CONFLICT(skill_name, key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
236
+ `).run(nowIso, nowIso);
237
+ }
238
+ } catch (_err) {
239
+ // never block session-start on nudge failure
240
+ }
212
241
  } catch (err) {
213
242
  if (isCorruptionError(err)) {
214
243
  recoverCorruptDb(db, dbPath, 'session-focus');
@@ -222,6 +251,19 @@ function main() {
222
251
  sourceChars += (outputLenAfterDb - outputLenBeforeDb);
223
252
  timings.db_total = Date.now() - tDb;
224
253
 
254
+ // Inject [Mindlore Learnings] block
255
+ try {
256
+ const mindloreDir = resolveMindloreHome();
257
+ const project = getProjectName();
258
+ const learningsBlock = loadLearningsBlock(mindloreDir, project);
259
+ if (learningsBlock) {
260
+ output.push(learningsBlock);
261
+ sourceChars += learningsBlock.length;
262
+ }
263
+ } catch (_err) {
264
+ // never block session-start on lessons loader failure
265
+ }
266
+
225
267
  timings.total = Date.now() - t0;
226
268
  hookLog('session-focus', 'info', `timings: ${JSON.stringify(timings)}`);
227
269
 
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "mindlore",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "AI-native knowledge system for Claude Code",
5
5
  "type": "commonjs",
6
6
  "bin": {
7
- "mindlore": "dist/scripts/init.js"
7
+ "mindlore": "dist/scripts/init.js",
8
+ "mindlore-clean-cache": "dist/scripts/mindlore-clean-cache.js"
8
9
  },
9
10
  "scripts": {
10
11
  "build": "tsc",
@@ -27,7 +28,7 @@
27
28
  "bundle:hooks": "npx tsx scripts/bundle-hooks.ts",
28
29
  "bundle:mcp": "npx esbuild scripts/mcp-server.ts --bundle --platform=node --target=node20 --format=cjs --outfile=mcp-server.cjs --external:better-sqlite3",
29
30
  "bundle": "npm run bundle:hooks && npm run bundle:mcp",
30
- "postinstall": "npm rebuild better-sqlite3"
31
+ "postinstall": "npm run build && npm rebuild better-sqlite3"
31
32
  },
32
33
  "keywords": [
33
34
  "claude-code",
@@ -55,6 +56,7 @@
55
56
  "dependencies": {
56
57
  "@modelcontextprotocol/sdk": "^1.29.0",
57
58
  "better-sqlite3": "^12.9.0",
59
+ "sqlite-vec": "^0.1.9",
58
60
  "zod": "^4.3.6"
59
61
  },
60
62
  "devDependencies": {
package/plugin.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "manifestVersion": 2,
3
3
  "name": "mindlore",
4
4
  "description": "AI-native knowledge system for Claude Code. Persistent, searchable, evolving knowledge base with FTS5 and Knowledge Graph.",
5
- "version": "0.7.3",
5
+ "version": "0.7.5",
6
6
  "skills": [
7
7
  {
8
8
  "name": "mindlore-ingest",
@@ -15,7 +15,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
15
15
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-decide" → `MINDLORE_PKG = {base_directory}/../..`
16
16
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
17
17
 
18
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
18
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-decide <script> [args...]` for all script commands.
19
19
 
20
20
  ## Scope
21
21
 
@@ -10,7 +10,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
10
10
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-diary" → `MINDLORE_PKG = {base_directory}/../..`
11
11
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
12
12
 
13
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
13
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-diary <script> [args...]` for all script commands.
14
14
 
15
15
  # /mindlore-diary
16
16
 
@@ -27,7 +27,7 @@ Determine target using `getActiveMindloreDir()` logic:
27
27
  ## On Start — Read skill_memory
28
28
 
29
29
  ```bash
30
- node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" get mindlore-diary last_diary_date
30
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-diary lib/skill-memory.js get mindlore-diary last_diary_date
31
31
  ```
32
32
  If last_diary_date is today, warn: "Diary already ran today. Continue anyway?"
33
33
 
@@ -73,8 +73,8 @@ If last_diary_date is today, warn: "Diary already ran today. Continue anyway?"
73
73
  ## On End — Write skill_memory
74
74
 
75
75
  ```bash
76
- node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-diary last_diary_date "$(date -I)"
77
- node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-diary last_episode_count "{N}"
76
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-diary lib/skill-memory.js set mindlore-diary last_diary_date "$(date -I)"
77
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-diary lib/skill-memory.js set mindlore-diary last_episode_count "{N}"
78
78
  ```
79
79
 
80
80
  ## Rules
@@ -12,7 +12,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
12
12
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-evolve" → `MINDLORE_PKG = {base_directory}/../..`
13
13
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
14
14
 
15
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
15
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-evolve <script> [args...]` for all script commands.
16
16
 
17
17
  # /mindlore-evolve
18
18
 
@@ -107,7 +107,7 @@ Apply suggested changes with user approval.
107
107
  **Rules:**
108
108
  - NEVER make automatic changes — always require user approval
109
109
  - Show diff preview before applying
110
- - After changes, run `node "$MINDLORE_PKG/dist/scripts/mindlore-fts5-index.js"` for FTS5 sync
110
+ - After changes, run `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-evolve mindlore-fts5-index.js` for FTS5 sync
111
111
  - Log every change to log.md with timestamp
112
112
  - The `[mindlore:evolve]` marker in the Agent prompt is required — it triggers the model-router hook to use the cost-optimized model (sonnet by default)
113
113
 
@@ -11,7 +11,7 @@ allowed-tools: [Bash, Read]
11
11
  Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
12
12
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-health" → `MINDLORE_PKG = {base_directory}/../..`
13
13
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
14
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
14
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-health <script> [args...]` for all script commands.
15
15
 
16
16
  # /mindlore-health
17
17
 
@@ -33,7 +33,7 @@ User says "health check", "mindlore health", "bilgi sistemi kontrol", "saglik ko
33
33
 
34
34
  1. Run the health check script:
35
35
  ```bash
36
- node "$MINDLORE_PKG/dist/scripts/mindlore-health-check.js"
36
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-health mindlore-health-check.js
37
37
  ```
38
38
 
39
39
  2. Read the output and provide LLM interpretation:
@@ -13,7 +13,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
13
13
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-ingest" → `MINDLORE_PKG = {base_directory}/../..`
14
14
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
15
15
 
16
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
16
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest <script> [args...]` for all script commands.
17
17
 
18
18
  # /mindlore-ingest
19
19
 
@@ -59,7 +59,7 @@ Birden fazla URL verildiğinde (boşluk veya virgülle ayrılmış):
59
59
 
60
60
  **Pre-check (before fetch):**
61
61
  ```bash
62
- node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" get mindlore-ingest last_ingest_urls
62
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest lib/skill-memory.js get mindlore-ingest last_ingest_urls
63
63
  ```
64
64
  If URL already in the list, warn user: "This URL was ingested recently. Re-ingest?"
65
65
 
@@ -67,7 +67,7 @@ If URL already in the list, warn user: "This URL was ingested recently. Re-inges
67
67
 
68
68
  1. **Fetch raw content (zero token):**
69
69
  ```bash
70
- node "$MINDLORE_PKG/dist/scripts/fetch-raw.js" "$URL" --out-dir "$MINDLORE_DIR/raw"
70
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest fetch-raw.js "$URL" --out-dir "$MINDLORE_DIR/raw"
71
71
  ```
72
72
  Script output: `{ "saved": "/path/to/raw/2026-04-18-abc123.md", "chars": 14823, "method": "curl" }`
73
73
 
@@ -88,7 +88,7 @@ If URL already in the list, warn user: "This URL was ingested recently. Re-inges
88
88
 
89
89
  5. **Update skill_memory:**
90
90
  ```bash
91
- node "$MINDLORE_PKG/dist/scripts/lib/skill-memory.js" set mindlore-ingest last_ingest_urls "$URL"
91
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest lib/skill-memory.js set mindlore-ingest last_ingest_urls "$URL"
92
92
  ```
93
93
 
94
94
  6. **Return to caller (this is all the ana session sees):**
@@ -176,7 +176,7 @@ After every ingest, verify all 7 checkpoints before reporting success:
176
176
 
177
177
  0. **Duplicate check** — Ingest öncesi mevcut DB'de benzer içerik ara:
178
178
  ```bash
179
- node "$MINDLORE_PKG/dist/scripts/lib/similarity.js" "<title or first 100 chars>"
179
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest lib/similarity.js "<title or first 100 chars>"
180
180
  ```
181
181
  Eğer score > 0.7 olan sonuç varsa KULLANICIYA SOR: "Bu içerik '${slug}' ile benzer görünüyor. Yine de eklensin mi?"
182
182
  Kullanıcı onaylarsa devam et, yoksa atla.
@@ -185,11 +185,11 @@ After every ingest, verify all 7 checkpoints before reporting success:
185
185
  3. **INDEX.md updated** — stats line incremented, Recent section has new entry
186
186
  4. **Domain updated** — if relevant domain exists, new finding added (max 1 domain per ingest)
187
187
  5. **log.md entry** — append `| {date} | ingest | {slug}.md |`
188
- 6. **FTS5 indexed** — FileChanged hook auto-triggers, but verify: `node "$MINDLORE_PKG/dist/scripts/mindlore-fts5-search.js" "{keyword}"` returns the new file
188
+ 6. **FTS5 indexed** — FileChanged hook auto-triggers, but verify: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest mindlore-fts5-search.js "{keyword}"` returns the new file
189
189
 
190
190
  If any checkpoint fails, fix it before reporting "ingest complete". Do NOT skip steps.
191
191
 
192
192
  Optional: run full health check for structural integrity:
193
193
  ```bash
194
- node "$MINDLORE_PKG/dist/scripts/mindlore-health-check.js"
194
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-ingest mindlore-health-check.js
195
195
  ```
@@ -15,7 +15,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
15
15
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-log" → `MINDLORE_PKG = {base_directory}/../..`
16
16
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
17
17
 
18
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
18
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-log <script> [args...]` for all script commands.
19
19
 
20
20
  ## Scope
21
21
 
@@ -12,7 +12,7 @@ Resolve `MINDLORE_PKG` (package root) using one of these methods, in order:
12
12
  1. If CC injected "Base directory for this skill: /path/to/skills/mindlore-maintain" → `MINDLORE_PKG = {base_directory}/../..`
13
13
  2. Fallback: run `node -e "console.log(require('path').join(require('child_process').execSync('npm root -g',{encoding:'utf8'}).trim(),'mindlore')))"`
14
14
 
15
- Use: `node "$MINDLORE_PKG/dist/scripts/..."` for all script commands.
15
+ Use: `node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-maintain <script> [args...]` for all script commands.
16
16
 
17
17
  # /mindlore-maintain
18
18
 
@@ -97,7 +97,7 @@ KB bakım skill'i. Reflect düşünür, maintain temizler.
97
97
 
98
98
  1. Deterministic wiki-lint:
99
99
  ```bash
100
- node "$MINDLORE_PKG/dist/scripts/mindlore-health-check.js" ~/.mindlore 2>/dev/null | grep -A 5 'contradiction'
100
+ node "$MINDLORE_PKG/dist/scripts/lib/skill-runner.js" mindlore-maintain mindlore-health-check.js ~/.mindlore 2>/dev/null | grep -A 5 'contradiction'
101
101
  ```
102
102
 
103
103
  2. Semantic analiz (opsiyonel, token harcar)