mindlore 0.7.5 → 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 +3 -3
  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 +37944 -0
  143. package/package.json +4 -2
  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 +141 -0
  148. package/templates/config.json +1 -1
@@ -71,7 +71,7 @@ var require_constants = __commonJS({
71
71
  return mod && mod.__esModule ? mod : { "default": mod };
72
72
  };
73
73
  Object.defineProperty(exports2, "__esModule", { value: true });
74
- 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;
74
+ 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;
75
75
  exports2.isKnownHookEvent = isKnownHookEvent;
76
76
  exports2.isSessionCategory = isSessionCategory;
77
77
  exports2.fixVersionTokens = fixVersionTokens;
@@ -392,6 +392,8 @@ var require_constants = __commonJS({
392
392
  reference: "memory",
393
393
  note: "memory"
394
394
  };
395
+ exports2.NESTED_DIR_TYPES = /* @__PURE__ */ new Set(["raw"]);
396
+ exports2.SLUG_OPTIONAL_TYPES = /* @__PURE__ */ new Set(["raw", "compaction-snapshot"]);
395
397
  exports2.CC_PLUGIN_CACHE_DIR = path_1.default.join(os_1.default.homedir(), ".claude", "plugins", "cache");
396
398
  exports2.CC_MEMORY_PATH_MARKER = path_1.default.join(".claude", "projects");
397
399
  exports2.CC_MEMORY_DIR = "memory";
@@ -463,6 +465,12 @@ var require_constants = __commonJS({
463
465
  exports2.DECAY_HALF_LIFE_DAYS = 30;
464
466
  exports2.STALE_THRESHOLD = 0.3;
465
467
  exports2.CONSOLIDATION_THRESHOLD = 50;
468
+ exports2.LEARNINGS_MAX_LESSONS = 10;
469
+ exports2.LEARNINGS_MAX_LINES_PER_LESSON = 5;
470
+ exports2.LEARNINGS_TOTAL_CHAR_BUDGET = 6e3;
471
+ exports2.REFLECT_THRESHOLD_DAYS = 7;
472
+ exports2.NUDGE_COOLDOWN_HOURS = 24;
473
+ exports2.CACHE_STALE_AGE_MS = 24 * 3600 * 1e3;
466
474
  }
467
475
  });
468
476
 
@@ -1086,6 +1094,42 @@ var require_search_engine = __commonJS({
1086
1094
  }
1087
1095
  });
1088
1096
 
1097
+ // dist/scripts/lib/search-throttle.js
1098
+ var require_search_throttle = __commonJS({
1099
+ "dist/scripts/lib/search-throttle.js"(exports2) {
1100
+ "use strict";
1101
+ Object.defineProperty(exports2, "__esModule", { value: true });
1102
+ exports2.SearchThrottle = void 0;
1103
+ var SearchThrottle = class {
1104
+ db;
1105
+ constructor(db) {
1106
+ this.db = db;
1107
+ }
1108
+ incrementCallCount(sessionId) {
1109
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1110
+ const row = this.db.prepare(`
1111
+ INSERT INTO search_throttle (session_id, call_count, last_call)
1112
+ VALUES (?, 1, ?)
1113
+ ON CONFLICT(session_id) DO UPDATE SET call_count = call_count + 1, last_call = ?
1114
+ RETURNING call_count
1115
+ `).get(sessionId, now, now);
1116
+ return row?.call_count ?? 1;
1117
+ }
1118
+ // baseMax: caller's adaptive ceiling (e.g. context-aware count from token estimator).
1119
+ // Throttle's role is a safety floor under high call counts; when callCount is low,
1120
+ // honor baseMax fully so adaptive expansion (up to 5) is reachable.
1121
+ getMaxResults(callCount, baseMax = 3) {
1122
+ if (callCount <= 10)
1123
+ return baseMax;
1124
+ if (callCount <= 20)
1125
+ return 1;
1126
+ return 0;
1127
+ }
1128
+ };
1129
+ exports2.SearchThrottle = SearchThrottle;
1130
+ }
1131
+ });
1132
+
1089
1133
  // dist/scripts/lib/search-cache.js
