micro-models-agent 0.58.2 → 0.60.0

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 (233) hide show
  1. package/CHANGELOG.md +578 -556
  2. package/README.md +358 -358
  3. package/dist/certification/certifications.json +493 -493
  4. package/dist/i18n/en.json +732 -716
  5. package/dist/i18n/ru.json +732 -716
  6. package/dist/main.js +1243 -448
  7. package/dist/modules/browser/bridge-server.mjs +219 -219
  8. package/dist/skills/builtin/git.md +36 -36
  9. package/dist/skills/builtin/typescript.md +35 -35
  10. package/package.json +51 -51
  11. package/dist/cli/commands.js +0 -447
  12. package/dist/cli/completer.js +0 -167
  13. package/dist/cli/index.js +0 -2
  14. package/dist/cli/main.js +0 -153
  15. package/dist/cli/plugin-commands.js +0 -36
  16. package/dist/cli/repl-commands.js +0 -761
  17. package/dist/cli/repl.js +0 -702
  18. package/dist/cli/run-result.js +0 -33
  19. package/dist/cli/security-commands.js +0 -164
  20. package/dist/cli/setup.js +0 -237
  21. package/dist/config/config.js +0 -276
  22. package/dist/config/defaults.js +0 -141
  23. package/dist/config/domains.js +0 -179
  24. package/dist/config/experts.js +0 -15
  25. package/dist/config/index.js +0 -4
  26. package/dist/config/security.js +0 -213
  27. package/dist/config/types.js +0 -1
  28. package/dist/core/agent-moe.js +0 -102
  29. package/dist/core/agent.js +0 -1018
  30. package/dist/core/bootstrap.js +0 -481
  31. package/dist/core/crash-handler.js +0 -51
  32. package/dist/core/environment.js +0 -199
  33. package/dist/core/index.js +0 -2
  34. package/dist/core/prompt-builder.js +0 -76
  35. package/dist/core/session-logger.js +0 -251
  36. package/dist/core/types.js +0 -1
  37. package/dist/core/version.js +0 -26
  38. package/dist/core/workspace.js +0 -76
  39. package/dist/i18n/index.js +0 -46
  40. package/dist/index.js +0 -22
  41. package/dist/llm/image-utils.js +0 -143
  42. package/dist/llm/index.js +0 -4
  43. package/dist/llm/model-loader.js +0 -78
  44. package/dist/llm/openai-compat.js +0 -497
  45. package/dist/llm/orchestrator.js +0 -200
  46. package/dist/llm/provider.js +0 -10
  47. package/dist/llm/response.js +0 -39
  48. package/dist/llm/token-counter.js +0 -39
  49. package/dist/llm/types.js +0 -1
  50. package/dist/logger/app-logger.js +0 -189
  51. package/dist/logger/file-log.js +0 -151
  52. package/dist/logger/index.js +0 -1
  53. package/dist/migration/backup.js +0 -45
  54. package/dist/migration/detect.js +0 -50
  55. package/dist/migration/index.js +0 -2
  56. package/dist/modules/artifacts/store.js +0 -61
  57. package/dist/modules/browser/actions.js +0 -76
  58. package/dist/modules/browser/bridge-client.js +0 -199
  59. package/dist/modules/browser/bridge-path.js +0 -10
  60. package/dist/modules/browser/cookie-store.js +0 -24
  61. package/dist/modules/browser/driver.js +0 -136
  62. package/dist/modules/browser/index.js +0 -7
  63. package/dist/modules/browser/module.js +0 -29
  64. package/dist/modules/browser/session.js +0 -342
  65. package/dist/modules/browser/snapshot.js +0 -148
  66. package/dist/modules/browser/types.js +0 -12
  67. package/dist/modules/certification/cli.js +0 -213
  68. package/dist/modules/certification/fact-checker.js +0 -82
  69. package/dist/modules/certification/loader.js +0 -106
  70. package/dist/modules/certification/manifest.js +0 -58
  71. package/dist/modules/certification/runner.js +0 -245
  72. package/dist/modules/certification/scenarios.js +0 -407
  73. package/dist/modules/certification/types.js +0 -1
  74. package/dist/modules/context/chunk-query.js +0 -100
  75. package/dist/modules/context/fact-extractor.js +0 -168
  76. package/dist/modules/context/history.js +0 -15
  77. package/dist/modules/context/index.js +0 -1
  78. package/dist/modules/context/manager.js +0 -440
  79. package/dist/modules/execution/audit-runners.js +0 -206
  80. package/dist/modules/execution/auditor.js +0 -218
  81. package/dist/modules/execution/execution-plugin.js +0 -431
  82. package/dist/modules/execution/index.js +0 -8
  83. package/dist/modules/execution/module.js +0 -625
  84. package/dist/modules/execution/moe-executor.js +0 -304
  85. package/dist/modules/execution/plan-coverage.js +0 -68
  86. package/dist/modules/execution/plan-persister.js +0 -46
  87. package/dist/modules/execution/plan-store.js +0 -196
  88. package/dist/modules/execution/plan-tool.js +0 -677
  89. package/dist/modules/execution/plan-validator.js +0 -153
  90. package/dist/modules/execution/planner.js +0 -94
  91. package/dist/modules/execution/stuck-detector.js +0 -746
  92. package/dist/modules/execution/tracker.js +0 -69
  93. package/dist/modules/execution/types.js +0 -1
  94. package/dist/modules/execution/verifier.js +0 -235
  95. package/dist/modules/execution/windows-commands.js +0 -41
  96. package/dist/modules/hallucination/confidence.js +0 -66
  97. package/dist/modules/hallucination/consistency.js +0 -26
  98. package/dist/modules/hallucination/detector.js +0 -47
  99. package/dist/modules/hallucination/factual.js +0 -169
  100. package/dist/modules/hallucination/index.js +0 -5
  101. package/dist/modules/hallucination/js-identifiers.js +0 -262
  102. package/dist/modules/hallucination/llm-judge.js +0 -101
  103. package/dist/modules/index.js +0 -5
  104. package/dist/modules/indexer/cache.js +0 -40
  105. package/dist/modules/indexer/index.js +0 -3
  106. package/dist/modules/indexer/module.js +0 -246
  107. package/dist/modules/indexer/project-profile.js +0 -183
  108. package/dist/modules/indexer/walker.js +0 -101
  109. package/dist/modules/lsp/check-tool.js +0 -58
  110. package/dist/modules/lsp/client.js +0 -389
  111. package/dist/modules/lsp/command.js +0 -60
  112. package/dist/modules/lsp/config.js +0 -135
  113. package/dist/modules/lsp/index.js +0 -3
  114. package/dist/modules/lsp/module.js +0 -260
  115. package/dist/modules/lsp/probe.js +0 -86
  116. package/dist/modules/lsp/project-root.js +0 -32
  117. package/dist/modules/lsp/startup-check.js +0 -144
  118. package/dist/modules/lsp/types.js +0 -1
  119. package/dist/modules/mcp/client.js +0 -399
  120. package/dist/modules/mcp/index.js +0 -3
  121. package/dist/modules/mcp/module.js +0 -142
  122. package/dist/modules/mcp/registry.js +0 -15
  123. package/dist/modules/memory/index.js +0 -1
  124. package/dist/modules/memory/module.js +0 -96
  125. package/dist/modules/memory/search.js +0 -42
  126. package/dist/modules/memory/store.js +0 -69
  127. package/dist/modules/pipelines/engine.js +0 -60
  128. package/dist/modules/pipelines/index.js +0 -3
  129. package/dist/modules/pipelines/parser.js +0 -56
  130. package/dist/modules/pipelines/template.js +0 -14
  131. package/dist/modules/plugins/builtin/lint-on-write.js +0 -334
  132. package/dist/modules/plugins/builtin/notify.js +0 -9
  133. package/dist/modules/plugins/index.js +0 -1
  134. package/dist/modules/plugins/loader.js +0 -70
  135. package/dist/modules/plugins/manager.js +0 -261
  136. package/dist/modules/plugins/types.js +0 -1
  137. package/dist/modules/pricing/index.js +0 -61
  138. package/dist/modules/pricing/prices.js +0 -129
  139. package/dist/modules/processes/detect.js +0 -34
  140. package/dist/modules/processes/index.js +0 -2
  141. package/dist/modules/processes/registry.js +0 -327
  142. package/dist/modules/processes/runner.js +0 -23
  143. package/dist/modules/providers/create.js +0 -22
  144. package/dist/modules/providers/fallback.js +0 -79
  145. package/dist/modules/providers/health.js +0 -46
  146. package/dist/modules/providers/index.js +0 -5
  147. package/dist/modules/providers/manager.js +0 -161
  148. package/dist/modules/providers/presets.js +0 -128
  149. package/dist/modules/providers/registry.js +0 -22
  150. package/dist/modules/providers/types.js +0 -1
  151. package/dist/modules/registry.js +0 -48
  152. package/dist/modules/security/audit-log.js +0 -136
  153. package/dist/modules/security/audit-notifier.js +0 -292
  154. package/dist/modules/security/command-validator.js +0 -219
  155. package/dist/modules/security/content-scanner.js +0 -53
  156. package/dist/modules/security/data-sanitizer.js +0 -89
  157. package/dist/modules/security/encryption.js +0 -242
  158. package/dist/modules/security/index.js +0 -14
  159. package/dist/modules/security/network-validator.js +0 -88
  160. package/dist/modules/security/path-validator.js +0 -203
  161. package/dist/modules/security/rate-limiter.js +0 -119
  162. package/dist/modules/security/security-policies.js +0 -531
  163. package/dist/modules/security/session-encryption.js +0 -210
  164. package/dist/modules/security/session-isolation.js +0 -95
  165. package/dist/modules/session/index.js +0 -3
  166. package/dist/modules/session/manager.js +0 -172
  167. package/dist/modules/session/module.js +0 -24
  168. package/dist/modules/session/store.js +0 -222
  169. package/dist/modules/session/types.js +0 -1
  170. package/dist/modules/skills/index.js +0 -2
  171. package/dist/modules/skills/loader.js +0 -72
  172. package/dist/modules/skills/matcher.js +0 -27
  173. package/dist/modules/skills/module.js +0 -129
  174. package/dist/modules/types.js +0 -1
  175. package/dist/modules/updater/checker.js +0 -96
  176. package/dist/modules/updater/index.js +0 -2
  177. package/dist/modules/updater/module.js +0 -116
  178. package/dist/modules/user-profile/compressor.js +0 -16
  179. package/dist/modules/user-profile/index.js +0 -1
  180. package/dist/modules/user-profile/profile.js +0 -68
  181. package/dist/tools/approve.js +0 -33
  182. package/dist/tools/attach-image.js +0 -101
  183. package/dist/tools/bash.js +0 -519
  184. package/dist/tools/browser.js +0 -115
  185. package/dist/tools/chunk-query.js +0 -100
  186. package/dist/tools/create-dir.js +0 -56
  187. package/dist/tools/delete-file.js +0 -63
  188. package/dist/tools/download-file.js +0 -117
  189. package/dist/tools/edit-file.js +0 -80
  190. package/dist/tools/enable-tools.js +0 -59
  191. package/dist/tools/executor.js +0 -154
  192. package/dist/tools/file-info.js +0 -47
  193. package/dist/tools/filter-tools.js +0 -17
  194. package/dist/tools/glob-tool.js +0 -27
  195. package/dist/tools/grep-tool.js +0 -125
  196. package/dist/tools/hidden-tools-block.js +0 -37
  197. package/dist/tools/index.js +0 -78
  198. package/dist/tools/list-dir.js +0 -49
  199. package/dist/tools/load-skill.js +0 -43
  200. package/dist/tools/mcp-call.js +0 -69
  201. package/dist/tools/move-file.js +0 -86
  202. package/dist/tools/path-utils.js +0 -101
  203. package/dist/tools/pipeline-run.js +0 -145
  204. package/dist/tools/preview.js +0 -2
  205. package/dist/tools/process-kill.js +0 -40
  206. package/dist/tools/process-list.js +0 -37
  207. package/dist/tools/process-log.js +0 -54
  208. package/dist/tools/question.js +0 -141
  209. package/dist/tools/read-file.js +0 -179
  210. package/dist/tools/recall.js +0 -118
  211. package/dist/tools/registry.js +0 -47
  212. package/dist/tools/remember.js +0 -68
  213. package/dist/tools/scope-check.js +0 -32
  214. package/dist/tools/search-history.js +0 -85
  215. package/dist/tools/subagent.js +0 -196
  216. package/dist/tools/types.js +0 -1
  217. package/dist/tools/user-input.js +0 -123
  218. package/dist/tools/web-browse.js +0 -87
  219. package/dist/tools/web-fetch.js +0 -119
  220. package/dist/tools/web-search.js +0 -105
  221. package/dist/tools/write-file.js +0 -82
  222. package/dist/ui/box.js +0 -77
  223. package/dist/ui/colors.js +0 -4
  224. package/dist/ui/diff.js +0 -178
  225. package/dist/ui/index.js +0 -6
  226. package/dist/ui/line-editor.js +0 -822
  227. package/dist/ui/line-math.js +0 -73
  228. package/dist/ui/md-formatter.js +0 -212
  229. package/dist/ui/output.js +0 -13
  230. package/dist/ui/plan-view.js +0 -103
  231. package/dist/ui/renderer.js +0 -259
  232. package/dist/ui/spinner.js +0 -70
  233. package/dist/ui/table.js +0 -144
package/dist/main.js CHANGED
@@ -2318,6 +2318,9 @@ var init_defaults = __esm(() => {
2318
2318
  responseReserve: 0.15,
2319
2319
  compactionThreshold: 0.75
2320
2320
  },
2321
+ instructions: {
2322
+ summarize: true
2323
+ },
2321
2324
  modelLoad: {
2322
2325
  autoLoad: false,
2323
2326
  flashAttention: true,
@@ -2508,7 +2511,7 @@ The path was joined onto the working directory because it does not exist as give
2508
2511
  "session.available": "Available sessions:",
2509
2512
  "session.no_match": 'No session matching "{query}"',
2510
2513
  "session.default_name": "Session {date}",
2511
- "session.info": '[Session: "{name}" ({id}) {count} messages so far]',
2514
+ "session.info_full": '[Session: "{name}" ({id}) | model: {model} | context: {contextWindow} tokens]',
2512
2515
  "session.col_active": "",
2513
2516
  "session.col_id": "ID",
2514
2517
  "session.col_name": "Name",
@@ -2912,6 +2915,8 @@ Excluded blocks: {count}`,
2912
2915
  "repl.agents_label": "Instructions:",
2913
2916
  "repl.not_found": "not found",
2914
2917
  "repl.disabled": "disabled (--no-agents-md)",
2918
+ "repl.context_probe_small": 'Context probe: model "{model}" is loaded with {actual} tokens, configured {configured} — overflow risk',
2919
+ "repl.context_probe_big": 'Context probe: model "{model}" supports {actual} tokens — consider "mma context {actual}"',
2915
2920
  "repl.show": "show",
2916
2921
  "repl.hide": "hide",
2917
2922
  "repl.resume_hint": "Use /resume <id> or /resume <name> to switch between sessions",
@@ -3186,7 +3191,27 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
3186
3191
  "moe.cycles_exhausted": "Max re-plan cycles ({max}) reached — returning partial results",
3187
3192
  "moe.partial_result": "Partial result",
3188
3193
  "moe.scope_approved": '🔓 Scope expanded for "{subtask}": {files}',
3189
- "moe.scope_rejected": '⛔ Scope request rejected for "{subtask}"'
3194
+ "moe.scope_rejected": '⛔ Scope request rejected for "{subtask}"',
3195
+ "prompt.overflow.exceeded": 'Prompt overflow: "{label}" ({original} tok) exceeded the system-prompt budget ({budget} tok) — {mode} to {resolved} tok. To fit fully, {hint}.',
3196
+ "prompt.overflow.failed": "Prompt overflow resolution failed: {error} — oversized blocks will be dropped.",
3197
+ "prompt.overflow.startup": "Startup check: {block} ({original} tok) exceeds the system-prompt budget ({budget} tok) — it will be summarized/truncated before the first run. To include it fully, {hint}.",
3198
+ "tool.session_info.no_active": "No active session",
3199
+ "tool.session_info.result": `Session: "{name}" ({id})
3200
+ Model: {model}
3201
+ Provider: {provider}
3202
+ Context window: {contextWindow} tokens
3203
+ Messages: {messages}
3204
+ Created: {createdAt}
3205
+ Updated: {updatedAt}`,
3206
+ "tool.session_info.context": "Context used: {used} / {budget} tokens ({percent}%)",
3207
+ "tool.friendly.session_info": "Session info",
3208
+ "cli.map.description": "Work with the project index / map",
3209
+ "cli.map.action": "Action: summary (default), refresh, find",
3210
+ "cli.map.query": "Search query for the find action",
3211
+ "repl.map": "Show the project map / index (summary, refresh, find)",
3212
+ "repl.map_usage": "Usage: /map [summary|refresh|find <query>]",
3213
+ "map.refreshed": "Project map refreshed",
3214
+ "map.find_usage": "Usage: map find <query>"
3190
3215
  };
3191
3216
  });
3192
3217
 
@@ -3276,7 +3301,7 @@ var init_ru = __esm(() => {
3276
3301
  "session.available": "Доступные сессии:",
3277
3302
  "session.no_match": 'Нет сессии подходящей по "{query}"',
3278
3303
  "session.default_name": "Сессия {date}",
3279
- "session.info": '[Сессия: "{name}" ({id}) {count} сообщений]',
3304
+ "session.info_full": '[Сессия: "{name}" ({id}) | модель: {model} | контекст: {contextWindow} токенов]',
3280
3305
  "session.col_active": "",
3281
3306
  "session.col_id": "ID",
3282
3307
  "session.col_name": "Имя",
@@ -3675,6 +3700,8 @@ var init_ru = __esm(() => {
3675
3700
  "repl.agents_label": "Инструкции:",
3676
3701
  "repl.not_found": "не найден",
3677
3702
  "repl.disabled": "отключено (--no-agents-md)",
3703
+ "repl.context_probe_small": 'Context-проб: модель "{model}" загружена с контекстом {actual} токенов, настроено {configured} — риск переполнения',
3704
+ "repl.context_probe_big": 'Context-проб: модель "{model}" поддерживает {actual} токенов — рассмотрите "mma context {actual}"',
3678
3705
  "repl.show": "показ",
3679
3706
  "repl.hide": "скрыть",
3680
3707
  "repl.resume_hint": "Используйте /resume <id> или /resume <имя> для переключения между сессиями",
@@ -3956,7 +3983,27 @@ var init_ru = __esm(() => {
3956
3983
  "moe.cycles_exhausted": "Достигнут лимит re-plan циклов ({max}) — возвращаю частичные результаты",
3957
3984
  "moe.partial_result": "Частичный результат",
3958
3985
  "moe.scope_approved": '🔓 Scope расширен для "{subtask}": {files}',
3959
- "moe.scope_rejected": '⛔ Запрос scope отклонён для "{subtask}"'
3986
+ "moe.scope_rejected": '⛔ Запрос scope отклонён для "{subtask}"',
3987
+ "prompt.overflow.exceeded": 'Промпт переполнен: "{label}" ({original} токенов) превысил бюджет системного промпта ({budget} токенов) — {mode} до {resolved} токенов. Чтобы включить полностью, {hint}.',
3988
+ "prompt.overflow.failed": "Не удалось разрешить переполнение промпта: {error} — слишком большие блоки будут отброшены.",
3989
+ "prompt.overflow.startup": "Проверка при старте: {block} ({original} токенов) превышает бюджет системного промпта ({budget} токенов) — будет суммаризован/обрезан перед первым запуском. Чтобы включить полностью, {hint}.",
3990
+ "tool.session_info.no_active": "Нет активной сессии",
3991
+ "tool.session_info.result": `Сессия: "{name}" ({id})
3992
+ Модель: {model}
3993
+ Провайдер: {provider}
3994
+ Контекстное окно: {contextWindow} токенов
3995
+ Сообщений: {messages}
3996
+ Создана: {createdAt}
3997
+ Обновлена: {updatedAt}`,
3998
+ "tool.session_info.context": "Использовано контекста: {used} / {budget} токенов ({percent}%)",
3999
+ "tool.friendly.session_info": "Информация о сессии",
4000
+ "cli.map.description": "Работа с индексом / картой проекта",
4001
+ "cli.map.action": "Действие: summary (по умолчанию), refresh, find",
4002
+ "cli.map.query": "Поисковый запрос для действия find",
4003
+ "repl.map": "Показать карту проекта / индекс (summary, refresh, find)",
4004
+ "repl.map_usage": "Использование: /map [summary|refresh|find <запрос>]",
4005
+ "map.refreshed": "Карта проекта обновлена",
4006
+ "map.find_usage": "Использование: map find <запрос>"
3960
4007
  };
3961
4008
  });
3962
4009
 
@@ -4466,6 +4513,7 @@ var init_domains = __esm(() => {
4466
4513
  "model",
4467
4514
  "contextWindow",
4468
4515
  "contextBudget",
4516
+ "instructions",
4469
4517
  "modelLoad",
4470
4518
  "maxToolIterations",
4471
4519
  "stuckThreshold",
@@ -6718,6 +6766,29 @@ var init_factory = __esm(() => {
6718
6766
  });
6719
6767
 
6720
6768
  // src/llm/model-loader.ts
6769
+ async function getLoadedContextLength(baseUrl, model, timeoutMs = 3000) {
6770
+ const base = baseUrl.replace(/\/$/, "").replace(/\/v1\/?$/, "");
6771
+ try {
6772
+ const response = await fetch(`${base}/api/v1/models`, {
6773
+ signal: AbortSignal.timeout(timeoutMs)
6774
+ });
6775
+ if (!response.ok)
6776
+ return null;
6777
+ const data = await response.json();
6778
+ const models = data.models || [];
6779
+ const found = models.find((m) => m.key === model || m.name === model || model.includes(m.key));
6780
+ if (!found)
6781
+ return null;
6782
+ const loadedInstance = (found.loaded_instances ?? [])[0];
6783
+ const actual = loadedInstance?.config?.context_length ?? found.max_context_length;
6784
+ if (typeof actual !== "number" || actual <= 0)
6785
+ return null;
6786
+ return { model: found.key ?? found.name ?? model, actual };
6787
+ } catch {
6788
+ return null;
6789
+ }
6790
+ }
6791
+
6721
6792
  class ModelLoader {
6722
6793
  baseUrl;
6723
6794
  logger;
@@ -9906,6 +9977,7 @@ class PromptBuilder {
9906
9977
  let usedTokens = 0;
9907
9978
  const included = [];
9908
9979
  const excluded = [];
9980
+ const excludedBlocks = [];
9909
9981
  const blocks = [];
9910
9982
  for (const block of essential) {
9911
9983
  included.push(block.content);
@@ -9926,6 +9998,7 @@ class PromptBuilder {
9926
9998
  usedTokens += tokens;
9927
9999
  } else {
9928
10000
  excluded.push(block.content);
10001
+ excludedBlocks.push(block);
9929
10002
  }
9930
10003
  blocks.push({
9931
10004
  label: blockLabel(block.content),
@@ -9940,6 +10013,7 @@ class PromptBuilder {
9940
10013
 
9941
10014
  `),
9942
10015
  excluded,
10016
+ excludedBlocks,
9943
10017
  blocks
9944
10018
  };
9945
10019
  }
@@ -14478,7 +14552,212 @@ var init_audit_gate = __esm(() => {
14478
14552
  init_i18n();
14479
14553
  });
14480
14554
 