1090
1134
  var require_search_cache = __commonJS({
1091
1135
  "dist/scripts/lib/search-cache.js"(exports2) {
@@ -1166,30 +1210,167 @@ var require_search_cache = __commonJS({
1166
1210
  }
1167
1211
  };
1168
1212
  exports2.SearchCache = SearchCache;
1169
- var SearchThrottle = class {
1170
- db;
1171
- constructor(db) {
1172
- this.db = db;
1213
+ var search_throttle_js_1 = require_search_throttle();
1214
+ Object.defineProperty(exports2, "SearchThrottle", { enumerable: true, get: function() {
1215
+ return search_throttle_js_1.SearchThrottle;
1216
+ } });
1217
+ }
1218
+ });
1219
+
1220
+ // dist/scripts/lib/transcript-token-estimator.js
1221
+ var require_transcript_token_estimator = __commonJS({
1222
+ "dist/scripts/lib/transcript-token-estimator.js"(exports2) {
1223
+ "use strict";
1224
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
1225
+ if (k2 === void 0) k2 = k;
1226
+ var desc = Object.getOwnPropertyDescriptor(m, k);
1227
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1228
+ desc = { enumerable: true, get: function() {
1229
+ return m[k];
1230
+ } };
1173
1231
  }
1174
- incrementCallCount(sessionId) {
1175
- const now = (/* @__PURE__ */ new Date()).toISOString();
1176
- const row = this.db.prepare(`
1177
- INSERT INTO search_throttle (session_id, call_count, last_call)
1178
- VALUES (?, 1, ?)
1179
- ON CONFLICT(session_id) DO UPDATE SET call_count = call_count + 1, last_call = ?
1180
- RETURNING call_count
1181
- `).get(sessionId, now, now);
1182
- return row?.call_count ?? 1;
1232
+ Object.defineProperty(o, k2, desc);
1233
+ }) : (function(o, m, k, k2) {
1234
+ if (k2 === void 0) k2 = k;
1235
+ o[k2] = m[k];
1236
+ }));
1237
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
1238
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
1239
+ }) : function(o, v) {
1240
+ o["default"] = v;
1241
+ });
1242
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
1243
+ var ownKeys = function(o) {
1244
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
1245
+ var ar = [];
1246
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
1247
+ return ar;
1248
+ };
1249
+ return ownKeys(o);
1250
+ };
1251
+ return function(mod) {
1252
+ if (mod && mod.__esModule) return mod;
1253
+ var result = {};
1254
+ if (mod != null) {
1255
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
1256
+ }
1257
+ __setModuleDefault(result, mod);
1258
+ return result;
1259
+ };
1260
+ })();
1261
+ Object.defineProperty(exports2, "__esModule", { value: true });
1262
+ exports2.estimateContextTokens = estimateContextTokens;
1263
+ exports2.getContextWindow = getContextWindow;
1264
+ exports2.resultCountFromContext = resultCountFromContext;
1265
+ exports2.adaptiveResultCount = adaptiveResultCount;
1266
+ var fs2 = __importStar(require("fs"));
1267
+ var CHAR_PER_TOKEN = 4;
1268
+ var DEFAULT_TAIL_LINES = 500;
1269
+ var AVG_BYTES_PER_TRANSCRIPT_LINE = 1500;
1270
+ var DEFAULT_CONTEXT_WINDOW = 2e5;
1271
+ var cache = /* @__PURE__ */ new Map();
1272
+ function isRecord(x) {
1273
+ return x !== null && typeof x === "object" && !Array.isArray(x);
1274
+ }
1275
+ function countContentChars(obj) {
1276
+ if (!isRecord(obj))
1277
+ return 0;
1278
+ const candidates = [];
1279
+ if (isRecord(obj.message))
1280
+ candidates.push(obj.message.content);
1281
+ candidates.push(obj.content);
1282
+ for (const content of candidates) {
1283
+ if (content === null || content === void 0)
1284
+ continue;
1285
+ if (typeof content === "string")
1286
+ return content.length;
1287
+ if (Array.isArray(content)) {
1288
+ let sum = 0;
1289
+ for (const block of content) {
1290
+ if (typeof block === "string") {
1291
+ sum += block.length;
1292
+ } else if (isRecord(block)) {
1293
+ if (typeof block.text === "string")
1294
+ sum += block.text.length;
1295
+ else if (typeof block.content === "string")
1296
+ sum += block.content.length;
1297
+ else
1298
+ sum += JSON.stringify(block).length;
1299
+ }
1300
+ }
1301
+ return sum;
1302
+ }
1303
+ return JSON.stringify(content).length;
1183
1304
  }
1184
- getMaxResults(callCount) {
1185
- if (callCount <= 10)
1186
- return 3;
1187
- if (callCount <= 20)
1188
- return 1;
1305
+ return 0;
1306
+ }
1307
+ function estimateContextTokens(transcriptPath, opts = {}) {
1308
+ const tail = opts.tailLines ?? DEFAULT_TAIL_LINES;
1309
+ let fd;
1310
+ try {
1311
+ const st = fs2.statSync(transcriptPath);
1312
+ const cached = cache.get(transcriptPath);
1313
+ if (cached && cached.mtime === st.mtimeMs)
1314
+ return cached.tokens;
1315
+ const readSize = Math.min(st.size, tail * AVG_BYTES_PER_TRANSCRIPT_LINE);
1316
+ if (readSize === 0) {
1317
+ cache.set(transcriptPath, { mtime: st.mtimeMs, tokens: 0 });
1318
+ return 0;
1319
+ }
1320
+ fd = fs2.openSync(transcriptPath, "r");
1321
+ const buf = Buffer.allocUnsafe(readSize);
1322
+ const bytesRead = fs2.readSync(fd, buf, 0, readSize, st.size - readSize);
1323
+ const text = buf.toString("utf8", 0, bytesRead);
1324
+ let chars = 0;
1325
+ for (const line of text.split("\n")) {
1326
+ if (!line)
1327
+ continue;
1328
+ try {
1329
+ const obj = JSON.parse(line);
1330
+ chars += countContentChars(obj);
1331
+ } catch {
1332
+ }
1333
+ }
1334
+ const tokens = Math.floor(chars / CHAR_PER_TOKEN);
1335
+ cache.set(transcriptPath, { mtime: st.mtimeMs, tokens });
1336
+ return tokens;
1337
+ } catch {
1189
1338
  return 0;
1339
+ } finally {
1340
+ if (fd !== void 0) {
1341
+ try {
1342
+ fs2.closeSync(fd);
1343
+ } catch {
1344
+ }
1345
+ }
1190
1346
  }
1191
- };
1192
- exports2.SearchThrottle = SearchThrottle;
1347
+ }
1348
+ function getContextWindow() {
1349
+ const env = process.env.CLAUDE_CONTEXT_WINDOW;
1350
+ if (env) {
1351
+ const n = parseInt(env, 10);
1352
+ if (!isNaN(n) && n > 0)
1353
+ return n;
1354
+ }
1355
+ return DEFAULT_CONTEXT_WINDOW;
1356
+ }
1357
+ function resultCountFromContext(pct) {
1358
+ if (pct < 0.5)
1359
+ return 5;
1360
+ if (pct < 0.75)
1361
+ return 3;
1362
+ if (pct < 0.9)
1363
+ return 2;
1364
+ return 1;
1365
+ }
1366
+ function adaptiveResultCount(transcriptPath) {
1367
+ if (!transcriptPath)
1368
+ return 3;
1369
+ const tokens = estimateContextTokens(transcriptPath);
1370
+ if (tokens === 0)
1371
+ return 3;
1372
+ return resultCountFromContext(tokens / getContextWindow());
1373
+ }
1193
1374
  }
1194
1375
  });
1195
1376
 
@@ -1197,6 +1378,7 @@ var require_search_cache = __commonJS({
1197
1378
  var fs = require("fs");
1198
1379
  var path = require("path");
1199
1380
  var { getAllDbs, openDatabase, extractHeadings, readConfig, hookLog, incrementRecallCount, withTelemetry } = require("./lib/mindlore-common.cjs");
1381
+ var { safeMkdir, safeWriteFile } = require("./lib/secure-io.cjs");
1200
1382
  var MAX_RESULTS = 3;
1201
1383
  var MIN_QUERY_WORDS = 3;
1202
1384
  var searchEngineMod;
@@ -1209,21 +1391,37 @@ try {
1209
1391
  SearchCacheMod = require_search_cache();
1210
1392
  } catch (_err) {
1211
1393
  }
1394
+ var TokenEstimatorMod;
1395
+ try {
1396
+ TokenEstimatorMod = require_transcript_token_estimator();
1397
+ } catch (_err) {
1398
+ }
1212
1399
  function parseStdin() {
1213
1400
  try {
1214
1401
  const raw = fs.readFileSync(0, "utf8").trim();
1215
- if (!raw) return { userMessage: "", sessionId: "unknown" };
1402
+ if (!raw) return { userMessage: "", sessionId: "unknown", transcriptPath: void 0 };
1216
1403
  const parsed = JSON.parse(raw);
1217
1404
  const userMessage = parsed.prompt || parsed.content || parsed.message || parsed.query || raw;
1218
1405
  const sessionId = parsed.session_id || "unknown";
1219
- return { userMessage, sessionId };
1406
+ const transcriptPath = parsed.transcript_path || parsed.transcriptPath;
1407
+ return { userMessage, sessionId, transcriptPath };
1220
1408
  } catch (_err) {
1221
- return { userMessage: "", sessionId: "unknown" };
1409
+ return { userMessage: "", sessionId: "unknown", transcriptPath: void 0 };
1410
+ }
1411
+ }
1412
+ function getBaseMax(transcriptPath) {
1413
+ if (TokenEstimatorMod) {
1414
+ try {
1415
+ return TokenEstimatorMod.adaptiveResultCount(transcriptPath);
1416
+ } catch (_err) {
1417
+ }
1222
1418
  }
1419
+ return MAX_RESULTS;
1223
1420
  }
1224
1421
  function main() {
1225
- const { userMessage, sessionId } = parseStdin();
1422
+ const { userMessage, sessionId, transcriptPath } = parseStdin();
1226
1423
  if (!userMessage || userMessage.length < MIN_QUERY_WORDS) return;
1424
+ const baseMax = getBaseMax(transcriptPath);
1227
1425
  let searchMs = 0;
1228
1426
  const dbPaths = getAllDbs();
1229
1427
  if (dbPaths.length === 0) return;
@@ -1235,17 +1433,19 @@ function main() {
1235
1433
  const config = readConfig(path.dirname(dbPaths[0]));
1236
1434
  const synonyms = config && config.synonyms ? config.synonyms : {};
1237
1435
  const allResults = [];
1436
+ let sessionEffectiveMax = baseMax;
1238
1437
  for (const dbPath of dbPaths) {
1239
1438
  const db = openDatabase(dbPath);
1240
1439
  if (!db) continue;
1241
1440
  try {
1242
1441
  let cache;
1243
- let effectiveMax = MAX_RESULTS;
1442
+ let effectiveMax = baseMax;
1244
1443
  if (SearchCacheMod) {
1245
1444
  cache = new SearchCacheMod.SearchCache(db, { ttlMs: 3e5 });
1246
1445
  const throttle = new SearchCacheMod.SearchThrottle(db);
1247
1446
  const callCount = throttle.incrementCallCount(sessionId);
1248
- effectiveMax = throttle.getMaxResults(callCount);
1447
+ effectiveMax = throttle.getMaxResults(callCount, baseMax);
1448
+ if (effectiveMax < sessionEffectiveMax) sessionEffectiveMax = effectiveMax;
1249
1449
  if (effectiveMax === 0) {
1250
1450
  hookLog("search", "info", `Throttled (call #${callCount})`);
1251
1451
  db.close();
@@ -1254,7 +1454,7 @@ function main() {
1254
1454
  const cached = cache.get(userMessage);
1255
1455
  if (cached) {
1256
1456
  const baseDir2 = path.dirname(dbPath);
1257
- for (const r of cached) allResults.push({ ...r, baseDir: baseDir2 });
1457
+ for (const r of cached.slice(0, effectiveMax)) allResults.push({ ...r, baseDir: baseDir2 });
1258
1458
  db.close();
1259
1459
  continue;
1260
1460
  }
@@ -1294,7 +1494,7 @@ function main() {
1294
1494
  }
1295
1495
  }
1296
1496
  unique.sort((a, b) => b.score - a.score);
1297
- const relevant = unique.slice(0, MAX_RESULTS);
1497
+ const relevant = unique.slice(0, sessionEffectiveMax);
1298
1498
  if (relevant.length === 0) return;
1299
1499
  const budget = config && config.tokenBudget || {};
1300
1500
  const perResultChars = (budget.perResult || 500) * 4;
@@ -1332,7 +1532,7 @@ Dosya: ${relativePath}${tagsStr}${headingStr}`;
1332
1532
  if (outputStr.length > OFFLOAD_THRESHOLD) {
1333
1533
  const baseDir = path.dirname(dbPaths[0]);
1334
1534
  const tmpDir = path.join(baseDir, "tmp");
1335
- fs.mkdirSync(tmpDir, { recursive: true });
1535
+ safeMkdir(tmpDir);
1336
1536
  try {
1337
1537
  const oneHourAgo = Date.now() - 36e5;
1338
1538
  const files = fs.readdirSync(tmpDir).filter((f) => f.startsWith("search-")).map((f) => ({ name: f, mtime: fs.statSync(path.join(tmpDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
@@ -1348,7 +1548,7 @@ Dosya: ${relativePath}${tagsStr}${headingStr}`;
1348
1548
  }
1349
1549
  const fileName = `search-${Date.now()}.md`;
1350
1550
  const filePath = path.join(tmpDir, fileName);
1351
- fs.writeFileSync(filePath, outputStr, "utf8");
1551
+ safeWriteFile(filePath, outputStr);
1352
1552
  const summary = outputStr.slice(0, 500).replace(/\n/g, " ").trim();
1353
1553
  outputStr = `[Mindlore Search: ${outputStr.length} chars offloaded to ${filePath}]
1354
1554
  Summary: ${summary}...
@@ -6,7 +6,7 @@ var fs = require("fs");
6
6
  var path = require("path");
7
7
  var os = require("os");
8
8
  var { execFileSync, spawn } = require("child_process");
9
- var { safeWriteFile, safeWriteJson } = require("./lib/secure-io.cjs");
9
+ var { safeMkdir, safeWriteFile, safeWriteJson } = require("./lib/secure-io.cjs");
10
10
  var { findMindloreDir, globalDir, getProjectName, openDatabase, ensureEpisodesTable, hasEpisodesTable, insertBareEpisode, insertFtsRow, hookLog, SHARED_EXPORT_DIRS, resolveWin32Bin, withTelemetry, getUnpromotedRawFiles, cleanupExpiredInjectLog } = require("./lib/mindlore-common.cjs");
11
11
  var EXPORT_DIRS = SHARED_EXPORT_DIRS;
12
12
  if (process.argv.includes("--worker")) {
@@ -118,9 +118,7 @@ function main() {
118
118
  const baseDir = findMindloreDir();
119
119
  if (!baseDir) return;
120
120
  const diaryDir = path.join(baseDir, "diary");
121
- if (!fs.existsSync(diaryDir)) {
122
- fs.mkdirSync(diaryDir, { recursive: true });
123
- }
121
+ safeMkdir(diaryDir);
124
122
  const now = /* @__PURE__ */ new Date();
125
123
  const dateStr = formatDate(now);
126
124
  const deltaPath = path.join(diaryDir, `delta-${dateStr}.md`);
@@ -248,7 +246,7 @@ function writeBareEpisode(baseDir, project, commits, changedFiles, reads) {
248
246
  }
249
247
  function writeEpisodeFile(baseDir, project, commits, changedFiles, reads) {
250
248
  const projDir = path.join(baseDir, "diary", project || "unknown");
251
- if (!fs.existsSync(projDir)) fs.mkdirSync(projDir, { recursive: true });
249
+ safeMkdir(projDir);
252
250
  const now = process.env.MINDLORE_EPISODE_TS ? new Date(process.env.MINDLORE_EPISODE_TS) : /* @__PURE__ */ new Date();
253
251
  const ts = formatDate(now);
254
252
  const filePath = path.join(projDir, `episode-${ts}.md`);
@@ -312,14 +310,14 @@ function exportMdFile(srcPath, destPath, convertFn) {
312
310
  }
313
311
  let content = fs.readFileSync(srcPath, "utf8");
314
312
  content = convertFn(content);
315
- fs.writeFileSync(destPath, content, "utf8");
313
+ safeWriteFile(destPath, content);
316
314
  return true;
317
315
  }
318
316
  function syncObsidian(baseDir) {
319
317
  try {
320
318
  let walkAndExport = function(srcDir, destDir) {
321
319
  if (!fs.existsSync(srcDir)) return;
322
- fs.mkdirSync(destDir, { recursive: true });
320
+ safeMkdir(destDir);
323
321
  for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
324
322
  if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
325
323
  const srcPath = path.join(srcDir, entry.name);
@@ -347,7 +345,7 @@ function syncObsidian(baseDir) {
347
345
  for (const rootFile of ["INDEX.md", "log.md"]) {
348
346
  const srcPath = path.join(baseDir, rootFile);
349
347
  if (!fs.existsSync(srcPath)) continue;
350
- fs.mkdirSync(destBase, { recursive: true });
348
+ safeMkdir(destBase);
351
349
  if (exportMdFile(srcPath, path.join(destBase, rootFile), convertFn)) exported++;
352
350
  }
353
351
  hookLog("session-end", "info", `obsidian exported=${exported}, dirs=${EXPORT_DIRS.length}, vault=${vaultPath}`);