14555
+ // src/core/prompt-overflow.ts
14556
+ import { createHash } from "crypto";
14557
+ import { existsSync as existsSync27, mkdirSync as mkdirSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
14558
+ import { join as join17 } from "path";
14559
+ function dryRunOverflow(allBlocks, systemBudget) {
14560
+ const builder = new PromptBuilder(systemBudget);
14561
+ builder.addBlocks(allBlocks);
14562
+ const result = builder.build();
14563
+ const includedTokens = result.blocks.filter((b) => b.included).reduce((sum, b) => sum + b.tokens, 0);
14564
+ const overflow = result.excludedBlocks.filter((b) => Boolean(b.kind));
14565
+ return { includedTokens, overflow };
14566
+ }
14567
+ function cacheKey(kind, content, maxTokens) {
14568
+ return createHash("sha256").update(`${kind}|${maxTokens}|${content}`).digest("hex").slice(0, 24);
14569
+ }
14570
+ function readCache(cacheDir, key) {
14571
+ try {
14572
+ const path = join17(cacheDir, `${key}.md`);
14573
+ if (!existsSync27(path))
14574
+ return null;
14575
+ const raw = readFileSync14(path, "utf-8").trim();
14576
+ if (!raw)
14577
+ return null;
14578
+ try {
14579
+ const parsed = JSON.parse(raw);
14580
+ if ((parsed.mode === "summary" || parsed.mode === "truncate") && typeof parsed.text === "string" && parsed.text) {
14581
+ return parsed;
14582
+ }
14583
+ } catch {
14584
+ return { mode: "summary", text: raw };
14585
+ }
14586
+ return null;
14587
+ } catch {}
14588
+ return null;
14589
+ }
14590
+ function writeCache(cacheDir, key, entry) {
14591
+ try {
14592
+ mkdirSync13(cacheDir, { recursive: true });
14593
+ writeFileSync10(join17(cacheDir, `${key}.md`), JSON.stringify(entry), "utf-8");
14594
+ } catch {}
14595
+ }
14596
+ async function collectText(provider, prompt, maxTokens) {
14597
+ let text = "";
14598
+ for await (const chunk of provider.chat([{ role: "user", content: prompt }], undefined, undefined, {
14599
+ maxTokens: maxTokens * 2,
14600
+ reasoningEffort: "none"
14601
+ })) {
14602
+ if (chunk.type === "text" && chunk.content)
14603
+ text += chunk.content;
14604
+ }
14605
+ return text.trim();
14606
+ }
14607
+ function truncateToTokens(content, maxTokens) {
14608
+ const maxChars = Math.max(200, maxTokens * CHARS_PER_TOKEN);
14609
+ if (content.length <= maxChars)
14610
+ return content;
14611
+ let cut = content.slice(0, maxChars);
14612
+ const lastBreak = cut.lastIndexOf(`
14613
+ `);
14614
+ if (lastBreak > maxChars * 0.5)
14615
+ cut = cut.slice(0, lastBreak);
14616
+ return `${cut.trimEnd()}
14617
+
14618
+ [...truncated — read the full file for details...]`;
14619
+ }
14620
+ function blockLabel2(content) {
14621
+ const first = content.split(`
14622
+ `)[0].trim();
14623
+ return first.length > 60 ? `${first.slice(0, 57)}...` : first;
14624
+ }
14625
+ async function resolvePromptOverflow(opts) {
14626
+ const { overflow, includedTokens, systemBudget, provider, cacheDir, logger } = opts;
14627
+ const sorted = [...overflow].sort((a, b) => KIND_ORDER.indexOf(a.kind) - KIND_ORDER.indexOf(b.kind));
14628
+ const replacements = [];
14629
+ const warnings = [];
14630
+ let used = includedTokens;
14631
+ let unresolved = [];
14632
+ for (const block of sorted) {
14633
+ const kind = block.kind;
14634
+ const maxTokens = systemBudget - used - HINT_BLOCK_TOKENS;
14635
+ if (maxTokens < 100) {
14636
+ unresolved.push(kind);
14637
+ continue;
14638
+ }
14639
+ let mode = "summary";
14640
+ let text = "";
14641
+ const key = cacheKey(kind, block.content, maxTokens);
14642
+ const cached = readCache(cacheDir, key);
14643
+ if (cached) {
14644
+ text = cached.text;
14645
+ mode = cached.mode;
14646
+ logger?.debug(`Prompt overflow: cache hit for ${kind} (${key}, ${mode})`);
14647
+ } else if (provider) {
14648
+ const targetChars = Math.floor(maxTokens * (CHARS_PER_TOKEN - 1));
14649
+ try {
14650
+ const prompt = [
14651
+ `Summarize the following ${KIND_LABEL[kind]} document.`,
14652
+ `Target length: at most ${targetChars} characters (~${maxTokens} tokens). Be strict about it.`,
14653
+ `Preserve concrete facts: file paths, commands, rules, naming conventions, workflow steps.`,
14654
+ `Keep the structure (headings / bullet lists). Output ONLY the summary text.`,
14655
+ ``,
14656
+ `--- DOCUMENT START ---`,
14657
+ block.content,
14658
+ `--- DOCUMENT END ---`
14659
+ ].join(`
14660
+ `);
14661
+ text = await collectText(provider, prompt, maxTokens);
14662
+ let retries = 0;
14663
+ while (text && estimateTokens(text) > maxTokens && retries < 1) {
14664
+ retries++;
14665
+ logger?.debug(`Prompt overflow: ${kind} summary overshot (${estimateTokens(text)} > ${maxTokens} tok), compressing (retry ${retries})`);
14666
+ text = await collectText(provider, [
14667
+ `Compress the following text to at most ${targetChars} characters.`,
14668
+ `Keep the structure (headings / bullet lists) and all concrete facts: file paths, commands, rules.`,
14669
+ `Output ONLY the compressed text.`,
14670
+ ``,
14671
+ `--- TEXT START ---`,
14672
+ text,
14673
+ `--- TEXT END ---`
14674
+ ].join(`
14675
+ `), maxTokens);
14676
+ }
14677
+ } catch (err) {
14678
+ logger?.warn(`Prompt overflow: summarization failed for ${kind}: ${err?.message ?? err}`);
14679
+ text = "";
14680
+ }
14681
+ }
14682
+ if (!text) {
14683
+ mode = "truncate";
14684
+ text = truncateToTokens(block.content, maxTokens);
14685
+ }
14686
+ if (estimateTokens(text) > maxTokens) {
14687
+ if (mode === "summary") {
14688
+ mode = "truncate";
14689
+ }
14690
+ text = truncateToTokens(text, maxTokens);
14691
+ }
14692
+ const resolvedTokens = estimateTokens(text);
14693
+ used += resolvedTokens;
14694
+ writeCache(cacheDir, key, { mode, text });
14695
+ replacements.push({
14696
+ content: text,
14697
+ priority: "high",
14698
+ essential: false,
14699
+ estimatedTokens: resolvedTokens,
14700
+ kind
14701
+ });
14702
+ warnings.push({
14703
+ kind,
14704
+ label: blockLabel2(block.content),
14705
+ originalTokens: block.estimatedTokens,
14706
+ resolvedTokens,
14707
+ mode
14708
+ });
14709
+ }
14710
+ const hintBlock = replacements.length > 0 ? {
14711
+ content: [
14712
+ `[Instructions note] Some project blocks exceeded the system-prompt budget and were compressed:`,
14713
+ ...warnings.map((w) => `- ${KIND_LABEL[w.kind]}: ${w.originalTokens} tokens → ${w.resolvedTokens} tokens (${w.mode})`),
14714
+ ...unresolved.length > 0 ? unresolved.map((k) => `- ${KIND_LABEL[k]}: did not fit at all — read it yourself if needed`) : [],
14715
+ ...warnings.filter((w) => KIND_SOURCE_FILE[w.kind]).map((w) => `Read the full ${KIND_SOURCE_FILE[w.kind]} with read_file if details are missing.`)
14716
+ ].join(`
14717
+ `),
14718
+ priority: "high",
14719
+ essential: true,
14720
+ estimatedTokens: HINT_BLOCK_TOKENS
14721
+ } : null;
14722
+ return { replacements, hintBlock, warnings };
14723
+ }
14724
+ function resolveContextWindowSource(config) {
14725
+ const entries = config.provider.entries ?? [];
14726
+ const activeLabel = config.provider.active;
14727
+ const activeEntry = entries.find((e) => e.label && e.label === activeLabel) ?? (entries.length === 1 ? entries[0] : undefined);
14728
+ if (activeEntry?.contextWindow) {
14729
+ return { source: "entry", label: activeEntry.label, value: activeEntry.contextWindow };
14730
+ }
14731
+ return { source: "global", value: config.contextWindow };
14732
+ }
14733
+ function contextWindowHint(config, configDir, recommended) {
14734
+ const src = resolveContextWindowSource(config);
14735
+ if (src.source === "global") {
14736
+ return `run "mma context ${recommended}"`;
14737
+ }
14738
+ return `edit "${join17(configDir, "config", "provider.json")}" → provider.entries[label="${src.label}"].contextWindow = ${recommended}`;
14739
+ }
14740
+ function recommendContextSize(neededSystemTokens) {
14741
+ const sizes = [8192, 16384, 32768, 65536, 131072, 262144];
14742
+ return sizes.find((s) => Math.floor(s * 0.1) >= neededSystemTokens) ?? sizes[sizes.length - 1];
14743
+ }
14744
+ var HINT_BLOCK_TOKENS = 60, CHARS_PER_TOKEN = 4, KIND_ORDER, KIND_LABEL, KIND_SOURCE_FILE;
14745
+ var init_prompt_overflow = __esm(() => {
14746
+ init_prompt_builder();
14747
+ init_token_counter();
14748
+ KIND_ORDER = ["instructions", "project-map"];
14749
+ KIND_LABEL = {
14750
+ instructions: "project instructions (AGENTS.md)",
14751
+ "project-map": "project map"
14752
+ };
14753
+ KIND_SOURCE_FILE = {
14754
+ instructions: "AGENTS.md",
14755
+ "project-map": ""
14756
+ };
14757
+ });
14758
+
14481
14759
  // src/core/agent.ts
14760
+ import { join as join18 } from "path";
14482
14761
  function mutationTargetKey(name, rawArgs) {
14483
14762
  let a = null;
14484
14763
  if (typeof rawArgs === "string") {
@@ -14516,6 +14795,9 @@ class Agent {
14516
14795
  probePassed;
14517
14796
  reasoningState;
14518
14797
  _currentIteration = 0;
14798
+ promptOverrides = new Map;
14799
+ overflowHintBlock = null;
14800
+ overflowResolved = false;
14519
14801
  constructor(deps) {
14520
14802
  this.deps = deps;
14521
14803
  this.costTracker = new CostTracker(deps.config.model, deps.config.pricing);
@@ -14561,10 +14843,11 @@ class Agent {
14561
14843
  buildSystemPrompt() {
14562
14844
  const systemBudget = Math.floor(this.deps.config.contextWindow * this.deps.config.contextBudget.systemPrompt);
14563
14845
  const builder = new PromptBuilder(systemBudget);
14564
- builder.addBlocks(this.deps.promptBlocks);
14846
+ const applyOverrides = (blocks) => blocks.map((b) => b.kind && this.promptOverrides.has(b.kind) ? this.promptOverrides.get(b.kind) : b);
14847
+ builder.addBlocks(applyOverrides(this.deps.promptBlocks));
14565
14848
  const dynamic = this.deps.getDynamicPromptBlocks?.() ?? [];
14566
14849
  if (dynamic.length > 0) {
14567
- builder.addBlocks(dynamic);
14850
+ builder.addBlocks(applyOverrides(dynamic));
14568
14851
  }
14569
14852
  const pluginBlocks = (this.deps.pluginManager.runOnBuildPrompt?.() ?? []).flatMap((content) => content && content.trim() !== "" ? [
14570
14853
  {
@@ -14577,10 +14860,14 @@ class Agent {
14577
14860
  if (pluginBlocks.length > 0) {
14578
14861
  builder.addBlocks(pluginBlocks);
14579
14862
  }
14863
+ if (this.overflowHintBlock) {
14864
+ builder.addBlock(this.overflowHintBlock);
14865
+ }
14580
14866
  const result = builder.build();
14581
14867
  return {
14582
14868
  prompt: result.prompt,
14583
14869
  excluded: result.excluded,
14870
+ excludedBlocks: result.excludedBlocks,
14584
14871
  blocks: result.blocks
14585
14872
  };
14586
14873
  }
@@ -14613,6 +14900,39 @@ class Agent {
14613
14900
  const tokenCount = this.deps.llmProvider.countTokens(prompt);
14614
14901
  return { text: prompt, tokenCount, excluded };
14615
14902
  }
14903
+ async resolvePromptOverflowOnce() {
14904
+ const cfg = this.deps.config;
14905
+ const dry = this.buildSystemPrompt();
14906
+ const overflow = dry.excludedBlocks.filter((b) => Boolean(b.kind));
14907
+ if (overflow.length === 0)
14908
+ return;
14909
+ const systemBudget = Math.floor(cfg.contextWindow * cfg.contextBudget.systemPrompt);
14910
+ const res = await resolvePromptOverflow({
14911
+ overflow,
14912
+ includedTokens: dry.blocks.filter((b) => b.included).reduce((s, b) => s + b.tokens, 0),
14913
+ systemBudget,
14914
+ provider: cfg.instructions?.summarize === false ? null : this.deps.llmProvider,
14915
+ cacheDir: join18(this.deps.baseDir, ".mma", "cache", "prompt-summaries"),
14916
+ logger: this.deps.logger
14917
+ });
14918
+ for (const r of res.replacements) {
14919
+ if (r.kind)
14920
+ this.promptOverrides.set(r.kind, r);
14921
+ }
14922
+ this.overflowHintBlock = res.hintBlock;
14923
+ const recommended = recommendContextSize(dry.blocks.filter((b) => b.included).reduce((s, b) => s + b.tokens, 0) + overflow.reduce((s, b) => s + b.estimatedTokens, 0) + HINT_BLOCK_TOKENS);
14924
+ const hint = this.deps.configDir ? contextWindowHint(cfg, this.deps.configDir, recommended) : `increase contextWindow (e.g. to ${recommended})`;
14925
+ for (const w of res.warnings) {
14926
+ this.deps.logger.warn(t("prompt.overflow.exceeded", {
14927
+ label: w.label,
14928
+ original: String(w.originalTokens),
14929
+ budget: String(systemBudget),
14930
+ mode: w.mode === "summary" ? "summarized" : "truncated",
14931
+ resolved: String(w.resolvedTokens),
14932
+ hint
14933
+ }));
14934
+ }
14935
+ }
14616
14936
  refreshSystemPrompt() {
14617
14937
  const { prompt } = this.buildSystemPrompt();
14618
14938
  const current = this.deps.contextManager.getActiveHistory().find((m) => m.role === "system");
@@ -14655,6 +14975,14 @@ class Agent {
14655
14975
  if (lazy.length > 0) {
14656
14976
  this.deps.promptBlocks.push(...lazy);
14657
14977
  }
14978
+ if (!this.overflowResolved) {
14979
+ this.overflowResolved = true;
14980
+ try {
14981
+ await this.resolvePromptOverflowOnce();
14982
+ } catch (err) {
14983
+ this.deps.logger.warn(t("prompt.overflow.failed", { error: String(err?.message ?? err) }));
14984
+ }
14985
+ }
14658
14986
  if (this.deps.reasoningProbe) {
14659
14987
  this.probePassed = await this.deps.reasoningProbe();
14660
14988
  }
@@ -15184,6 +15512,7 @@ var init_agent = __esm(() => {
15184
15512
  init_tool_batch();
15185
15513
  init_hallucination_gate();
15186
15514
  init_audit_gate();
15515
+ init_prompt_overflow();
15187
15516
  init_tool_output();
15188
15517
  });
15189
15518
 
@@ -15761,8 +16090,8 @@ var init_confidence = __esm(() => {
15761
16090
  });
15762
16091
 
15763
16092
  // src/modules/hallucination/factual.ts
15764
- import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
15765
- import { resolve as resolve14, isAbsolute as isAbsolute4, join as join17 } from "path";
16093
+ import { existsSync as existsSync28, readdirSync as readdirSync8 } from "fs";
16094
+ import { resolve as resolve14, isAbsolute as isAbsolute4, join as join19 } from "path";
15766
16095
 
15767
16096
  class FactualCheck {
15768
16097
  baseDir;
@@ -15805,13 +16134,13 @@ class FactualCheck {
15805
16134
  }
15806
16135
  pathExists(fp) {
15807
16136
  if (isAbsolute4(fp))
15808
- return existsSync27(fp);
16137
+ return existsSync28(fp);
15809
16138
  if (this.knownFiles.has(fp))
15810
16139
  return true;
15811
16140
  for (const cand of this.dotfileVariants(fp)) {
15812
16141
  if (this.knownFiles.has(cand))
15813
16142
  return true;
15814
- if (existsSync27(resolve14(this.baseDir, cand)))
16143
+ if (existsSync28(resolve14(this.baseDir, cand)))
15815
16144
  return true;
15816
16145
  }
15817
16146
  if (!fp.includes("/") && !fp.includes("\\")) {
@@ -15839,7 +16168,7 @@ class FactualCheck {
15839
16168
  }
15840
16169
  bareNameExists(name) {
15841
16170
  for (const cand of this.dotfileVariants(name)) {
15842
- if (existsSync27(resolve14(this.baseDir, cand)))
16171
+ if (existsSync28(resolve14(this.baseDir, cand)))
15843
16172
  return true;
15844
16173
  if (this.indexHas(cand))
15845
16174
  return true;
@@ -15885,7 +16214,7 @@ class FactualCheck {
15885
16214
  for (const entry of entries) {
15886
16215
  if (count >= FactualCheck.MAX_INDEXED_FILES)
15887
16216
  break;
15888
- const full = join17(dir, entry.name);
16217
+ const full = join19(dir, entry.name);
15889
16218
  if (entry.isDirectory()) {
15890
16219
  if (!IGNORED_DIRS2.has(entry.name)) {
15891
16220
  count = this.scanDir(full, index, count);
@@ -16067,8 +16396,8 @@ var init_detector = __esm(() => {
16067
16396
  });
16068
16397
 
16069
16398
  // src/modules/lsp/command.ts
16070
- import { delimiter, join as join18 } from "path";
16071
- import { existsSync as existsSync28 } from "fs";
16399
+ import { delimiter, join as join20 } from "path";
16400
+ import { existsSync as existsSync29 } from "fs";
16072
16401
  import { platform as platform4 } from "os";
16073
16402
  function resolveSpawnCommand(command, platformName = platform4(), pathEnv = process.env.PATH ?? "") {
16074
16403
  if (platformName !== "win32")
@@ -16079,8 +16408,8 @@ function resolveSpawnCommand(command, platformName = platform4(), pathEnv = proc
16079
16408
  const dirs = pathEnv.split(delimiter).filter(Boolean);
16080
16409
  for (const dir of dirs) {
16081
16410
  for (const ext of WIN_EXTS) {
16082
- const candidate = join18(dir, `${command}${ext}`);
16083
- if (existsSync28(candidate))
16411
+ const candidate = join20(dir, `${command}${ext}`);
16412
+ if (existsSync29(candidate))
16084
16413
  return `${command}${ext}`;
16085
16414
  }
16086
16415
  }
@@ -16724,7 +17053,7 @@ var init_chunk_query = __esm(() => {
16724
17053
  });
16725
17054
 
16726
17055
  // src/tools/chunk-query.ts
16727
- import { readFileSync as readFileSync14 } from "node:fs";
17056
+ import { readFileSync as readFileSync15 } from "node:fs";
16728
17057
  import { resolve as resolve15 } from "node:path";
16729
17058
  var chunkQueryTool;
16730
17059
  var init_chunk_query2 = __esm(() => {
@@ -16797,7 +17126,7 @@ var init_chunk_query2 = __esm(() => {
16797
17126
  return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
16798
17127
  }
16799
17128
  try {
16800
- content = readFileSync14(resolvedInput, "utf8");
17129
+ content = readFileSync15(resolvedInput, "utf8");
16801
17130
  } catch (e) {
16802
17131
  return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
16803
17132
  }
@@ -17249,7 +17578,7 @@ var init_web_browse = __esm(() => {
17249
17578
  });
17250
17579
 
17251
17580
  // src/tools/download-file.ts
17252
- import { writeFileSync as writeFileSync10, mkdirSync as mkdirSync13 } from "fs";
17581
+ import { writeFileSync as writeFileSync11, mkdirSync as mkdirSync14 } from "fs";
17253
17582
  import { dirname as dirname11 } from "path";
17254
17583
  var MAX_DOWNLOAD_BYTES, downloadFileTool;
17255
17584
  var init_download_file = __esm(() => {
@@ -17338,8 +17667,8 @@ var init_download_file = __esm(() => {
17338
17667
  output: t("tool.download_too_large", { max: String(maxBytes) })
17339
17668
  };
17340
17669
  }
17341
- mkdirSync13(dirname11(resolved), { recursive: true });
17342
- writeFileSync10(resolved, buffer);
17670
+ mkdirSync14(dirname11(resolved), { recursive: true });
17671
+ writeFileSync11(resolved, buffer);
17343
17672
  const contentType = response.headers.get("content-type")?.split(";")[0]?.trim() || "unknown";
17344
17673
  logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
17345
17674
  logFileWrite(ctx.sessionId, resolved, true, `Downloaded ${buffer.byteLength} bytes`);
@@ -18205,7 +18534,7 @@ ${JSON.stringify(result, null, 2)}`
18205
18534
 
18206
18535
  // src/tools/search-history.ts
18207
18536
  import * as fs from "fs";
18208
- import { join as join19 } from "path";
18537
+ import { join as join21 } from "path";
18209
18538
  import { homedir as homedir6 } from "os";
18210
18539
  function searchFile(filePath, query, maxResults, results) {
18211
18540
  if (!fs.existsSync(filePath))
@@ -18250,7 +18579,7 @@ var init_search_history = __esm(() => {
18250
18579
  const query = String(args.query || "").toLowerCase();
18251
18580
  const maxResults = Number(args.maxResults) || 5;
18252
18581
  const sessionId = args.sessionId ? String(args.sessionId) : null;
18253
- const sessionDir = join19(homedir6(), ".mma", "sessions");
18582
+ const sessionDir = join21(homedir6(), ".mma", "sessions");
18254
18583
  const results = [];
18255
18584
  try {
18256
18585
  if (!fs.existsSync(sessionDir)) {
@@ -18265,7 +18594,7 @@ var init_search_history = __esm(() => {
18265
18594
  continue;
18266
18595
  if (sessionId && entry.name !== sessionId)
18267
18596
  continue;
18268
- const historyFile = join19(sessionDir, entry.name, "history.jsonl");
18597
+ const historyFile = join21(sessionDir, entry.name, "history.jsonl");
18269
18598
  searchFile(historyFile, query, maxResults, results);
18270
18599
  if (results.length >= maxResults)
18271
18600
  break;
@@ -18292,8 +18621,8 @@ var init_search_history = __esm(() => {
18292
18621
  });
18293
18622
 
18294
18623
  // src/modules/memory/search.ts
18295
- import { readFileSync as readFileSync16, existsSync as existsSync30 } from "fs";
18296
- import { join as join20 } from "path";
18624
+ import { readFileSync as readFileSync17, existsSync as existsSync31 } from "fs";
18625
+ import { join as join22 } from "path";
18297
18626
 
18298
18627
  class MemorySearch {
18299
18628
  memoryDir;
@@ -18304,10 +18633,10 @@ class MemorySearch {
18304
18633
  const results = [];
18305
18634
  const lowerQuery = query.toLowerCase();
18306
18635
  for (const name of MEMORY_FILES) {
18307
- const path = join20(this.memoryDir, `${name}.md`);
18308
- if (!existsSync30(path))
18636
+ const path = join22(this.memoryDir, `${name}.md`);
18637
+ if (!existsSync31(path))
18309
18638
  continue;
18310
- const content = readFileSync16(path, "utf-8");
18639
+ const content = readFileSync17(path, "utf-8");
18311
18640
  const lines = content.split(`
18312
18641
  `);
18313
18642
  for (const line of lines) {
@@ -18316,10 +18645,10 @@ class MemorySearch {
18316
18645
  }
18317
18646
  }
18318
18647
  }
18319
- const prefsPath = join20(this.memoryDir, "preferences.json");
18320
- if (existsSync30(prefsPath)) {
18648
+ const prefsPath = join22(this.memoryDir, "preferences.json");
18649
+ if (existsSync31(prefsPath)) {
18321
18650
  try {
18322
- const prefs = JSON.parse(readFileSync16(prefsPath, "utf-8"));
18651
+ const prefs = JSON.parse(readFileSync17(prefsPath, "utf-8"));
18323
18652
  for (const [key, value] of Object.entries(prefs)) {
18324
18653
  const searchStr = `${key}=${value}`;
18325
18654
  if (searchStr.toLowerCase().includes(lowerQuery)) {
@@ -18337,8 +18666,8 @@ var init_search = __esm(() => {
18337
18666
  });
18338
18667
 
18339
18668
  // src/modules/memory/store.ts
18340
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, appendFileSync as appendFileSync5, existsSync as existsSync31, mkdirSync as mkdirSync14 } from "fs";
18341
- import { join as join21 } from "path";
18669
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, appendFileSync as appendFileSync5, existsSync as existsSync32, mkdirSync as mkdirSync15 } from "fs";
18670
+ import { join as join23 } from "path";
18342
18671
 
18343
18672
  class MemoryStore {
18344
18673
  memoryDir;
@@ -18346,27 +18675,27 @@ class MemoryStore {
18346
18675
  this.memoryDir = memoryDir;
18347
18676
  this.ensureDir();
18348
18677
  for (const name of MEMORY_FILES2) {
18349
- const path = join21(this.memoryDir, `${name}.md`);
18350
- if (!existsSync31(path)) {
18351
- writeFileSync11(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
18678
+ const path = join23(this.memoryDir, `${name}.md`);
18679
+ if (!existsSync32(path)) {
18680
+ writeFileSync12(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
18352
18681
 
18353
18682
  `, "utf-8");
18354
18683
  }
18355
18684
  }
18356
18685
  }
18357
18686
  ensureDir() {
18358
- if (!existsSync31(this.memoryDir)) {
18359
- mkdirSync14(this.memoryDir, { recursive: true });
18687
+ if (!existsSync32(this.memoryDir)) {
18688
+ mkdirSync15(this.memoryDir, { recursive: true });
18360
18689
  }
18361
18690
  }
18362
18691
  read(name) {
18363
- const path = join21(this.memoryDir, `${name}.md`);
18364
- if (!existsSync31(path))
18692
+ const path = join23(this.memoryDir, `${name}.md`);
18693
+ if (!existsSync32(path))
18365
18694
  return "";
18366
- return readFileSync17(path, "utf-8");
18695
+ return readFileSync18(path, "utf-8");
18367
18696
  }
18368
18697
  append(name, entry) {
18369
- const path = join21(this.memoryDir, `${name}.md`);
18698
+ const path = join23(this.memoryDir, `${name}.md`);
18370
18699
  const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
18371
18700
  const formatted = `- **${timestamp}** — ${entry}
18372
18701
  `;
@@ -18377,14 +18706,14 @@ class MemoryStore {
18377
18706
  return searchModule.query(query);
18378
18707
  }
18379
18708
  prefsPath() {
18380
- return join21(this.memoryDir, "preferences.json");
18709
+ return join23(this.memoryDir, "preferences.json");
18381
18710
  }
18382
18711
  getPreferences() {
18383
18712
  const path = this.prefsPath();
18384
- if (!existsSync31(path))
18713
+ if (!existsSync32(path))
18385
18714
  return {};
18386
18715
  try {
18387
- return JSON.parse(readFileSync17(path, "utf-8"));
18716
+ return JSON.parse(readFileSync18(path, "utf-8"));
18388
18717
  } catch {
18389
18718
  return {};
18390
18719
  }
@@ -18392,14 +18721,14 @@ class MemoryStore {
18392
18721
  setPreference(key, value) {
18393
18722
  const prefs = this.getPreferences();
18394
18723
  prefs[key] = value;
18395
- writeFileSync11(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
18724
+ writeFileSync12(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
18396
18725
  }
18397
18726
  deletePreference(key) {
18398
18727
  const prefs = this.getPreferences();
18399
18728
  if (!(key in prefs))
18400
18729
  return false;
18401
18730
  delete prefs[key];
18402
- writeFileSync11(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
18731
+ writeFileSync12(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
18403
18732
  return true;
18404
18733
  }
18405
18734
  appendRule(category, pattern, cause, solution) {
@@ -18417,7 +18746,7 @@ var init_store2 = __esm(() => {
18417
18746
 
18418
18747
  // src/tools/remember.ts
18419
18748
  import { homedir as homedir7 } from "os";
18420
- import { join as join22 } from "path";
18749
+ import { join as join24 } from "path";
18421
18750
  var CATEGORIES, rememberTool;
18422
18751
  var init_remember = __esm(() => {
18423
18752
  init_i18n();
@@ -18456,7 +18785,7 @@ var init_remember = __esm(() => {
18456
18785
  if (!CATEGORIES.includes(category)) {
18457
18786
  return { success: false, output: t("tool.invalid_params") };
18458
18787
  }
18459
- const memoryDir = join22(homedir7(), ".mma", "memory");
18788
+ const memoryDir = join24(homedir7(), ".mma", "memory");
18460
18789
  const store = new MemoryStore(memoryDir);
18461
18790
  try {
18462
18791
  if (category === "preferences") {
@@ -18489,7 +18818,7 @@ var init_remember = __esm(() => {
18489
18818
 
18490
18819
  // src/tools/recall.ts
18491
18820
  import { homedir as homedir8 } from "os";
18492
- import { join as join23 } from "path";
18821
+ import { join as join25 } from "path";
18493
18822
  function formatAll(store) {
18494
18823
  const parts = [];
18495
18824
  const prefs = store.getPreferences();
@@ -18573,7 +18902,7 @@ var init_recall = __esm(() => {
18573
18902
  handler: async (_ctx, args) => {
18574
18903
  const query = args.query ? String(args.query) : "";
18575
18904
  const category = args.category ? String(args.category) : "";
18576
- const memoryDir = join23(homedir8(), ".mma", "memory");
18905
+ const memoryDir = join25(homedir8(), ".mma", "memory");
18577
18906
  const store = new MemoryStore(memoryDir);
18578
18907
  try {
18579
18908
  if (!query && !category) {
@@ -18611,9 +18940,9 @@ var init_recall = __esm(() => {
18611
18940
  });
18612
18941
 
18613
18942
  // src/modules/browser/bridge-path.ts
18614
- import { existsSync as existsSync32 } from "fs";
18943
+ import { existsSync as existsSync33 } from "fs";
18615
18944
  function pickExistingPath(candidates, fallback = candidates[0]) {
18616
- return candidates.find((p) => existsSync32(p)) ?? fallback;
18945
+ return candidates.find((p) => existsSync33(p)) ?? fallback;
18617
18946
  }
18618
18947
  var init_bridge_path = () => {};
18619
18948
 
@@ -18624,13 +18953,13 @@ __export(exports_bridge_client, {
18624
18953
  });
18625
18954
  import { spawn as spawn6 } from "child_process";
18626
18955
  import { createInterface } from "readline";
18627
- import { dirname as dirname12, join as join24 } from "path";
18956
+ import { dirname as dirname12, join as join26 } from "path";
18628
18957
  import { fileURLToPath } from "url";
18629
18958
  function bridgeScriptPath() {
18630
18959
  const dir = dirname12(fileURLToPath(import.meta.url));
18631
18960
  const candidates = [
18632
- join24(dir, "bridge-server.mjs"),
18633
- join24(dir, "modules", "browser", "bridge-server.mjs")
18961
+ join26(dir, "bridge-server.mjs"),
18962
+ join26(dir, "modules", "browser", "bridge-server.mjs")
18634
18963
  ];
18635
18964
  return pickExistingPath(candidates);
18636
18965
  }
@@ -19184,15 +19513,15 @@ function buildTextExtractionScript() {
19184
19513
 
19185
19514
  // src/modules/browser/cookie-store.ts
19186
19515
  import { readFile, writeFile, mkdir } from "fs/promises";
19187
- import { join as join25 } from "path";
19516
+ import { join as join27 } from "path";
19188
19517
 
19189
19518
  class CookieStore {
19190
19519
  filePath;
19191
19520
  constructor(cookieDir) {
19192
- this.filePath = join25(cookieDir, "cookies.json");
19521
+ this.filePath = join27(cookieDir, "cookies.json");
19193
19522
  }
19194
19523
  async save(cookies) {
19195
- await mkdir(join25(this.filePath, ".."), { recursive: true });
19524
+ await mkdir(join27(this.filePath, ".."), { recursive: true });
19196
19525
  await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
19197
19526
  }
19198
19527
  async load() {
@@ -19550,10 +19879,10 @@ var init_session = __esm(() => {
19550
19879
  });
19551
19880
 
19552
19881
  // src/tools/browser.ts
19553
- import { join as join26 } from "path";
19882
+ import { join as join28 } from "path";
19554
19883
  function getSession(ctx) {
19555
19884
  if (!session) {
19556
- const cookieDir = join26(ctx.baseDir, ".mma", "browser");
19885
+ const cookieDir = join28(ctx.baseDir, ".mma", "browser");
19557
19886
  session = new BrowserSession({
19558
19887
  ...DEFAULT_BROWSER_CONFIG,
19559
19888
  headless: ctx.config.browser?.headless ?? true,
@@ -19679,7 +20008,7 @@ __export(exports_image_utils, {
19679
20008
  detectMime: () => detectMime,
19680
20009
  bufferToDataUrl: () => bufferToDataUrl
19681
20010
  });
19682
- import { readFileSync as readFileSync18 } from "fs";
20011
+ import { readFileSync as readFileSync19 } from "fs";
19683
20012
  import { extname as extname4 } from "path";
19684
20013
  function detectMime(filePath) {
19685
20014
  const ext = extname4(filePath).toLowerCase();
@@ -19700,11 +20029,11 @@ async function readClipboardImage() {
19700
20029
  async function readClipboardFallback() {
19701
20030
  const { platform: platform6 } = await import("os");
19702
20031
  const { execSync } = await import("child_process");
19703
- const { readFileSync: readFileSync19, unlinkSync: unlinkSync5 } = await import("fs");
19704
- const { join: join27 } = await import("path");
20032
+ const { readFileSync: readFileSync20, unlinkSync: unlinkSync5 } = await import("fs");
20033
+ const { join: join29 } = await import("path");
19705
20034
  if (platform6() !== "linux")
19706
20035
  return null;
19707
- const tmpPath = join27(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
20036
+ const tmpPath = join29(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
19708
20037
  const commands = [
19709
20038
  `wl-paste --type image/png > "${tmpPath}" 2>/dev/null`,
19710
20039
  `xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`
@@ -19712,7 +20041,7 @@ async function readClipboardFallback() {
19712
20041
  for (const cmd of commands) {
19713
20042
  try {
19714
20043
  execSync(cmd, { timeout: 5000 });
19715
- const buf = readFileSync19(tmpPath);
20044
+ const buf = readFileSync20(tmpPath);
19716
20045
  unlinkSync5(tmpPath);
19717
20046
  if (buf.length > 0)
19718
20047
  return buf;
@@ -19724,7 +20053,7 @@ async function readClipboardFallback() {
19724
20053
  return null;
19725
20054
  }
19726
20055
  async function loadFileAsDataUrl(filePath) {
19727
- const buf = readFileSync18(filePath);
20056
+ const buf = readFileSync19(filePath);
19728
20057
  if (typeof Bun !== "undefined" && typeof Bun.Image !== "undefined") {
19729
20058
  try {
19730
20059
  const img = new Bun.Image(buf);
@@ -19784,7 +20113,7 @@ var init_image_utils = __esm(() => {
19784
20113
  });
19785
20114
 
19786
20115
  // src/tools/attach-image.ts
19787
- import { existsSync as existsSync33 } from "fs";
20116
+ import { existsSync as existsSync34 } from "fs";
19788
20117
  import { resolve as resolve16 } from "path";
19789
20118
  var attachImageTool;
19790
20119
  var init_attach_image = __esm(() => {
@@ -19836,7 +20165,7 @@ var init_attach_image = __esm(() => {
19836
20165
  dataUrl = result.dataUrl;
19837
20166
  } else {
19838
20167
  const absPath = resolve16(ctx.baseDir, source);
19839
- if (!existsSync33(absPath)) {
20168
+ if (!existsSync34(absPath)) {
19840
20169
  return {
19841
20170
  success: false,
19842
20171
  output: t("image.not_found", { path: source })
@@ -19936,6 +20265,56 @@ var init_enable_tools = __esm(() => {
19936
20265
  };
19937
20266
  });
19938
20267
 
20268
+ // src/tools/session-info.ts
20269
+ var sessionInfoTool;
20270
+ var init_session_info = __esm(() => {
20271
+ init_i18n();
20272
+ sessionInfoTool = {
20273
+ name: "session_info",
20274
+ icon: "ℹ️",
20275
+ description: "Show metadata about the current session: id, name, model, provider, context window, message count, and how much of the context budget is used. Use when the user asks which session this is or how much context is left.",
20276
+ alwaysOn: true,
20277
+ boundedOutput: true,
20278
+ parameters: {
20279
+ type: "object",
20280
+ properties: {}
20281
+ },
20282
+ handler: async (ctx) => {
20283
+ const meta = ctx.sessionManager?.getActiveMeta();
20284
+ if (!meta) {
20285
+ return { success: true, output: t("tool.session_info.no_active") };
20286
+ }
20287
+ const provider = ctx.config.provider;
20288
+ const providerName = provider.active ?? provider.type ?? "unknown";
20289
+ const lines = [
20290
+ t("tool.session_info.result", {
20291
+ id: meta.id,
20292
+ name: meta.name,
20293
+ model: meta.model ?? ctx.config.model ?? "unknown",
20294
+ provider: providerName,
20295
+ contextWindow: String(meta.contextWindow ?? ctx.config.contextWindow),
20296
+ messages: String(meta.messageCount),
20297
+ createdAt: meta.createdAt,
20298
+ updatedAt: meta.updatedAt
20299
+ })
20300
+ ];
20301
+ const snapshot = ctx.contextManager?.getSnapshot();
20302
+ if (snapshot) {
20303
+ const used = snapshot.tokens;
20304
+ const budget = snapshot.budget.history;
20305
+ const percent = budget > 0 ? Math.round(used / budget * 100) : 0;
20306
+ lines.push(t("tool.session_info.context", {
20307
+ used: String(used),
20308
+ budget: String(budget),
20309
+ percent: String(percent)
20310
+ }));
20311
+ }
20312
+ return { success: true, output: lines.join(`
20313
+ `) };
20314
+ }
20315
+ };
20316
+ });
20317
+
19939
20318
  // src/tools/index.ts
19940
20319
  function registerAllTools(registry2, skillsModule, opts) {
19941
20320
  const tools = [
@@ -19962,7 +20341,8 @@ function registerAllTools(registry2, skillsModule, opts) {
19962
20341
  pipelineRunTool,
19963
20342
  mcpCallTool,
19964
20343
  searchHistoryTool,
19965
- attachImageTool
20344
+ attachImageTool,
20345
+ sessionInfoTool
19966
20346
  ];
19967
20347
  if (opts?.enableOnDemand !== false) {
19968
20348
  tools.push(enableToolsTool);
@@ -20005,6 +20385,7 @@ var init_tools = __esm(() => {
20005
20385
  init_browser();
20006
20386
  init_attach_image();
20007
20387
  init_enable_tools();
20388
+ init_session_info();
20008
20389
  });
20009
20390
 
20010
20391
  // src/tools/hidden-tools-block.ts
@@ -20093,16 +20474,16 @@ class ModuleRegistry {
20093
20474
  }
20094
20475
 
20095
20476
  // src/modules/plugins/loader.ts
20096
- import { readdirSync as readdirSync10, existsSync as existsSync34, statSync as statSync6 } from "fs";
20097
- import { join as join27, basename as basename3 } from "path";
20477
+ import { readdirSync as readdirSync10, existsSync as existsSync35, statSync as statSync6 } from "fs";
20478
+ import { join as join29, basename as basename3 } from "path";
20098
20479
 
20099
20480
  class PluginLoader {
20100
20481
  loadFromDir(dirPath, pluginManager, logger2, options) {
20101
- if (!existsSync34(dirPath))
20482
+ if (!existsSync35(dirPath))
20102
20483
  return;
20103
20484
  const entries = readdirSync10(dirPath).sort();
20104
20485
  for (const entry of entries) {
20105
- const fullPath = join27(dirPath, entry);
20486
+ const fullPath = join29(dirPath, entry);
20106
20487
  const stat = statSync6(fullPath);
20107
20488
  if (stat.isFile()) {
20108
20489
  if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
@@ -20118,8 +20499,8 @@ class PluginLoader {
20118
20499
  }
20119
20500
  findEntryFile(dir) {
20120
20501
  for (const name of FOLDER_ENTRY_NAMES) {
20121
- const candidate = join27(dir, name);
20122
- if (existsSync34(candidate))
20502
+ const candidate = join29(dir, name);
20503
+ if (existsSync35(candidate))
20123
20504
  return candidate;
20124
20505
  }
20125
20506
  return null;
@@ -20324,8 +20705,8 @@ var init_auto_fixer = __esm(() => {
20324
20705
 
20325
20706
  // src/modules/plugins/builtin/lint-on-write.ts
20326
20707
  import { spawn as spawn7, execSync } from "child_process";
20327
- import { existsSync as existsSync35, readFileSync as readFileSync19, writeFileSync as writeFileSync12 } from "fs";
20328
- import { resolve as resolve17, extname as extname6, join as join28 } from "path";
20708
+ import { existsSync as existsSync36, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "fs";
20709
+ import { resolve as resolve17, extname as extname6, join as join30 } from "path";
20329
20710
  import { platform as platform6 } from "os";
20330
20711
  function lintCacheKey(baseDir, lintScript) {
20331
20712
  return `${baseDir}::${lintScript}`;
@@ -20401,7 +20782,7 @@ class LintOnWritePlugin {
20401
20782
  if (!path)
20402
20783
  return;
20403
20784
  const fullPath = resolve17(ctx.baseDir, path);
20404
- if (!existsSync35(fullPath))
20785
+ if (!existsSync36(fullPath))
20405
20786
  return;
20406
20787
  const signal = ctx.signal;
20407
20788
  if (signal?.aborted)
@@ -20425,7 +20806,7 @@ class LintOnWritePlugin {
20425
20806
  if (ext === ".ts" || ext === ".tsx" || ext === ".cts" || ext === ".mts") {
20426
20807
  let content = "";
20427
20808
  try {
20428
- content = readFileSync19(filePath, "utf-8");
20809
+ content = readFileSync20(filePath, "utf-8");
20429
20810
  } catch {
20430
20811
  return null;
20431
20812
  }
@@ -20467,11 +20848,11 @@ class LintOnWritePlugin {
20467
20848
  async runProjectLint(ctx, result, signal) {
20468
20849
  let lintScript;
20469
20850
  try {
20470
- const packageJsonPath = join28(ctx.baseDir, "package.json");
20471
- if (!existsSync35(packageJsonPath)) {
20851
+ const packageJsonPath = join30(ctx.baseDir, "package.json");
20852
+ if (!existsSync36(packageJsonPath)) {
20472
20853
  return;
20473
20854
  }
20474
- const packageJson = JSON.parse(readFileSync19(packageJsonPath, "utf-8"));
20855
+ const packageJson = JSON.parse(readFileSync20(packageJsonPath, "utf-8"));
20475
20856
  lintScript = packageJson.scripts?.lint;
20476
20857
  if (!lintScript) {
20477
20858
  return;
@@ -20504,8 +20885,8 @@ ${stdout}`;
20504
20885
  }
20505
20886
  async runProjectTypeCheck(filePath, baseDir, result, signal) {
20506
20887
  const projectRoot = findProjectRoot(filePath, baseDir, ["tsconfig.json", "package.json"]);
20507
- const tsconfigPath = join28(projectRoot, "tsconfig.json");
20508
- if (!existsSync35(tsconfigPath)) {
20888
+ const tsconfigPath = join30(projectRoot, "tsconfig.json");
20889
+ if (!existsSync36(tsconfigPath)) {
20509
20890
  return;
20510
20891
  }
20511
20892
  const now = Date.now();
@@ -20526,9 +20907,9 @@ ${stdout}`;
20526
20907
  const output = stderr || stdout;
20527
20908
  const errors = parseTscOutput(output);
20528
20909
  if (errors.length > 0) {
20529
- const fixResult = autoFixErrors(filePath, readFileSync19(filePath, "utf-8"), errors);
20910
+ const fixResult = autoFixErrors(filePath, readFileSync20(filePath, "utf-8"), errors);
20530
20911
  if (fixResult.fixed) {
20531
- writeFileSync12(filePath, fixResult.newContent, "utf-8");
20912
+ writeFileSync13(filePath, fixResult.newContent, "utf-8");
20532
20913
  result.output += `
20533
20914
 
20534
20915
  [Auto-fixed]: ${fixResult.applied.join("; ")}`;
@@ -20791,11 +21172,11 @@ class PlanTracker {
20791
21172
  var init_tracker = () => {};
20792
21173
 
20793
21174
  // src/modules/execution/plan-store.ts
20794
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, renameSync as renameSync3, mkdirSync as mkdirSync15, existsSync as existsSync36, readdirSync as readdirSync11, rmSync } from "fs";
20795
- import { join as join29 } from "path";
21175
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync14, renameSync as renameSync3, mkdirSync as mkdirSync16, existsSync as existsSync37, readdirSync as readdirSync11, rmSync } from "fs";
21176
+ import { join as join31 } from "path";
20796
21177
  function readPlanFile(path, fallbackBaseDir) {
20797
21178
  try {
20798
- const raw = readFileSync20(path, "utf-8");
21179
+ const raw = readFileSync21(path, "utf-8");
20799
21180
  if (!raw.trim())
20800
21181
  return null;
20801
21182
  const parsed = JSON.parse(raw);
@@ -20815,14 +21196,14 @@ function readPlanFile(path, fallbackBaseDir) {
20815
21196
  }
20816
21197
  function writePlanFile(path, plan) {
20817
21198
  const tmpPath = `${path}.tmp`;
20818
- writeFileSync13(tmpPath, JSON.stringify(plan, null, 2), "utf-8");
21199
+ writeFileSync14(tmpPath, JSON.stringify(plan, null, 2), "utf-8");
20819
21200
  renameSync3(tmpPath, path);
20820
21201
  }
20821
21202
  function listDir(dir, baseDir) {
20822
- if (!existsSync36(dir))
21203
+ if (!existsSync37(dir))
20823
21204
  return [];
20824
21205
  const files = readdirSync11(dir).filter((f) => f.endsWith(".json"));
20825
- return files.map((f) => readPlanFile(join29(dir, f), baseDir)).filter((p) => p !== null);
21206
+ return files.map((f) => readPlanFile(join31(dir, f), baseDir)).filter((p) => p !== null);
20826
21207
  }
20827
21208
  function toMeta(plan, status) {
20828
21209
  return {
@@ -20843,33 +21224,33 @@ class PlanStore {
20843
21224
  archiveDir;
20844
21225
  legacyPath;
20845
21226
  constructor(baseDir) {
20846
- const mmaDir = join29(baseDir, ".mma");
20847
- if (!existsSync36(mmaDir))
20848
- mkdirSync15(mmaDir, { recursive: true });
21227
+ const mmaDir = join31(baseDir, ".mma");
21228
+ if (!existsSync37(mmaDir))
21229
+ mkdirSync16(mmaDir, { recursive: true });
20849
21230
  this.baseDir = baseDir;
20850
- this.plansDir = join29(mmaDir, "plans");
20851
- this.draftsDir = join29(this.plansDir, "drafts");
20852
- this.archiveDir = join29(this.plansDir, "archive");
20853
- this.legacyPath = join29(mmaDir, LEGACY_FILE);
21231
+ this.plansDir = join31(mmaDir, "plans");
21232
+ this.draftsDir = join31(this.plansDir, "drafts");
21233
+ this.archiveDir = join31(this.plansDir, "archive");
21234
+ this.legacyPath = join31(mmaDir, LEGACY_FILE);
20854
21235
  for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
20855
- if (!existsSync36(dir))
20856
- mkdirSync15(dir, { recursive: true });
21236
+ if (!existsSync37(dir))
21237
+ mkdirSync16(dir, { recursive: true });
20857
21238
  }
20858
21239
  }
20859
21240
  activePath() {
20860
- return join29(this.plansDir, "active.json");
21241
+ return join31(this.plansDir, "active.json");
20861
21242
  }
20862
21243
  saveActive(plan) {
20863
21244
  writePlanFile(this.activePath(), plan);
20864
21245
  }
20865
21246
  loadActive() {
20866
21247
  const activePath = this.activePath();
20867
- if (existsSync36(activePath)) {
21248
+ if (existsSync37(activePath)) {
20868
21249
  const plan = readPlanFile(activePath, this.baseDir);
20869
21250
  if (plan)
20870
21251
  return plan;
20871
21252
  }
20872
- if (existsSync36(this.legacyPath)) {
21253
+ if (existsSync37(this.legacyPath)) {
20873
21254
  const legacy = readPlanFile(this.legacyPath, this.baseDir);
20874
21255
  if (legacy) {
20875
21256
  this.saveActive(legacy);
@@ -20888,26 +21269,26 @@ class PlanStore {
20888
21269
  }
20889
21270
  clearActive() {
20890
21271
  const p = this.activePath();
20891
- if (existsSync36(p))
21272
+ if (existsSync37(p))
20892
21273
  rmSync(p, { force: true });
20893
21274
  }
20894
21275
  saveDraft(plan) {
20895
- writePlanFile(join29(this.draftsDir, `${plan.id}.json`), plan);
21276
+ writePlanFile(join31(this.draftsDir, `${plan.id}.json`), plan);
20896
21277
  }
20897
21278
  loadDraft(id) {
20898
- const p = join29(this.draftsDir, `${id}.json`);
20899
- return existsSync36(p) ? readPlanFile(p, this.baseDir) : null;
21279
+ const p = join31(this.draftsDir, `${id}.json`);
21280
+ return existsSync37(p) ? readPlanFile(p, this.baseDir) : null;
20900
21281
  }
20901
21282
  removeDraft(id) {
20902
- const p = join29(this.draftsDir, `${id}.json`);
20903
- if (existsSync36(p))
21283
+ const p = join31(this.draftsDir, `${id}.json`);
21284
+ if (existsSync37(p))
20904
21285
  rmSync(p, { force: true });
20905
21286
  }
20906
21287
  listDrafts() {
20907
21288
  return listDir(this.draftsDir, this.baseDir);
20908
21289
  }
20909
21290
  archivePlan(plan) {
20910
- writePlanFile(join29(this.archiveDir, `${plan.id}.json`), plan);
21291
+ writePlanFile(join31(this.archiveDir, `${plan.id}.json`), plan);
20911
21292
  this.removeDraft(plan.id);
20912
21293
  const active = this.loadActive();
20913
21294
  if (active && active.id === plan.id) {
@@ -20918,8 +21299,8 @@ class PlanStore {
20918
21299
  return listDir(this.archiveDir, this.baseDir);
20919
21300
  }
20920
21301
  removeArchived(id) {
20921
- const p = join29(this.archiveDir, `${id}.json`);
20922
- if (existsSync36(p))
21302
+ const p = join31(this.archiveDir, `${id}.json`);
21303
+ if (existsSync37(p))
20923
21304
  rmSync(p, { force: true });
20924
21305
  }
20925
21306
  listAll() {
@@ -20951,13 +21332,13 @@ class PlanStore {
20951
21332
  this.clearActive();
20952
21333
  return "active";
20953
21334
  }
20954
- const draftPath = join29(this.draftsDir, `${id}.json`);
20955
- if (existsSync36(draftPath)) {
21335
+ const draftPath = join31(this.draftsDir, `${id}.json`);
21336
+ if (existsSync37(draftPath)) {
20956
21337
  rmSync(draftPath, { force: true });
20957
21338
  return "draft";
20958
21339
  }
20959
- const archivedPath = join29(this.archiveDir, `${id}.json`);
20960
- if (existsSync36(archivedPath)) {
21340
+ const archivedPath = join31(this.archiveDir, `${id}.json`);
21341
+ if (existsSync37(archivedPath)) {
20961
21342
  rmSync(archivedPath, { force: true });
20962
21343
  return "archived";
20963
21344
  }
@@ -22077,7 +22458,7 @@ var init_plan_tool = __esm(() => {
22077
22458
  });
22078
22459
 
22079
22460
  // src/modules/execution/module.ts
22080
- import { existsSync as existsSync37, readFileSync as readFileSync21 } from "fs";
22461
+ import { existsSync as existsSync38, readFileSync as readFileSync22 } from "fs";
22081
22462
  import { resolve as resolve18 } from "path";
22082
22463
 
22083
22464
  class ExecutionModule {
@@ -22436,7 +22817,7 @@ class ExecutionModule {
22436
22817
  "poetry.lock",
22437
22818
  "requirements.txt"
22438
22819
  ];
22439
- const hasLockFile = lockFiles.some((f) => existsSync37(resolve18(this.baseDir, f)));
22820
+ const hasLockFile = lockFiles.some((f) => existsSync38(resolve18(this.baseDir, f)));
22440
22821
  if (!hasLockFile) {
22441
22822
  if (contextManager) {
22442
22823
  const hints = this.state.depsGateHints.get(step.id) || 0;
@@ -22468,7 +22849,7 @@ class ExecutionModule {
22468
22849
  if (!r)
22469
22850
  continue;
22470
22851
  try {
22471
- const content = readFileSync21(r, "utf-8");
22852
+ const content = readFileSync22(r, "utf-8");
22472
22853
  if (content.trim().length < 10) {
22473
22854
  emptyFiles.push(r);
22474
22855
  }
@@ -22576,8 +22957,8 @@ var init_module = __esm(() => {
22576
22957
  });
22577
22958
 
22578
22959
  // src/modules/security/session-encryption.ts
22579
- import { readFileSync as readFileSync22, writeFileSync as writeFileSync14, existsSync as existsSync38, readdirSync as readdirSync12, unlinkSync as unlinkSync5 } from "fs";
22580
- import { join as join30 } from "path";
22960
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, existsSync as existsSync39, readdirSync as readdirSync12, unlinkSync as unlinkSync5 } from "fs";
22961
+ import { join as join32 } from "path";
22581
22962
  import { homedir as homedir9 } from "os";
22582
22963
 
22583
22964
  class SessionFileEncryptor {
@@ -22586,7 +22967,7 @@ class SessionFileEncryptor {
22586
22967
  constructor(config) {
22587
22968
  this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
22588
22969
  this.encryptor = new ConfigEncryptor({
22589
- keyPath: config?.keyPath || join30(homedir9(), ".mma", ".session-encryption-key")
22970
+ keyPath: config?.keyPath || join32(homedir9(), ".mma", ".session-encryption-key")
22590
22971
  });
22591
22972
  }
22592
22973
  isEnabled() {
@@ -22638,23 +23019,23 @@ class SessionFileEncryptor {
22638
23019
  });
22639
23020
  }
22640
23021
  readSessionFile(filePath) {
22641
- const content = readFileSync22(filePath, "utf8");
23022
+ const content = readFileSync23(filePath, "utf8");
22642
23023
  return this.decryptFileContent(content);
22643
23024
  }
22644
23025
  writeSessionFile(filePath, content) {
22645
23026
  const encrypted = this.encryptFileContent(content);
22646
- writeFileSync14(filePath, encrypted, "utf8");
23027
+ writeFileSync15(filePath, encrypted, "utf8");
22647
23028
  }
22648
23029
  readSessionJSON(filePath) {
22649
- const content = readFileSync22(filePath, "utf8");
23030
+ const content = readFileSync23(filePath, "utf8");
22650
23031
  return this.decryptJSON(content);
22651
23032
  }
22652
23033
  writeSessionJSON(filePath, obj) {
22653
23034
  const content = this.encryptJSON(obj);
22654
- writeFileSync14(filePath, content, "utf8");
23035
+ writeFileSync15(filePath, content, "utf8");
22655
23036
  }
22656
23037
  readSessionJSONL(filePath) {
22657
- const content = readFileSync22(filePath, "utf8");
23038
+ const content = readFileSync23(filePath, "utf8");
22658
23039
  const lines = content.split(`
22659
23040
  `).filter((line) => line.trim());
22660
23041
  const decryptedLines = this.decryptJSONL(lines);
@@ -22668,7 +23049,7 @@ class SessionFileEncryptor {
22668
23049
  }
22669
23050
  appendToSessionJSONL(filePath, obj) {
22670
23051
  const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
22671
- writeFileSync14(filePath, encryptedLine + `
23052
+ writeFileSync15(filePath, encryptedLine + `
22672
23053
  `, {
22673
23054
  flag: "a",
22674
23055
  encoding: "utf8"
@@ -22679,12 +23060,12 @@ class SessionFileEncryptor {
22679
23060
  return;
22680
23061
  const files = readdirSync12(sessionDir);
22681
23062
  for (const file of files) {
22682
- const filePath = join30(sessionDir, file);
22683
- if (existsSync38(filePath) && !file.endsWith(".enc")) {
23063
+ const filePath = join32(sessionDir, file);
23064
+ if (existsSync39(filePath) && !file.endsWith(".enc")) {
22684
23065
  try {
22685
- const content = readFileSync22(filePath, "utf8");
23066
+ const content = readFileSync23(filePath, "utf8");
22686
23067
  const encrypted = this.encryptFileContent(content);
22687
- writeFileSync14(filePath + ".enc", encrypted, "utf8");
23068
+ writeFileSync15(filePath + ".enc", encrypted, "utf8");
22688
23069
  unlinkSync5(filePath);
22689
23070
  } catch {}
22690
23071
  }
@@ -22696,12 +23077,12 @@ class SessionFileEncryptor {
22696
23077
  const files = readdirSync12(sessionDir);
22697
23078
  for (const file of files) {
22698
23079
  if (file.endsWith(".enc")) {
22699
- const encFilePath = join30(sessionDir, file);
23080
+ const encFilePath = join32(sessionDir, file);
22700
23081
  const decFilePath = encFilePath.slice(0, -4);
22701
23082
  try {
22702
- const content = readFileSync22(encFilePath, "utf8");
23083
+ const content = readFileSync23(encFilePath, "utf8");
22703
23084
  const decrypted = this.decryptFileContent(content);
22704
- writeFileSync14(decFilePath, decrypted, "utf8");
23085
+ writeFileSync15(decFilePath, decrypted, "utf8");
22705
23086
  unlinkSync5(encFilePath);
22706
23087
  } catch {}
22707
23088
  }
@@ -22721,15 +23102,15 @@ var init_session_encryption = __esm(() => {
22721
23102
 
22722
23103
  // src/modules/session/store.ts
22723
23104
  import {
22724
- existsSync as existsSync39,
22725
- mkdirSync as mkdirSync16,
23105
+ existsSync as existsSync40,
23106
+ mkdirSync as mkdirSync17,
22726
23107
  readdirSync as readdirSync13,
22727
- readFileSync as readFileSync23,
23108
+ readFileSync as readFileSync24,
22728
23109
  rmSync as rmSync2,
22729
- writeFileSync as writeFileSync15,
23110
+ writeFileSync as writeFileSync16,
22730
23111
  appendFileSync as appendFileSync6
22731
23112
  } from "fs";
22732
- import { join as join31 } from "path";
23113
+ import { join as join33 } from "path";
22733
23114
  import { gzipSync } from "zlib";
22734
23115
 
22735
23116
  class SessionStore {
@@ -22743,7 +23124,7 @@ class SessionStore {
22743
23124
  }
22744
23125
  }
22745
23126
  getSessionDir(id) {
22746
- return join31(this.baseDir, id);
23127
+ return join33(this.baseDir, id);
22747
23128
  }
22748
23129
  updateEncryption(config) {
22749
23130
  if (config?.enabled) {
@@ -22756,32 +23137,32 @@ class SessionStore {
22756
23137
  return this.encryptor?.isEnabled() ?? false;
22757
23138
  }
22758
23139
  init() {
22759
- mkdirSync16(this.baseDir, { recursive: true, mode: 448 });
23140
+ mkdirSync17(this.baseDir, { recursive: true, mode: 448 });
22760
23141
  }
22761
23142
  sessionDir(id) {
22762
- return join31(this.baseDir, id);
23143
+ return join33(this.baseDir, id);
22763
23144
  }
22764
23145
  metaPath(id) {
22765
- return join31(this.sessionDir(id), "meta.json");
23146
+ return join33(this.sessionDir(id), "meta.json");
22766
23147
  }
22767
23148
  historyPath(id) {
22768
- return join31(this.sessionDir(id), "history.jsonl");
23149
+ return join33(this.sessionDir(id), "history.jsonl");
22769
23150
  }
22770
23151
  sessionLogPath(id) {
22771
- return join31(this.sessionDir(id), "session.jsonl");
23152
+ return join33(this.sessionDir(id), "session.jsonl");
22772
23153
  }
22773
23154
  sessionExists(id) {
22774
- return existsSync39(this.metaPath(id));
23155
+ return existsSync40(this.metaPath(id));
22775
23156
  }
22776
23157
  saveMeta(id, meta) {
22777
23158
  this._metaCache.set(id, meta);
22778
23159
  const dir = this.sessionDir(id);
22779
- mkdirSync16(dir, { recursive: true, mode: 448 });
23160
+ mkdirSync17(dir, { recursive: true, mode: 448 });
22780
23161
  const content = JSON.stringify(meta, null, 2);
22781
23162
  if (this.encryptor) {
22782
- writeFileSync15(this.metaPath(id), this.encryptor.encryptFileContent(content), { encoding: "utf-8", mode: 384 });
23163
+ writeFileSync16(this.metaPath(id), this.encryptor.encryptFileContent(content), { encoding: "utf-8", mode: 384 });
22783
23164
  } else {
22784
- writeFileSync15(this.metaPath(id), content, { encoding: "utf-8", mode: 384 });
23165
+ writeFileSync16(this.metaPath(id), content, { encoding: "utf-8", mode: 384 });
22785
23166
  }
22786
23167
  }
22787
23168
  loadMeta(id) {
@@ -22789,10 +23170,10 @@ class SessionStore {
22789
23170
  if (cached)
22790
23171
  return cached;
22791
23172
  const path = this.metaPath(id);
22792
- if (!existsSync39(path))
23173
+ if (!existsSync40(path))
22793
23174
  return null;
22794
23175
  try {
22795
- const raw = readFileSync23(path, "utf-8");
23176
+ const raw = readFileSync24(path, "utf-8");
22796
23177
  const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
22797
23178
  const meta = JSON.parse(content);
22798
23179
  this._metaCache.set(id, meta);
@@ -22803,10 +23184,10 @@ class SessionStore {
22803
23184
  }
22804
23185
  readMetaFromDisk(id) {
22805
23186
  const path = this.metaPath(id);
22806
- if (!existsSync39(path))
23187
+ if (!existsSync40(path))
22807
23188
  return null;
22808
23189
  try {
22809
- const raw = readFileSync23(path, "utf-8");
23190
+ const raw = readFileSync24(path, "utf-8");
22810
23191
  const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
22811
23192
  return JSON.parse(content);
22812
23193
  } catch {
@@ -22815,7 +23196,7 @@ class SessionStore {
22815
23196
  }
22816
23197
  appendMessage(id, msg) {
22817
23198
  const dir = this.sessionDir(id);
22818
- mkdirSync16(dir, { recursive: true, mode: 448 });
23199
+ mkdirSync17(dir, { recursive: true, mode: 448 });
22819
23200
  const line = JSON.stringify(msg);
22820
23201
  if (this.encryptor?.isEnabled()) {
22821
23202
  appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
@@ -22833,10 +23214,10 @@ class SessionStore {
22833
23214
  }
22834
23215
  loadHistory(id) {
22835
23216
  const path = this.historyPath(id);
22836
- if (!existsSync39(path))
23217
+ if (!existsSync40(path))
22837
23218
  return [];
22838
23219
  try {
22839
- const raw = readFileSync23(path, "utf-8");
23220
+ const raw = readFileSync24(path, "utf-8");
22840
23221
  const lines = raw.split(`
22841
23222
  `).filter(Boolean);
22842
23223
  const parseLine = (line) => {
@@ -22862,7 +23243,7 @@ class SessionStore {
22862
23243
  }
22863
23244
  appendSessionLog(id, entry) {
22864
23245
  const dir = this.sessionDir(id);
22865
- mkdirSync16(dir, { recursive: true, mode: 448 });
23246
+ mkdirSync17(dir, { recursive: true, mode: 448 });
22866
23247
  const line = JSON.stringify(entry);
22867
23248
  if (this.encryptor?.isEnabled()) {
22868
23249
  appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
@@ -22874,10 +23255,10 @@ class SessionStore {
22874
23255
  }
22875
23256
  loadSessionLog(id) {
22876
23257
  const path = this.sessionLogPath(id);
22877
- if (!existsSync39(path))
23258
+ if (!existsSync40(path))
22878
23259
  return [];
22879
23260
  try {
22880
- const raw = readFileSync23(path, "utf-8");
23261
+ const raw = readFileSync24(path, "utf-8");
22881
23262
  const lines = raw.split(`
22882
23263
  `).filter(Boolean);
22883
23264
  const parseLine = (line) => {
@@ -22902,7 +23283,7 @@ class SessionStore {
22902
23283
  }
22903
23284
  }
22904
23285
  listSessions() {
22905
- if (!existsSync39(this.baseDir))
23286
+ if (!existsSync40(this.baseDir))
22906
23287
  return [];
22907
23288
  const entries = readdirSync13(this.baseDir, { withFileTypes: true });
22908
23289
  const sessions = [];
@@ -22919,7 +23300,7 @@ class SessionStore {
22919
23300
  deleteSession(id) {
22920
23301
  this._metaCache.delete(id);
22921
23302
  const dir = this.sessionDir(id);
22922
- if (existsSync39(dir)) {
23303
+ if (existsSync40(dir)) {
22923
23304
  rmSync2(dir, { recursive: true, force: true });
22924
23305
  }
22925
23306
  }
@@ -22931,11 +23312,11 @@ class SessionStore {
22931
23312
  const updatedAt = new Date(session2.updatedAt);
22932
23313
  if (updatedAt < thirtyDaysAgo) {
22933
23314
  const historyPath = this.historyPath(session2.id);
22934
- if (existsSync39(historyPath)) {
22935
- const content = readFileSync23(historyPath, "utf-8");
23315
+ if (existsSync40(historyPath)) {
23316
+ const content = readFileSync24(historyPath, "utf-8");
22936
23317
  const compressed = gzipSync(content);
22937
- const gzPath = join31(this.baseDir, `${session2.id}.jsonl.gz`);
22938
- writeFileSync15(gzPath, compressed);
23318
+ const gzPath = join33(this.baseDir, `${session2.id}.jsonl.gz`);
23319
+ writeFileSync16(gzPath, compressed);
22939
23320
  rmSync2(historyPath);
22940
23321
  const meta = this.loadMeta(session2.id);
22941
23322
  if (meta) {
@@ -23116,13 +23497,18 @@ class SessionModule {
23116
23497
  }
23117
23498
  getSystemPromptBlock() {
23118
23499
  const meta = this.manager.getActiveMeta();
23119
- if (!meta || meta.messageCount === 0)
23500
+ if (!meta)
23120
23501
  return null;
23121
23502
  return {
23122
- content: t("session.info", { name: meta.name, id: meta.id, count: meta.messageCount }),
23503
+ content: t("session.info_full", {
23504
+ name: meta.name,
23505
+ id: meta.id,
23506
+ model: meta.model,
23507
+ contextWindow: meta.contextWindow
23508
+ }),
23123
23509
  priority: "low",
23124
23510
  essential: false,
23125
- estimatedTokens: 20
23511
+ estimatedTokens: 30
23126
23512
  };
23127
23513
  }
23128
23514
  getPlugin() {
@@ -23159,8 +23545,8 @@ class ProfileCompressor {
23159
23545
  }
23160
23546
 
23161
23547
  // src/modules/user-profile/profile.ts
23162
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync16, existsSync as existsSync40, mkdirSync as mkdirSync17 } from "fs";
23163
- import { join as join32 } from "path";
23548
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync17, existsSync as existsSync41, mkdirSync as mkdirSync18 } from "fs";
23549
+ import { join as join34 } from "path";
23164
23550
  import { homedir as homedir10, hostname, platform as platform8, type } from "os";
23165
23551
  import { env } from "process";
23166
23552
 
@@ -23184,17 +23570,17 @@ class UserProfile {
23184
23570
  return this.info;
23185
23571
  }
23186
23572
  save() {
23187
- if (!existsSync40(this.profileDir)) {
23188
- mkdirSync17(this.profileDir, { recursive: true });
23573
+ if (!existsSync41(this.profileDir)) {
23574
+ mkdirSync18(this.profileDir, { recursive: true });
23189
23575
  }
23190
- writeFileSync16(join32(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
23576
+ writeFileSync17(join34(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
23191
23577
  }
23192
23578
  load() {
23193
- const path = join32(this.profileDir, "profile.json");
23194
- if (!existsSync40(path))
23579
+ const path = join34(this.profileDir, "profile.json");
23580
+ if (!existsSync41(path))
23195
23581
  return null;
23196
23582
  try {
23197
- const data = JSON.parse(readFileSync24(path, "utf-8"));
23583
+ const data = JSON.parse(readFileSync25(path, "utf-8"));
23198
23584
  this.info = {
23199
23585
  platform: data.platform,
23200
23586
  os: data.os,
@@ -23229,12 +23615,12 @@ class UserProfile {
23229
23615
  var init_profile = () => {};
23230
23616
 
23231
23617
  // src/modules/skills/loader.ts
23232
- import { readdirSync as readdirSync14, readFileSync as readFileSync25, existsSync as existsSync41, statSync as statSync7 } from "fs";
23233
- import { join as join33 } from "path";
23618
+ import { readdirSync as readdirSync14, readFileSync as readFileSync26, existsSync as existsSync42, statSync as statSync7 } from "fs";
23619
+ import { join as join35 } from "path";
23234
23620
 
23235
23621
  class SkillsLoader {
23236
23622
  loadFromDir(dirPath) {
23237
- if (!existsSync41(dirPath))
23623
+ if (!existsSync42(dirPath))
23238
23624
  return [];
23239
23625
  const skills = [];
23240
23626
  this.scanDir(dirPath, skills);
@@ -23243,7 +23629,7 @@ class SkillsLoader {
23243
23629
  scanDir(dirPath, skills) {
23244
23630
  const entries = readdirSync14(dirPath);
23245
23631
  for (const entry of entries) {
23246
- const fullPath = join33(dirPath, entry);
23632
+ const fullPath = join35(dirPath, entry);
23247
23633
  let stat;
23248
23634
  try {
23249
23635
  stat = statSync7(fullPath);
@@ -23256,7 +23642,7 @@ class SkillsLoader {
23256
23642
  }
23257
23643
  if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
23258
23644
  continue;
23259
- const content = readFileSync25(fullPath, "utf-8");
23645
+ const content = readFileSync26(fullPath, "utf-8");
23260
23646
  const parsed = this.parseSkillFile(content, fullPath);
23261
23647
  if (parsed)
23262
23648
  skills.push(parsed);
@@ -23903,11 +24289,11 @@ var init_check_tool = __esm(() => {
23903
24289
  });
23904
24290
 
23905
24291
  // src/modules/lsp/module.ts
23906
- import { existsSync as existsSync42 } from "fs";
24292
+ import { existsSync as existsSync43 } from "fs";
23907
24293
  import { relative as relative5, resolve as resolve21 } from "path";
23908
- import { join as join34 } from "path";
24294
+ import { join as join36 } from "path";
23909
24295
  function hasTypeEnvironment(projectRoot) {
23910
- return existsSync42(join34(projectRoot, "tsconfig.json")) || existsSync42(join34(projectRoot, "jsconfig.json")) || existsSync42(join34(projectRoot, "node_modules"));
24296
+ return existsSync43(join36(projectRoot, "tsconfig.json")) || existsSync43(join36(projectRoot, "jsconfig.json")) || existsSync43(join36(projectRoot, "node_modules"));
23911
24297
  }
23912
24298
 
23913
24299
  class LspModule {
@@ -23962,7 +24348,7 @@ class LspModule {
23962
24348
  if (!filePath)
23963
24349
  return;
23964
24350
  const fullPath = resolve21(_ctx.baseDir, filePath);
23965
- if (!existsSync42(fullPath))
24351
+ if (!existsSync43(fullPath))
23966
24352
  return;
23967
24353
  const serverConfig = getServerForFile(fullPath, self.config);
23968
24354
  if (!serverConfig)
@@ -24054,7 +24440,7 @@ ${items}`;
24054
24440
  })
24055
24441
  };
24056
24442
  }
24057
- if (!existsSync42(resolved)) {
24443
+ if (!existsSync43(resolved)) {
24058
24444
  return { success: false, output: t("lsp.check_notfound", { path }) };
24059
24445
  }
24060
24446
  const files = await collectCheckFiles(resolved, this.config);
@@ -24171,8 +24557,8 @@ var init_lsp = __esm(() => {
24171
24557
  });
24172
24558
 
24173
24559
  // src/modules/lsp/startup-check.ts
24174
- import { existsSync as existsSync43 } from "fs";
24175
- import { join as join35 } from "path";
24560
+ import { existsSync as existsSync44 } from "fs";
24561
+ import { join as join37 } from "path";
24176
24562
  import { spawn as spawn9 } from "child_process";
24177
24563
  async function runStartupHealthCheck(config, baseDir, deps = {}) {
24178
24564
  if (!config.enabled)
@@ -24199,7 +24585,7 @@ ${result.lines.join(`
24199
24585
  }
24200
24586
  async function runCheck(config, baseDir, deps) {
24201
24587
  const projectRoot = findProjectRoot(baseDir, baseDir, ["tsconfig.json", "package.json"]);
24202
- if (existsSync43(join35(projectRoot, "tsconfig.json"))) {
24588
+ if (existsSync44(join37(projectRoot, "tsconfig.json"))) {
24203
24589
  const runTsc = deps.runTsc ?? runTscDefault;
24204
24590
  const errors = await runTsc(projectRoot, STARTUP_CHECK_TIMEOUT_MS);
24205
24591
  if (errors.length === 0)
@@ -24300,9 +24686,186 @@ var init_startup_check = __esm(() => {
24300
24686
  init_utils();
24301
24687
  });
24302
24688
 
24689
+ // src/modules/indexer/symbols.ts
24690
+ function dedupe2(names) {
24691
+ const seen = new Set;
24692
+ const out = [];
24693
+ for (const name of names) {
24694
+ if (name && !seen.has(name)) {
24695
+ seen.add(name);
24696
+ out.push(name);
24697
+ }
24698
+ }
24699
+ return out;
24700
+ }
24701
+ function collect(content, patterns) {
24702
+ const names = [];
24703
+ for (const re of patterns) {
24704
+ re.lastIndex = 0;
24705
+ let match;
24706
+ while ((match = re.exec(content)) !== null) {
24707
+ if (match[1])
24708
+ names.push(match[1]);
24709
+ if (match.index === re.lastIndex)
24710
+ re.lastIndex++;
24711
+ }
24712
+ }
24713
+ return names;
24714
+ }
24715
+ function collectExportClauses(content) {
24716
+ const names = [];
24717
+ const re = /export\s+(?:type\s+)?\{([^}]*)\}/g;
24718
+ let match;
24719
+ while ((match = re.exec(content)) !== null) {
24720
+ for (const part of match[1].split(",")) {
24721
+ const cleaned = part.trim().replace(/^type\s+/, "");
24722
+ if (!cleaned || cleaned.startsWith("//"))
24723
+ continue;
24724
+ const alias = cleaned.split(/\s+as\s+/);
24725
+ const exported = (alias.length > 1 ? alias[1] : alias[0]).trim();
24726
+ if (/^\w+$/.test(exported))
24727
+ names.push(exported);
24728
+ }
24729
+ }
24730
+ return names;
24731
+ }
24732
+ function tsLike(content) {
24733
+ return dedupe2([...collect(content, TS_JS_PATTERNS), ...collectExportClauses(content)]);
24734
+ }
24735
+ function languageIdForExt(ext) {
24736
+ return EXT_TO_LANGUAGE[ext.toLowerCase()] ?? null;
24737
+ }
24738
+ function isCodeLanguage(languageId) {
24739
+ return RULES[languageId]?.code ?? false;
24740
+ }
24741
+ function extractSymbols(content, languageId) {
24742
+ const rule = RULES[languageId];
24743
+ if (!rule)
24744
+ return [];
24745
+ return dedupe2(rule.extract(content)).slice(0, MAX_SYMBOLS_PER_FILE);
24746
+ }
24747
+ var MAX_SYMBOLS_PER_FILE = 40, TS_JS_PATTERNS, PYTHON_PATTERNS, RUST_PATTERNS, GO_PATTERNS, JAVA_PATTERNS, KOTLIN_PATTERNS, CSHARP_PATTERNS, RUBY_PATTERNS, PHP_PATTERNS, SWIFT_PATTERNS, SCALA_PATTERNS, C_CPP_PATTERNS, SHELL_PATTERNS, LUA_PATTERNS, NO_SYMBOLS = () => [], RULES, EXT_TO_LANGUAGE;
24748
+ var init_symbols = __esm(() => {
24749
+ TS_JS_PATTERNS = [
24750
+ /^export\s+(?:default\s+)?(?:declare\s+)?(?:abstract\s+)?(?:async\s+)?(?:const|let|var|function|class|interface|type|enum)\s+(\w+)/gm,
24751
+ /^export\s+default\s+(?:class|function)\s+(\w+)/gm
24752
+ ];
24753
+ PYTHON_PATTERNS = [/^(?:async\s+)?def\s+(\w+)/gm, /^class\s+(\w+)/gm];
24754
+ RUST_PATTERNS = [
24755
+ /^\s*pub(?:\([^)]*\))?\s+(?:async\s+)?(?:unsafe\s+)?(?:fn|struct|enum|trait|const|static|type|mod)\s+(\w+)/gm,
24756
+ /macro_rules!\s+(\w+)/g
24757
+ ];
24758
+ GO_PATTERNS = [
24759
+ /^func\s+(\w+)\s*[([]/gm,
24760
+ /^func\s+\([^)]*\)\s+(\w+)\s*[([]/gm,
24761
+ /^type\s+(\w+)/gm,
24762
+ /^(?:var|const)\s+(\w+)/gm
24763
+ ];
24764
+ JAVA_PATTERNS = [
24765
+ /^\s*(?:(?:public|protected|private|final|abstract|static|sealed|non-sealed|strictfp)\s+)*(?:class|interface|enum|record)\s+(\w+)/gm
24766
+ ];
24767
+ KOTLIN_PATTERNS = [
24768
+ /^\s*(?:(?:public|internal|private|protected|open|abstract|sealed|data|enum|annotation|value|inline)\s+)*(?:class|interface|object)\s+(\w+)/gm,
24769
+ /^\s*(?:(?:public|internal|private|protected|open|override|suspend|inline|operator|infix|tailrec|external)\s+)*fun\s+(\w+)/gm
24770
+ ];
24771
+ CSHARP_PATTERNS = [
24772
+ /^\s*(?:(?:public|internal|private|protected|static|sealed|abstract|partial|readonly|unsafe|new|record)\s+)*(?:class|interface|struct|enum|record)\s+(\w+)/gm
24773
+ ];
24774
+ RUBY_PATTERNS = [/^\s*(?:def|class|module)\s+([A-Za-z_]\w*[?!]?)/gm];
24775
+ PHP_PATTERNS = [/\b(?:function|class|interface|trait|enum)\s+(\w+)/g];
24776
+ SWIFT_PATTERNS = [/\b(?:func|class|struct|enum|protocol|extension)\s+(\w+)/g];
24777
+ SCALA_PATTERNS = [
24778
+ /^\s*(?:(?:private|protected|final|abstract|sealed|implicit|lazy|override)\s+)*(?:def|class|object|trait)\s+(\w+)/gm
24779
+ ];
24780
+ C_CPP_PATTERNS = [
24781
+ /^\s*(?:typedef\s+)?(?:class|struct|enum|union|namespace)\s+(\w+)/gm,
24782
+ /\}\s*(\w+)\s*;/g
24783
+ ];
24784
+ SHELL_PATTERNS = [/^\s*(?:function\s+)?(\w+)\s*\(\s*\)\s*\{/gm];
24785
+ LUA_PATTERNS = [/^\s*(?:local\s+)?function\s+([\w.:]+)/gm];
24786
+ RULES = {
24787
+ typescript: { code: true, extract: tsLike },
24788
+ "typescript-react": { code: true, extract: tsLike },
24789
+ javascript: { code: true, extract: tsLike },
24790
+ "javascript-react": { code: true, extract: tsLike },
24791
+ python: { code: true, extract: (c) => collect(c, PYTHON_PATTERNS) },
24792
+ rust: { code: true, extract: (c) => collect(c, RUST_PATTERNS) },
24793
+ go: { code: true, extract: (c) => collect(c, GO_PATTERNS) },
24794
+ java: { code: true, extract: (c) => collect(c, JAVA_PATTERNS) },
24795
+ kotlin: { code: true, extract: (c) => collect(c, KOTLIN_PATTERNS) },
24796
+ csharp: { code: true, extract: (c) => collect(c, CSHARP_PATTERNS) },
24797
+ ruby: { code: true, extract: (c) => collect(c, RUBY_PATTERNS) },
24798
+ php: { code: true, extract: (c) => collect(c, PHP_PATTERNS) },
24799
+ swift: { code: true, extract: (c) => collect(c, SWIFT_PATTERNS) },
24800
+ scala: { code: true, extract: (c) => collect(c, SCALA_PATTERNS) },
24801
+ c: { code: true, extract: (c) => collect(c, C_CPP_PATTERNS) },
24802
+ cpp: { code: true, extract: (c) => collect(c, C_CPP_PATTERNS) },
24803
+ shell: { code: true, extract: (c) => collect(c, SHELL_PATTERNS) },
24804
+ lua: { code: true, extract: (c) => collect(c, LUA_PATTERNS) },
24805
+ json: { code: false, extract: NO_SYMBOLS },
24806
+ markdown: { code: false, extract: NO_SYMBOLS },
24807
+ yaml: { code: false, extract: NO_SYMBOLS },
24808
+ toml: { code: false, extract: NO_SYMBOLS },
24809
+ xml: { code: false, extract: NO_SYMBOLS },
24810
+ html: { code: false, extract: NO_SYMBOLS },
24811
+ css: { code: false, extract: NO_SYMBOLS }
24812
+ };
24813
+ EXT_TO_LANGUAGE = {
24814
+ ".ts": "typescript",
24815
+ ".mts": "typescript",
24816
+ ".cts": "typescript",
24817
+ ".tsx": "typescript-react",
24818
+ ".js": "javascript",
24819
+ ".mjs": "javascript",
24820
+ ".cjs": "javascript",
24821
+ ".jsx": "javascript-react",
24822
+ ".py": "python",
24823
+ ".pyi": "python",
24824
+ ".rs": "rust",
24825
+ ".go": "go",
24826
+ ".java": "java",
24827
+ ".kt": "kotlin",
24828
+ ".kts": "kotlin",
24829
+ ".cs": "csharp",
24830
+ ".rb": "ruby",
24831
+ ".php": "php",
24832
+ ".swift": "swift",
24833
+ ".scala": "scala",
24834
+ ".c": "c",
24835
+ ".h": "c",
24836
+ ".cpp": "cpp",
24837
+ ".cc": "cpp",
24838
+ ".cxx": "cpp",
24839
+ ".hpp": "cpp",
24840
+ ".hxx": "cpp",
24841
+ ".sh": "shell",
24842
+ ".bash": "shell",
24843
+ ".zsh": "shell",
24844
+ ".lua": "lua",
24845
+ ".json": "json",
24846
+ ".md": "markdown",
24847
+ ".markdown": "markdown",
24848
+ ".yaml": "yaml",
24849
+ ".yml": "yaml",
24850
+ ".toml": "toml",
24851
+ ".xml": "xml",
24852
+ ".html": "html",
24853
+ ".htm": "html",
24854
+ ".css": "css",
24855
+ ".scss": "css",
24856
+ ".less": "css"
24857
+ };
24858
+ });
24859
+
24303
24860
  // src/modules/indexer/walker.ts
24304
- import { readdirSync as readdirSync15, readFileSync as readFileSync26, statSync as statSync8, lstatSync, existsSync as existsSync44, watch } from "fs";
24305
- import { join as join36, relative as relative6, extname as extname7 } from "path";
24861
+ import { readdirSync as readdirSync15, readFileSync as readFileSync27, statSync as statSync8, lstatSync, existsSync as existsSync45, watch } from "fs";
24862
+ import { join as join38, relative as relative6, extname as extname7 } from "path";
24863
+ function isIgnoredDirName(name) {
24864
+ return IGNORE_DIRS.has(name.toLowerCase());
24865
+ }
24866
+ function isIgnoredPath(filename) {
24867
+ return filename.split(/[\\/]/).some((segment) => isIgnoredDirName(segment));
24868
+ }
24306
24869
 
24307
24870
  class Indexer {
24308
24871
  baseDir;
@@ -24313,7 +24876,7 @@ class Indexer {
24313
24876
  }
24314
24877
  watch(callback) {
24315
24878
  this.watcher = watch(this.baseDir, { recursive: true }, (event, filename) => {
24316
- if (filename && !Array.from(IGNORE_DIRS).some((dir) => filename.includes(dir))) {
24879
+ if (filename && !isIgnoredPath(filename)) {
24317
24880
  callback(event, filename);
24318
24881
  }
24319
24882
  });
@@ -24329,7 +24892,7 @@ class Indexer {
24329
24892
  let totalSize = 0;
24330
24893
  let count = 0;
24331
24894
  const walkDir2 = (dir) => {
24332
- if (!existsSync44(dir))
24895
+ if (!existsSync45(dir))
24333
24896
  return;
24334
24897
  let entries;
24335
24898
  try {
@@ -24340,7 +24903,7 @@ class Indexer {
24340
24903
  for (const entry of entries) {
24341
24904
  if (count >= this.MAX_FILES)
24342
24905
  return;
24343
- const fullPath = join36(dir, entry);
24906
+ const fullPath = join38(dir, entry);
24344
24907
  const relPath = relative6(this.baseDir, fullPath);
24345
24908
  try {
24346
24909
  const lst = lstatSync(fullPath, { throwIfNoEntry: false });
@@ -24348,15 +24911,15 @@ class Indexer {
24348
24911
  continue;
24349
24912
  const stat2 = statSync8(fullPath);
24350
24913
  if (stat2.isDirectory()) {
24351
- if (!IGNORE_DIRS.has(entry)) {
24914
+ if (!isIgnoredDirName(entry)) {
24352
24915
  walkDir2(fullPath);
24353
24916
  }
24354
24917
  } else if (stat2.isFile()) {
24355
24918
  const ext = extname7(entry).toLowerCase();
24356
- const language = LANGUAGES[ext];
24919
+ const language = languageIdForExt(ext);
24357
24920
  if (language) {
24358
- const content = readFileSync26(fullPath, "utf-8");
24359
- const exports = this.extractExports(content, language);
24921
+ const content = readFileSync27(fullPath, "utf-8");
24922
+ const exports = extractSymbols(content, language);
24360
24923
  files.push({ path: relPath, language, exports, size: stat2.size });
24361
24924
  totalSize += stat2.size;
24362
24925
  count++;
@@ -24371,18 +24934,6 @@ class Indexer {
24371
24934
  walkDir2(this.baseDir);
24372
24935
  return { files, totalSize };
24373
24936
  }
24374
- extractExports(content, language) {
24375
- if (language === "typescript" || language === "javascript") {
24376
- const exports = [];
24377
- const exportRegex = /export\s+(?:const|function|class|interface|type|enum|default\s+(?:class|function))\s+(\w+)/g;
24378
- let match;
24379
- while ((match = exportRegex.exec(content)) !== null) {
24380
- exports.push(match[1]);
24381
- }
24382
- return exports;
24383
- }
24384
- return [];
24385
- }
24386
24937
  summarize(result) {
24387
24938
  const byLang = {};
24388
24939
  for (const f of result.files) {
@@ -24392,43 +24943,66 @@ class Indexer {
24392
24943
  return `[Index: ${result.files.length} files, ${(result.totalSize / 1024).toFixed(1)}KB (${langs})]`;
24393
24944
  }
24394
24945
  }
24395
- var logger2, LANGUAGES, IGNORE_DIRS;
24946
+ var logger2, IGNORE_DIRS;
24396
24947
  var init_walker = __esm(() => {
24397
24948
  init_app_logger();
24949
+ init_symbols();
24398
24950
  logger2 = new Logger("warn", "indexer");
24399
- LANGUAGES = {
24400
- ".ts": "typescript",
24401
- ".tsx": "typescript-react",
24402
- ".js": "javascript",
24403
- ".jsx": "javascript-react",
24404
- ".json": "json",
24405
- ".md": "markdown",
24406
- ".yaml": "yaml",
24407
- ".yml": "yaml",
24408
- ".py": "python",
24409
- ".rs": "rust",
24410
- ".go": "go"
24411
- };
24412
- IGNORE_DIRS = new Set(["node_modules", ".git", "dist", "build", ".mma", "coverage"]);
24951
+ IGNORE_DIRS = new Set([
24952
+ ".git",
24953
+ ".hg",
24954
+ ".svn",
24955
+ ".mma",
24956
+ "node_modules",
24957
+ "dist",
24958
+ "build",
24959
+ "coverage",
24960
+ ".next",
24961
+ ".nuxt",
24962
+ ".svelte-kit",
24963
+ ".turbo",
24964
+ ".parcel-cache",
24965
+ ".cache",
24966
+ "venv",
24967
+ ".venv",
24968
+ "env",
24969
+ "virtualenv",
24970
+ "__pycache__",
24971
+ ".pytest_cache",
24972
+ ".mypy_cache",
24973
+ ".ruff_cache",
24974
+ ".tox",
24975
+ "site-packages",
24976
+ "target",
24977
+ "vendor",
24978
+ ".bundle",
24979
+ ".gradle",
24980
+ "out",
24981
+ "obj",
24982
+ "pods",
24983
+ "deriveddata",
24984
+ ".idea",
24985
+ ".vscode"
24986
+ ]);
24413
24987
  });
24414
24988
 
24415
24989
  // src/modules/indexer/cache.ts
24416
- import { readFileSync as readFileSync27, writeFileSync as writeFileSync17, existsSync as existsSync45, mkdirSync as mkdirSync18, rmSync as rmSync3 } from "fs";
24417
- import { join as join37 } from "path";
24990
+ import { readFileSync as readFileSync28, writeFileSync as writeFileSync18, existsSync as existsSync46, mkdirSync as mkdirSync19, rmSync as rmSync3 } from "fs";
24991
+ import { join as join39 } from "path";
24418
24992
 
24419
24993
  class IndexCache {
24420
24994
  cachePath;
24421
24995
  cache = null;
24422
24996
  constructor(cacheDir) {
24423
- this.cachePath = join37(cacheDir, "index-cache.json");
24997
+ this.cachePath = join39(cacheDir, "index-cache.json");
24424
24998
  }
24425
24999
  load() {
24426
25000
  if (this.cache)
24427
25001
  return this.cache;
24428
- if (!existsSync45(this.cachePath))
25002
+ if (!existsSync46(this.cachePath))
24429
25003
  return null;
24430
25004
  try {
24431
- this.cache = JSON.parse(readFileSync27(this.cachePath, "utf-8"));
25005
+ this.cache = JSON.parse(readFileSync28(this.cachePath, "utf-8"));
24432
25006
  return this.cache;
24433
25007
  } catch {
24434
25008
  return null;
@@ -24436,14 +25010,14 @@ class IndexCache {
24436
25010
  }
24437
25011
  save(result) {
24438
25012
  this.cache = result;
24439
- const dir = join37(this.cachePath, "..");
24440
- if (!existsSync45(dir))
24441
- mkdirSync18(dir, { recursive: true });
24442
- writeFileSync17(this.cachePath, JSON.stringify(result), "utf-8");
25013
+ const dir = join39(this.cachePath, "..");
25014
+ if (!existsSync46(dir))
25015
+ mkdirSync19(dir, { recursive: true });
25016
+ writeFileSync18(this.cachePath, JSON.stringify(result), "utf-8");
24443
25017
  }
24444
25018
  invalidate() {
24445
25019
  this.cache = null;
24446
- if (existsSync45(this.cachePath)) {
25020
+ if (existsSync46(this.cachePath)) {
24447
25021
  try {
24448
25022
  rmSync3(this.cachePath);
24449
25023
  } catch {}
@@ -24452,12 +25026,77 @@ class IndexCache {
24452
25026
  }
24453
25027
  var init_cache = () => {};
24454
25028
 
25029
+ // src/modules/indexer/map-select.ts
25030
+ function isNoiseFile(file) {
25031
+ const base = toForwardSlash(file.path).split("/").pop()?.toLowerCase() ?? "";
25032
+ return NOISE_BASENAMES.has(base);
25033
+ }
25034
+ function isTestFile(path) {
25035
+ return path.startsWith("test/") || path.startsWith("tests/") || path.includes("/test/") || path.includes("/tests/") || path.includes("__tests__/") || /\.(test|spec)\.[a-z0-9]+$/i.test(path);
25036
+ }
25037
+ function rank(file) {
25038
+ const path = toForwardSlash(file.path).toLowerCase();
25039
+ if (isTestFile(path))
25040
+ return 1;
25041
+ if (isCodeLanguage(file.language))
25042
+ return 0;
25043
+ return 2;
25044
+ }
25045
+ function topDir(path) {
25046
+ const normalized = toForwardSlash(path);
25047
+ const slash = normalized.indexOf("/");
25048
+ return slash >= 0 ? normalized.slice(0, slash) : normalized;
25049
+ }
25050
+ function codeCountByTopDir(files) {
25051
+ const counts = new Map;
25052
+ for (const file of files) {
25053
+ if (isNoiseFile(file) || rank(file) !== 0)
25054
+ continue;
25055
+ const dir = topDir(file.path);
25056
+ counts.set(dir, (counts.get(dir) ?? 0) + 1);
25057
+ }
25058
+ return counts;
25059
+ }
25060
+ function selectMapFiles(files, max) {
25061
+ const codeByDir = codeCountByTopDir(files);
25062
+ return files.filter((file) => !isNoiseFile(file)).sort((a, b) => {
25063
+ const rankDiff = rank(a) - rank(b);
25064
+ if (rankDiff !== 0)
25065
+ return rankDiff;
25066
+ const densityDiff = (codeByDir.get(topDir(b.path)) ?? 0) - (codeByDir.get(topDir(a.path)) ?? 0);
25067
+ if (densityDiff !== 0)
25068
+ return densityDiff;
25069
+ const pathA = toForwardSlash(a.path);
25070
+ const pathB = toForwardSlash(b.path);
25071
+ const depthDiff = pathA.split("/").length - pathB.split("/").length;
25072
+ if (depthDiff !== 0)
25073
+ return depthDiff;
25074
+ return pathA < pathB ? -1 : pathA > pathB ? 1 : 0;
25075
+ }).slice(0, max);
25076
+ }
25077
+ var NOISE_BASENAMES;
25078
+ var init_map_select = __esm(() => {
25079
+ init_path_utils();
25080
+ init_symbols();
25081
+ NOISE_BASENAMES = new Set([
25082
+ "package-lock.json",
25083
+ "bun.lock",
25084
+ "bun.lockb",
25085
+ "yarn.lock",
25086
+ "pnpm-lock.yaml",
25087
+ "cargo.lock",
25088
+ "go.sum",
25089
+ "composer.lock",
25090
+ "poetry.lock"
25091
+ ]);
25092
+ });
25093
+
24455
25094
  // src/modules/indexer/project-profile.ts
24456
- import { readFileSync as readFileSync28, existsSync as existsSync46 } from "fs";
24457
- import { join as join38 } from "path";
25095
+ import { readFileSync as readFileSync29, existsSync as existsSync47 } from "fs";
25096
+ import { join as join40 } from "path";
24458
25097
  function detectManifest(baseDir) {
24459
25098
  for (const manifest of MANIFEST_ORDER) {
24460
- if (existsSync46(join38(baseDir, manifest)))
25099
+ if (existsSync47(join40(baseDir, manifest)))
24461
25100
  return manifest;
24462
25101
  }
24463
25102
  return null;
@@ -24474,7 +25113,7 @@ function cleanDependency(entry) {
24474
25113
  }
24475
25114
  function readPackageJson(baseDir) {
24476
25115
  try {
24477
- const raw = JSON.parse(readFileSync28(join38(baseDir, "package.json"), "utf-8"));
25116
+ const raw = JSON.parse(readFileSync29(join40(baseDir, "package.json"), "utf-8"));
24478
25117
  if (!raw || typeof raw !== "object")
24479
25118
  return null;
24480
25119
  const profile = {
@@ -24498,7 +25137,7 @@ function readPackageJson(baseDir) {
24498
25137
  }
24499
25138
  function readPyproject(baseDir) {
24500
25139
  try {
24501
- const content = readFileSync28(join38(baseDir, "pyproject.toml"), "utf-8");
25140
+ const content = readFileSync29(join40(baseDir, "pyproject.toml"), "utf-8");
24502
25141
  const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
24503
25142
  const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
24504
25143
  if (nameMatch)
@@ -24514,7 +25153,7 @@ function readPyproject(baseDir) {
24514
25153
  }
24515
25154
  function readCargo(baseDir) {
24516
25155
  try {
24517
- const content = readFileSync28(join38(baseDir, "Cargo.toml"), "utf-8");
25156
+ const content = readFileSync29(join40(baseDir, "Cargo.toml"), "utf-8");
24518
25157
  const profile = { runtime: "rust", deps: [], devDeps: [], scripts: {} };
24519
25158
  const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
24520
25159
  if (nameMatch)
@@ -24538,7 +25177,7 @@ function readCargo(baseDir) {
24538
25177
  }
24539
25178
  function readGoMod(baseDir) {
24540
25179
  try {
24541
- const content = readFileSync28(join38(baseDir, "go.mod"), "utf-8");
25180
+ const content = readFileSync29(join40(baseDir, "go.mod"), "utf-8");
24542
25181
  const profile = { runtime: "go", deps: [], devDeps: [], scripts: {} };
24543
25182
  const moduleMatch = content.match(/^module\s+(\S+)/m);
24544
25183
  if (moduleMatch)
@@ -24556,7 +25195,7 @@ function readGoMod(baseDir) {
24556
25195
  }
24557
25196
  function readRequirements(baseDir) {
24558
25197
  try {
24559
- const content = readFileSync28(join38(baseDir, "requirements.txt"), "utf-8");
25198
+ const content = readFileSync29(join40(baseDir, "requirements.txt"), "utf-8");
24560
25199
  const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
24561
25200
  for (const line of content.split(`
24562
25201
  `)) {
@@ -24666,6 +25305,22 @@ class IndexerModule {
24666
25305
  return path.includes(q) || f.exports.some((e) => e.toLowerCase().includes(q));
24667
25306
  });
24668
25307
  }
25308
+ formatFind(query) {
25309
+ const matches = this.find(query);
25310
+ if (matches.length === 0) {
25311
+ return t("indexer.no_matches", { query });
25312
+ }
25313
+ const lines = matches.map((f) => {
25314
+ const path = toForwardSlash(f.path);
25315
+ const exports = f.exports.length > 0 ? `: ${f.exports.join(", ")}` : "";
25316
+ return `- ${path}${exports}`;
25317
+ }).join(`
25318
+ `);
25319
+ return t("indexer.find_results", { count: matches.length, results: lines });
25320
+ }
25321
+ getPromptMap() {
25322
+ return this.index ? this.formatMap(this.index) : null;
25323
+ }
24669
25324
  watch() {
24670
25325
  this.unwatch();
24671
25326
  try {
@@ -24695,7 +25350,8 @@ class IndexerModule {
24695
25350
  content,
24696
25351
  priority: "normal",
24697
25352
  essential: false,
24698
- estimatedTokens: this.estimateTokens(content)
25353
+ estimatedTokens: this.estimateTokens(content),
25354
+ kind: "project-map"
24699
25355
  };
24700
25356
  }
24701
25357
  getToolDefinitions() {
@@ -24718,13 +25374,14 @@ class IndexerModule {
24718
25374
  const stackLine = buildProjectProfileLine(this.baseDir);
24719
25375
  const dirCounts = this.getDirectoryCounts(result);
24720
25376
  const topDirs = Object.entries(dirCounts).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([dir, count]) => `${dir} (${count})`).join(", ") || "-";
24721
- const fileLines = result.files.slice(0, 100).map((f) => {
25377
+ const listed = selectMapFiles(result.files, MAP_FILE_LIMIT);
25378
+ const fileLines = listed.map((f) => {
24722
25379
  const path = toForwardSlash(f.path);
24723
25380
  const exports = f.exports.length > 0 ? `: ${f.exports.join(", ")}` : "";
24724
25381
  return `- ${path}${exports}`;
24725
25382
  });
24726
- const more = result.files.length > 100 ? `
24727
- ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
25383
+ const more = result.files.length > listed.length ? `
25384
+ ${t("indexer.and_more", { count: result.files.length - listed.length })}` : "";
24728
25385
  const duplicates = this.findDuplicateBasenames(result);
24729
25386
  return [
24730
25387
  `${t("indexer.map_header")} (${this.baseDir})`,
@@ -24816,20 +25473,7 @@ ${stackLine2}` : summary2;
24816
25473
  const query = String(args.query || "").toLowerCase();
24817
25474
  if (!query)
24818
25475
  return { success: false, output: t("tool.invalid_params") };
24819
- const matches = this.find(query);
24820
- if (matches.length === 0) {
24821
- return this.makeResult(t("indexer.no_matches", { query }));
24822
- }
24823
- const lines = matches.map((f) => {
24824
- const path = toForwardSlash(f.path);
24825
- const exports = f.exports.length > 0 ? `: ${f.exports.join(", ")}` : "";
24826
- return `- ${path}${exports}`;
24827
- }).join(`
24828
- `);
24829
- return this.makeResult(t("indexer.find_results", {
24830
- count: matches.length,
24831
- results: lines
24832
- }));
25476
+ return this.makeResult(this.formatFind(query));
24833
25477
  }
24834
25478
  if (!this.index) {
24835
25479
  await this.buildIndex();
@@ -24849,9 +25493,11 @@ ${stackLine}` : summary;
24849
25493
  return { success: true, output, display: output };
24850
25494
  }
24851
25495
  }
25496
+ var MAP_FILE_LIMIT = 80;
24852
25497
  var init_module6 = __esm(() => {
24853
25498
  init_walker();
24854
25499
  init_cache();
25500
+ init_map_select();
24855
25501
  init_project_profile();
24856
25502
  init_i18n();
24857
25503
  init_path_utils();
@@ -25105,7 +25751,7 @@ var init_mcp = __esm(() => {
25105
25751
 
25106
25752
  // src/modules/memory/module.ts
25107
25753
  import { homedir as homedir11 } from "os";
25108
- import { join as join39 } from "path";
25754
+ import { join as join41 } from "path";
25109
25755
 
25110
25756
  class MemoryModule {
25111
25757
  name = "memory";
@@ -25114,7 +25760,7 @@ class MemoryModule {
25114
25760
  if (storeOrDir instanceof MemoryStore) {
25115
25761
  this.store = storeOrDir;
25116
25762
  } else {
25117
- const dir = storeOrDir || join39(homedir11(), ".mma", "memory");
25763
+ const dir = storeOrDir || join41(homedir11(), ".mma", "memory");
25118
25764
  this.store = new MemoryStore(dir);
25119
25765
  }
25120
25766
  }
@@ -25201,16 +25847,16 @@ var init_module8 = __esm(() => {
25201
25847
  });
25202
25848
 
25203
25849
  // src/core/version.ts
25204
- import { existsSync as existsSync47, readFileSync as readFileSync29 } from "fs";
25205
- import { join as join40, dirname as dirname15 } from "path";
25850
+ import { existsSync as existsSync48, readFileSync as readFileSync30 } from "fs";
25851
+ import { join as join42, dirname as dirname15 } from "path";
25206
25852
  import { fileURLToPath as fileURLToPath2 } from "url";
25207
25853
  function readMmaVersion() {
25208
25854
  const here = dirname15(fileURLToPath2(import.meta.url));
25209
- const candidates = [join40(here, "..", "..", "package.json"), join40(here, "..", "package.json")];
25855
+ const candidates = [join42(here, "..", "..", "package.json"), join42(here, "..", "package.json")];
25210
25856
  for (const p of candidates) {
25211
- if (existsSync47(p)) {
25857
+ if (existsSync48(p)) {
25212
25858
  try {
25213
- const raw = JSON.parse(readFileSync29(p, "utf8"));
25859
+ const raw = JSON.parse(readFileSync30(p, "utf8"));
25214
25860
  if (raw.version)
25215
25861
  return raw.version;
25216
25862
  } catch {}
@@ -25221,21 +25867,21 @@ function readMmaVersion() {
25221
25867
  var init_version = () => {};
25222
25868
 
25223
25869
  // src/core/environment.ts
25224
- import { existsSync as existsSync48, readFileSync as readFileSync30, readdirSync as readdirSync16 } from "fs";
25870
+ import { existsSync as existsSync49, readFileSync as readFileSync31, readdirSync as readdirSync16 } from "fs";
25225
25871
  import { spawnSync as spawnSync3 } from "child_process";
25226
25872
  import { createRequire as createRequire2 } from "module";
25227
- import { join as join41, dirname as dirname16 } from "path";
25873
+ import { join as join43, dirname as dirname16 } from "path";
25228
25874
  import { fileURLToPath as fileURLToPath3 } from "url";
25229
25875
  import { arch, homedir as homedir12, hostname as hostname2, platform as platform10, release } from "os";
25230
25876
  import { env as env2 } from "process";
25231
25877
  function readEngineRequirement() {
25232
25878
  const here = dirname16(fileURLToPath3(import.meta.url));
25233
- const candidates = [join41(here, "..", "..", "package.json"), join41(here, "..", "package.json")];
25879
+ const candidates = [join43(here, "..", "..", "package.json"), join43(here, "..", "package.json")];
25234
25880
  for (const p of candidates) {
25235
- if (!existsSync48(p))
25881
+ if (!existsSync49(p))
25236
25882
  continue;
25237
25883
  try {
25238
- const raw = JSON.parse(readFileSync30(p, "utf8"));
25884
+ const raw = JSON.parse(readFileSync31(p, "utf8"));
25239
25885
  if (raw.engines?.node)
25240
25886
  return String(raw.engines.node);
25241
25887
  } catch {}
@@ -25298,7 +25944,7 @@ function toolVersion(cmd) {
25298
25944
  function playwrightBrowsersDir() {
25299
25945
  if (process.env.PLAYWRIGHT_BROWSERS_PATH)
25300
25946
  return process.env.PLAYWRIGHT_BROWSERS_PATH;
25301
- return process.platform === "win32" ? join41(homedir12(), "AppData", "Local", "ms-playwright") : join41(homedir12(), ".cache", "ms-playwright");
25947
+ return process.platform === "win32" ? join43(homedir12(), "AppData", "Local", "ms-playwright") : join43(homedir12(), ".cache", "ms-playwright");
25302
25948
  }
25303
25949
  function playwrightInfo() {
25304
25950
  let installed = false;
@@ -25307,14 +25953,14 @@ function playwrightInfo() {
25307
25953
  try {
25308
25954
  const require2 = createRequire2(import.meta.url);
25309
25955
  const pkgPath = require2.resolve("playwright/package.json");
25310
- installed = existsSync48(pkgPath);
25311
- version = JSON.parse(readFileSync30(pkgPath, "utf8")).version || "";
25956
+ installed = existsSync49(pkgPath);
25957
+ version = JSON.parse(readFileSync31(pkgPath, "utf8")).version || "";
25312
25958
  } catch {
25313
25959
  installed = false;
25314
25960
  }
25315
25961
  let browsersInstalled = false;
25316
25962
  try {
25317
- if (existsSync48(browsersDir)) {
25963
+ if (existsSync49(browsersDir)) {
25318
25964
  browsersInstalled = readdirSync16(browsersDir).some((d) => /chrom/i.test(d));
25319
25965
  }
25320
25966
  } catch {
@@ -25421,24 +26067,24 @@ __export(exports_manifest, {
25421
26067
  getCertMark: () => getCertMark,
25422
26068
  bundledManifestPath: () => bundledManifestPath
25423
26069
  });
25424
- import { existsSync as existsSync49, readFileSync as readFileSync31, mkdirSync as mkdirSync19, writeFileSync as writeFileSync18 } from "fs";
25425
- import { dirname as dirname17, join as join42 } from "path";
26070
+ import { existsSync as existsSync50, readFileSync as readFileSync32, mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "fs";
26071
+ import { dirname as dirname17, join as join44 } from "path";
25426
26072
  import { fileURLToPath as fileURLToPath4 } from "url";
25427
26073
  import { homedir as homedir13 } from "os";
25428
26074
  function manifestPath(projectDir) {
25429
- return join42(projectDir, "certification", "certifications.json");
26075
+ return join44(projectDir, "certification", "certifications.json");
25430
26076
  }
25431
26077
  function globalManifestDir(override) {
25432
- return override || process.env.MMA_CERT_HOME || join42(homedir13(), ".mma");
26078
+ return override || process.env.MMA_CERT_HOME || join44(homedir13(), ".mma");
25433
26079
  }
25434
26080
  function globalManifestPath(override) {
25435
- return join42(globalManifestDir(override), "certifications.json");
26081
+ return join44(globalManifestDir(override), "certifications.json");
25436
26082
  }
25437
26083
  function readManifest(projectDir) {
25438
26084
  const path = manifestPath(projectDir);
25439
26085
  try {
25440
- if (existsSync49(path)) {
25441
- const raw = JSON.parse(readFileSync31(path, "utf-8"));
26086
+ if (existsSync50(path)) {
26087
+ const raw = JSON.parse(readFileSync32(path, "utf-8"));
25442
26088
  return { version: 1, certifications: raw.certifications ?? [] };
25443
26089
  }
25444
26090
  } catch {}
@@ -25446,14 +26092,14 @@ function readManifest(projectDir) {
25446
26092
  }
25447
26093
  function saveManifest(m, projectDir) {
25448
26094
  const path = manifestPath(projectDir);
25449
- mkdirSync19(join42(projectDir, "certification"), { recursive: true });
25450
- writeFileSync18(path, JSON.stringify(m, null, 2), "utf-8");
26095
+ mkdirSync20(join44(projectDir, "certification"), { recursive: true });
26096
+ writeFileSync19(path, JSON.stringify(m, null, 2), "utf-8");
25451
26097
  }
25452
26098
  function readGlobalManifest(override) {
25453
26099
  const path = globalManifestPath(override);
25454
26100
  try {
25455
- if (existsSync49(path)) {
25456
- const raw = JSON.parse(readFileSync31(path, "utf-8"));
26101
+ if (existsSync50(path)) {
26102
+ const raw = JSON.parse(readFileSync32(path, "utf-8"));
25457
26103
  return { version: 1, certifications: raw.certifications ?? [] };
25458
26104
  }
25459
26105
  } catch {}
@@ -25461,8 +26107,8 @@ function readGlobalManifest(override) {
25461
26107
  }
25462
26108
  function saveGlobalManifest(m, override) {
25463
26109
  const dir = globalManifestDir(override);
25464
- mkdirSync19(dir, { recursive: true });
25465
- writeFileSync18(globalManifestPath(override), JSON.stringify(m, null, 2), "utf-8");
26110
+ mkdirSync20(dir, { recursive: true });
26111
+ writeFileSync19(globalManifestPath(override), JSON.stringify(m, null, 2), "utf-8");
25466
26112
  }
25467
26113
  function readMergedManifest(projectDir, override) {
25468
26114
  const merged = new Map;
@@ -25519,17 +26165,17 @@ function getCertMark(model, providerUrl, currentVersion, projectDir, globalOverr
25519
26165
  return isFullyPassed(entry) ? "certified" : "none";
25520
26166
  }
25521
26167
  function syncSnapshotPath(override) {
25522
- return join42(globalManifestDir(override), "certifications.synced.json");
26168
+ return join44(globalManifestDir(override), "certifications.synced.json");
25523
26169
  }
25524
26170
  function bundledManifestPath() {
25525
26171
  const here = dirname17(fileURLToPath4(import.meta.url));
25526
26172
  const candidates = [
25527
- join42(here, "certification", "certifications.json"),
25528
- join42(here, "..", "certification", "certifications.json"),
25529
- join42(here, "..", "..", "..", "certification", "certifications.json")
26173
+ join44(here, "certification", "certifications.json"),
26174
+ join44(here, "..", "certification", "certifications.json"),
26175
+ join44(here, "..", "..", "..", "certification", "certifications.json")
25530
26176
  ];
25531
26177
  for (const p of candidates) {
25532
- if (existsSync49(p))
26178
+ if (existsSync50(p))
25533
26179
  return p;
25534
26180
  }
25535
26181
  return null;
@@ -25537,11 +26183,11 @@ function bundledManifestPath() {
25537
26183
  function syncGlobalManifest(override, bundledPathOverride) {
25538
26184
  try {
25539
26185
  const bundledPath = bundledPathOverride ?? bundledManifestPath();
25540
- if (!bundledPath || !existsSync49(bundledPath))
26186
+ if (!bundledPath || !existsSync50(bundledPath))
25541
26187
  return { synced: false, reason: "no-bundled" };
25542
- const raw = readFileSync31(bundledPath, "utf-8");
26188
+ const raw = readFileSync32(bundledPath, "utf-8");
25543
26189
  const snapshotPath = syncSnapshotPath(override);
25544
- if (existsSync49(snapshotPath) && readFileSync31(snapshotPath, "utf-8") === raw) {
26190
+ if (existsSync50(snapshotPath) && readFileSync32(snapshotPath, "utf-8") === raw) {
25545
26191
  return { synced: false, reason: "unchanged" };
25546
26192
  }
25547
26193
  const bundled = JSON.parse(raw);
@@ -25552,8 +26198,8 @@ function syncGlobalManifest(override, bundledPathOverride) {
25552
26198
  for (const e of bundled.certifications ?? [])
25553
26199
  merged.set(certKey(e), e);
25554
26200
  saveGlobalManifest({ version: 1, certifications: [...merged.values()] }, override);
25555
- mkdirSync19(globalManifestDir(override), { recursive: true });
25556
- writeFileSync18(snapshotPath, raw, "utf-8");
26201
+ mkdirSync20(globalManifestDir(override), { recursive: true });
26202
+ writeFileSync19(snapshotPath, raw, "utf-8");
25557
26203
  return { synced: true, reason: "synced" };
25558
26204
  } catch {
25559
26205
  return { synced: false, reason: "error" };
@@ -25569,13 +26215,13 @@ __export(exports_probe, {
25569
26215
  resetProbeCache: () => resetProbeCache,
25570
26216
  probeReasoningSupport: () => probeReasoningSupport,
25571
26217
  getCachedProbeResult: () => getCachedProbeResult,
25572
- cacheKey: () => cacheKey
26218
+ cacheKey: () => cacheKey2
25573
26219
  });
25574
- import { existsSync as existsSync50, readFileSync as readFileSync32, writeFileSync as writeFileSync19, mkdirSync as mkdirSync20 } from "fs";
25575
- import { join as join43, dirname as dirname18 } from "path";
26220
+ import { existsSync as existsSync51, readFileSync as readFileSync33, writeFileSync as writeFileSync20, mkdirSync as mkdirSync21 } from "fs";
26221
+ import { join as join45, dirname as dirname18 } from "path";
25576
26222
  import { homedir as homedir14 } from "os";
25577
26223
  function cachePath() {
25578
- return join43(homedir14(), ".mma", "reasoning-cache.json");
26224
+ return join45(homedir14(), ".mma", "reasoning-cache.json");
25579
26225
  }
25580
26226
  async function probeReasoningSupport(provider, strategy, signal) {
25581
26227
  if (strategy === "none")
@@ -25595,7 +26241,7 @@ async function probeReasoningSupport(provider, strategy, signal) {
25595
26241
  return null;
25596
26242
  }
25597
26243
  }
25598
- function cacheKey(baseUrl, model) {
26244
+ function cacheKey2(baseUrl, model) {
25599
26245
  return `${baseUrl}|${model}`;
25600
26246
  }
25601
26247
  function getCachedProbeResult(key) {
@@ -25624,15 +26270,15 @@ function setCachedProbeResult(key, result) {
25624
26270
  function resetProbeCache() {
25625
26271
  memCache.clear();
25626
26272
  const path = cachePath();
25627
- if (existsSync50(path)) {
25628
- writeFileSync19(path, "{}", "utf-8");
26273
+ if (existsSync51(path)) {
26274
+ writeFileSync20(path, "{}", "utf-8");
25629
26275
  }
25630
26276
  }
25631
26277
  function readDiskCache() {
25632
26278
  try {
25633
26279
  const path = cachePath();
25634
- if (existsSync50(path)) {
25635
- return JSON.parse(readFileSync32(path, "utf-8"));
26280
+ if (existsSync51(path)) {
26281
+ return JSON.parse(readFileSync33(path, "utf-8"));
25636
26282
  }
25637
26283
  } catch {}
25638
26284
  return {};
@@ -25640,8 +26286,8 @@ function readDiskCache() {
25640
26286
  function writeDiskCache(data) {
25641
26287
  try {
25642
26288
  const path = cachePath();
25643
- mkdirSync20(dirname18(path), { recursive: true });
25644
- writeFileSync19(path, JSON.stringify(data, null, 2), "utf-8");
26289
+ mkdirSync21(dirname18(path), { recursive: true });
26290
+ writeFileSync20(path, JSON.stringify(data, null, 2), "utf-8");
25645
26291
  } catch {}
25646
26292
  }
25647
26293
  var PROBE_MESSAGES, CACHE_TTL_MS, memCache;
@@ -25733,8 +26379,8 @@ __export(exports_bootstrap, {
25733
26379
  bootstrap: () => bootstrap
25734
26380
  });
25735
26381
  import { homedir as homedir15 } from "os";
25736
- import { join as join44, resolve as resolve22 } from "path";
25737
- import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
26382
+ import { join as join46, resolve as resolve22 } from "path";
26383
+ import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
25738
26384
  function applyReasoningCliOverride(config, reasoningLevel) {
25739
26385
  if (!reasoningLevel || reasoningLevel === "auto")
25740
26386
  return;
@@ -25760,19 +26406,20 @@ function loadAgentsMdBlocks(baseDir, dir, skip) {
25760
26406
  return [];
25761
26407
  const blocks = [];
25762
26408
  const candidates = [
25763
- join44(baseDir, "AGENTS.md"),
25764
- join44(baseDir, ".mma", "AGENTS.md"),
25765
- join44(dir, "AGENTS.md")
26409
+ join46(baseDir, "AGENTS.md"),
26410
+ join46(baseDir, ".mma", "AGENTS.md"),
26411
+ join46(dir, "AGENTS.md")
25766
26412
  ];
25767
26413
  for (const p of candidates) {
25768
- if (existsSync51(p)) {
25769
- const content = readFileSync33(p, "utf-8").trim();
26414
+ if (existsSync52(p)) {
26415
+ const content = readFileSync34(p, "utf-8").trim();
25770
26416
  if (content) {
25771
26417
  blocks.push({
25772
26418
  content,
25773
26419
  priority: "high",
25774
26420
  essential: false,
25775
- estimatedTokens: estimateTokens(content)
26421
+ estimatedTokens: estimateTokens(content),
26422
+ kind: "instructions"
25776
26423
  });
25777
26424
  }
25778
26425
  }
@@ -25843,8 +26490,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
25843
26490
  `);
25844
26491
  }
25845
26492
  async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reasoningLevel) {
25846
- const dir = configDir || process.env.MMA_CONFIG_DIR || join44(homedir15(), ".mma");
25847
- const projectConfigPath = projectDir ? join44(projectDir, ".mmrc") : join44(process.cwd(), ".mmrc");
26493
+ const dir = configDir || process.env.MMA_CONFIG_DIR || join46(homedir15(), ".mma");
26494
+ const projectConfigPath = projectDir ? join46(projectDir, ".mmrc") : join46(process.cwd(), ".mmrc");
25848
26495
  const { config, legacyDetected } = loadConfig({ configDir: dir, projectConfigPath });
25849
26496
  setLocale(config.locale);
25850
26497
  applyReasoningCliOverride(config, reasoningLevel);
@@ -25855,7 +26502,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
25855
26502
  }
25856
26503
  } catch {}
25857
26504
  const logger4 = new Logger(config.logLevel);
25858
- logger4.setLogDir(join44(dir, "logs"));
26505
+ logger4.setLogDir(join46(dir, "logs"));
25859
26506
  logger4.debug("MMA bootstrap", {
25860
26507
  version: config.version,
25861
26508
  model: config.model
@@ -25884,7 +26531,24 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
25884
26531
  logger4.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
25885
26532
  }
25886
26533
  }
25887
- const profile = new UserProfile(join44(dir));
26534
+ const contextProbePromise = (async () => {
26535
+ try {
26536
+ const probe = await getLoadedContextLength(config.provider.baseUrl, config.model);
26537
+ if (!probe)
26538
+ return null;
26539
+ if (probe.actual < config.contextWindow) {
26540
+ logger4.warn(`Context probe: model "${probe.model}" is loaded with ${probe.actual} tokens, but contextWindow is configured as ${config.contextWindow} — overflow/429 risk. Lower contextWindow or reload the model with a larger context.`);
26541
+ } else if (probe.actual > config.contextWindow) {
26542
+ logger4.info(`Context probe: model "${probe.model}" supports ${probe.actual} tokens — consider "mma context ${probe.actual}" to use the full window.`);
26543
+ } else {
26544
+ logger4.debug(`Context probe: configured contextWindow matches loaded context (${probe.actual})`);
26545
+ }
26546
+ return probe;
26547
+ } catch {
26548
+ return null;
26549
+ }
26550
+ })();
26551
+ const profile = new UserProfile(join46(dir));
25888
26552
  profile.load() || profile.collect();
25889
26553
  profile.save();
25890
26554
  const llmProvider = buildActiveProvider(config, logger4).provider;
@@ -25918,7 +26582,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
25918
26582
  for (const warning of envReport.warnings) {
25919
26583
  logger4.warn(warning);
25920
26584
  }
25921
- const projectMapCacheDir = join44(baseDir, ".mma");
26585
+ const projectMapCacheDir = join46(baseDir, ".mma");
25922
26586
  const indexerModule = new IndexerModule({
25923
26587
  baseDir,
25924
26588
  cacheDir: projectMapCacheDir
@@ -25929,9 +26593,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
25929
26593
  logger4.warn(`Project indexing failed: ${err.message}`);
25930
26594
  }
25931
26595
  const skillsLoader = new SkillsLoader;
25932
- const builtinDir = join44(import.meta.dirname, "skills", "builtin");
25933
- const globalDir = join44(homedir15(), ".agents", "skills");
25934
- const projectSkillsDir = join44(baseDir, ".mma", "skills");
26596
+ const builtinDir = join46(import.meta.dirname, "skills", "builtin");
26597
+ const globalDir = join46(homedir15(), ".agents", "skills");
26598
+ const projectSkillsDir = join46(baseDir, ".mma", "skills");
25935
26599
  const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
25936
26600
  const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
25937
26601
  const skillsModule = new SkillsModule(availableSkills, skillsBudget);
@@ -25947,7 +26611,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
25947
26611
  essential: true,
25948
26612
  estimatedTokens: estimateTokens(systemInfoContent)
25949
26613
  };
25950
- const sessionDir = join44(dir, "sessions");
26614
+ const sessionDir = join46(dir, "sessions");
25951
26615
  const sessionStore = new SessionStore(sessionDir);
25952
26616
  sessionStore.init();
25953
26617
  const sessionManager = new SessionManager(sessionStore, {
@@ -26010,6 +26674,10 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26010
26674
  get: () => sessionManager.getSessionContext() ?? undefined,
26011
26675
  configurable: true
26012
26676
  });
26677
+ Object.defineProperty(toolCtx, "sessionManager", {
26678
+ get: () => sessionManager,
26679
+ configurable: true
26680
+ });
26013
26681
  const toolExecutor = new ToolExecutor(toolRegistry, toolCtx, pluginManager);
26014
26682
  toolCtx.llmProvider = llmProvider;
26015
26683
  toolCtx.toolExecutor = toolExecutor;
@@ -26031,7 +26699,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26031
26699
  logger4.warn(`MCP init failed or timed out (${err instanceof Error ? err.message.slice(0, 120) : String(err)}) — continuing without MCP tools.`);
26032
26700
  }
26033
26701
  moduleRegistry.register(mcpModule);
26034
- const memoryStore = new MemoryStore(join44(dir, "memory"));
26702
+ const memoryStore = new MemoryStore(join46(dir, "memory"));
26035
26703
  const memoryModule = new MemoryModule(memoryStore);
26036
26704
  moduleRegistry.register(memoryModule);
26037
26705
  if (config.browser.enabled) {
@@ -26058,8 +26726,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26058
26726
  pluginManager.register(plugin);
26059
26727
  pluginManager.register(plugin2);
26060
26728
  const pluginLoader = new PluginLoader;
26061
- const globalPluginsDir = join44(homedir15(), ".mma", "plugins");
26062
- const projectPluginsDir = join44(baseDir, ".mma", "plugins");
26729
+ const globalPluginsDir = join46(homedir15(), ".mma", "plugins");
26730
+ const projectPluginsDir = join46(baseDir, ".mma", "plugins");
26063
26731
  const mmaVersion = readMmaVersion();
26064
26732
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger4, {
26065
26733
  source: "global",
@@ -26084,7 +26752,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26084
26752
  const agentsMdBlocks = loadAgentsMdBlocks(baseDir, dir, noAgentsMd === true);
26085
26753
  const promptBlocks = [
26086
26754
  systemInfoPrompt,
26087
- ...moduleRegistry.collectPromptBlocks(["indexer"]),
26755
+ ...moduleRegistry.collectPromptBlocks(["indexer", "session"]),
26088
26756
  ...agentsMdBlocks,
26089
26757
  {
26090
26758
  content: "[Plan Reminder] An active plan may exist for this session. Before creating a new plan, check with `plan show`. If a plan is active, continue it — do NOT create a new plan.",
@@ -26093,6 +26761,39 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26093
26761
  estimatedTokens: 50
26094
26762
  }
26095
26763
  ];
26764
+ {
26765
+ const dynamicBlocks = [];
26766
+ const skillsBlock = skillsModule.getSystemPromptBlock();
26767
+ if (skillsBlock)
26768
+ dynamicBlocks.push(skillsBlock);
26769
+ const mapBlock = indexerModule.getSystemPromptBlock();
26770
+ if (mapBlock)
26771
+ dynamicBlocks.push(mapBlock);
26772
+ const hiddenToolsBlock = buildHiddenToolsBlock(toolRegistry.getAll(), activeToolTags);
26773
+ if (hiddenToolsBlock) {
26774
+ dynamicBlocks.push({
26775
+ content: hiddenToolsBlock,
26776
+ priority: "low",
26777
+ essential: false,
26778
+ estimatedTokens: estimateTokens(hiddenToolsBlock)
26779
+ });
26780
+ }
26781
+ const systemBudget = Math.floor(config.contextWindow * config.contextBudget.systemPrompt);
26782
+ const dry = dryRunOverflow([...promptBlocks, ...dynamicBlocks], systemBudget);
26783
+ if (dry.overflow.length > 0) {
26784
+ const overflowTokens = dry.overflow.reduce((s, b) => s + b.estimatedTokens, 0);
26785
+ const recommended = recommendContextSize(dry.includedTokens + overflowTokens);
26786
+ const hint = contextWindowHint(config, dir, recommended);
26787
+ for (const b of dry.overflow) {
26788
+ logger4.warn(t("prompt.overflow.startup", {
26789
+ block: b.kind === "instructions" ? "AGENTS.md" : "project map",
26790
+ original: String(b.estimatedTokens),
26791
+ budget: String(systemBudget),
26792
+ hint
26793
+ }));
26794
+ }
26795
+ }
26796
+ }
26096
26797
  const agentDeps = {
26097
26798
  config,
26098
26799
  configRef,
@@ -26103,6 +26804,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26103
26804
  hallucinationDetector,
26104
26805
  logger: logger4,
26105
26806
  baseDir,
26807
+ configDir: dir,
26106
26808
  toolTags: activeToolTags,
26107
26809
  promptBlocks,
26108
26810
  envReport,
@@ -26111,6 +26813,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26111
26813
  const skillsBlock = skillsModule.getSystemPromptBlock();
26112
26814
  if (skillsBlock)
26113
26815
  blocks.push(skillsBlock);
26816
+ const sessionBlock = sessionModule.getSystemPromptBlock();
26817
+ if (sessionBlock)
26818
+ blocks.push(sessionBlock);
26114
26819
  const mapBlock = indexerModule.getSystemPromptBlock();
26115
26820
  if (mapBlock)
26116
26821
  blocks.push(mapBlock);
@@ -26159,7 +26864,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete, reas
26159
26864
  baseDir,
26160
26865
  noAgentsMd: noAgentsMd === true,
26161
26866
  envReport,
26162
- legacyDetected
26867
+ legacyDetected,
26868
+ contextProbe: contextProbePromise
26163
26869
  };
26164
26870
  }
26165
26871
  var init_bootstrap = __esm(() => {
@@ -26192,6 +26898,7 @@ var init_bootstrap = __esm(() => {
26192
26898
  init_agent();
26193
26899
  init_version();
26194
26900
  init_environment();
26901
+ init_prompt_overflow();
26195
26902
  });
26196
26903
 
26197
26904
  // node_modules/ansi-regex/index.js
@@ -26946,6 +27653,41 @@ var init_setup = __esm(() => {
26946
27653
  ];
26947
27654
  });
26948
27655
 
27656
+ // src/modules/indexer/map-command.ts
27657
+ async function runMapAction(module, action, query) {
27658
+ const summary = async () => {
27659
+ const result = await module.buildIndex();
27660
+ if (!result)
27661
+ return { ok: false, output: t("indexer.not_indexed") };
27662
+ return { ok: true, output: module.getPromptMap() ?? t("indexer.not_indexed") };
27663
+ };
27664
+ switch (action) {
27665
+ case "refresh": {
27666
+ const result = await module.refresh();
27667
+ if (!result)
27668
+ return { ok: false, output: t("indexer.not_indexed") };
27669
+ return {
27670
+ ok: true,
27671
+ output: `${t("map.refreshed")}
27672
+ ${module.getPromptMap() ?? ""}`.trimEnd()
27673
+ };
27674
+ }
27675
+ case "find": {
27676
+ const q = (query ?? "").trim();
27677
+ if (!q)
27678
+ return { ok: false, output: t("map.find_usage") };
27679
+ await module.buildIndex();
27680
+ return { ok: true, output: module.formatFind(q) };
27681
+ }
27682
+ case "summary":
27683
+ default:
27684
+ return summary();
27685
+ }
27686
+ }
27687
+ var init_map_command = __esm(() => {
27688
+ init_i18n();
27689
+ });
27690
+
26949
27691
  // node_modules/yaml/dist/nodes/identity.js
26950
27692
  var require_identity = __commonJS((exports) => {
26951
27693
  var ALIAS = Symbol.for("yaml.alias");
@@ -34505,8 +35247,8 @@ var init_scenarios = __esm(() => {
34505
35247
  });
34506
35248
 
34507
35249
  // src/modules/certification/loader.ts
34508
- import { existsSync as existsSync53, readdirSync as readdirSync17, readFileSync as readFileSync35 } from "fs";
34509
- import { join as join47 } from "path";
35250
+ import { existsSync as existsSync54, readdirSync as readdirSync17, readFileSync as readFileSync36 } from "fs";
35251
+ import { join as join49 } from "path";
34510
35252
  function validateScenario(s) {
34511
35253
  const errors2 = [];
34512
35254
  const isSkip = s.mode === "skip";
@@ -34558,12 +35300,12 @@ function loadScenarios(userDir) {
34558
35300
  else
34559
35301
  scenarios.push(s);
34560
35302
  }
34561
- if (userDir && existsSync53(userDir)) {
35303
+ if (userDir && existsSync54(userDir)) {
34562
35304
  for (const file of readdirSync17(userDir)) {
34563
35305
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
34564
35306
  continue;
34565
35307
  try {
34566
- const raw = readFileSync35(join47(userDir, file), "utf-8");
35308
+ const raw = readFileSync36(join49(userDir, file), "utf-8");
34567
35309
  const data = $parse(raw);
34568
35310
  const parsed = normalizeScenario(data, file);
34569
35311
  const errs = validateScenario(parsed);
@@ -34626,8 +35368,8 @@ var init_loader3 = __esm(() => {
34626
35368
  });
34627
35369
 
34628
35370
  // src/modules/certification/fact-checker.ts
34629
- import { existsSync as existsSync54, readFileSync as readFileSync36, statSync as statSync9 } from "fs";
34630
- import { join as join48 } from "path";
35371
+ import { existsSync as existsSync55, readFileSync as readFileSync37, statSync as statSync9 } from "fs";
35372
+ import { join as join50 } from "path";
34631
35373
  function checkSandbox(sandboxDir, checks, exitCode, output) {
34632
35374
  const failures = [];
34633
35375
  for (const check of checks) {
@@ -34644,16 +35386,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
34644
35386
  case "outputContains":
34645
35387
  return output.includes(check.text);
34646
35388
  case "fileExists":
34647
- return isFile(join48(sandboxDir, check.path));
35389
+ return isFile(join50(sandboxDir, check.path));
34648
35390
  case "fileNotExists":
34649
- return !existsSync54(join48(sandboxDir, check.path));
35391
+ return !existsSync55(join50(sandboxDir, check.path));
34650
35392
  case "dirExists":
34651
- return isDir(join48(sandboxDir, check.path));
35393
+ return isDir(join50(sandboxDir, check.path));
34652
35394
  case "fileContent": {
34653
- const abs = join48(sandboxDir, check.path);
35395
+ const abs = join50(sandboxDir, check.path);
34654
35396
  if (!isFile(abs))
34655
35397
  return false;
34656
- const content = readFileSync36(abs, "utf-8");
35398
+ const content = readFileSync37(abs, "utf-8");
34657
35399
  if (check.contains !== undefined)
34658
35400
  return content.includes(check.contains);
34659
35401
  if (check.equals !== undefined)
@@ -34661,10 +35403,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
34661
35403
  return false;
34662
35404
  }
34663
35405
  case "fileRegex": {
34664
- const abs = join48(sandboxDir, check.path);
35406
+ const abs = join50(sandboxDir, check.path);
34665
35407
  if (!isFile(abs))
34666
35408
  return false;
34667
- return new RegExp(check.pattern).test(readFileSync36(abs, "utf-8"));
35409
+ return new RegExp(check.pattern).test(readFileSync37(abs, "utf-8"));
34668
35410
  }
34669
35411
  default:
34670
35412
  return false;
@@ -34672,14 +35414,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
34672
35414
  }
34673
35415
  function isFile(p) {
34674
35416
  try {
34675
- return existsSync54(p) && statSync9(p).isFile();
35417
+ return existsSync55(p) && statSync9(p).isFile();
34676
35418
  } catch {
34677
35419
  return false;
34678
35420
  }
34679
35421
  }
34680
35422
  function isDir(p) {
34681
35423
  try {
34682
- return existsSync54(p) && statSync9(p).isDirectory();
35424
+ return existsSync55(p) && statSync9(p).isDirectory();
34683
35425
  } catch {
34684
35426
  return false;
34685
35427
  }
@@ -34710,8 +35452,8 @@ var init_fact_checker = () => {};
34710
35452
 
34711
35453
  // src/modules/certification/runner.ts
34712
35454
  import { spawn as spawn10 } from "child_process";
34713
- import { existsSync as existsSync55, mkdirSync as mkdirSync21, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync21, readdirSync as readdirSync18, readFileSync as readFileSync37 } from "fs";
34714
- import { join as join49, resolve as resolve23, dirname as dirname21, relative as relative7 } from "path";
35455
+ import { existsSync as existsSync56, mkdirSync as mkdirSync22, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync22, readdirSync as readdirSync18, readFileSync as readFileSync38 } from "fs";
35456
+ import { join as join51, resolve as resolve23, dirname as dirname21, relative as relative7 } from "path";
34715
35457
  async function runScenario(scenario, opts) {
34716
35458
  if (scenario.mode === "skip") {
34717
35459
  return {
@@ -34731,7 +35473,7 @@ async function runScenario(scenario, opts) {
34731
35473
  let firstError;
34732
35474
  let lastFailedSandbox;
34733
35475
  for (let i = 1;i <= reps; i++) {
34734
- const sandbox = join49(opts.sandboxBase, `run-${scenario.id}-${i}`);
35476
+ const sandbox = join51(opts.sandboxBase, `run-${scenario.id}-${i}`);
34735
35477
  let failures = [];
34736
35478
  let exitCode = -1;
34737
35479
  let output = "";
@@ -34755,9 +35497,9 @@ async function runScenario(scenario, opts) {
34755
35497
  env3.MMA_PROVIDER_APIKEY = opts.providerKey;
34756
35498
  if (scenario.config && opts.baseConfig) {
34757
35499
  const merged = deepMergeAny(opts.baseConfig, scenario.config);
34758
- const certConfigDir = join49(sandbox, ".mma");
34759
- mkdirSync21(certConfigDir, { recursive: true });
34760
- writeFileSync21(join49(certConfigDir, "config.json"), JSON.stringify(merged, null, 2), "utf-8");
35500
+ const certConfigDir = join51(sandbox, ".mma");
35501
+ mkdirSync22(certConfigDir, { recursive: true });
35502
+ writeFileSync22(join51(certConfigDir, "config.json"), JSON.stringify(merged, null, 2), "utf-8");
34761
35503
  env3.MMA_CONFIG_DIR = certConfigDir;
34762
35504
  }
34763
35505
  const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
@@ -34802,14 +35544,14 @@ ${res.stderr}`;
34802
35544
  }
34803
35545
  function prepareSandbox(sandbox, scenario, mmaRoot) {
34804
35546
  rmSync4(sandbox, { recursive: true, force: true });
34805
- mkdirSync21(sandbox, { recursive: true });
35547
+ mkdirSync22(sandbox, { recursive: true });
34806
35548
  for (const f of scenario.fixtures ?? []) {
34807
- const src = join49(mmaRoot, f.source);
34808
- if (!existsSync55(src)) {
35549
+ const src = join51(mmaRoot, f.source);
35550
+ if (!existsSync56(src)) {
34809
35551
  throw new Error(`fixture missing: ${f.source}`);
34810
35552
  }
34811
- const dest = join49(sandbox, f.dest);
34812
- mkdirSync21(dirname21(dest), { recursive: true });
35553
+ const dest = join51(sandbox, f.dest);
35554
+ mkdirSync22(dirname21(dest), { recursive: true });
34813
35555
  cpSync2(src, dest);
34814
35556
  }
34815
35557
  }
@@ -34821,10 +35563,10 @@ function collectDiagnostics(sandbox) {
34821
35563
  } else {
34822
35564
  lines.push(" Files created: (none)");
34823
35565
  }
34824
- const planPath = join49(sandbox, ".mma", "plans", "active.json");
34825
- if (existsSync55(planPath)) {
35566
+ const planPath = join51(sandbox, ".mma", "plans", "active.json");
35567
+ if (existsSync56(planPath)) {
34826
35568
  try {
34827
- const plan = JSON.parse(readFileSync37(planPath, "utf-8"));
35569
+ const plan = JSON.parse(readFileSync38(planPath, "utf-8"));
34828
35570
  const steps = plan.steps ?? [];
34829
35571
  const done = steps.filter((s) => s.status === "done").length;
34830
35572
  const pending = steps.filter((s) => s.status === "pending" || s.status === "in_progress");
@@ -34843,7 +35585,7 @@ function listFiles(dir, root) {
34843
35585
  for (const entry of readdirSync18(dir, { withFileTypes: true })) {
34844
35586
  if (entry.name === ".mma")
34845
35587
  continue;
34846
- const abs = join49(dir, entry.name);
35588
+ const abs = join51(dir, entry.name);
34847
35589
  const rel = toForwardSlash(relative7(root, abs));
34848
35590
  if (entry.isDirectory()) {
34849
35591
  result.push(...listFiles(abs, root));
@@ -34855,15 +35597,15 @@ function listFiles(dir, root) {
34855
35597
  return result;
34856
35598
  }
34857
35599
  function resolveMmaEntry(mmaRoot) {
34858
- const dev = join49(mmaRoot, "src", "cli", "main.ts");
34859
- if (existsSync55(dev))
35600
+ const dev = join51(mmaRoot, "src", "cli", "main.ts");
35601
+ if (existsSync56(dev))
34860
35602
  return dev;
34861
- return join49(mmaRoot, "dist", "main.js");
35603
+ return join51(mmaRoot, "dist", "main.js");
34862
35604
  }
34863
35605
  function findMmaRoot(fromDir) {
34864
35606
  const candidates = [resolve23(fromDir, "..", "..", ".."), resolve23(fromDir, "..")];
34865
35607
  for (const c of candidates) {
34866
- if (existsSync55(join49(c, "package.json")))
35608
+ if (existsSync56(join51(c, "package.json")))
34867
35609
  return c;
34868
35610
  }
34869
35611
  return process.cwd();
@@ -34930,16 +35672,16 @@ __export(exports_cli, {
34930
35672
  certStatus: () => certStatus,
34931
35673
  certList: () => certList
34932
35674
  });
34933
- import { rmSync as rmSync5, writeFileSync as writeFileSync22 } from "fs";
34934
- import { join as join50, dirname as dirname22 } from "path";
35675
+ import { rmSync as rmSync5, writeFileSync as writeFileSync23 } from "fs";
35676
+ import { join as join52, dirname as dirname22 } from "path";
34935
35677
  import { fileURLToPath as fileURLToPath5 } from "url";
34936
- import { existsSync as existsSync56, readFileSync as readFileSync38 } from "fs";
35678
+ import { existsSync as existsSync57, readFileSync as readFileSync39 } from "fs";
34937
35679
  function readVersion() {
34938
- const candidates = [join50(MMA_ROOT, "package.json")];
35680
+ const candidates = [join52(MMA_ROOT, "package.json")];
34939
35681
  for (const p of candidates) {
34940
- if (existsSync56(p)) {
35682
+ if (existsSync57(p)) {
34941
35683
  try {
34942
- const raw = JSON.parse(readFileSync38(p, "utf-8"));
35684
+ const raw = JSON.parse(readFileSync39(p, "utf-8"));
34943
35685
  if (raw.version)
34944
35686
  return raw.version;
34945
35687
  } catch {}
@@ -34952,7 +35694,7 @@ function parseTags(s) {
34952
35694
  }
34953
35695
  async function certify(opts) {
34954
35696
  const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
34955
- const { scenarios, errors: errors2 } = loadScenarios(join50(opts.projectDir, ".mma", "certification", "scenarios"));
35697
+ const { scenarios, errors: errors2 } = loadScenarios(join52(opts.projectDir, ".mma", "certification", "scenarios"));
34956
35698
  for (const e of errors2)
34957
35699
  console.error(pc2.yellow(` ${e}`));
34958
35700
  let selected = filterByTags(scenarios, opts.tags);
@@ -34983,7 +35725,7 @@ async function certify(opts) {
34983
35725
  return;
34984
35726
  }
34985
35727
  console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
34986
- const sandboxBase = join50(process.cwd(), ".mma", "certification");
35728
+ const sandboxBase = join52(process.cwd(), ".mma", "certification");
34987
35729
  const results = [];
34988
35730
  const total = selected.length;
34989
35731
  let idx = 0;
@@ -35116,10 +35858,10 @@ function printResults(results) {
35116
35858
  }
35117
35859
  }
35118
35860
  function writeReport(entry, projectDir) {
35119
- const reportDir = join50(projectDir, "certification");
35861
+ const reportDir = join52(projectDir, "certification");
35120
35862
  const ts = entry.certifiedAt.replace(/[:.]/g, "-").slice(0, 19);
35121
35863
  const filename = `report-${entry.model.replace(/[/\\:]/g, "_")}-${ts}.json`;
35122
- const reportPath = join50(reportDir, filename);
35864
+ const reportPath = join52(reportDir, filename);
35123
35865
  const report = {
35124
35866
  model: entry.model,
35125
35867
  providerUrl: entry.providerUrl,
@@ -35138,7 +35880,7 @@ function writeReport(entry, projectDir) {
35138
35880
  }))
35139
35881
  };
35140
35882
  try {
35141
- writeFileSync22(reportPath, JSON.stringify(report, null, 2), "utf-8");
35883
+ writeFileSync23(reportPath, JSON.stringify(report, null, 2), "utf-8");
35142
35884
  console.log(pc2.dim(`
35143
35885
  Report: ${reportPath}`));
35144
35886
  } catch (e) {
@@ -35162,8 +35904,8 @@ __export(exports_repl_commands, {
35162
35904
  registerAllCommands: () => registerAllCommands,
35163
35905
  COMMAND_GROUPS: () => COMMAND_GROUPS
35164
35906
  });
35165
- import { join as join52, dirname as dirname24 } from "path";
35166
- import { existsSync as existsSync58 } from "fs";
35907
+ import { join as join54, dirname as dirname24 } from "path";
35908
+ import { existsSync as existsSync59 } from "fs";
35167
35909
  function registerAllCommands(ctx) {
35168
35910
  registerBuiltinCommands(ctx);
35169
35911
  registerMmaCommands(ctx);
@@ -35220,7 +35962,7 @@ function registerRunCommands(ctx) {
35220
35962
  }
35221
35963
  try {
35222
35964
  const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
35223
- const { existsSync: existsSync59 } = await import("fs");
35965
+ const { existsSync: existsSync60 } = await import("fs");
35224
35966
  const { resolve: resolve24 } = await import("path");
35225
35967
  let dataUrl;
35226
35968
  let label;
@@ -35240,7 +35982,7 @@ function registerRunCommands(ctx) {
35240
35982
  label = source;
35241
35983
  } else {
35242
35984
  const absPath = resolve24(process.cwd(), source);
35243
- if (!existsSync59(absPath)) {
35985
+ if (!existsSync60(absPath)) {
35244
35986
  console.log(pc2.red(t("image.not_found", { path: source })));
35245
35987
  return;
35246
35988
  }
@@ -35345,7 +36087,7 @@ function registerConfigCommands(ctx) {
35345
36087
  console.log(pc2.yellow(t("repl.wizard_running")));
35346
36088
  await ctx.withExclusiveInput(async () => {
35347
36089
  const answers = await runSetup(ctx.rl);
35348
- const configPath = join52(ctx.configDir, "config.json");
36090
+ const configPath = join54(ctx.configDir, "config.json");
35349
36091
  ctx.config.provider.type = answers.provider;
35350
36092
  ctx.config.provider.baseUrl = answers.apiBase;
35351
36093
  ctx.config.provider.apiKey = answers.apiKey;
@@ -35380,6 +36122,22 @@ function registerConfigCommands(ctx) {
35380
36122
  }
35381
36123
  }
35382
36124
  });
36125
+ ctx.registerCommand({
36126
+ name: "map",
36127
+ description: t("repl.map"),
36128
+ usage: t("repl.map_usage"),
36129
+ action: async (args) => {
36130
+ const indexer = ctx.agent.getModule("indexer");
36131
+ if (!indexer) {
36132
+ console.log(pc2.yellow(t("indexer.not_indexed")));
36133
+ return;
36134
+ }
36135
+ const action = args[0] || "summary";
36136
+ const query = args.slice(1).join(" ");
36137
+ const result = await runMapAction(indexer, action, query);
36138
+ console.log(result.output);
36139
+ }
36140
+ });
35383
36141
  }
35384
36142
  function registerProviderCommands(ctx) {
35385
36143
  ctx.registerCommand({
@@ -35469,7 +36227,7 @@ function registerProviderCommands(ctx) {
35469
36227
  return;
35470
36228
  }
35471
36229
  ctx.config.model = name;
35472
- const configPath = join52(ctx.configDir, "config.json");
36230
+ const configPath = join54(ctx.configDir, "config.json");
35473
36231
  saveConfig(ctx.config, configPath, dirname24(configPath));
35474
36232
  await ctx.agent.reconfigure(ctx.config);
35475
36233
  console.log(pc2.green(t("repl.model_set", { name })));
@@ -35494,7 +36252,7 @@ function registerProviderCommands(ctx) {
35494
36252
  return;
35495
36253
  }
35496
36254
  ctx.config.contextWindow = size;
35497
- const configPath = join52(ctx.configDir, "config.json");
36255
+ const configPath = join54(ctx.configDir, "config.json");
35498
36256
  saveConfig(ctx.config, configPath, dirname24(configPath));
35499
36257
  await ctx.agent.reconfigure(ctx.config);
35500
36258
  console.log(pc2.green(t("cli.context_set", { size })));
@@ -35858,21 +36616,21 @@ async function runConfigMigrate(ctx) {
35858
36616
  const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
35859
36617
  const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_config2(), exports_config));
35860
36618
  const configDir = ctx.configDir;
35861
- const configPath = join52(configDir, "config.json");
36619
+ const configPath = join54(configDir, "config.json");
35862
36620
  if (hasDomainFiles3(configDir)) {
35863
36621
  console.log(pc2.yellow(t("config.migrate_no_legacy")));
35864
36622
  return;
35865
36623
  }
35866
- if (!existsSync58(configPath)) {
36624
+ if (!existsSync59(configPath)) {
35867
36625
  console.log(pc2.yellow(t("config.migrate_no_legacy")));
35868
36626
  return;
35869
36627
  }
35870
36628
  console.log(t("config.migrate_start"));
35871
- const { config } = loadCfg({ configDir, projectConfigPath: join52(configDir, ".mmrc") });
36629
+ const { config } = loadCfg({ configDir, projectConfigPath: join54(configDir, ".mmrc") });
35872
36630
  saveConfig(config, configPath, configDir);
35873
36631
  const { renameSync: renameSync4, readdirSync: readdirSync19 } = await import("fs");
35874
36632
  renameSync4(configPath, configPath + ".bak");
35875
- const domainFiles = readdirSync19(join52(configDir, "config")).filter((f) => f.endsWith(".json"));
36633
+ const domainFiles = readdirSync19(join54(configDir, "config")).filter((f) => f.endsWith(".json"));
35876
36634
  console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
35877
36635
  }
35878
36636
  var version2, COMMAND_GROUPS;
@@ -35884,6 +36642,7 @@ var init_repl_commands = __esm(() => {
35884
36642
  init_setup();
35885
36643
  init_config2();
35886
36644
  init_token_counter();
36645
+ init_map_command();
35887
36646
  init_utils();
35888
36647
  version2 = readMmaVersion();
35889
36648
  COMMAND_GROUPS = {
@@ -35901,6 +36660,7 @@ var init_repl_commands = __esm(() => {
35901
36660
  reload: "agent",
35902
36661
  wizard: "agent",
35903
36662
  sysprompt: "agent",
36663
+ map: "agent",
35904
36664
  lsp: "agent",
35905
36665
  sessions: "session",
35906
36666
  new: "session",
@@ -35934,14 +36694,14 @@ init_config2();
35934
36694
  init_setup();
35935
36695
  init_i18n();
35936
36696
  init_colors();
35937
- import { join as join51, dirname as dirname23 } from "path";
36697
+ import { join as join53, dirname as dirname23 } from "path";
35938
36698
  import { homedir as homedir17 } from "os";
35939
- import { existsSync as existsSync57 } from "fs";
36699
+ import { existsSync as existsSync58 } from "fs";
35940
36700
 
35941
36701
  // src/cli/security-commands.ts
35942
36702
  init_bootstrap();
35943
36703
  init_config2();
35944
- import { join as join45, dirname as dirname19 } from "path";
36704
+ import { join as join47, dirname as dirname19 } from "path";
35945
36705
  import { homedir as homedir16 } from "os";
35946
36706
 
35947
36707
  // src/modules/security/security-policies.ts
@@ -36467,7 +37227,7 @@ function createSecurityCommand(program2) {
36467
37227
  }
36468
37228
  });
36469
37229
  securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
36470
- const configPath = join45(homedir16(), ".mma", "config.json");
37230
+ const configPath = join47(homedir16(), ".mma", "config.json");
36471
37231
  const { config: appConfig } = await bootstrap();
36472
37232
  const validPresets = ["strict", "balanced", "permissive"];
36473
37233
  if (!validPresets.includes(preset)) {
@@ -36482,7 +37242,7 @@ function createSecurityCommand(program2) {
36482
37242
  console.log(t("cli.security.policy_description", { description: policy.description }));
36483
37243
  });
36484
37244
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
36485
- const configPath = join45(homedir16(), ".mma", "config.json");
37245
+ const configPath = join47(homedir16(), ".mma", "config.json");
36486
37246
  const { config: appConfig } = await bootstrap();
36487
37247
  const security = appConfig.security = appConfig.security || {};
36488
37248
  toggleSessionEncryption(security, true);
@@ -36490,7 +37250,7 @@ function createSecurityCommand(program2) {
36490
37250
  console.log(t("cli.security.encryption_enabled"));
36491
37251
  });
36492
37252
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
36493
- const configPath = join45(homedir16(), ".mma", "config.json");
37253
+ const configPath = join47(homedir16(), ".mma", "config.json");
36494
37254
  const { config: appConfig } = await bootstrap();
36495
37255
  const security = appConfig.security = appConfig.security || {};
36496
37256
  toggleSessionEncryption(security, false);
@@ -36498,7 +37258,7 @@ function createSecurityCommand(program2) {
36498
37258
  console.log(t("cli.security.encryption_disabled"));
36499
37259
  });
36500
37260
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
36501
- const configPath = join45(homedir16(), ".mma", "config.json");
37261
+ const configPath = join47(homedir16(), ".mma", "config.json");
36502
37262
  const { config: appConfig } = await bootstrap();
36503
37263
  const security = appConfig.security = appConfig.security || {};
36504
37264
  toggleAuditNotifier(security, true);
@@ -36506,7 +37266,7 @@ function createSecurityCommand(program2) {
36506
37266
  console.log(t("cli.security.audit_enabled"));
36507
37267
  });
36508
37268
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
36509
- const configPath = join45(homedir16(), ".mma", "config.json");
37269
+ const configPath = join47(homedir16(), ".mma", "config.json");
36510
37270
  const { config: appConfig } = await bootstrap();
36511
37271
  const security = appConfig.security = appConfig.security || {};
36512
37272
  toggleAuditNotifier(security, false);
@@ -36611,10 +37371,11 @@ function targetsFromProviders(entries) {
36611
37371
 
36612
37372
  // src/cli/commands.ts
36613
37373
  init_version();
37374
+ init_map_command();
36614
37375
 
36615
37376
  // src/modules/updater/changelog-reader.ts
36616
- import { readFileSync as readFileSync34, existsSync as existsSync52 } from "fs";
36617
- import { dirname as dirname20, join as join46 } from "path";
37377
+ import { readFileSync as readFileSync35, existsSync as existsSync53 } from "fs";
37378
+ import { dirname as dirname20, join as join48 } from "path";
36618
37379
  function readChangelog(packageName) {
36619
37380
  try {
36620
37381
  let dir = dirname20(import.meta.url);
@@ -36622,13 +37383,13 @@ function readChangelog(packageName) {
36622
37383
  dir = decodeURIComponent(dir.slice(7));
36623
37384
  }
36624
37385
  for (let i = 0;i < 10; i++) {
36625
- const pkgPath = join46(dir, "package.json");
36626
- if (existsSync52(pkgPath)) {
36627
- const pkg = JSON.parse(readFileSync34(pkgPath, "utf-8"));
37386
+ const pkgPath = join48(dir, "package.json");
37387
+ if (existsSync53(pkgPath)) {
37388
+ const pkg = JSON.parse(readFileSync35(pkgPath, "utf-8"));
36628
37389
  if (pkg.name === packageName) {
36629
- const changelogPath = join46(dir, "CHANGELOG.md");
36630
- if (existsSync52(changelogPath)) {
36631
- return readFileSync34(changelogPath, "utf-8");
37390
+ const changelogPath = join48(dir, "CHANGELOG.md");
37391
+ if (existsSync53(changelogPath)) {
37392
+ return readFileSync35(changelogPath, "utf-8");
36632
37393
  }
36633
37394
  return null;
36634
37395
  }
@@ -36695,7 +37456,7 @@ var version = readMmaVersion();
36695
37456
  function buildInitCommand(program2) {
36696
37457
  program2.command("init").description(t("cli.init")).action(async () => {
36697
37458
  const answers = await runSetup();
36698
- const configPath = join51(homedir17(), ".mma", "config.json");
37459
+ const configPath = join53(homedir17(), ".mma", "config.json");
36699
37460
  const { config } = await bootstrap();
36700
37461
  config.provider.type = answers.provider;
36701
37462
  config.provider.baseUrl = answers.apiBase;
@@ -36742,7 +37503,7 @@ function buildInitCommand(program2) {
36742
37503
  function buildConfigCommands(program2) {
36743
37504
  const configCmd = program2.command("config").description(t("cli.manage_config"));
36744
37505
  configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
36745
- const configPath = join51(homedir17(), ".mma", "config.json");
37506
+ const configPath = join53(homedir17(), ".mma", "config.json");
36746
37507
  const { config } = await bootstrap();
36747
37508
  const keys = key.split(".");
36748
37509
  let obj = config;
@@ -36772,24 +37533,24 @@ function buildConfigCommands(program2) {
36772
37533
  configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
36773
37534
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
36774
37535
  const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
36775
- const configDir = join51(homedir17(), ".mma");
36776
- const configPath = join51(configDir, "config.json");
37536
+ const configDir = join53(homedir17(), ".mma");
37537
+ const configPath = join53(configDir, "config.json");
36777
37538
  if (hasDomainFiles3(configDir)) {
36778
37539
  console.log(pc2.yellow(t("config.migrate_no_legacy")));
36779
37540
  return;
36780
37541
  }
36781
- if (!existsSync57(configPath)) {
37542
+ if (!existsSync58(configPath)) {
36782
37543
  console.log(pc2.yellow(t("config.migrate_no_legacy")));
36783
37544
  return;
36784
37545
  }
36785
37546
  console.log(t("config.migrate_start"));
36786
- const { config } = loadConfig2({ configDir, projectConfigPath: join51(configDir, ".mmrc") });
37547
+ const { config } = loadConfig2({ configDir, projectConfigPath: join53(configDir, ".mmrc") });
36787
37548
  saveConfig(config, configPath, configDir);
36788
37549
  const bakPath = configPath + ".bak";
36789
37550
  const { renameSync: renameSync4 } = await import("fs");
36790
37551
  renameSync4(configPath, bakPath);
36791
37552
  const { readdirSync: readdirSync19 } = await import("fs");
36792
- const domainFiles = readdirSync19(join51(configDir, "config")).filter((f) => f.endsWith(".json"));
37553
+ const domainFiles = readdirSync19(join53(configDir, "config")).filter((f) => f.endsWith(".json"));
36793
37554
  console.log(pc2.green(t("config.migrate_done", { count: String(domainFiles.length) })));
36794
37555
  });
36795
37556
  }
@@ -36831,7 +37592,7 @@ function buildModelCommands(program2) {
36831
37592
  console.log(t("cli.model_hint"));
36832
37593
  });
36833
37594
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
36834
- const configPath = join51(homedir17(), ".mma", "config.json");
37595
+ const configPath = join53(homedir17(), ".mma", "config.json");
36835
37596
  const { config } = await bootstrap();
36836
37597
  config.model = name;
36837
37598
  saveConfig(config, configPath, dirname23(configPath));
@@ -36872,7 +37633,7 @@ function buildModelCommands(program2) {
36872
37633
  }
36873
37634
  function buildContextCommand(program2) {
36874
37635
  program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
36875
- const configPath = join51(homedir17(), ".mma", "config.json");
37636
+ const configPath = join53(homedir17(), ".mma", "config.json");
36876
37637
  const { config } = await bootstrap();
36877
37638
  const contextWindow = parseInt(size, 10);
36878
37639
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -36884,6 +37645,18 @@ function buildContextCommand(program2) {
36884
37645
  console.log(t("cli.context_set", { size: contextWindow }));
36885
37646
  });
36886
37647
  }
37648
+ function buildMapCommand(program2) {
37649
+ program2.command("map").description(t("cli.map.description")).argument("[action]", t("cli.map.action"), "summary").argument("[query]", t("cli.map.query")).action(async (action, query) => {
37650
+ const { agent } = await bootstrap();
37651
+ const indexer = agent.getModule("indexer");
37652
+ if (!indexer) {
37653
+ console.log(t("indexer.not_indexed"));
37654
+ return;
37655
+ }
37656
+ const result = await runMapAction(indexer, action, query);
37657
+ console.log(result.output);
37658
+ });
37659
+ }
36887
37660
  function buildProviderCommands(program2) {
36888
37661
  const provider = program2.command("provider").description(t("cli.manage_providers"));
36889
37662
  provider.command("check").description(t("cli.provider_check")).option("--timeout <ms>", "Per-provider probe timeout in ms").action(async (opts) => {
@@ -36920,7 +37693,7 @@ function buildProviderCommands(program2) {
36920
37693
  console.log(t("cli.base_url"), config.provider.baseUrl);
36921
37694
  });
36922
37695
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
36923
- const configPath = join51(homedir17(), ".mma", "config.json");
37696
+ const configPath = join53(homedir17(), ".mma", "config.json");
36924
37697
  const { config, agent } = await bootstrap();
36925
37698
  if (config.provider.entries && config.provider.entries.length > 0) {
36926
37699
  try {
@@ -36943,7 +37716,7 @@ function buildProviderCommands(program2) {
36943
37716
  }
36944
37717
  });
36945
37718
  provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
36946
- const configPath = join51(homedir17(), ".mma", "config.json");
37719
+ const configPath = join53(homedir17(), ".mma", "config.json");
36947
37720
  const { config } = await bootstrap();
36948
37721
  const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
36949
37722
  if (entries.length === 0) {
@@ -37067,6 +37840,7 @@ function createProgram() {
37067
37840
  buildConfigCommands(program2);
37068
37841
  buildModelCommands(program2);
37069
37842
  buildContextCommand(program2);
37843
+ buildMapCommand(program2);
37070
37844
  buildProviderCommands(program2);
37071
37845
  buildSessionCommands(program2);
37072
37846
  createSecurityCommand(program2);
@@ -37954,8 +38728,8 @@ class LineEditor {
37954
38728
  }
37955
38729
 
37956
38730
  // src/cli/repl.ts
37957
- import { existsSync as existsSync59, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
37958
- import { join as join53 } from "path";
38731
+ import { existsSync as existsSync60, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
38732
+ import { join as join55 } from "path";
37959
38733
  import { homedir as homedir18 } from "os";
37960
38734
 
37961
38735
  // src/cli/completer.ts
@@ -38569,8 +39343,8 @@ async function probeLspServers(config, baseDir, deps = {}) {
38569
39343
  const timeoutCap = deps.timeoutMs ?? DEFAULT_PROBE_TIMEOUT_MS;
38570
39344
  const deadlineMs = deps.deadlineMs ?? DEFAULT_PROBE_DEADLINE_MS;
38571
39345
  const maxParallel = deps.maxParallel ?? DEFAULT_MAX_PARALLEL;
38572
- const collect = deps.collectFiles ?? collectCheckFiles;
38573
- const files = await collect(baseDir, config);
39346
+ const collect2 = deps.collectFiles ?? collectCheckFiles;
39347
+ const files = await collect2(baseDir, config);
38574
39348
  const seen = new Set;
38575
39349
  const servers = [];
38576
39350
  for (const file of files) {
@@ -38776,7 +39550,8 @@ class Repl {
38776
39550
  logger;
38777
39551
  slog;
38778
39552
  envReport;
38779
- constructor(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, exitOnClose, envReport, historyPath, execModule) {
39553
+ contextProbe;
39554
+ constructor(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, exitOnClose, envReport, historyPath, execModule, contextProbe) {
38780
39555
  this.agent = agent;
38781
39556
  this.config = config;
38782
39557
  this.exitOnClose = exitOnClose === true;
@@ -38785,12 +39560,13 @@ class Repl {
38785
39560
  this.pluginManager = pluginManager;
38786
39561
  this.logger = logger4;
38787
39562
  this.envReport = envReport;
39563
+ this.contextProbe = contextProbe;
38788
39564
  this.execModule = execModule;
38789
39565
  this.slog = new SessionLogger(sessionManager, logger4);
38790
- this.configDir = configDir || join53(homedir18(), ".mma");
39566
+ this.configDir = configDir || join55(homedir18(), ".mma");
38791
39567
  this.baseDir = baseDir || process.cwd();
38792
39568
  this.noAgentsMd = noAgentsMd === true;
38793
- this.historyPath = historyPath ?? join53(homedir18(), ".mma", "repl-history");
39569
+ this.historyPath = historyPath ?? join55(homedir18(), ".mma", "repl-history");
38794
39570
  this.loadHistory();
38795
39571
  this.rl = process.stdin.isTTY ? new LineEditor({
38796
39572
  input: process.stdin,
@@ -38845,7 +39621,7 @@ class Repl {
38845
39621
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
38846
39622
  const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
38847
39623
  this.agent.shutdown();
38848
- const projectConfigPath = join53(this.baseDir, ".mmrc");
39624
+ const projectConfigPath = join55(this.baseDir, ".mmrc");
38849
39625
  const { config: freshConfig } = loadConfig2({
38850
39626
  configDir: this.configDir,
38851
39627
  projectConfigPath
@@ -38861,9 +39637,9 @@ class Repl {
38861
39637
  this.setupCompleter();
38862
39638
  }
38863
39639
  loadHistory() {
38864
- if (existsSync59(this.historyPath)) {
39640
+ if (existsSync60(this.historyPath)) {
38865
39641
  try {
38866
- const raw = readFileSync40(this.historyPath, "utf-8");
39642
+ const raw = readFileSync41(this.historyPath, "utf-8");
38867
39643
  this.history = raw.split(`
38868
39644
  `).filter(Boolean).slice(-this.maxHistory);
38869
39645
  } catch {
@@ -38873,7 +39649,7 @@ class Repl {
38873
39649
  }
38874
39650
  saveHistory() {
38875
39651
  const allHistory = this.history.slice(-this.maxHistory);
38876
- writeFileSync23(this.historyPath, allHistory.join(`
39652
+ writeFileSync24(this.historyPath, allHistory.join(`
38877
39653
  `), "utf-8");
38878
39654
  }
38879
39655
  setupCompleter() {
@@ -39264,11 +40040,11 @@ ${t("image.clipboard_empty")}`));
39264
40040
  row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
39265
40041
  } else {
39266
40042
  const agentsMdCandidates = [
39267
- join53(this.baseDir, "AGENTS.md"),
39268
- join53(this.baseDir, ".mma", "AGENTS.md"),
39269
- join53(this.configDir, "AGENTS.md")
40043
+ join55(this.baseDir, "AGENTS.md"),
40044
+ join55(this.baseDir, ".mma", "AGENTS.md"),
40045
+ join55(this.configDir, "AGENTS.md")
39270
40046
  ];
39271
- const foundAgents = agentsMdCandidates.filter((p) => existsSync59(p));
40047
+ const foundAgents = agentsMdCandidates.filter((p) => existsSync60(p));
39272
40048
  if (foundAgents.length > 0) {
39273
40049
  for (const p of foundAgents) {
39274
40050
  row(t("repl.agents_label"), pc2.dim(p));
@@ -39279,7 +40055,7 @@ ${t("image.clipboard_empty")}`));
39279
40055
  }
39280
40056
  const meta = this.sessionManager?.getActiveMeta();
39281
40057
  if (meta) {
39282
- const sessionPath = join53(this.configDir, "sessions", meta.id);
40058
+ const sessionPath = join55(this.configDir, "sessions", meta.id);
39283
40059
  row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
39284
40060
  }
39285
40061
  const isTty2 = process.stdout.isTTY === true;
@@ -39322,6 +40098,24 @@ ${line}
39322
40098
  }
39323
40099
  }).catch(() => {});
39324
40100
  }
40101
+ if (this.contextProbe) {
40102
+ this.contextProbe.then((probe) => {
40103
+ if (!probe)
40104
+ return;
40105
+ this.sessionManager?.appendLog({
40106
+ ts: new Date().toISOString(),
40107
+ type: "context_probe",
40108
+ content: `model=${probe.model} actual=${probe.actual} configured=${this.config.contextWindow}`
40109
+ });
40110
+ const line = probe.actual < this.config.contextWindow ? `${pc2.yellow("⚠")} ${t("repl.context_probe_small", { model: probe.model, actual: probe.actual, configured: this.config.contextWindow })}` : probe.actual > this.config.contextWindow ? `${pc2.dim(t("repl.context_probe_big", { model: probe.model, actual: probe.actual }))}` : null;
40111
+ if (line) {
40112
+ process.stdout.write(`\x1B[2K\r${divider()}
40113
+ ${line}
40114
+ `);
40115
+ this.rl.prompt();
40116
+ }
40117
+ }).catch(() => {});
40118
+ }
39325
40119
  }
39326
40120
  async probeLspBanner() {
39327
40121
  const config = this.config.lsp ?? DEFAULT_LSP_CONFIG;
@@ -39394,8 +40188,8 @@ init_setup();
39394
40188
  init_config2();
39395
40189
  init_i18n();
39396
40190
  init_colors();
39397
- import { existsSync as existsSync60 } from "fs";
39398
- import { join as join55, dirname as dirname25 } from "path";
40191
+ import { existsSync as existsSync61 } from "fs";
40192
+ import { join as join57, dirname as dirname25 } from "path";
39399
40193
  import { homedir as homedir20 } from "os";
39400
40194
 
39401
40195
  // src/modules/updater/index.ts
@@ -39509,10 +40303,10 @@ init_environment();
39509
40303
  init_data_sanitizer();
39510
40304
  init_i18n();
39511
40305
  init_utils();
39512
- import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync22 } from "fs";
39513
- import { join as join54 } from "path";
40306
+ import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync23 } from "fs";
40307
+ import { join as join56 } from "path";
39514
40308
  import { homedir as homedir19 } from "os";
39515
- var CRASH_LOG_DIR = join54(homedir19(), ".mma", "logs");
40309
+ var CRASH_LOG_DIR = join56(homedir19(), ".mma", "logs");
39516
40310
  var CRASH_LOG_FILE = "crash.jsonl";
39517
40311
  function formatCrashEntry(type2, err) {
39518
40312
  const message = errMsg(err);
@@ -39527,8 +40321,8 @@ function formatCrashEntry(type2, err) {
39527
40321
  }
39528
40322
  function writeCrashEntry(dir, entry) {
39529
40323
  try {
39530
- mkdirSync22(dir, { recursive: true });
39531
- appendFileSync7(join54(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
40324
+ mkdirSync23(dir, { recursive: true });
40325
+ appendFileSync7(join56(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
39532
40326
  `, "utf-8");
39533
40327
  } catch {}
39534
40328
  }
@@ -39705,9 +40499,9 @@ async function main() {
39705
40499
  await updater?.waitForIdle();
39706
40500
  process.exit(exitCode);
39707
40501
  } else {
39708
- const mmaDir = process.env.MMA_CONFIG_DIR || join55(homedir20(), ".mma");
39709
- const legacyConfigPath = join55(mmaDir, "config.json");
39710
- let hasAnyConfig = existsSync60(legacyConfigPath);
40502
+ const mmaDir = process.env.MMA_CONFIG_DIR || join57(homedir20(), ".mma");
40503
+ const legacyConfigPath = join57(mmaDir, "config.json");
40504
+ let hasAnyConfig = existsSync61(legacyConfigPath);
39711
40505
  if (!hasAnyConfig) {
39712
40506
  try {
39713
40507
  const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
@@ -39724,9 +40518,10 @@ async function main() {
39724
40518
  configDir,
39725
40519
  baseDir,
39726
40520
  logger: logger4,
39727
- envReport
40521
+ envReport,
40522
+ contextProbe
39728
40523
  } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete, reasoningLevel);
39729
- const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, true, envReport, undefined, execModule);
40524
+ const repl = new Repl(agent, config, sessionManager, skillsModule, pluginManager, configDir, baseDir, noAgentsMd, logger4, true, envReport, undefined, execModule, contextProbe);
39730
40525
  if (!hasAnyConfig && !exitOnComplete) {
39731
40526
  console.log(pc2.yellow(`
39732
40527
  ` + t("cli.first_run") + `