micro-models-agent 0.28.0 → 0.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/main.js +826 -650
  2. package/package.json +1 -1
  3. package/dist/cli/commands.js +0 -220
  4. package/dist/cli/completer.js +0 -168
  5. package/dist/cli/index.js +0 -2
  6. package/dist/cli/main.js +0 -113
  7. package/dist/cli/repl.js +0 -987
  8. package/dist/cli/security-commands.js +0 -166
  9. package/dist/cli/setup.js +0 -229
  10. package/dist/config/config.js +0 -186
  11. package/dist/config/defaults.js +0 -91
  12. package/dist/config/experts.js +0 -15
  13. package/dist/config/index.js +0 -3
  14. package/dist/config/security.js +0 -193
  15. package/dist/config/types.js +0 -1
  16. package/dist/core/agent-moe.js +0 -98
  17. package/dist/core/agent.js +0 -461
  18. package/dist/core/bootstrap.js +0 -321
  19. package/dist/core/index.js +0 -2
  20. package/dist/core/prompt-builder.js +0 -55
  21. package/dist/core/session-logger.js +0 -122
  22. package/dist/core/types.js +0 -1
  23. package/dist/i18n/en.json +0 -461
  24. package/dist/i18n/index.js +0 -43
  25. package/dist/i18n/ru.json +0 -461
  26. package/dist/index.js +0 -22
  27. package/dist/llm/image-utils.js +0 -144
  28. package/dist/llm/index.js +0 -4
  29. package/dist/llm/model-loader.js +0 -78
  30. package/dist/llm/openai-compat.js +0 -324
  31. package/dist/llm/orchestrator.js +0 -194
  32. package/dist/llm/provider.js +0 -10
  33. package/dist/llm/response.js +0 -39
  34. package/dist/llm/token-counter.js +0 -39
  35. package/dist/llm/types.js +0 -1
  36. package/dist/logger/app-logger.js +0 -76
  37. package/dist/logger/index.js +0 -1
  38. package/dist/migration/backup.js +0 -45
  39. package/dist/migration/detect.js +0 -50
  40. package/dist/migration/index.js +0 -2
  41. package/dist/modules/browser/actions.js +0 -46
  42. package/dist/modules/browser/cookie-store.js +0 -24
  43. package/dist/modules/browser/index.js +0 -5
  44. package/dist/modules/browser/module.js +0 -28
  45. package/dist/modules/browser/session.js +0 -287
  46. package/dist/modules/browser/snapshot.js +0 -114
  47. package/dist/modules/browser/types.js +0 -9
  48. package/dist/modules/context/history.js +0 -15
  49. package/dist/modules/context/index.js +0 -1
  50. package/dist/modules/context/manager.js +0 -240
  51. package/dist/modules/execution/auditor.js +0 -72
  52. package/dist/modules/execution/index.js +0 -6
  53. package/dist/modules/execution/module.js +0 -337
  54. package/dist/modules/execution/moe-executor.js +0 -209
  55. package/dist/modules/execution/plan-validator.js +0 -153
  56. package/dist/modules/execution/planner.js +0 -35
  57. package/dist/modules/execution/stuck-detector.js +0 -134
  58. package/dist/modules/execution/tracker.js +0 -53
  59. package/dist/modules/execution/types.js +0 -1
  60. package/dist/modules/execution/verifier.js +0 -149
  61. package/dist/modules/hallucination/confidence.js +0 -54
  62. package/dist/modules/hallucination/consistency.js +0 -60
  63. package/dist/modules/hallucination/detector.js +0 -41
  64. package/dist/modules/hallucination/factual.js +0 -170
  65. package/dist/modules/hallucination/index.js +0 -4
  66. package/dist/modules/index.js +0 -5
  67. package/dist/modules/indexer/cache.js +0 -38
  68. package/dist/modules/indexer/index.js +0 -3
  69. package/dist/modules/indexer/module.js +0 -192
  70. package/dist/modules/indexer/walker.js +0 -101
  71. package/dist/modules/mcp/client.js +0 -393
  72. package/dist/modules/mcp/index.js +0 -3
  73. package/dist/modules/mcp/module.js +0 -146
  74. package/dist/modules/mcp/registry.js +0 -15
  75. package/dist/modules/memory/index.js +0 -1
  76. package/dist/modules/memory/module.js +0 -48
  77. package/dist/modules/memory/search.js +0 -40
  78. package/dist/modules/memory/store.js +0 -65
  79. package/dist/modules/pipelines/engine.js +0 -60
  80. package/dist/modules/pipelines/index.js +0 -3
  81. package/dist/modules/pipelines/parser.js +0 -53
  82. package/dist/modules/pipelines/template.js +0 -14
  83. package/dist/modules/plugins/builtin/lint-on-write.js +0 -121
  84. package/dist/modules/plugins/builtin/notify.js +0 -8
  85. package/dist/modules/plugins/index.js +0 -1
  86. package/dist/modules/plugins/loader.js +0 -28
  87. package/dist/modules/plugins/manager.js +0 -161
  88. package/dist/modules/plugins/types.js +0 -1
  89. package/dist/modules/processes/detect.js +0 -34
  90. package/dist/modules/processes/index.js +0 -3
  91. package/dist/modules/processes/registry.js +0 -148
  92. package/dist/modules/processes/runner.js +0 -124
  93. package/dist/modules/registry.js +0 -45
  94. package/dist/modules/security/audit-log.js +0 -116
  95. package/dist/modules/security/audit-notifier.js +0 -292
  96. package/dist/modules/security/command-validator.js +0 -185
  97. package/dist/modules/security/content-scanner.js +0 -52
  98. package/dist/modules/security/data-sanitizer.js +0 -97
  99. package/dist/modules/security/encryption.js +0 -240
  100. package/dist/modules/security/index.js +0 -14
  101. package/dist/modules/security/network-validator.js +0 -79
  102. package/dist/modules/security/path-validator.js +0 -155
  103. package/dist/modules/security/rate-limiter.js +0 -119
  104. package/dist/modules/security/security-policies.js +0 -393
  105. package/dist/modules/security/session-encryption.js +0 -193
  106. package/dist/modules/security/session-isolation.js +0 -95
  107. package/dist/modules/session/index.js +0 -3
  108. package/dist/modules/session/manager.js +0 -167
  109. package/dist/modules/session/module.js +0 -24
  110. package/dist/modules/session/store.js +0 -174
  111. package/dist/modules/session/types.js +0 -1
  112. package/dist/modules/skills/index.js +0 -3
  113. package/dist/modules/skills/loader.js +0 -72
  114. package/dist/modules/skills/matcher.js +0 -27
  115. package/dist/modules/skills/module.js +0 -143
  116. package/dist/modules/types.js +0 -1
  117. package/dist/modules/updater/checker.js +0 -32
  118. package/dist/modules/updater/index.js +0 -1
  119. package/dist/modules/user-profile/compressor.js +0 -16
  120. package/dist/modules/user-profile/index.js +0 -1
  121. package/dist/modules/user-profile/profile.js +0 -68
  122. package/dist/tools/approve.js +0 -32
  123. package/dist/tools/attach-image.js +0 -89
  124. package/dist/tools/bash.js +0 -140
  125. package/dist/tools/browser.js +0 -97
  126. package/dist/tools/create-dir.js +0 -56
  127. package/dist/tools/delete-file.js +0 -63
  128. package/dist/tools/edit-file.js +0 -77
  129. package/dist/tools/executor.js +0 -95
  130. package/dist/tools/file-info.js +0 -45
  131. package/dist/tools/filter-tools.js +0 -10
  132. package/dist/tools/glob-tool.js +0 -26
  133. package/dist/tools/grep-tool.js +0 -64
  134. package/dist/tools/index.js +0 -52
  135. package/dist/tools/list-dir.js +0 -47
  136. package/dist/tools/load-skill.js +0 -48
  137. package/dist/tools/mcp-call.js +0 -68
  138. package/dist/tools/move-file.js +0 -84
  139. package/dist/tools/path-utils.js +0 -51
  140. package/dist/tools/pipeline-run.js +0 -144
  141. package/dist/tools/preview.js +0 -2
  142. package/dist/tools/process-kill.js +0 -29
  143. package/dist/tools/process-list.js +0 -38
  144. package/dist/tools/process-log.js +0 -41
  145. package/dist/tools/question.js +0 -142
  146. package/dist/tools/read-file.js +0 -73
  147. package/dist/tools/recall.js +0 -110
  148. package/dist/tools/registry.js +0 -36
  149. package/dist/tools/remember.js +0 -67
  150. package/dist/tools/scope-check.js +0 -30
  151. package/dist/tools/search-history.js +0 -64
  152. package/dist/tools/subagent.js +0 -142
  153. package/dist/tools/types.js +0 -1
  154. package/dist/tools/user-input.js +0 -123
  155. package/dist/tools/web-browse.js +0 -57
  156. package/dist/tools/web-fetch.js +0 -72
  157. package/dist/tools/web-search.js +0 -59
  158. package/dist/tools/write-file.js +0 -80
  159. package/dist/ui/box.js +0 -81
  160. package/dist/ui/colors.js +0 -4
  161. package/dist/ui/diff.js +0 -185
  162. package/dist/ui/index.js +0 -6
  163. package/dist/ui/md-formatter.js +0 -212
  164. package/dist/ui/output.js +0 -13
  165. package/dist/ui/renderer.js +0 -141
  166. package/dist/ui/spinner.js +0 -70
  167. package/dist/ui/table.js +0 -144
package/dist/main.js CHANGED
@@ -2210,7 +2210,7 @@ var init_defaults = __esm(() => {
2210
2210
  maxDelay: 30000
2211
2211
  },
2212
2212
  maxToolIterations: 1000,
2213
- stuckThreshold: 8,
2213
+ stuckThreshold: 6,
2214
2214
  autoPlan: true,
2215
2215
  showReasoning: false,
2216
2216
  logLevel: "info",
@@ -2418,6 +2418,7 @@ Command: {command}`,
2418
2418
  "plan.step_marked": "Step {step} marked as {status}",
2419
2419
  "plan.aborted": "Plan aborted",
2420
2420
  "plan.unknown_action": "Unknown plan action: {action}",
2421
+ "plan.updated": "Plan updated: {title} ({steps} steps)",
2421
2422
  "plan.acknowledged": "Plan {action}: acknowledged",
2422
2423
  "plan.step_status": "Step {step}: {status}",
2423
2424
  "plan.no_active": "No active plan",
@@ -2962,6 +2963,7 @@ var init_ru = __esm(() => {
2962
2963
  "plan.step_marked": "Шаг {step} отмечен как {status}",
2963
2964
  "plan.aborted": "План отменён",
2964
2965
  "plan.unknown_action": "Неизвестное действие плана: {action}",
2966
+ "plan.updated": "План обновлён: {title} ({steps} шагов)",
2965
2967
  "plan.acknowledged": "План {action}: принято",
2966
2968
  "plan.step_status": "Шаг {step}: {status}",
2967
2969
  "plan.no_active": "Нет активного плана",
@@ -3351,7 +3353,10 @@ function flatten(obj, prefix = "") {
3351
3353
  if (typeof val === "string") {
3352
3354
  result[fullKey] = val;
3353
3355
  } else if (typeof val === "object" && val !== null) {
3354
- result = { ...result, ...flatten(val, fullKey) };
3356
+ result = {
3357
+ ...result,
3358
+ ...flatten(val, fullKey)
3359
+ };
3355
3360
  }
3356
3361
  }
3357
3362
  return result;
@@ -3364,7 +3369,7 @@ function setLocale(locale) {
3364
3369
  function t(key, params) {
3365
3370
  const localeDict = flat[currentLocale];
3366
3371
  const enDict = flat["en"];
3367
- let template = localeDict?.[key] || enDict?.[key];
3372
+ let template = localeDict?.[key] ?? enDict?.[key] ?? key;
3368
3373
  if (!template)
3369
3374
  return key;
3370
3375
  if (params) {
@@ -3686,7 +3691,13 @@ __export(exports_config, {
3686
3691
  saveConfig: () => saveConfig,
3687
3692
  loadConfig: () => loadConfig
3688
3693
  });
3689
- import { existsSync as existsSync4, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2 } from "fs";
3694
+ import {
3695
+ existsSync as existsSync4,
3696
+ readFileSync as readFileSync3,
3697
+ unlinkSync,
3698
+ writeFileSync as writeFileSync3,
3699
+ mkdirSync as mkdirSync2
3700
+ } from "fs";
3690
3701
  import { join as join4, dirname } from "path";
3691
3702
  function restoreDangerousPatterns(patterns, defaults) {
3692
3703
  const fallback = Array.isArray(defaults) ? defaults : [];
@@ -3760,12 +3771,21 @@ function applyEnvVars(config) {
3760
3771
  result.logLevel = env.MMA_LOG_LEVEL;
3761
3772
  if (env.MMA_LOCALE)
3762
3773
  result.locale = env.MMA_LOCALE;
3763
- if (env.MMA_CONTEXT_WINDOW)
3764
- result.contextWindow = parseInt(env.MMA_CONTEXT_WINDOW, 10);
3765
- if (env.MMA_MAX_TOOL_ITERATIONS)
3766
- result.maxToolIterations = parseInt(env.MMA_MAX_TOOL_ITERATIONS, 10);
3767
- if (env.MMA_STUCK_THRESHOLD)
3768
- result.stuckThreshold = parseInt(env.MMA_STUCK_THRESHOLD, 10);
3774
+ if (env.MMA_CONTEXT_WINDOW) {
3775
+ const v = parseInt(env.MMA_CONTEXT_WINDOW, 10);
3776
+ if (!isNaN(v))
3777
+ result.contextWindow = v;
3778
+ }
3779
+ if (env.MMA_MAX_TOOL_ITERATIONS) {
3780
+ const v = parseInt(env.MMA_MAX_TOOL_ITERATIONS, 10);
3781
+ if (!isNaN(v))
3782
+ result.maxToolIterations = v;
3783
+ }
3784
+ if (env.MMA_STUCK_THRESHOLD) {
3785
+ const v = parseInt(env.MMA_STUCK_THRESHOLD, 10);
3786
+ if (!isNaN(v))
3787
+ result.stuckThreshold = v;
3788
+ }
3769
3789
  if (env.MMA_AUTO_PLAN)
3770
3790
  result.autoPlan = env.MMA_AUTO_PLAN === "true";
3771
3791
  if (env.MMA_MOE_ENABLED)
@@ -3825,7 +3845,9 @@ function saveConfig(config, configPath) {
3825
3845
  mkdirSync2(dir, { recursive: true });
3826
3846
  try {
3827
3847
  const encryptor = new ConfigEncryptor;
3828
- const encryptedConfig = encryptor.encrypt({ ...config });
3848
+ const encryptedConfig = encryptor.encrypt({
3849
+ ...config
3850
+ });
3829
3851
  writeFileSync3(configPath, JSON.stringify(encryptedConfig, regexReplacer, 2), "utf-8");
3830
3852
  } catch (e) {
3831
3853
  console.warn(t("config.encryption_warning", { error: e.message }));
@@ -3899,14 +3921,88 @@ var init_data_sanitizer = __esm(() => {
3899
3921
  ];
3900
3922
  });
3901
3923
 
3924
+ // node_modules/picocolors/picocolors.js
3925
+ var require_picocolors = __commonJS((exports, module) => {
3926
+ var p = process || {};
3927
+ var argv = p.argv || [];
3928
+ var env = p.env || {};
3929
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
3930
+ var formatter = (open, close, replace = open) => (input) => {
3931
+ let string = "" + input, index = string.indexOf(close, open.length);
3932
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
3933
+ };
3934
+ var replaceClose = (string, close, replace, index) => {
3935
+ let result = "", cursor = 0;
3936
+ do {
3937
+ result += string.substring(cursor, index) + replace;
3938
+ cursor = index + close.length;
3939
+ index = string.indexOf(close, cursor);
3940
+ } while (~index);
3941
+ return result + string.substring(cursor);
3942
+ };
3943
+ var createColors = (enabled = isColorSupported) => {
3944
+ let f = enabled ? formatter : () => String;
3945
+ return {
3946
+ isColorSupported: enabled,
3947
+ reset: f("\x1B[0m", "\x1B[0m"),
3948
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
3949
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
3950
+ italic: f("\x1B[3m", "\x1B[23m"),
3951
+ underline: f("\x1B[4m", "\x1B[24m"),
3952
+ inverse: f("\x1B[7m", "\x1B[27m"),
3953
+ hidden: f("\x1B[8m", "\x1B[28m"),
3954
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
3955
+ black: f("\x1B[30m", "\x1B[39m"),
3956
+ red: f("\x1B[31m", "\x1B[39m"),
3957
+ green: f("\x1B[32m", "\x1B[39m"),
3958
+ yellow: f("\x1B[33m", "\x1B[39m"),
3959
+ blue: f("\x1B[34m", "\x1B[39m"),
3960
+ magenta: f("\x1B[35m", "\x1B[39m"),
3961
+ cyan: f("\x1B[36m", "\x1B[39m"),
3962
+ white: f("\x1B[37m", "\x1B[39m"),
3963
+ gray: f("\x1B[90m", "\x1B[39m"),
3964
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
3965
+ bgRed: f("\x1B[41m", "\x1B[49m"),
3966
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
3967
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
3968
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
3969
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
3970
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
3971
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
3972
+ blackBright: f("\x1B[90m", "\x1B[39m"),
3973
+ redBright: f("\x1B[91m", "\x1B[39m"),
3974
+ greenBright: f("\x1B[92m", "\x1B[39m"),
3975
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
3976
+ blueBright: f("\x1B[94m", "\x1B[39m"),
3977
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
3978
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
3979
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
3980
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
3981
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
3982
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
3983
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
3984
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
3985
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
3986
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
3987
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
3988
+ };
3989
+ };
3990
+ module.exports = createColors();
3991
+ module.exports.createColors = createColors;
3992
+ });
3993
+
3902
3994
  // src/logger/app-logger.ts
3903
3995
  import { appendFileSync, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
3904
3996
  import { join as join5 } from "path";
3997
+ function isColorEnabled() {
3998
+ return !process.env.NO_COLOR && !process.env.CI && process.stdout.isTTY === true;
3999
+ }
3905
4000
 
3906
4001
  class Logger {
3907
4002
  level;
3908
4003
  prefix;
3909
4004
  logDir = null;
4005
+ sessionDir = null;
3910
4006
  constructor(level = "info", prefix = "") {
3911
4007
  this.level = level;
3912
4008
  this.prefix = prefix;
@@ -3920,10 +4016,21 @@ class Logger {
3920
4016
  mkdirSync3(dir, { recursive: true });
3921
4017
  }
3922
4018
  }
4019
+ setSessionDir(dir) {
4020
+ this.sessionDir = dir;
4021
+ if (!existsSync5(dir)) {
4022
+ mkdirSync3(dir, { recursive: true });
4023
+ }
4024
+ }
4025
+ clearSessionDir() {
4026
+ this.sessionDir = null;
4027
+ }
3923
4028
  child(prefix) {
3924
4029
  const childLogger = new Logger(this.level, this.prefix ? `${this.prefix}:${prefix}` : prefix);
3925
4030
  if (this.logDir)
3926
4031
  childLogger.setLogDir(this.logDir);
4032
+ if (this.sessionDir)
4033
+ childLogger.setSessionDir(this.sessionDir);
3927
4034
  return childLogger;
3928
4035
  }
3929
4036
  debug(msg, meta) {
@@ -3947,10 +4054,17 @@ class Logger {
3947
4054
  const prefix = this.prefix ? ` [${this.prefix}]` : "";
3948
4055
  const metaStr = sanitizedMeta ? ` ${JSON.stringify(sanitizedMeta)}` : "";
3949
4056
  const line = `[${level.toUpperCase()}]${prefix} ${ts} — ${sanitizedMsg}${metaStr}`;
3950
- console.log(line);
3951
- if (this.logDir) {
4057
+ console.log(isColorEnabled() ? LEVEL_COLORS[level](line) : line);
4058
+ const logTarget = this.sessionDir ?? this.logDir;
4059
+ if (logTarget) {
3952
4060
  try {
3953
- appendFileSync(join5(this.logDir, "app.jsonl"), JSON.stringify({ level, ts, prefix: this.prefix, msg: sanitizedMsg, meta: sanitizedMeta ?? null }) + `
4061
+ appendFileSync(join5(logTarget, "app.jsonl"), JSON.stringify({
4062
+ level,
4063
+ ts,
4064
+ prefix: this.prefix,
4065
+ msg: sanitizedMsg,
4066
+ meta: sanitizedMeta ?? null
4067
+ }) + `
3954
4068
  `, "utf-8");
3955
4069
  } catch {}
3956
4070
  }
@@ -3969,10 +4083,17 @@ class Logger {
3969
4083
  return sanitized;
3970
4084
  }
3971
4085
  }
3972
- var LEVELS;
4086
+ var import_picocolors, LEVELS, LEVEL_COLORS;
3973
4087
  var init_app_logger = __esm(() => {
3974
4088
  init_data_sanitizer();
4089
+ import_picocolors = __toESM(require_picocolors(), 1);
3975
4090
  LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
4091
+ LEVEL_COLORS = {
4092
+ debug: (s) => import_picocolors.default.dim(s),
4093
+ info: (s) => s,
4094
+ warn: (s) => import_picocolors.default.yellow(s),
4095
+ error: (s) => import_picocolors.default.red(s)
4096
+ };
3976
4097
  });
3977
4098
 
3978
4099
  // node_modules/base64-js/index.js
@@ -4569,7 +4690,18 @@ class OpenAICompatProvider {
4569
4690
  const controller = new AbortController;
4570
4691
  const totalTimeoutMs = 120000;
4571
4692
  const timeoutId = setTimeout(() => controller.abort(), totalTimeoutMs);
4572
- const abortSignal = signal ? AbortSignal.any([controller.signal, signal]) : controller.signal;
4693
+ const abortSignal = (() => {
4694
+ if (!signal)
4695
+ return controller.signal;
4696
+ try {
4697
+ return AbortSignal.any([controller.signal, signal]);
4698
+ } catch {
4699
+ signal.addEventListener("abort", () => controller.abort(), {
4700
+ once: true
4701
+ });
4702
+ return controller.signal;
4703
+ }
4704
+ })();
4573
4705
  const response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
4574
4706
  method: "POST",
4575
4707
  headers,
@@ -5500,18 +5632,25 @@ var init_audit_notifier = __esm(() => {
5500
5632
 
5501
5633
  // src/modules/security/audit-log.ts
5502
5634
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, appendFileSync as appendFileSync3 } from "fs";
5503
- import { resolve as resolve2 } from "path";
5635
+ import { resolve as resolve2, join as join7 } from "path";
5504
5636
  import { homedir as homedir3 } from "os";
5505
- function ensureAuditLogDir() {
5506
- if (!existsSync7(AUDIT_LOG_DIR)) {
5507
- mkdirSync5(AUDIT_LOG_DIR, { recursive: true, mode: 448 });
5637
+ function getAuditDir() {
5638
+ return _sessionAuditDir ?? _globalAuditDir;
5639
+ }
5640
+ function setAuditSessionDir(dir) {
5641
+ _sessionAuditDir = dir;
5642
+ if (!existsSync7(dir)) {
5643
+ mkdirSync5(dir, { recursive: true, mode: 448 });
5508
5644
  }
5509
5645
  }
5510
5646
  function logAudit(entry) {
5511
- ensureAuditLogDir();
5647
+ const dir = getAuditDir();
5648
+ if (!existsSync7(dir)) {
5649
+ mkdirSync5(dir, { recursive: true, mode: 448 });
5650
+ }
5512
5651
  try {
5513
5652
  const logEntry = JSON.stringify(entry);
5514
- appendFileSync3(AUDIT_LOG_PATH, logEntry + `
5653
+ appendFileSync3(join7(dir, "audit.jsonl"), logEntry + `
5515
5654
  `, "utf8");
5516
5655
  } catch {}
5517
5656
  try {
@@ -5568,11 +5707,10 @@ function logSecurityBlock(sessionId, action, reason, details) {
5568
5707
  details
5569
5708
  });
5570
5709
  }
5571
- var AUDIT_LOG_DIR, AUDIT_LOG_PATH;
5710
+ var _globalAuditDir, _sessionAuditDir = null;
5572
5711
  var init_audit_log = __esm(() => {
5573
5712
  init_audit_notifier();
5574
- AUDIT_LOG_DIR = resolve2(homedir3(), ".mma", "logs");
5575
- AUDIT_LOG_PATH = resolve2(AUDIT_LOG_DIR, "audit.jsonl");
5713
+ _globalAuditDir = resolve2(homedir3(), ".mma", "logs");
5576
5714
  });
5577
5715
 
5578
5716
  // src/tools/path-utils.ts
@@ -5748,13 +5886,13 @@ var init_content_scanner = __esm(() => {
5748
5886
  });
5749
5887
 
5750
5888
  // src/modules/security/session-isolation.ts
5751
- import { join as join7, resolve as resolve5 } from "path";
5889
+ import { join as join8, resolve as resolve5 } from "path";
5752
5890
  import { homedir as homedir4 } from "os";
5753
5891
  import { mkdirSync as mkdirSync6, existsSync as existsSync10 } from "fs";
5754
5892
  function createSessionContext(sessionId, projectDir, isolationConfig, securityOverrides) {
5755
5893
  const config = { ...DEFAULT_SESSION_ISOLATION, ...isolationConfig };
5756
- const baseDir = config.baseDir || join7(homedir4(), ".mma", "sessions", sessionId);
5757
- const tempDir = join7(baseDir, "temp");
5894
+ const baseDir = config.baseDir || join8(homedir4(), ".mma", "sessions", sessionId);
5895
+ const tempDir = join8(baseDir, "temp");
5758
5896
  if (config.isolateTempFiles && !existsSync10(tempDir)) {
5759
5897
  try {
5760
5898
  mkdirSync6(tempDir, { recursive: true, mode: 448 });
@@ -5793,82 +5931,12 @@ var init_session_isolation = __esm(() => {
5793
5931
  };
5794
5932
  });
5795
5933
 
5796
- // node_modules/picocolors/picocolors.js
5797
- var require_picocolors = __commonJS((exports, module) => {
5798
- var p = process || {};
5799
- var argv = p.argv || [];
5800
- var env = p.env || {};
5801
- var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
5802
- var formatter = (open, close, replace = open) => (input) => {
5803
- let string = "" + input, index = string.indexOf(close, open.length);
5804
- return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
5805
- };
5806
- var replaceClose = (string, close, replace, index) => {
5807
- let result = "", cursor = 0;
5808
- do {
5809
- result += string.substring(cursor, index) + replace;
5810
- cursor = index + close.length;
5811
- index = string.indexOf(close, cursor);
5812
- } while (~index);
5813
- return result + string.substring(cursor);
5814
- };
5815
- var createColors = (enabled = isColorSupported) => {
5816
- let f = enabled ? formatter : () => String;
5817
- return {
5818
- isColorSupported: enabled,
5819
- reset: f("\x1B[0m", "\x1B[0m"),
5820
- bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
5821
- dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
5822
- italic: f("\x1B[3m", "\x1B[23m"),
5823
- underline: f("\x1B[4m", "\x1B[24m"),
5824
- inverse: f("\x1B[7m", "\x1B[27m"),
5825
- hidden: f("\x1B[8m", "\x1B[28m"),
5826
- strikethrough: f("\x1B[9m", "\x1B[29m"),
5827
- black: f("\x1B[30m", "\x1B[39m"),
5828
- red: f("\x1B[31m", "\x1B[39m"),
5829
- green: f("\x1B[32m", "\x1B[39m"),
5830
- yellow: f("\x1B[33m", "\x1B[39m"),
5831
- blue: f("\x1B[34m", "\x1B[39m"),
5832
- magenta: f("\x1B[35m", "\x1B[39m"),
5833
- cyan: f("\x1B[36m", "\x1B[39m"),
5834
- white: f("\x1B[37m", "\x1B[39m"),
5835
- gray: f("\x1B[90m", "\x1B[39m"),
5836
- bgBlack: f("\x1B[40m", "\x1B[49m"),
5837
- bgRed: f("\x1B[41m", "\x1B[49m"),
5838
- bgGreen: f("\x1B[42m", "\x1B[49m"),
5839
- bgYellow: f("\x1B[43m", "\x1B[49m"),
5840
- bgBlue: f("\x1B[44m", "\x1B[49m"),
5841
- bgMagenta: f("\x1B[45m", "\x1B[49m"),
5842
- bgCyan: f("\x1B[46m", "\x1B[49m"),
5843
- bgWhite: f("\x1B[47m", "\x1B[49m"),
5844
- blackBright: f("\x1B[90m", "\x1B[39m"),
5845
- redBright: f("\x1B[91m", "\x1B[39m"),
5846
- greenBright: f("\x1B[92m", "\x1B[39m"),
5847
- yellowBright: f("\x1B[93m", "\x1B[39m"),
5848
- blueBright: f("\x1B[94m", "\x1B[39m"),
5849
- magentaBright: f("\x1B[95m", "\x1B[39m"),
5850
- cyanBright: f("\x1B[96m", "\x1B[39m"),
5851
- whiteBright: f("\x1B[97m", "\x1B[39m"),
5852
- bgBlackBright: f("\x1B[100m", "\x1B[49m"),
5853
- bgRedBright: f("\x1B[101m", "\x1B[49m"),
5854
- bgGreenBright: f("\x1B[102m", "\x1B[49m"),
5855
- bgYellowBright: f("\x1B[103m", "\x1B[49m"),
5856
- bgBlueBright: f("\x1B[104m", "\x1B[49m"),
5857
- bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
5858
- bgCyanBright: f("\x1B[106m", "\x1B[49m"),
5859
- bgWhiteBright: f("\x1B[107m", "\x1B[49m")
5860
- };
5861
- };
5862
- module.exports = createColors();
5863
- module.exports.createColors = createColors;
5864
- });
5865
-
5866
5934
  // src/ui/colors.ts
5867
- var import_picocolors, isTty = () => process.stdout.isTTY === true, enabled, pc;
5935
+ var import_picocolors2, isTty = () => process.stdout.isTTY === true, enabled, pc2;
5868
5936
  var init_colors = __esm(() => {
5869
- import_picocolors = __toESM(require_picocolors(), 1);
5937
+ import_picocolors2 = __toESM(require_picocolors(), 1);
5870
5938
  enabled = isTty() && !process.env.CI && !process.env.NO_COLOR;
5871
- pc = import_picocolors.createColors(enabled);
5939
+ pc2 = import_picocolors2.createColors(enabled);
5872
5940
  });
5873
5941
 
5874
5942
  // src/ui/diff.ts
@@ -5978,11 +6046,11 @@ function formatLine(line, maxNumWidth) {
5978
6046
  const num = line.type === "remove" ? line.oldNum : line.newNum;
5979
6047
  const numStr = num !== null ? String(num).padStart(maxNumWidth) : " ".repeat(maxNumWidth);
5980
6048
  if (line.type === "remove") {
5981
- return `${numStr} ${pc.red("-")} ${line.content}`;
6049
+ return `${numStr} ${pc2.red("-")} ${line.content}`;
5982
6050
  } else if (line.type === "add") {
5983
- return `${numStr} ${pc.green("+")} ${line.content}`;
6051
+ return `${numStr} ${pc2.green("+")} ${line.content}`;
5984
6052
  } else if (line.content === "...") {
5985
- return pc.dim(` ${" ".repeat(maxNumWidth)}...`);
6053
+ return pc2.dim(` ${" ".repeat(maxNumWidth)}...`);
5986
6054
  } else {
5987
6055
  return ` ${numStr} ${line.content}`;
5988
6056
  }
@@ -5994,19 +6062,18 @@ function generateDiff(oldContent, newContent) {
5994
6062
  `);
5995
6063
  const newLines = newContent.split(`
5996
6064
  `);
5997
- if (oldLines.length === 1 && oldLines[0] === "" && newLines.length === 1 && newLines[0] === "") {
5998
- return "";
5999
- }
6000
6065
  const diff = buildDiff(oldLines, newLines);
6001
6066
  if (diff.length === 0)
6002
6067
  return "";
6003
- const maxOldNum = Math.max(...diff.filter((l) => l.oldNum !== null).map((l) => l.oldNum));
6004
- const maxNewNum = Math.max(...diff.filter((l) => l.newNum !== null).map((l) => l.newNum));
6068
+ const oldNums = diff.filter((l) => l.oldNum !== null).map((l) => l.oldNum);
6069
+ const newNums = diff.filter((l) => l.newNum !== null).map((l) => l.newNum);
6070
+ const maxOldNum = oldNums.length > 0 ? Math.max(...oldNums) : 0;
6071
+ const maxNewNum = newNums.length > 0 ? Math.max(...newNums) : 0;
6005
6072
  const maxNumWidth = Math.max(String(maxOldNum).length, String(maxNewNum).length, 3);
6006
6073
  let lines = diff.map((l) => formatLine(l, maxNumWidth));
6007
6074
  if (lines.length > MAX_DIFF_LINES) {
6008
6075
  const truncated = lines.slice(0, MAX_DIFF_LINES);
6009
- truncated.push(pc.dim(` ... (${lines.length - MAX_DIFF_LINES} more lines)`));
6076
+ truncated.push(pc2.dim(` ... (${lines.length - MAX_DIFF_LINES} more lines)`));
6010
6077
  lines = truncated;
6011
6078
  }
6012
6079
  return lines.join(`
@@ -6019,11 +6086,11 @@ function generateNewFileDiff(content) {
6019
6086
  const diffLines = [];
6020
6087
  for (let i = 0;i < lines.length; i++) {
6021
6088
  const numStr = String(i + 1).padStart(maxNumWidth);
6022
- diffLines.push(`${numStr} ${pc.green("+")} ${lines[i]}`);
6089
+ diffLines.push(`${numStr} ${pc2.green("+")} ${lines[i]}`);
6023
6090
  }
6024
6091
  if (diffLines.length > MAX_DIFF_LINES) {
6025
6092
  const truncated = diffLines.slice(0, MAX_DIFF_LINES);
6026
- truncated.push(pc.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
6093
+ truncated.push(pc2.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
6027
6094
  return truncated.join(`
6028
6095
  `);
6029
6096
  }
@@ -6037,11 +6104,11 @@ function generateDeleteDiff(content) {
6037
6104
  const diffLines = [];
6038
6105
  for (let i = 0;i < lines.length; i++) {
6039
6106
  const numStr = String(i + 1).padStart(maxNumWidth);
6040
- diffLines.push(`${numStr} ${pc.red("-")} ${lines[i]}`);
6107
+ diffLines.push(`${numStr} ${pc2.red("-")} ${lines[i]}`);
6041
6108
  }
6042
6109
  if (diffLines.length > MAX_DIFF_LINES) {
6043
6110
  const truncated = diffLines.slice(0, MAX_DIFF_LINES);
6044
- truncated.push(pc.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
6111
+ truncated.push(pc2.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
6045
6112
  return truncated.join(`
6046
6113
  `);
6047
6114
  }
@@ -6049,10 +6116,7 @@ function generateDeleteDiff(content) {
6049
6116
  `);
6050
6117
  }
6051
6118
  function generateMoveDiff(fromPath, toPath) {
6052
- return [
6053
- pc.red(` - ${fromPath}`),
6054
- pc.green(` + ${toPath}`)
6055
- ].join(`
6119
+ return [pc2.red(` - ${fromPath}`), pc2.green(` + ${toPath}`)].join(`
6056
6120
  `);
6057
6121
  }
6058
6122
  var CONTEXT_LINES = 3, MAX_DIFF_LINES = 100;
@@ -6061,7 +6125,7 @@ var init_diff = __esm(() => {
6061
6125
  });
6062
6126
 
6063
6127
  // src/tools/write-file.ts
6064
- import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
6128
+ import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
6065
6129
  import { dirname as dirname4 } from "path";
6066
6130
  var writeFileTool;
6067
6131
  var init_write_file = __esm(() => {
@@ -6125,7 +6189,7 @@ var init_write_file = __esm(() => {
6125
6189
  if (fileExists) {
6126
6190
  oldContent = readFileSync6(resolved, "utf-8");
6127
6191
  }
6128
- writeFileSync6(resolved, content, "utf-8");
6192
+ writeFileSync5(resolved, content, "utf-8");
6129
6193
  const diff = fileExists ? generateDiff(oldContent, content) : generateNewFileDiff(content);
6130
6194
  ctx.fileOperationsCount = currentCount + 1;
6131
6195
  logFileWrite(ctx.sessionId, path, true, `File ${fileExists ? "updated" : "created"}`);
@@ -6135,7 +6199,7 @@ var init_write_file = __esm(() => {
6135
6199
  });
6136
6200
 
6137
6201
  // src/tools/edit-file.ts
6138
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
6202
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
6139
6203
  var editFileTool;
6140
6204
  var init_edit_file = __esm(() => {
6141
6205
  init_i18n();
@@ -6199,7 +6263,7 @@ var init_edit_file = __esm(() => {
6199
6263
  output: `[SECURITY BLOCKED] ${scanResult.reason}`
6200
6264
  };
6201
6265
  }
6202
- writeFileSync7(resolved, updated, "utf-8");
6266
+ writeFileSync6(resolved, updated, "utf-8");
6203
6267
  const diff = generateDiff(content, updated);
6204
6268
  ctx.fileOperationsCount = currentCount + 1;
6205
6269
  logFileWrite(ctx.sessionId, path, true, "File edited");
@@ -6239,7 +6303,7 @@ var init_glob_tool = __esm(() => {
6239
6303
  });
6240
6304
 
6241
6305
  // src/tools/grep-tool.ts
6242
- import { execFileSync, execSync } from "child_process";
6306
+ import { execFileSync } from "child_process";
6243
6307
  import { resolve as resolve7 } from "path";
6244
6308
  function truncateLines(output) {
6245
6309
  const lines = output.split(`
@@ -6262,8 +6326,14 @@ var init_grep_tool = __esm(() => {
6262
6326
  type: "object",
6263
6327
  properties: {
6264
6328
  pattern: { type: "string", description: "Regex pattern to search" },
6265
- include: { type: "string", description: "File pattern to filter (e.g. *.ts)" },
6266
- path: { type: "string", description: "Directory to search (defaults to baseDir)" }
6329
+ include: {
6330
+ type: "string",
6331
+ description: "File pattern to filter (e.g. *.ts)"
6332
+ },
6333
+ path: {
6334
+ type: "string",
6335
+ description: "Directory to search (defaults to baseDir)"
6336
+ }
6267
6337
  },
6268
6338
  required: ["pattern"]
6269
6339
  },
@@ -6281,22 +6351,34 @@ var init_grep_tool = __esm(() => {
6281
6351
  maxBuffer: 1024 * 1024,
6282
6352
  cwd: ctx.baseDir
6283
6353
  });
6284
- return { success: true, output: truncateLines(output || t("file.no_matches")) };
6354
+ return {
6355
+ success: true,
6356
+ output: truncateLines(output || t("file.no_matches"))
6357
+ };
6285
6358
  } catch (e) {
6286
6359
  if (e.status === 1)
6287
6360
  return { success: true, output: t("file.no_matches") };
6288
6361
  try {
6289
- const cmd = `grep -rn "${pattern.replace(/"/g, "\\\"")}" "${searchPath}"`;
6290
- const output = execSync(cmd, {
6362
+ const grepArgs = ["-rn", pattern, searchPath];
6363
+ if (args.include) {
6364
+ grepArgs.push("--include", String(args.include));
6365
+ }
6366
+ const output = execFileSync("grep", grepArgs, {
6291
6367
  encoding: "utf-8",
6292
6368
  maxBuffer: 1024 * 1024,
6293
6369
  cwd: ctx.baseDir
6294
6370
  });
6295
- return { success: true, output: truncateLines(output || t("file.no_matches")) };
6371
+ return {
6372
+ success: true,
6373
+ output: truncateLines(output || t("file.no_matches"))
6374
+ };
6296
6375
  } catch (e2) {
6297
6376
  if (e2.status === 1)
6298
6377
  return { success: true, output: t("file.no_matches") };
6299
- return { success: false, output: t("error.grep_failed", { message: e2.message }) };
6378
+ return {
6379
+ success: false,
6380
+ output: t("error.grep_failed", { message: e2.message })
6381
+ };
6300
6382
  }
6301
6383
  }
6302
6384
  }
@@ -6476,6 +6558,7 @@ var init_move_file = __esm(() => {
6476
6558
  init_audit_log();
6477
6559
  init_session_isolation();
6478
6560
  init_diff();
6561
+ init_path_utils();
6479
6562
  moveFileTool = {
6480
6563
  name: "move_file",
6481
6564
  description: "Move or rename a file or directory.",
@@ -6492,8 +6575,8 @@ var init_move_file = __esm(() => {
6492
6575
  const fromPath = String(args.from);
6493
6576
  const toPath = String(args.to);
6494
6577
  const baseDir = resolve9(ctx.baseDir);
6495
- const fromResolved = resolve9(baseDir, normalize3(fromPath));
6496
- const toResolved = resolve9(baseDir, normalize3(toPath));
6578
+ const fromResolved = safeResolvePath(baseDir, normalize3(fromPath));
6579
+ const toResolved = safeResolvePath(baseDir, normalize3(toPath));
6497
6580
  const securityConfig = ctx.sessionContext ? getSessionSecurityConfig(ctx.config, ctx.sessionContext) : ctx.config.security;
6498
6581
  const maxFileOps = securityConfig?.maxFileOperations ?? 100;
6499
6582
  const currentCount = ctx.fileOperationsCount ?? 0;
@@ -6810,7 +6893,19 @@ class ProcessRegistry {
6810
6893
  }
6811
6894
  this.children.set(id, child);
6812
6895
  entry.pid = child.pid ?? 0;
6813
- const decoder = platform() === "win32" ? new TextDecoder("ibm866") : null;
6896
+ const decoder = platform() === "win32" ? (() => {
6897
+ try {
6898
+ const cpOut = __require("child_process").execSync("chcp.com", {
6899
+ encoding: "utf-8",
6900
+ timeout: 2000,
6901
+ windowsHide: true
6902
+ }).toString();
6903
+ const m = cpOut.match(/(\d+)/);
6904
+ if (m)
6905
+ return new TextDecoder("ibm" + m[1]);
6906
+ } catch {}
6907
+ return null;
6908
+ })() : null;
6814
6909
  let buf = "";
6815
6910
  const pushLine = (line) => {
6816
6911
  if (entry.log.length >= MAX_LOG_LINES) {
@@ -7013,30 +7108,30 @@ var init_bash = __esm(() => {
7013
7108
  init_i18n();
7014
7109
  bashGraceMs = BASH_GRACE_MS;
7015
7110
  UNIX_TO_WIN_HINTS = {
7016
- ls: 'Use "dir" or the list_dir tool instead.',
7017
- pwd: 'Use "echo %cd%" or the file_info tool instead.',
7018
- cat: 'Use "type" or the read_file tool instead.',
7019
- cp: 'Use "copy" or the move_file tool instead.',
7020
- mv: 'Use "move" or the move_file tool instead.',
7021
- rm: 'Use "del" or the delete_file tool instead.',
7022
- grep: 'Use "findstr" or the grep tool instead.',
7023
- chmod: "Use icacls or the chmod tool instead.",
7024
- touch: "Use type nul > file or the write_file tool instead.",
7025
- find: 'Use "dir /s" or the glob tool instead.',
7111
+ ls: "Use the list_dir tool instead.",
7112
+ pwd: "Use the file_info tool instead.",
7113
+ cat: "Use the read_file tool instead.",
7114
+ cp: "Use the move_file tool instead.",
7115
+ mv: "Use the move_file tool instead.",
7116
+ rm: "Use the delete_file tool instead.",
7117
+ grep: "Use the grep tool instead.",
7118
+ chmod: "Use the chmod tool instead.",
7119
+ touch: "Use the write_file tool instead.",
7120
+ find: "Use the glob tool instead.",
7026
7121
  head: "Use the read_file tool with offset/limit instead.",
7027
7122
  tail: "Use the read_file tool instead.",
7028
7123
  wc: "Use the read_file tool instead.",
7029
7124
  diff: "Use the diff tool instead.",
7030
7125
  which: 'Use "where" instead.',
7031
7126
  echo: "echo works on Windows, but avoid pipes (|).",
7032
- "Get-Content": 'The shell is cmd.exe, not PowerShell. Use "type" or the read_file tool instead.',
7033
- "Select-Object": "The shell is cmd.exe, not PowerShell. Use the read_file tool with offset/limit instead."
7127
+ "Get-Content": "Use the read_file tool instead.",
7128
+ "Select-Object": "Use the read_file tool with offset/limit instead."
7034
7129
  };
7035
7130
  UNIX_TO_WIN_TRANSLATE = {
7036
- ls: "dir",
7037
- pwd: "echo %cd%",
7038
- cat: "type",
7039
- wc: 'find /c /v ""'
7131
+ ls: "Get-ChildItem",
7132
+ pwd: "Get-Location",
7133
+ cat: "Get-Content",
7134
+ wc: "@(Get-Content).Count"
7040
7135
  };
7041
7136
  bashTool = {
7042
7137
  name: "bash",
@@ -7046,8 +7141,14 @@ var init_bash = __esm(() => {
7046
7141
  type: "object",
7047
7142
  properties: {
7048
7143
  command: { type: "string", description: "Shell command to execute" },
7049
- workdir: { type: "string", description: "Working directory (default: baseDir)" },
7050
- background: { type: "boolean", description: "Return a process id immediately without waiting (default: commands still running after a few seconds are auto-promoted to the background)" }
7144
+ workdir: {
7145
+ type: "string",
7146
+ description: "Working directory (default: baseDir)"
7147
+ },
7148
+ background: {
7149
+ type: "boolean",
7150
+ description: "Return a process id immediately without waiting (default: commands still running after a few seconds are auto-promoted to the background)"
7151
+ }
7051
7152
  },
7052
7153
  required: ["command"]
7053
7154
  },
@@ -7327,8 +7428,21 @@ var init_prompt_builder = __esm(() => {
7327
7428
  // src/core/session-logger.ts
7328
7429
  class SessionLogger {
7329
7430
  session;
7330
- constructor(session) {
7431
+ logger;
7432
+ constructor(session, logger) {
7331
7433
  this.session = session;
7434
+ this.logger = logger;
7435
+ this.bindSessionDir();
7436
+ }
7437
+ bindSessionDir() {
7438
+ const meta = this.session?.getActiveMeta();
7439
+ if (!meta)
7440
+ return;
7441
+ const dir = this.session.getSessionDirectory(meta.id);
7442
+ if (this.logger) {
7443
+ this.logger.setSessionDir(dir);
7444
+ }
7445
+ setAuditSessionDir(dir);
7332
7446
  }
7333
7447
  get active() {
7334
7448
  return !!this.session?.getActive();
@@ -7365,7 +7479,13 @@ class SessionLogger {
7365
7479
  ts: new Date().toISOString(),
7366
7480
  type: "assistant",
7367
7481
  content,
7368
- ...toolCalls ? { tool_calls: toolCalls.map((tc) => ({ id: tc.id, name: tc.name, arguments: tc.arguments })) } : {},
7482
+ ...toolCalls ? {
7483
+ tool_calls: toolCalls.map((tc) => ({
7484
+ id: tc.id,
7485
+ name: tc.name,
7486
+ arguments: tc.arguments
7487
+ }))
7488
+ } : {},
7369
7489
  iteration
7370
7490
  });
7371
7491
  }
@@ -7449,6 +7569,9 @@ class SessionLogger {
7449
7569
  });
7450
7570
  }
7451
7571
  }
7572
+ var init_session_logger = __esm(() => {
7573
+ init_audit_log();
7574
+ });
7452
7575
 
7453
7576
  // node_modules/jsonrepair/lib/esm/utils/JSONRepairError.js
7454
7577
  var JSONRepairError;
@@ -8591,7 +8714,7 @@ class StuckDetector {
8591
8714
  escalationThreshold = 3;
8592
8715
  fileRewriteCount = new Map;
8593
8716
  fileRewriteThreshold = 3;
8594
- constructor(threshold = 8, errorThreshold = 3) {
8717
+ constructor(threshold = 6, errorThreshold = 3) {
8595
8718
  this.threshold = threshold;
8596
8719
  this.errorThreshold = errorThreshold;
8597
8720
  }
@@ -8824,22 +8947,6 @@ class StuckDetector {
8824
8947
  }
8825
8948
  return "";
8826
8949
  }
8827
- checkOffTrack(toolName, call) {
8828
- if (!this.currentStepDescription)
8829
- return null;
8830
- const toolArgStr = JSON.stringify(call.arguments).toLowerCase();
8831
- const pathInStep = (this.currentStepDescription.match(/\b[\w./-]+\.[a-z]+/gi) || []).map((p) => p.toLowerCase());
8832
- const pathInCall = (toolArgStr.match(/\b[\w./-]+\.[a-z]+/gi) || []).map((p) => p.toLowerCase());
8833
- const overlaps = pathInCall.some((p) => pathInStep.some((s) => p.includes(s) || s.includes(p)));
8834
- if (!overlaps && pathInStep.length > 0 && pathInCall.length > 0) {
8835
- return t("exec.off_track", {
8836
- stepId: String(this.currentStepId),
8837
- description: this.currentStepDescription,
8838
- tool: toolName
8839
- });
8840
- }
8841
- return null;
8842
- }
8843
8950
  reset() {
8844
8951
  this.currentStepId = null;
8845
8952
  this.iterationsOnCurrentStep = 0;
@@ -9401,18 +9508,29 @@ async function runWithMoE(deps, input, fallback, opts = {}) {
9401
9508
  ];
9402
9509
  const verification = await verifier.verifyMoEManifest(plan, config, knownTags);
9403
9510
  onPhase?.("thinking");
9404
- const verifyResult = await orchestrator.verifyAndMerge({
9405
- plan,
9406
- results: planResults.results.map((r) => ({
9407
- subtaskId: r.subtaskId,
9408
- success: r.success,
9409
- summary: r.summary,
9410
- result: r.result,
9411
- error: r.error
9412
- })),
9413
- verifierErrors: verification.errors,
9414
- verifierWarnings: verification.warnings
9415
- });
9511
+ let verifyResult;
9512
+ try {
9513
+ verifyResult = await orchestrator.verifyAndMerge({
9514
+ plan,
9515
+ results: planResults.results.map((r) => ({
9516
+ subtaskId: r.subtaskId,
9517
+ success: r.success,
9518
+ summary: r.summary,
9519
+ result: r.result,
9520
+ error: r.error
9521
+ })),
9522
+ verifierErrors: verification.errors,
9523
+ verifierWarnings: verification.warnings
9524
+ });
9525
+ } catch (err) {
9526
+ onPhase?.("done");
9527
+ return {
9528
+ success: false,
9529
+ text: `MoE verifyAndMerge crashed: ${err.message}`,
9530
+ error: err.message,
9531
+ iterationCount: 0
9532
+ };
9533
+ }
9416
9534
  onPhase?.("done");
9417
9535
  const outputLines = [`## MoE Execution Results
9418
9536
  `];
@@ -9442,7 +9560,7 @@ var init_agent_moe = __esm(() => {
9442
9560
 
9443
9561
  // src/modules/memory/search.ts
9444
9562
  import { readFileSync as readFileSync9, existsSync as existsSync18 } from "fs";
9445
- import { join as join8 } from "path";
9563
+ import { join as join9 } from "path";
9446
9564
 
9447
9565
  class MemorySearch {
9448
9566
  memoryDir;
@@ -9453,7 +9571,7 @@ class MemorySearch {
9453
9571
  const results = [];
9454
9572
  const lowerQuery = query.toLowerCase();
9455
9573
  for (const name of MEMORY_FILES) {
9456
- const path = join8(this.memoryDir, `${name}.md`);
9574
+ const path = join9(this.memoryDir, `${name}.md`);
9457
9575
  if (!existsSync18(path))
9458
9576
  continue;
9459
9577
  const content = readFileSync9(path, "utf-8");
@@ -9465,7 +9583,7 @@ class MemorySearch {
9465
9583
  }
9466
9584
  }
9467
9585
  }
9468
- const prefsPath = join8(this.memoryDir, "preferences.json");
9586
+ const prefsPath = join9(this.memoryDir, "preferences.json");
9469
9587
  if (existsSync18(prefsPath)) {
9470
9588
  try {
9471
9589
  const prefs = JSON.parse(readFileSync9(prefsPath, "utf-8"));
@@ -9486,8 +9604,8 @@ var init_search = __esm(() => {
9486
9604
  });
9487
9605
 
9488
9606
  // src/modules/memory/store.ts
9489
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, appendFileSync as appendFileSync4, existsSync as existsSync19, mkdirSync as mkdirSync10 } from "fs";
9490
- import { join as join9 } from "path";
9607
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, appendFileSync as appendFileSync4, existsSync as existsSync19, mkdirSync as mkdirSync10 } from "fs";
9608
+ import { join as join10 } from "path";
9491
9609
 
9492
9610
  class MemoryStore {
9493
9611
  memoryDir;
@@ -9495,9 +9613,9 @@ class MemoryStore {
9495
9613
  this.memoryDir = memoryDir;
9496
9614
  this.ensureDir();
9497
9615
  for (const name of MEMORY_FILES2) {
9498
- const path = join9(this.memoryDir, `${name}.md`);
9616
+ const path = join10(this.memoryDir, `${name}.md`);
9499
9617
  if (!existsSync19(path)) {
9500
- writeFileSync8(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
9618
+ writeFileSync7(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
9501
9619
 
9502
9620
  `, "utf-8");
9503
9621
  }
@@ -9509,13 +9627,13 @@ class MemoryStore {
9509
9627
  }
9510
9628
  }
9511
9629
  read(name) {
9512
- const path = join9(this.memoryDir, `${name}.md`);
9630
+ const path = join10(this.memoryDir, `${name}.md`);
9513
9631
  if (!existsSync19(path))
9514
9632
  return "";
9515
9633
  return readFileSync10(path, "utf-8");
9516
9634
  }
9517
9635
  append(name, entry) {
9518
- const path = join9(this.memoryDir, `${name}.md`);
9636
+ const path = join10(this.memoryDir, `${name}.md`);
9519
9637
  const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
9520
9638
  const formatted = `- **${timestamp}** — ${entry}
9521
9639
  `;
@@ -9526,7 +9644,7 @@ class MemoryStore {
9526
9644
  return searchModule.query(query);
9527
9645
  }
9528
9646
  prefsPath() {
9529
- return join9(this.memoryDir, "preferences.json");
9647
+ return join10(this.memoryDir, "preferences.json");
9530
9648
  }
9531
9649
  getPreferences() {
9532
9650
  const path = this.prefsPath();
@@ -9541,14 +9659,14 @@ class MemoryStore {
9541
9659
  setPreference(key, value) {
9542
9660
  const prefs = this.getPreferences();
9543
9661
  prefs[key] = value;
9544
- writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
9662
+ writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
9545
9663
  }
9546
9664
  deletePreference(key) {
9547
9665
  const prefs = this.getPreferences();
9548
9666
  if (!(key in prefs))
9549
9667
  return false;
9550
9668
  delete prefs[key];
9551
- writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
9669
+ writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
9552
9670
  return true;
9553
9671
  }
9554
9672
  appendRule(category, pattern, cause, solution) {
@@ -9565,7 +9683,7 @@ var init_store = __esm(() => {
9565
9683
  });
9566
9684
 
9567
9685
  // src/core/agent.ts
9568
- import { join as join10 } from "path";
9686
+ import { join as join11 } from "path";
9569
9687
  function isToolCallJson(text) {
9570
9688
  const trimmed = text.trim();
9571
9689
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
@@ -9655,7 +9773,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
9655
9773
  sessionManager,
9656
9774
  baseDir
9657
9775
  } = this.deps;
9658
- const slog = new SessionLogger(sessionManager);
9776
+ const slog = new SessionLogger(sessionManager, logger);
9659
9777
  if (sessionManager && !sessionManager.getActive()) {
9660
9778
  sessionManager.create();
9661
9779
  logger.debug(`Session started: ${sessionManager.getActive()}`);
@@ -9677,7 +9795,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
9677
9795
  verifier.runTypeCheck().then((tc) => {
9678
9796
  if (!tc.passed) {
9679
9797
  logger.warn(`Baseline typecheck has issues: ${tc.message?.slice(0, 500)}`);
9680
- onMeta?.(pc.yellow(`
9798
+ onMeta?.(pc2.yellow(`
9681
9799
  ⚠ Baseline typecheck has issues
9682
9800
  `));
9683
9801
  }
@@ -9709,7 +9827,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
9709
9827
  sessionManager,
9710
9828
  baseDir
9711
9829
  } = this.deps;
9712
- const slog = new SessionLogger(sessionManager);
9830
+ const slog = new SessionLogger(sessionManager, logger);
9713
9831
  this.abortController = new AbortController;
9714
9832
  let iteration = 0;
9715
9833
  let lastText = "";
@@ -9782,7 +9900,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
9782
9900
  if (config.showReasoning) {
9783
9901
  const metaOut = pluginManager.runOnMeta({ iteration, logger }, chunk.content);
9784
9902
  if (metaOut) {
9785
- onMeta?.(pc.dim(metaOut));
9903
+ onMeta?.(pc2.dim(metaOut));
9786
9904
  }
9787
9905
  emittedReasoning = true;
9788
9906
  }
@@ -9900,7 +10018,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
9900
10018
  } else {
9901
10019
  const metaOut = pluginManager.runOnMeta({ iteration, logger }, result.output);
9902
10020
  onMeta?.(`
9903
- ` + pc.dim(metaOut) + `
10021
+ ` + pc2.dim(metaOut) + `
9904
10022
  `);
9905
10023
  }
9906
10024
  if (result.diff) {
@@ -9957,7 +10075,7 @@ ${taskReminder}</system-summary>`
9957
10075
  if (sessionManager) {
9958
10076
  const activeSession = sessionManager.getActiveMeta();
9959
10077
  if (activeSession) {
9960
- const memDir = join10(baseDir, ".mma", "memory");
10078
+ const memDir = join11(baseDir, ".mma", "memory");
9961
10079
  const memStore = new MemoryStore(memDir);
9962
10080
  memStore.appendRule("errors", `${consecutiveToolFailures} consecutive tool failures`, "Multiple tools failing suggests environment or configuration issue", "Check dependencies, verify file paths, try write_file directly instead of shell commands");
9963
10081
  }
@@ -9973,13 +10091,13 @@ ${taskReminder}</system-summary>`
9973
10091
  const ctxPct = Math.min(100, Math.round(ctxTokens / ctxBudget.history * 100));
9974
10092
  const barLen = 10;
9975
10093
  const filled = Math.round(ctxPct / 100 * barLen);
9976
- const ctxBar = pc.green("█".repeat(filled)) + pc.dim("░".repeat(barLen - filled));
9977
- const pctColor = ctxPct >= 75 ? pc.yellow : pc.dim;
10094
+ const ctxBar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
10095
+ const pctColor = ctxPct >= 75 ? pc2.yellow : pc2.dim;
9978
10096
  const compCount = contextManager.getCompactionCount();
9979
10097
  const quality2 = contextManager.getQuality();
9980
- const qualityColor = quality2 >= 70 ? pc.green : quality2 >= 40 ? pc.yellow : pc.red;
10098
+ const qualityColor = quality2 >= 70 ? pc2.green : quality2 >= 40 ? pc2.yellow : pc2.red;
9981
10099
  onMeta?.(`
9982
- ${ctxBar} ${pctColor(`${ctxPct}%`)} ${pc.dim(`ctx: ${ctxTokens}/${ctxBudget.history}`)} ${pc.dim(`compactions: ${compCount}`)} ${qualityColor(`quality: ${quality2}%`)}
10100
+ ${ctxBar} ${pctColor(`${ctxPct}%`)} ${pc2.dim(`ctx: ${ctxTokens}/${ctxBudget.history}`)} ${pc2.dim(`compactions: ${compCount}`)} ${qualityColor(`quality: ${quality2}%`)}
9983
10101
  `);
9984
10102
  continue;
9985
10103
  }
@@ -10120,6 +10238,7 @@ ${taskReminder}</system-summary>`
10120
10238
  });
10121
10239
  this.deps.llmProvider = newProvider;
10122
10240
  this.deps.toolExecutor.updateProvider(newProvider);
10241
+ this.deps.toolExecutor.ctx.llmProvider = newProvider;
10123
10242
  const newTokenCounter = new TokenCounter2(config.model);
10124
10243
  this.deps.contextManager.resize(config.contextWindow, config.contextBudget, newTokenCounter);
10125
10244
  this.deps.config = config;
@@ -10161,6 +10280,7 @@ var init_agent = __esm(() => {
10161
10280
  init_colors();
10162
10281
  init_prompt_builder();
10163
10282
  init_processes();
10283
+ init_session_logger();
10164
10284
  init_agent_moe();
10165
10285
  init_store();
10166
10286
  init_verifier();
@@ -10342,6 +10462,7 @@ class ContextManager {
10342
10462
  return totalTokens > this.budget.history * this.compactionThreshold;
10343
10463
  }
10344
10464
  compact() {
10465
+ this.iterationsSinceCompaction = 0;
10345
10466
  if (this.messages.length <= KEEP_LAST_N * 2)
10346
10467
  return;
10347
10468
  this.compactionCount++;
@@ -10360,7 +10481,7 @@ class ContextManager {
10360
10481
  if (this.errorFacts.length > 0) {
10361
10482
  parts.push(`[Errors: ${this.errorFacts.slice(-3).join("; ")}]`);
10362
10483
  }
10363
- const triedAndFailed = extractTriedAndFailed(this.messages);
10484
+ const triedAndFailed = extractTriedAndFailed(oldTurns);
10364
10485
  if (triedAndFailed.length > 0) {
10365
10486
  const lines = triedAndFailed.map((t2) => `- ${t2.tool}(${t2.args}): ${t2.error} (failed ${t2.count}x)`);
10366
10487
  parts.push(`[Already tried & failed — do NOT repeat:]
@@ -10996,6 +11117,8 @@ var init_subagent = __esm(() => {
10996
11117
  const subContextManager = new ContextManager(ctx.config.contextWindow, ctx.config.contextBudget);
10997
11118
  const subPluginManager = new PluginManager;
10998
11119
  const hallucinationDetector = new HallucinationDetector(ctx.baseDir, ctx.llmProvider);
11120
+ const parentScope = ctx.scope;
11121
+ ctx.toolExecutor.setScope(scope || { allowed_files: [], read_only_files: [] });
10999
11122
  const systemPrompt = {
11000
11123
  content: `You are a sub-agent working on a specific task. ${context ? `Context: ${context}` : ""}`,
11001
11124
  priority: "critical",
@@ -11020,21 +11143,24 @@ var init_subagent = __esm(() => {
11020
11143
  const fullTask = context ? `${task}
11021
11144
 
11022
11145
  Context: ${context}` : task;
11023
- const result = await subAgent.run(fullTask);
11024
- if (result.success) {
11025
- return {
11146
+ let scopeRestored = false;
11147
+ try {
11148
+ const result = await subAgent.run(fullTask);
11149
+ return result.success ? {
11026
11150
  success: true,
11027
11151
  output: `Sub-agent completed:
11028
11152
  ${result.text}
11029
11153
 
11030
11154
  Iterations: ${result.iterationCount}`
11031
- };
11032
- } else {
11033
- return {
11155
+ } : {
11034
11156
  success: false,
11035
11157
  output: `Sub-agent failed: ${result.error}
11036
11158
  Partial output: ${result.text}`
11037
11159
  };
11160
+ } finally {
11161
+ if (!scopeRestored) {
11162
+ ctx.toolExecutor.setScope(parentScope || { allowed_files: [], read_only_files: [] });
11163
+ }
11038
11164
  }
11039
11165
  } catch (e) {
11040
11166
  return { success: false, output: `Sub-agent error: ${e.message}` };
@@ -11756,19 +11882,25 @@ class MCPClient {
11756
11882
  env: { ...process.env, ...this.config.env },
11757
11883
  stdio: ["pipe", "pipe", "pipe"]
11758
11884
  });
11885
+ let _resolved = false;
11759
11886
  child.on("error", (err) => {
11760
11887
  this._connected = false;
11761
- reject(err);
11888
+ if (!_resolved) {
11889
+ _resolved = true;
11890
+ reject(err);
11891
+ }
11762
11892
  });
11763
11893
  child.on("exit", (code) => {
11764
11894
  this._connected = false;
11765
- if (code !== 0) {
11895
+ if (code !== 0 && !_resolved) {
11896
+ _resolved = true;
11766
11897
  reject(new Error(`MCP server exited with code ${code}`));
11767
11898
  }
11768
11899
  });
11769
11900
  child.on("spawn", () => {
11770
11901
  this._connected = true;
11771
11902
  this.process = child;
11903
+ _resolved = true;
11772
11904
  resolve12();
11773
11905
  });
11774
11906
  });
@@ -12125,7 +12257,7 @@ ${JSON.stringify(result, null, 2)}`
12125
12257
 
12126
12258
  // src/tools/search-history.ts
12127
12259
  import * as fs from "fs";
12128
- import { join as join11 } from "path";
12260
+ import { join as join12 } from "path";
12129
12261
  import { homedir as homedir5 } from "os";
12130
12262
  function searchFile(filePath, query, maxResults, results) {
12131
12263
  if (!fs.existsSync(filePath))
@@ -12154,8 +12286,14 @@ var init_search_history = __esm(() => {
12154
12286
  type: "object",
12155
12287
  properties: {
12156
12288
  query: { type: "string", description: "Search query" },
12157
- maxResults: { type: "number", description: "Maximum results (default 5)" },
12158
- sessionId: { type: "string", description: "Optional: limit search to a specific session" }
12289
+ maxResults: {
12290
+ type: "number",
12291
+ description: "Maximum results (default 5)"
12292
+ },
12293
+ sessionId: {
12294
+ type: "string",
12295
+ description: "Optional: limit search to a specific session"
12296
+ }
12159
12297
  },
12160
12298
  required: ["query"]
12161
12299
  },
@@ -12163,11 +12301,14 @@ var init_search_history = __esm(() => {
12163
12301
  const query = String(args.query || "").toLowerCase();
12164
12302
  const maxResults = Number(args.maxResults) || 5;
12165
12303
  const sessionId = args.sessionId ? String(args.sessionId) : null;
12166
- const sessionDir = join11(homedir5(), ".mma", "sessions");
12304
+ const sessionDir = join12(homedir5(), ".mma", "sessions");
12167
12305
  const results = [];
12168
12306
  try {
12169
12307
  if (!fs.existsSync(sessionDir)) {
12170
- return { success: true, output: t("tool.no_sessions_dir", { dir: sessionDir }) };
12308
+ return {
12309
+ success: true,
12310
+ output: t("tool.no_sessions_dir", { dir: sessionDir })
12311
+ };
12171
12312
  }
12172
12313
  const entries = fs.readdirSync(sessionDir, { withFileTypes: true });
12173
12314
  for (const entry of entries) {
@@ -12175,7 +12316,7 @@ var init_search_history = __esm(() => {
12175
12316
  continue;
12176
12317
  if (sessionId && entry.name !== sessionId)
12177
12318
  continue;
12178
- const historyFile = join11(sessionDir, entry.name, "history.jsonl");
12319
+ const historyFile = join12(sessionDir, entry.name, "history.jsonl");
12179
12320
  searchFile(historyFile, query, maxResults, results);
12180
12321
  if (results.length >= maxResults)
12181
12322
  break;
@@ -12183,10 +12324,19 @@ var init_search_history = __esm(() => {
12183
12324
  if (results.length === 0) {
12184
12325
  return { success: true, output: t("tool.no_history", { query }) };
12185
12326
  }
12186
- return { success: true, output: t("tool.history_results", { query, results: results.join(`
12187
- `) }) };
12327
+ return {
12328
+ success: true,
12329
+ output: t("tool.history_results", {
12330
+ query,
12331
+ results: results.join(`
12332
+ `)
12333
+ })
12334
+ };
12188
12335
  } catch (err) {
12189
- return { success: true, output: t("tool.history_error", { error: String(err) }) };
12336
+ return {
12337
+ success: false,
12338
+ output: t("tool.history_error", { error: String(err) })
12339
+ };
12190
12340
  }
12191
12341
  }
12192
12342
  };
@@ -12194,7 +12344,7 @@ var init_search_history = __esm(() => {
12194
12344
 
12195
12345
  // src/tools/remember.ts
12196
12346
  import { homedir as homedir6 } from "os";
12197
- import { join as join12 } from "path";
12347
+ import { join as join13 } from "path";
12198
12348
  var CATEGORIES, rememberTool;
12199
12349
  var init_remember = __esm(() => {
12200
12350
  init_i18n();
@@ -12232,7 +12382,7 @@ var init_remember = __esm(() => {
12232
12382
  if (!CATEGORIES.includes(category)) {
12233
12383
  return { success: false, output: t("tool.invalid_params") };
12234
12384
  }
12235
- const memoryDir = join12(homedir6(), ".mma", "memory");
12385
+ const memoryDir = join13(homedir6(), ".mma", "memory");
12236
12386
  const store = new MemoryStore(memoryDir);
12237
12387
  try {
12238
12388
  if (category === "preferences") {
@@ -12265,7 +12415,7 @@ var init_remember = __esm(() => {
12265
12415
 
12266
12416
  // src/tools/recall.ts
12267
12417
  import { homedir as homedir7 } from "os";
12268
- import { join as join13 } from "path";
12418
+ import { join as join14 } from "path";
12269
12419
  function formatAll(store) {
12270
12420
  const parts = [];
12271
12421
  const prefs = store.getPreferences();
@@ -12348,7 +12498,7 @@ var init_recall = __esm(() => {
12348
12498
  handler: async (_ctx, args) => {
12349
12499
  const query = args.query ? String(args.query) : "";
12350
12500
  const category = args.category ? String(args.category) : "";
12351
- const memoryDir = join13(homedir7(), ".mma", "memory");
12501
+ const memoryDir = join14(homedir7(), ".mma", "memory");
12352
12502
  const store = new MemoryStore(memoryDir);
12353
12503
  try {
12354
12504
  if (!query && !category) {
@@ -12544,15 +12694,15 @@ function buildIndexInjectionScript() {
12544
12694
 
12545
12695
  // src/modules/browser/cookie-store.ts
12546
12696
  import { readFile, writeFile, mkdir } from "fs/promises";
12547
- import { join as join14 } from "path";
12697
+ import { join as join15 } from "path";
12548
12698
 
12549
12699
  class CookieStore {
12550
12700
  filePath;
12551
12701
  constructor(cookieDir) {
12552
- this.filePath = join14(cookieDir, "cookies.json");
12702
+ this.filePath = join15(cookieDir, "cookies.json");
12553
12703
  }
12554
12704
  async save(cookies) {
12555
- await mkdir(join14(this.filePath, ".."), { recursive: true });
12705
+ await mkdir(join15(this.filePath, ".."), { recursive: true });
12556
12706
  await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
12557
12707
  }
12558
12708
  async load() {
@@ -12872,10 +13022,10 @@ var init_types = __esm(() => {
12872
13022
  });
12873
13023
 
12874
13024
  // src/tools/browser.ts
12875
- import { join as join15 } from "path";
13025
+ import { join as join16 } from "path";
12876
13026
  function getSession(ctx) {
12877
13027
  if (!session) {
12878
- const cookieDir = join15(ctx.baseDir, ".mma", "browser");
13028
+ const cookieDir = join16(ctx.baseDir, ".mma", "browser");
12879
13029
  session = new BrowserSession({
12880
13030
  ...DEFAULT_BROWSER_CONFIG,
12881
13031
  headless: ctx.config.browser?.headless ?? true,
@@ -13003,13 +13153,13 @@ async function readClipboardImage() {
13003
13153
  }
13004
13154
  async function readClipboardFallback() {
13005
13155
  const { platform: platform3 } = await import("os");
13006
- const { execSync: execSync2 } = await import("child_process");
13156
+ const { execSync } = await import("child_process");
13007
13157
  const { readFileSync: readFileSync13, unlinkSync: unlinkSync3 } = await import("fs");
13008
- const { join: join16 } = await import("path");
13009
- const tmpPath = join16(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13158
+ const { join: join17 } = await import("path");
13159
+ const tmpPath = join17(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13010
13160
  try {
13011
13161
  if (platform3() === "linux") {
13012
- execSync2(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
13162
+ execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
13013
13163
  } else {
13014
13164
  return null;
13015
13165
  }
@@ -13284,7 +13434,7 @@ class ModuleRegistry {
13284
13434
 
13285
13435
  // src/modules/plugins/loader.ts
13286
13436
  import { readdirSync as readdirSync5, existsSync as existsSync23, statSync as statSync4 } from "fs";
13287
- import { join as join16 } from "path";
13437
+ import { join as join17 } from "path";
13288
13438
 
13289
13439
  class PluginLoader {
13290
13440
  loadFromDir(dirPath, pluginManager, logger) {
@@ -13292,7 +13442,7 @@ class PluginLoader {
13292
13442
  return;
13293
13443
  const entries = readdirSync5(dirPath);
13294
13444
  for (const entry of entries) {
13295
- const fullPath = join16(dirPath, entry);
13445
+ const fullPath = join17(dirPath, entry);
13296
13446
  if (!statSync4(fullPath).isFile())
13297
13447
  continue;
13298
13448
  if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
@@ -13317,11 +13467,13 @@ var init_loader = __esm(() => {
13317
13467
  // src/modules/plugins/builtin/lint-on-write.ts
13318
13468
  import { spawn as spawn4 } from "child_process";
13319
13469
  import { existsSync as existsSync24, readFileSync as readFileSync13 } from "fs";
13320
- import { resolve as resolve13, extname as extname4, join as join17 } from "path";
13470
+ import { resolve as resolve13, extname as extname4, join as join18 } from "path";
13321
13471
 
13322
13472
  class LintOnWritePlugin {
13323
13473
  name = "lint-on-write";
13324
13474
  priority = 10;
13475
+ _checkPromise = null;
13476
+ _checkTimestamp = 0;
13325
13477
  async onAfterTool(ctx, call, result) {
13326
13478
  if (call.name !== "write_file" && call.name !== "edit_file") {
13327
13479
  return;
@@ -13379,7 +13531,7 @@ class LintOnWritePlugin {
13379
13531
  }
13380
13532
  async runProjectLint(ctx, result) {
13381
13533
  try {
13382
- const packageJsonPath = join17(ctx.baseDir, "package.json");
13534
+ const packageJsonPath = join18(ctx.baseDir, "package.json");
13383
13535
  if (!existsSync24(packageJsonPath)) {
13384
13536
  return;
13385
13537
  }
@@ -13399,13 +13551,13 @@ class LintOnWritePlugin {
13399
13551
  }
13400
13552
  }
13401
13553
  async runProjectTypeCheck(ctx, result) {
13402
- const tsconfigPath = join17(ctx.baseDir, "tsconfig.json");
13554
+ const tsconfigPath = join18(ctx.baseDir, "tsconfig.json");
13403
13555
  if (!existsSync24(tsconfigPath)) {
13404
13556
  return;
13405
13557
  }
13406
13558
  const now = Date.now();
13407
- if (projectTypeCheckPromise && now - projectTypeCheckTimestamp < TYPE_CHECK_DEBOUNCE_MS) {
13408
- const error2 = await projectTypeCheckPromise;
13559
+ if (this._checkPromise && now - this._checkTimestamp < TYPE_CHECK_DEBOUNCE_MS) {
13560
+ const error2 = await this._checkPromise;
13409
13561
  if (error2) {
13410
13562
  result.output += `
13411
13563
 
@@ -13413,9 +13565,9 @@ class LintOnWritePlugin {
13413
13565
  }
13414
13566
  return;
13415
13567
  }
13416
- projectTypeCheckTimestamp = now;
13417
- projectTypeCheckPromise = this.runTscCheck(ctx.baseDir);
13418
- const error = await projectTypeCheckPromise;
13568
+ this._checkTimestamp = now;
13569
+ this._checkPromise = this.runTscCheck(ctx.baseDir);
13570
+ const error = await this._checkPromise;
13419
13571
  if (error) {
13420
13572
  result.output += `
13421
13573
 
@@ -13478,7 +13630,7 @@ function runAsync(command, cwd, timeoutMs) {
13478
13630
  });
13479
13631
  });
13480
13632
  }
13481
- var projectTypeCheckPromise = null, projectTypeCheckTimestamp = 0, TYPE_CHECK_DEBOUNCE_MS = 2000, plugin;
13633
+ var TYPE_CHECK_DEBOUNCE_MS = 2000, plugin;
13482
13634
  var init_lint_on_write = __esm(() => {
13483
13635
  plugin = new LintOnWritePlugin;
13484
13636
  });
@@ -13530,7 +13682,7 @@ class PlanCreator {
13530
13682
  const stepCount = stepDescriptions.length;
13531
13683
  return {
13532
13684
  id: generatePlanId(),
13533
- title: `[${stepCount} ст.] ${title}`,
13685
+ title: `[${stepCount}] ${title}`,
13534
13686
  steps: stepDescriptions.map((desc, i) => ({
13535
13687
  id: i + 1,
13536
13688
  description: desc,
@@ -13670,17 +13822,17 @@ var init_auditor = __esm(() => {
13670
13822
  });
13671
13823
 
13672
13824
  // src/modules/execution/plan-persister.ts
13673
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync11, existsSync as existsSync26 } from "fs";
13674
- import { join as join18 } from "path";
13825
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11, existsSync as existsSync26 } from "fs";
13826
+ import { join as join19 } from "path";
13675
13827
 
13676
13828
  class PlanPersister {
13677
13829
  filePath;
13678
13830
  constructor(baseDir) {
13679
- const mmaDir = join18(baseDir, ".mma");
13831
+ const mmaDir = join19(baseDir, ".mma");
13680
13832
  if (!existsSync26(mmaDir)) {
13681
13833
  mkdirSync11(mmaDir, { recursive: true });
13682
13834
  }
13683
- this.filePath = join18(mmaDir, "plan.json");
13835
+ this.filePath = join19(mmaDir, "plan.json");
13684
13836
  }
13685
13837
  save(plan) {
13686
13838
  const file = {
@@ -13691,7 +13843,7 @@ class PlanPersister {
13691
13843
  updatedAt: new Date().toISOString(),
13692
13844
  baseDir: plan.baseDir
13693
13845
  };
13694
- writeFileSync9(this.filePath, JSON.stringify(file, null, 2), "utf-8");
13846
+ writeFileSync8(this.filePath, JSON.stringify(file, null, 2), "utf-8");
13695
13847
  }
13696
13848
  load() {
13697
13849
  if (!existsSync26(this.filePath))
@@ -13712,7 +13864,7 @@ class PlanPersister {
13712
13864
  }
13713
13865
  clear() {
13714
13866
  if (existsSync26(this.filePath)) {
13715
- writeFileSync9(this.filePath, "", "utf-8");
13867
+ writeFileSync8(this.filePath, "", "utf-8");
13716
13868
  }
13717
13869
  }
13718
13870
  }
@@ -13777,8 +13929,7 @@ var init_plan_coverage = __esm(() => {
13777
13929
  "css",
13778
13930
  "scss",
13779
13931
  "less",
13780
- "html",
13781
- "jsx"
13932
+ "html"
13782
13933
  ]);
13783
13934
  });
13784
13935
 
@@ -13797,7 +13948,8 @@ class ExecutionModule {
13797
13948
  lastRecoveryIteration = -STUCK_RECOVERY_COOLDOWN;
13798
13949
  consecutivePlanWarnings = 0;
13799
13950
  lastStepId = -1;
13800
- constructor(baseDir, stuckThreshold = 8) {
13951
+ _auditSkipsRemaining = 0;
13952
+ constructor(baseDir, stuckThreshold = 6) {
13801
13953
  this.baseDir = baseDir;
13802
13954
  this.verifier = new StepVerifier(baseDir);
13803
13955
  this.stuckDetector = new StuckDetector(stuckThreshold);
@@ -13807,6 +13959,7 @@ class ExecutionModule {
13807
13959
  setPlan(plan) {
13808
13960
  this.tracker = new PlanTracker(plan);
13809
13961
  this.persister.save(plan);
13962
+ this._auditSkipsRemaining = 0;
13810
13963
  }
13811
13964
  restorePlan() {
13812
13965
  const plan = this.persister.load();
@@ -13814,6 +13967,7 @@ class ExecutionModule {
13814
13967
  return false;
13815
13968
  this.tracker = new PlanTracker(plan);
13816
13969
  this.tracker.syncCurrentStep();
13970
+ this._auditSkipsRemaining = 1;
13817
13971
  return true;
13818
13972
  }
13819
13973
  getTracker() {
@@ -13825,6 +13979,10 @@ class ExecutionModule {
13825
13979
  async runFinalAudit() {
13826
13980
  if (!this.tracker)
13827
13981
  return null;
13982
+ if (this._auditSkipsRemaining > 0) {
13983
+ this._auditSkipsRemaining--;
13984
+ return null;
13985
+ }
13828
13986
  const plan = this.tracker.getPlan();
13829
13987
  const audit = await this.auditor.audit(plan);
13830
13988
  const pendingSteps = plan.steps.filter((s) => s.status !== "done" && s.status !== "skipped").map((s) => `${s.id}. ${s.description}`);
@@ -13888,7 +14046,10 @@ Write CONCRETE steps with exact file paths and commands:
13888
14046
  const plan = PlanCreator.createPlan(title, steps, this.baseDir);
13889
14047
  this.setPlan(plan);
13890
14048
  const display = PlanCreator.toPromptBlock(plan, 0);
13891
- let output = t("plan.created", { title, steps: String(steps.length) });
14049
+ let output = t("plan.created", {
14050
+ title,
14051
+ steps: String(steps.length)
14052
+ });
13892
14053
  let displayOut = display;
13893
14054
  const taskText = this.getTaskText(_ctx);
13894
14055
  if (taskText) {
@@ -13937,6 +14098,22 @@ ${progress}`,
13937
14098
  display
13938
14099
  };
13939
14100
  }
14101
+ if (action === "update" && Array.isArray(args.steps) && args.steps.length > 0 && this.tracker) {
14102
+ const title = String(args.title || this.tracker.getPlan().title);
14103
+ const steps = args.steps.map(String);
14104
+ const plan = PlanCreator.createPlan(title, steps, this.baseDir);
14105
+ this.setPlan(plan);
14106
+ const display = PlanCreator.toPromptBlock(plan, 0);
14107
+ const output = t("plan.updated", {
14108
+ title,
14109
+ steps: String(steps.length)
14110
+ });
14111
+ return {
14112
+ success: true,
14113
+ output,
14114
+ display
14115
+ };
14116
+ }
13940
14117
  if (action === "abort") {
13941
14118
  this.tracker = null;
13942
14119
  this.persister.clear();
@@ -13983,9 +14160,20 @@ ${progress}`,
13983
14160
  };
13984
14161
  }
13985
14162
  if (action === "done") {
14163
+ if (!currentStep) {
14164
+ return { success: false, output: t("plan.step_not_found") };
14165
+ }
14166
+ this.tracker.updateStepStatus(currentStep.id, "done");
14167
+ this.tracker.syncCurrentStep();
14168
+ this.persister.save(this.tracker.getPlan());
14169
+ const display = this.tracker.toPromptBlock();
13986
14170
  return {
13987
14171
  success: true,
13988
- output: t("todo.marked_done", { count: "1" })
14172
+ output: t("plan.step_status", {
14173
+ step: String(currentStep.id),
14174
+ status: "done"
14175
+ }),
14176
+ display
13989
14177
  };
13990
14178
  }
13991
14179
  if (action === "list") {
@@ -14073,8 +14261,10 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
14073
14261
  }
14074
14262
  const hints = this.stuckDetector.getHints();
14075
14263
  if (hints.length > 0 && ctx.contextManager) {
14076
- const hintMsg = t("exec.hints", { hints: hints.map((h) => `- ${h}`).join(`
14077
- `) });
14264
+ const hintMsg = t("exec.hints", {
14265
+ hints: hints.map((h) => `- ${h}`).join(`
14266
+ `)
14267
+ });
14078
14268
  ctx.contextManager.addMessage({
14079
14269
  role: "user",
14080
14270
  content: `<system-summary>${hintMsg}</system-summary>`
@@ -14093,7 +14283,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
14093
14283
  const step2 = this.tracker?.getCurrentStep();
14094
14284
  ctx.contextManager.addMessage({
14095
14285
  role: "user",
14096
- content: `<system-summary>CRITICAL: You have been stuck on step ${step2?.id ?? "?"} ("${step2?.description ?? ""}") for ${this.stuckDetector.getIterationsOnCurrentStep()} iterations. You MUST stop trying the same approach. Options: 1) Skip this step via plan update step=${step2?.id ?? "?"} status=skipped with a note explaining why. 2) Mark the step as done if the code runs correctly, even if there are type errors. 3) Try a completely different approach. Do NOT continue with the current approach.</system-summary>`
14286
+ content: `<system-summary>STOP. Step ${step2?.id ?? "?"} ("${step2?.description ?? ""}") took ${this.stuckDetector.getIterationsOnCurrentStep()} iterations with no progress. DO NOT continue this step. Immediately call: plan update step=${step2?.id ?? "?"} status=done (if code works despite warnings) OR plan update step=${step2?.id ?? "?"} status=skipped note="reason". Do NOT make any other tool calls before updating the plan.</system-summary>`
14097
14287
  });
14098
14288
  }
14099
14289
  }
@@ -14162,7 +14352,10 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
14162
14352
  const file = this.stuckDetector.getExcessiveRewriteFile();
14163
14353
  const count = this.stuckDetector.getFileRewriteCount(file);
14164
14354
  if (ctx.onMeta) {
14165
- ctx.onMeta(t("exec.file_rewrite_warning", { file, count: String(count) }));
14355
+ ctx.onMeta(t("exec.file_rewrite_warning", {
14356
+ file,
14357
+ count: String(count)
14358
+ }));
14166
14359
  }
14167
14360
  }
14168
14361
  }
@@ -14288,7 +14481,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
14288
14481
  return getMessageText(firstUser.content).trim();
14289
14482
  }
14290
14483
  }
14291
- var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD = 15;
14484
+ var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD = 10;
14292
14485
  var init_module = __esm(() => {
14293
14486
  init_i18n();
14294
14487
  init_tracker();
@@ -14301,8 +14494,8 @@ var init_module = __esm(() => {
14301
14494
  });
14302
14495
 
14303
14496
  // src/modules/security/session-encryption.ts
14304
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, existsSync as existsSync28, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
14305
- import { join as join19 } from "path";
14497
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, existsSync as existsSync28, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
14498
+ import { join as join20 } from "path";
14306
14499
  import { homedir as homedir8 } from "os";
14307
14500
 
14308
14501
  class SessionFileEncryptor {
@@ -14311,7 +14504,7 @@ class SessionFileEncryptor {
14311
14504
  constructor(config) {
14312
14505
  this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
14313
14506
  this.encryptor = new ConfigEncryptor({
14314
- keyPath: config?.keyPath || join19(homedir8(), ".mma", ".session-encryption-key")
14507
+ keyPath: config?.keyPath || join20(homedir8(), ".mma", ".session-encryption-key")
14315
14508
  });
14316
14509
  }
14317
14510
  isEnabled() {
@@ -14356,7 +14549,7 @@ class SessionFileEncryptor {
14356
14549
  }
14357
14550
  writeSessionFile(filePath, content) {
14358
14551
  const encrypted = this.encryptFileContent(content);
14359
- writeFileSync10(filePath, encrypted, "utf8");
14552
+ writeFileSync9(filePath, encrypted, "utf8");
14360
14553
  }
14361
14554
  readSessionJSON(filePath) {
14362
14555
  const content = readFileSync16(filePath, "utf8");
@@ -14364,7 +14557,7 @@ class SessionFileEncryptor {
14364
14557
  }
14365
14558
  writeSessionJSON(filePath, obj) {
14366
14559
  const content = this.encryptJSON(obj);
14367
- writeFileSync10(filePath, content, "utf8");
14560
+ writeFileSync9(filePath, content, "utf8");
14368
14561
  }
14369
14562
  readSessionJSONL(filePath) {
14370
14563
  const content = readFileSync16(filePath, "utf8");
@@ -14375,7 +14568,7 @@ class SessionFileEncryptor {
14375
14568
  }
14376
14569
  appendToSessionJSONL(filePath, obj) {
14377
14570
  const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
14378
- writeFileSync10(filePath, encryptedLine + `
14571
+ writeFileSync9(filePath, encryptedLine + `
14379
14572
  `, { flag: "a", encoding: "utf8" });
14380
14573
  }
14381
14574
  encryptSessionDirectory(sessionDir) {
@@ -14383,12 +14576,12 @@ class SessionFileEncryptor {
14383
14576
  return;
14384
14577
  const files = readdirSync6(sessionDir);
14385
14578
  for (const file of files) {
14386
- const filePath = join19(sessionDir, file);
14579
+ const filePath = join20(sessionDir, file);
14387
14580
  if (existsSync28(filePath) && !file.endsWith(".enc")) {
14388
14581
  try {
14389
14582
  const content = readFileSync16(filePath, "utf8");
14390
14583
  const encrypted = this.encryptFileContent(content);
14391
- writeFileSync10(filePath + ".enc", encrypted, "utf8");
14584
+ writeFileSync9(filePath + ".enc", encrypted, "utf8");
14392
14585
  unlinkSync3(filePath);
14393
14586
  } catch {}
14394
14587
  }
@@ -14400,12 +14593,12 @@ class SessionFileEncryptor {
14400
14593
  const files = readdirSync6(sessionDir);
14401
14594
  for (const file of files) {
14402
14595
  if (file.endsWith(".enc")) {
14403
- const encFilePath = join19(sessionDir, file);
14596
+ const encFilePath = join20(sessionDir, file);
14404
14597
  const decFilePath = encFilePath.slice(0, -4);
14405
14598
  try {
14406
14599
  const content = readFileSync16(encFilePath, "utf8");
14407
14600
  const decrypted = this.decryptFileContent(content);
14408
- writeFileSync10(decFilePath, decrypted, "utf8");
14601
+ writeFileSync9(decFilePath, decrypted, "utf8");
14409
14602
  unlinkSync3(encFilePath);
14410
14603
  } catch {}
14411
14604
  }
@@ -14430,21 +14623,25 @@ import {
14430
14623
  readdirSync as readdirSync7,
14431
14624
  readFileSync as readFileSync17,
14432
14625
  rmSync,
14433
- writeFileSync as writeFileSync11,
14626
+ writeFileSync as writeFileSync10,
14434
14627
  appendFileSync as appendFileSync5
14435
14628
  } from "fs";
14436
- import { join as join20 } from "path";
14629
+ import { join as join21 } from "path";
14437
14630
  import { gzipSync } from "zlib";
14438
14631
 
14439
14632
  class SessionStore {
14440
14633
  baseDir;
14441
14634
  encryptor = null;
14635
+ _metaCache = new Map;
14442
14636
  constructor(baseDir, encryptionConfig) {
14443
14637
  this.baseDir = baseDir;
14444
14638
  if (encryptionConfig?.enabled) {
14445
14639
  this.encryptor = new SessionFileEncryptor(encryptionConfig);
14446
14640
  }
14447
14641
  }
14642
+ getSessionDir(id) {
14643
+ return join21(this.baseDir, id);
14644
+ }
14448
14645
  updateEncryption(config) {
14449
14646
  if (config?.enabled) {
14450
14647
  this.encryptor = new SessionFileEncryptor(config);
@@ -14459,38 +14656,44 @@ class SessionStore {
14459
14656
  mkdirSync12(this.baseDir, { recursive: true });
14460
14657
  }
14461
14658
  sessionDir(id) {
14462
- return join20(this.baseDir, id);
14659
+ return join21(this.baseDir, id);
14463
14660
  }
14464
14661
  metaPath(id) {
14465
- return join20(this.sessionDir(id), "meta.json");
14662
+ return join21(this.sessionDir(id), "meta.json");
14466
14663
  }
14467
14664
  historyPath(id) {
14468
- return join20(this.sessionDir(id), "history.jsonl");
14665
+ return join21(this.sessionDir(id), "history.jsonl");
14469
14666
  }
14470
14667
  sessionLogPath(id) {
14471
- return join20(this.sessionDir(id), "session.jsonl");
14668
+ return join21(this.sessionDir(id), "session.jsonl");
14472
14669
  }
14473
14670
  sessionExists(id) {
14474
14671
  return existsSync29(this.metaPath(id));
14475
14672
  }
14476
14673
  saveMeta(id, meta) {
14674
+ this._metaCache.set(id, meta);
14477
14675
  const dir = this.sessionDir(id);
14478
14676
  mkdirSync12(dir, { recursive: true });
14479
14677
  const content = JSON.stringify(meta, null, 2);
14480
14678
  if (this.encryptor) {
14481
- writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
14679
+ writeFileSync10(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
14482
14680
  } else {
14483
- writeFileSync11(this.metaPath(id), content, "utf-8");
14681
+ writeFileSync10(this.metaPath(id), content, "utf-8");
14484
14682
  }
14485
14683
  }
14486
14684
  loadMeta(id) {
14685
+ const cached = this._metaCache.get(id);
14686
+ if (cached)
14687
+ return cached;
14487
14688
  const path = this.metaPath(id);
14488
14689
  if (!existsSync29(path))
14489
14690
  return null;
14490
14691
  try {
14491
14692
  const raw = readFileSync17(path, "utf-8");
14492
14693
  const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
14493
- return JSON.parse(content);
14694
+ const meta = JSON.parse(content);
14695
+ this._metaCache.set(id, meta);
14696
+ return meta;
14494
14697
  } catch {
14495
14698
  return null;
14496
14699
  }
@@ -14521,11 +14724,23 @@ class SessionStore {
14521
14724
  const raw = readFileSync17(path, "utf-8");
14522
14725
  const lines = raw.split(`
14523
14726
  `).filter(Boolean);
14727
+ const parseLine = (line) => {
14728
+ try {
14729
+ return JSON.parse(line);
14730
+ } catch {
14731
+ return null;
14732
+ }
14733
+ };
14524
14734
  if (this.encryptor?.isEnabled()) {
14525
- const decryptedLines = lines.map((line) => this.encryptor.decryptFileContent(line));
14526
- return decryptedLines.map((line) => JSON.parse(line));
14735
+ return lines.map((line) => {
14736
+ try {
14737
+ return this.encryptor.decryptFileContent(line);
14738
+ } catch {
14739
+ return null;
14740
+ }
14741
+ }).filter((l) => l !== null).map(parseLine).filter((m) => m !== null);
14527
14742
  }
14528
- return lines.map((line) => JSON.parse(line));
14743
+ return lines.map(parseLine).filter((m) => m !== null);
14529
14744
  } catch {
14530
14745
  return [];
14531
14746
  }
@@ -14550,11 +14765,23 @@ class SessionStore {
14550
14765
  const raw = readFileSync17(path, "utf-8");
14551
14766
  const lines = raw.split(`
14552
14767
  `).filter(Boolean);
14768
+ const parseLine = (line) => {
14769
+ try {
14770
+ return JSON.parse(line);
14771
+ } catch {
14772
+ return null;
14773
+ }
14774
+ };
14553
14775
  if (this.encryptor?.isEnabled()) {
14554
- const decryptedLines = lines.map((line) => this.encryptor.decryptFileContent(line));
14555
- return decryptedLines.map((line) => JSON.parse(line));
14776
+ return lines.map((line) => {
14777
+ try {
14778
+ return this.encryptor.decryptFileContent(line);
14779
+ } catch {
14780
+ return null;
14781
+ }
14782
+ }).filter((l) => l !== null).map(parseLine).filter((e) => e !== null);
14556
14783
  }
14557
- return lines.map((line) => JSON.parse(line));
14784
+ return lines.map(parseLine).filter((e) => e !== null);
14558
14785
  } catch {
14559
14786
  return [];
14560
14787
  }
@@ -14575,6 +14802,7 @@ class SessionStore {
14575
14802
  return sessions;
14576
14803
  }
14577
14804
  deleteSession(id) {
14805
+ this._metaCache.delete(id);
14578
14806
  const dir = this.sessionDir(id);
14579
14807
  if (existsSync29(dir)) {
14580
14808
  rmSync(dir, { recursive: true, force: true });
@@ -14591,8 +14819,8 @@ class SessionStore {
14591
14819
  if (existsSync29(historyPath)) {
14592
14820
  const content = readFileSync17(historyPath, "utf-8");
14593
14821
  const compressed = gzipSync(content);
14594
- const gzPath = join20(this.baseDir, `${session2.id}.jsonl.gz`);
14595
- writeFileSync11(gzPath, compressed);
14822
+ const gzPath = join21(this.baseDir, `${session2.id}.jsonl.gz`);
14823
+ writeFileSync10(gzPath, compressed);
14596
14824
  rmSync(historyPath);
14597
14825
  }
14598
14826
  }
@@ -14702,6 +14930,9 @@ class SessionManager {
14702
14930
  return;
14703
14931
  return this.getSessionContextById(this.activeId);
14704
14932
  }
14933
+ getSessionDirectory(id) {
14934
+ return this.store.getSessionDir(id);
14935
+ }
14705
14936
  getSessionContextById(sessionId) {
14706
14937
  if (!this.sessionContexts.has(sessionId)) {
14707
14938
  const meta = this.store.loadMeta(sessionId);
@@ -14798,8 +15029,8 @@ class ProfileCompressor {
14798
15029
  }
14799
15030
 
14800
15031
  // src/modules/user-profile/profile.ts
14801
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
14802
- import { join as join21 } from "path";
15032
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
15033
+ import { join as join22 } from "path";
14803
15034
  import { homedir as homedir9, hostname, platform as platform3, type } from "os";
14804
15035
  import { env } from "process";
14805
15036
 
@@ -14826,10 +15057,10 @@ class UserProfile {
14826
15057
  if (!existsSync30(this.profileDir)) {
14827
15058
  mkdirSync13(this.profileDir, { recursive: true });
14828
15059
  }
14829
- writeFileSync12(join21(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
15060
+ writeFileSync11(join22(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
14830
15061
  }
14831
15062
  load() {
14832
- const path = join21(this.profileDir, "profile.json");
15063
+ const path = join22(this.profileDir, "profile.json");
14833
15064
  if (!existsSync30(path))
14834
15065
  return null;
14835
15066
  try {
@@ -14869,7 +15100,7 @@ var init_profile = () => {};
14869
15100
 
14870
15101
  // src/modules/skills/loader.ts
14871
15102
  import { readdirSync as readdirSync8, readFileSync as readFileSync19, existsSync as existsSync31, statSync as statSync5 } from "fs";
14872
- import { join as join22 } from "path";
15103
+ import { join as join23 } from "path";
14873
15104
 
14874
15105
  class SkillsLoader {
14875
15106
  loadFromDir(dirPath) {
@@ -14882,7 +15113,7 @@ class SkillsLoader {
14882
15113
  scanDir(dirPath, skills) {
14883
15114
  const entries = readdirSync8(dirPath);
14884
15115
  for (const entry of entries) {
14885
- const fullPath = join22(dirPath, entry);
15116
+ const fullPath = join23(dirPath, entry);
14886
15117
  const stat = statSync5(fullPath);
14887
15118
  if (stat.isDirectory()) {
14888
15119
  this.scanDir(fullPath, skills);
@@ -15162,7 +15393,7 @@ var init_browser2 = __esm(() => {
15162
15393
  });
15163
15394
 
15164
15395
  // src/modules/lsp/client.ts
15165
- import { spawn as spawn5, execSync as execSync2 } from "child_process";
15396
+ import { spawn as spawn5, execSync } from "child_process";
15166
15397
  import { resolve as resolve16 } from "path";
15167
15398
 
15168
15399
  class LspClient {
@@ -15219,7 +15450,7 @@ class LspClient {
15219
15450
  async startServer(config, baseDir) {
15220
15451
  if (config.autoInstall === false) {
15221
15452
  try {
15222
- execSync2(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
15453
+ execSync(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
15223
15454
  } catch {
15224
15455
  throw new Error(`${config.command} not found in PATH`);
15225
15456
  }
@@ -15267,6 +15498,11 @@ class LspClient {
15267
15498
  continue;
15268
15499
  }
15269
15500
  this.contentLength = parseInt(match[1], 10);
15501
+ if (this.contentLength > 10485760) {
15502
+ this.buffer = this.buffer.slice(headerEnd + 4);
15503
+ this.contentLength = -1;
15504
+ continue;
15505
+ }
15270
15506
  this.buffer = this.buffer.slice(headerEnd + 4);
15271
15507
  }
15272
15508
  if (this.buffer.length < this.contentLength)
@@ -15474,7 +15710,7 @@ var init_lsp = __esm(() => {
15474
15710
 
15475
15711
  // src/modules/indexer/walker.ts
15476
15712
  import { readdirSync as readdirSync9, readFileSync as readFileSync20, statSync as statSync6, existsSync as existsSync33, watch } from "fs";
15477
- import { join as join23, relative, extname as extname5 } from "path";
15713
+ import { join as join24, relative, extname as extname5 } from "path";
15478
15714
 
15479
15715
  class Indexer {
15480
15716
  baseDir;
@@ -15512,7 +15748,7 @@ class Indexer {
15512
15748
  for (const entry of entries) {
15513
15749
  if (count >= this.MAX_FILES)
15514
15750
  return;
15515
- const fullPath = join23(dir, entry);
15751
+ const fullPath = join24(dir, entry);
15516
15752
  const relPath = relative(this.baseDir, fullPath);
15517
15753
  const stat = statSync6(fullPath);
15518
15754
  if (stat.isDirectory()) {
@@ -15575,14 +15811,14 @@ var init_walker = __esm(() => {
15575
15811
  });
15576
15812
 
15577
15813
  // src/modules/indexer/cache.ts
15578
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync13, existsSync as existsSync34, mkdirSync as mkdirSync14, rmSync as rmSync2 } from "fs";
15579
- import { join as join24 } from "path";
15814
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, existsSync as existsSync34, mkdirSync as mkdirSync14, rmSync as rmSync2 } from "fs";
15815
+ import { join as join25 } from "path";
15580
15816
 
15581
15817
  class IndexCache {
15582
15818
  cachePath;
15583
15819
  cache = null;
15584
15820
  constructor(cacheDir) {
15585
- this.cachePath = join24(cacheDir, "index-cache.json");
15821
+ this.cachePath = join25(cacheDir, "index-cache.json");
15586
15822
  }
15587
15823
  load() {
15588
15824
  if (this.cache)
@@ -15598,10 +15834,10 @@ class IndexCache {
15598
15834
  }
15599
15835
  save(result) {
15600
15836
  this.cache = result;
15601
- const dir = join24(this.cachePath, "..");
15837
+ const dir = join25(this.cachePath, "..");
15602
15838
  if (!existsSync34(dir))
15603
15839
  mkdirSync14(dir, { recursive: true });
15604
- writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
15840
+ writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
15605
15841
  }
15606
15842
  invalidate() {
15607
15843
  this.cache = null;
@@ -15963,13 +16199,13 @@ var init_mcp = __esm(() => {
15963
16199
 
15964
16200
  // src/modules/memory/module.ts
15965
16201
  import { homedir as homedir10 } from "os";
15966
- import { join as join25 } from "path";
16202
+ import { join as join26 } from "path";
15967
16203
 
15968
16204
  class MemoryModule {
15969
16205
  name = "memory";
15970
16206
  store;
15971
16207
  constructor(memoryDir) {
15972
- const dir = memoryDir || join25(homedir10(), ".mma", "memory");
16208
+ const dir = memoryDir || join26(homedir10(), ".mma", "memory");
15973
16209
  this.store = new MemoryStore(dir);
15974
16210
  }
15975
16211
  getSystemPromptBlock() {
@@ -16016,8 +16252,8 @@ __export(exports_bootstrap, {
16016
16252
  bootstrap: () => bootstrap
16017
16253
  });
16018
16254
  import { homedir as homedir11 } from "os";
16019
- import { join as join26, resolve as resolve18 } from "path";
16020
- import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "fs";
16255
+ import { join as join27, resolve as resolve18 } from "path";
16256
+ import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
16021
16257
  function buildSystemInfo(config, baseDir, profileCompressed) {
16022
16258
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
16023
16259
  const isWin = profileCompressed.toLowerCase().includes("win32");
@@ -16036,7 +16272,7 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
16036
16272
  `- DRY: Do not duplicate code, logic, or configuration — reuse existing utilities and patterns.`
16037
16273
  ];
16038
16274
  if (isWin) {
16039
- lines.push(``, `Windows environment — use Windows-compatible commands (shell is cmd.exe, not PowerShell):`, `- Use "dir" instead of "ls". Use "dir /b" for bare listing. For file listings prefer the list_dir tool.`, `- Use "type" instead of "cat". For reading files prefer the read_file tool.`, `- Use "cd" instead of "pwd". Use "echo %cd%" to print working directory.`, `- Use "copy" instead of "cp", "move" instead of "mv", "del" instead of "rm".`, `- Do not use "mkdir -p" Windows mkdir creates intermediate dirs by default. Use the create_dir tool instead.`, `- Do not use "head" or "tail" — they are Unix commands. Use the read_file tool with offset/limit instead.`, `- Do not use "grep" use the grep tool instead. Do not use PowerShell cmdlets (Get-Content, Select-Object, cat) in bash — the shell is cmd.exe.`, `- Use forward slashes (/) or escaped backslashes (\\\\) in file paths.`, `- Your working directory is: ${baseDir}`);
16275
+ lines.push(``, `Windows environment — the shell is PowerShell. Use these rules:`, `- For file listings, prefer the list_dir tool over "dir".`, `- For reading files, prefer the read_file tool over "type".`, `- For deleting files, prefer the delete_file tool over "del".`, `- For creating directories, prefer the create_dir tool over "mkdir".`, `- Do NOT use PowerShell cmdlets (Get-Content, Select-Object, Write-Output) use dedicated tools instead.`, `- Do not use "head", "tail", "grep", "cat" — they are Unix commands. Use the read_file and grep tools instead.`, `- Use forward slashes (/) or escaped backslashes (\\\\) in file paths.`, `- Your working directory is: ${baseDir}`);
16040
16276
  }
16041
16277
  lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory. Prefer workdir over "cd dir && cmd" chaining.`, `- Run one command per tool call. Split multi-step shell operations into separate bash calls.`, `- Dev servers, watchers and other long-running processes: pass "background: true" to get a process id immediately. Without it, any command still running after a few seconds is automatically moved to the background — check output with process_log.`);
16042
16278
  lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`, ``, `=== PLAN QUALITY RULES — your plan MUST follow these ===`, ``, `- Each step must describe CONCRETE deliverables: exact filenames with paths, exact packages to install, exact CLI commands to run. Avoid vague steps — be specific.`, `- A step like "Настройка проекта" or "Setup the project" is too vague — describe what exactly needs to be configured or set up.`, `- A step like "Создать src/components/Header.tsx с навигацией и логотипом, добавить в src/App.tsx импорт <Header />" is GOOD.`, `- Include file extensions (.tsx, .css, .json) and directory paths. Every step must mention at least one file or command.`, `- The plan must cover EVERYTHING needed: init → deps → framework setup → code → verification.`, `- Number of steps: 5-8 for a typical task. Too few means you're being vague. Too many means you're over-splitting.`);
@@ -16051,8 +16287,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
16051
16287
  `);
16052
16288
  }
16053
16289
  async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16054
- const dir = configDir || join26(homedir11(), ".mma");
16055
- const projectConfigPath = projectDir ? join26(projectDir, ".mmrc") : join26(process.cwd(), ".mmrc");
16290
+ const dir = configDir || join27(homedir11(), ".mma");
16291
+ const projectConfigPath = projectDir ? join27(projectDir, ".mmrc") : join27(process.cwd(), ".mmrc");
16056
16292
  const config = loadConfig({ configDir: dir, projectConfigPath });
16057
16293
  setLocale(config.locale);
16058
16294
  try {
@@ -16062,7 +16298,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16062
16298
  }
16063
16299
  } catch {}
16064
16300
  const logger = new Logger(config.logLevel);
16065
- logger.setLogDir(join26(dir, "logs"));
16301
+ logger.setLogDir(join27(dir, "logs"));
16066
16302
  logger.debug("MMA bootstrap", {
16067
16303
  version: config.version,
16068
16304
  model: config.model
@@ -16084,7 +16320,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16084
16320
  logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
16085
16321
  }
16086
16322
  }
16087
- const profile = new UserProfile(join26(dir));
16323
+ const profile = new UserProfile(join27(dir));
16088
16324
  profile.load() || profile.collect();
16089
16325
  profile.save();
16090
16326
  const llmProvider = new OpenAICompatProvider({
@@ -16096,7 +16332,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16096
16332
  rateLimits: config.security?.rateLimits
16097
16333
  });
16098
16334
  const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
16099
- const projectMapCacheDir = join26(baseDir, ".mma");
16335
+ const projectMapCacheDir = join27(baseDir, ".mma");
16100
16336
  const indexerModule = new IndexerModule({
16101
16337
  baseDir,
16102
16338
  cacheDir: projectMapCacheDir
@@ -16107,9 +16343,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16107
16343
  logger.warn(`Project indexing failed: ${err.message}`);
16108
16344
  }
16109
16345
  const skillsLoader = new SkillsLoader;
16110
- const builtinDir = join26(import.meta.dirname, "skills", "builtin");
16111
- const globalDir = join26(homedir11(), ".agents", "skills");
16112
- const projectSkillsDir = join26(baseDir, ".mma", "skills");
16346
+ const builtinDir = join27(import.meta.dirname, "skills", "builtin");
16347
+ const globalDir = join27(homedir11(), ".agents", "skills");
16348
+ const projectSkillsDir = join27(baseDir, ".mma", "skills");
16113
16349
  const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
16114
16350
  const skillsMatcher = new SkillsMatcher;
16115
16351
  const skillsBudget = Math.floor(config.contextWindow * 0.1);
@@ -16123,11 +16359,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16123
16359
  essential: true,
16124
16360
  estimatedTokens: 250
16125
16361
  };
16126
- const agentsMdGlobal = join26(dir, "AGENTS.md");
16362
+ const agentsMdGlobal = join27(dir, "AGENTS.md");
16127
16363
  if (!existsSync35(agentsMdGlobal)) {
16128
- writeFileSync14(agentsMdGlobal, "", "utf-8");
16364
+ writeFileSync13(agentsMdGlobal, "", "utf-8");
16129
16365
  }
16130
- const sessionDir = join26(dir, "sessions");
16366
+ const sessionDir = join27(dir, "sessions");
16131
16367
  const sessionStore = new SessionStore(sessionDir);
16132
16368
  sessionStore.init();
16133
16369
  const sessionManager = new SessionManager(sessionStore, {
@@ -16183,7 +16419,10 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16183
16419
  const hallucinationDetector = new HallucinationDetector(baseDir, llmProvider);
16184
16420
  const moduleRegistry = new ModuleRegistry;
16185
16421
  const execModule = new ExecutionModule(baseDir, config.stuckThreshold);
16186
- execModule.restorePlan();
16422
+ const activeMeta = sessionManager.getActiveMeta();
16423
+ if (activeMeta && activeMeta.messageCount > 0) {
16424
+ execModule.restorePlan();
16425
+ }
16187
16426
  moduleRegistry.register(execModule);
16188
16427
  const sessionModule = new SessionModule(sessionManager);
16189
16428
  moduleRegistry.register(sessionModule);
@@ -16192,7 +16431,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16192
16431
  const mcpModule = new MCPModule(config);
16193
16432
  await mcpModule.initialize();
16194
16433
  moduleRegistry.register(mcpModule);
16195
- const memoryModule = new MemoryModule(join26(dir, "memory"));
16434
+ const memoryModule = new MemoryModule(join27(dir, "memory"));
16196
16435
  moduleRegistry.register(memoryModule);
16197
16436
  if (config.browser.enabled) {
16198
16437
  const browserModule = new BrowserModule;
@@ -16242,8 +16481,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16242
16481
  pluginManager.register(plugin);
16243
16482
  pluginManager.register(plugin2);
16244
16483
  const pluginLoader = new PluginLoader;
16245
- const globalPluginsDir = join26(homedir11(), ".mma", "plugins");
16246
- const projectPluginsDir = join26(dir, ".mma", "plugins");
16484
+ const globalPluginsDir = join27(homedir11(), ".mma", "plugins");
16485
+ const projectPluginsDir = join27(baseDir, ".mma", "plugins");
16247
16486
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
16248
16487
  pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
16249
16488
  contextManager.onCompact = (summary) => {
@@ -16261,9 +16500,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16261
16500
  const skipAgentsMd = noAgentsMd === true;
16262
16501
  if (!skipAgentsMd) {
16263
16502
  const agentsMdCandidates = [
16264
- join26(baseDir, "AGENTS.md"),
16265
- join26(baseDir, ".mma", "AGENTS.md"),
16266
- join26(dir, "AGENTS.md")
16503
+ join27(baseDir, "AGENTS.md"),
16504
+ join27(baseDir, ".mma", "AGENTS.md"),
16505
+ join27(dir, "AGENTS.md")
16267
16506
  ];
16268
16507
  for (const p of agentsMdCandidates) {
16269
16508
  if (existsSync35(p)) {
@@ -16349,7 +16588,7 @@ function ansiRegex({ onlyFirst = false } = {}) {
16349
16588
  return new RegExp(pattern, onlyFirst ? undefined : "g");
16350
16589
  }
16351
16590
 
16352
- // node_modules/strip-ansi/index.js
16591
+ // node_modules/string-width/node_modules/strip-ansi/index.js
16353
16592
  function stripAnsi(string) {
16354
16593
  if (typeof string !== "string") {
16355
16594
  throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
@@ -16448,135 +16687,65 @@ var init_get_east_asian_width = __esm(() => {
16448
16687
  init_lookup();
16449
16688
  });
16450
16689
 
16690
+ // node_modules/emoji-regex/index.js
16691
+ var require_emoji_regex = __commonJS((exports, module) => {
16692
+ module.exports = () => {
16693
+ return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
16694
+ };
16695
+ });
16696
+
16451
16697
  // node_modules/string-width/index.js
16452
- function isDoubleWidthNonRgiEmojiSequence(segment) {
16453
- if (segment.length > 50) {
16454
- return false;
16455
- }
16456
- if (unqualifiedKeycapRegex.test(segment)) {
16457
- return true;
16458
- }
16459
- if (segment.includes("‍")) {
16460
- const pictographics = segment.match(extendedPictographicRegex);
16461
- return pictographics !== null && pictographics.length >= 2;
16462
- }
16463
- return false;
16464
- }
16465
- function baseVisible(segment) {
16466
- return segment.replace(leadingNonPrintingRegex, "");
16467
- }
16468
- function isZeroWidthCluster(segment) {
16469
- return zeroWidthClusterRegex.test(segment);
16470
- }
16471
- function isHangulLeadingJamo(codePoint) {
16472
- return codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388;
16473
- }
16474
- function isHangulVowelJamo(codePoint) {
16475
- return codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238;
16476
- }
16477
- function isHangulTrailingJamo(codePoint) {
16478
- return codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291;
16479
- }
16480
- function isHangulJamo(codePoint) {
16481
- return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
16482
- }
16483
- function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
16484
- const codePoints = [];
16485
- for (const character of visibleSegment) {
16486
- if (zeroWidthClusterRegex.test(character)) {
16487
- continue;
16488
- }
16489
- codePoints.push(character.codePointAt(0));
16490
- }
16491
- if (codePoints.length === 0) {
16492
- return;
16493
- }
16494
- let width = 0;
16495
- for (let index = 0;index < codePoints.length; index++) {
16496
- const codePoint = codePoints[index];
16497
- if (!isHangulJamo(codePoint)) {
16498
- if (width === 0) {
16499
- return;
16500
- }
16501
- for (let remaining = index;remaining < codePoints.length; remaining++) {
16502
- width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
16503
- }
16504
- return width;
16505
- }
16506
- if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
16507
- width += 2;
16508
- index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
16509
- continue;
16510
- }
16511
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
16512
- }
16513
- return width;
16514
- }
16515
- function trailingWidth(visibleSegment, eastAsianWidthOptions) {
16516
- let extra = 0;
16517
- let first = true;
16518
- for (const character of visibleSegment) {
16519
- if (first) {
16520
- first = false;
16521
- continue;
16522
- }
16523
- if (spacingMarkRegex.test(character) || character >= "＀" && character <= "￯") {
16524
- extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
16525
- }
16526
- }
16527
- return extra;
16528
- }
16529
- function stringWidth(input, options = {}) {
16530
- if (typeof input !== "string" || input.length === 0) {
16698
+ function stringWidth(string, options = {}) {
16699
+ if (typeof string !== "string" || string.length === 0) {
16531
16700
  return 0;
16532
16701
  }
16533
16702
  const {
16534
16703
  ambiguousIsNarrow = true,
16535
16704
  countAnsiEscapeCodes = false
16536
16705
  } = options;
16537
- let string = input;
16538
- if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("›"))) {
16706
+ if (!countAnsiEscapeCodes) {
16539
16707
  string = stripAnsi(string);
16540
16708
  }
16541
16709
  if (string.length === 0) {
16542
16710
  return 0;
16543
16711
  }
16544
- if (/^[\u0020-\u007E]*$/.test(string)) {
16545
- return string.length;
16546
- }
16547
16712
  let width = 0;
16548
16713
  const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
16549
- for (const { segment } of segmenter.segment(string)) {
16550
- if (isZeroWidthCluster(segment)) {
16714
+ for (const { segment: character } of segmenter.segment(string)) {
16715
+ const codePoint = character.codePointAt(0);
16716
+ if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
16551
16717
  continue;
16552
16718
  }
16553
- if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
16554
- width += 2;
16719
+ if (codePoint >= 8203 && codePoint <= 8207 || codePoint === 65279) {
16720
+ continue;
16721
+ }
16722
+ if (codePoint >= 768 && codePoint <= 879 || codePoint >= 6832 && codePoint <= 6911 || codePoint >= 7616 && codePoint <= 7679 || codePoint >= 8400 && codePoint <= 8447 || codePoint >= 65056 && codePoint <= 65071) {
16723
+ continue;
16724
+ }
16725
+ if (codePoint >= 55296 && codePoint <= 57343) {
16726
+ continue;
16727
+ }
16728
+ if (codePoint >= 65024 && codePoint <= 65039) {
16729
+ continue;
16730
+ }
16731
+ if (defaultIgnorableCodePointRegex.test(character)) {
16555
16732
  continue;
16556
16733
  }
16557
- const visibleSegment = baseVisible(segment);
16558
- const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
16559
- if (hangulWidth !== undefined) {
16560
- width += hangulWidth;
16734
+ if (import_emoji_regex.default().test(character)) {
16735
+ width += 2;
16561
16736
  continue;
16562
16737
  }
16563
- const codePoint = visibleSegment.codePointAt(0);
16564
16738
  width += eastAsianWidth(codePoint, eastAsianWidthOptions);
16565
- width += trailingWidth(visibleSegment, eastAsianWidthOptions);
16566
16739
  }
16567
16740
  return width;
16568
16741
  }
16569
- var segmenter, zeroWidthClusterRegex, leadingNonPrintingRegex, spacingMarkRegex, rgiEmojiRegex, unqualifiedKeycapRegex, extendedPictographicRegex;
16742
+ var import_emoji_regex, segmenter, defaultIgnorableCodePointRegex;
16570
16743
  var init_string_width = __esm(() => {
16571
16744
  init_strip_ansi();
16572
16745
  init_get_east_asian_width();
16746
+ import_emoji_regex = __toESM(require_emoji_regex(), 1);
16573
16747
  segmenter = new Intl.Segmenter;
16574
- zeroWidthClusterRegex = /^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Format}|\p{Nonspacing_Mark}|\p{Enclosing_Mark}|\p{Surrogate})+$/v;
16575
- leadingNonPrintingRegex = /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Nonspacing_Mark}\p{Enclosing_Mark}\p{Surrogate}]+/v;
16576
- spacingMarkRegex = /\p{Spacing_Mark}/v;
16577
- rgiEmojiRegex = /^\p{RGI_Emoji}$/v;
16578
- unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
16579
- extendedPictographicRegex = /\p{Extended_Pictographic}/gu;
16748
+ defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
16580
16749
  });
16581
16750
 
16582
16751
  // src/ui/table.ts
@@ -16681,12 +16850,12 @@ function formatTable(tableLines, opts = {}) {
16681
16850
  const a = isHeader && align[c] === undefined ? "center" : align[c] ?? "left";
16682
16851
  cells.push(pad(cell, widths[c], a));
16683
16852
  }
16684
- const content = cells.map((c) => pc.dim("│ ") + c).join("") + pc.dim("│");
16685
- return isHeader ? pc.bold(content) : content;
16853
+ const content = cells.map((c) => pc2.dim("│ ") + c).join("") + pc2.dim("│");
16854
+ return isHeader ? pc2.bold(content) : content;
16686
16855
  };
16687
16856
  const border = (l, m, r) => {
16688
16857
  const seg = widths.map((w) => "─".repeat(w + 2)).join(m);
16689
- return pc.dim(l + seg + r);
16858
+ return pc2.dim(l + seg + r);
16690
16859
  };
16691
16860
  const out = [];
16692
16861
  out.push(border("┌", "┬", "┐"));
@@ -16784,7 +16953,7 @@ class Spinner {
16784
16953
  return;
16785
16954
  const frame = FRAMES[this.frame % FRAMES.length];
16786
16955
  this.frame++;
16787
- this.stream.write("\r" + pc.cyan(frame) + " " + this.message + "\x1B[K");
16956
+ this.stream.write("\r" + pc2.cyan(frame) + " " + this.message + "\x1B[K");
16788
16957
  }
16789
16958
  }
16790
16959
  var FRAMES;
@@ -16851,19 +17020,19 @@ function box(lines, opts = {}) {
16851
17020
  const title = opts.title ?? "";
16852
17021
  if (title) {
16853
17022
  const head = `─ ${title} `;
16854
- out.push(pc.dim(`┌${head}${"─".repeat(Math.max(0, width - 2 - stringWidth(head)))}┐`));
17023
+ out.push(pc2.dim(`┌${head}${"─".repeat(Math.max(0, width - 2 - stringWidth(head)))}┐`));
16855
17024
  } else {
16856
- out.push(pc.dim(`┌${"─".repeat(width - 2)}┐`));
17025
+ out.push(pc2.dim(`┌${"─".repeat(width - 2)}┐`));
16857
17026
  }
16858
17027
  for (const line of wrapped) {
16859
- out.push(pc.dim("│") + " ".repeat(pad2) + padTo(line, inner) + " ".repeat(pad2) + pc.dim("│"));
17028
+ out.push(pc2.dim("│") + " ".repeat(pad2) + padTo(line, inner) + " ".repeat(pad2) + pc2.dim("│"));
16860
17029
  }
16861
- out.push(pc.dim(`└${"─".repeat(width - 2)}┘`));
17030
+ out.push(pc2.dim(`└${"─".repeat(width - 2)}┘`));
16862
17031
  return out;
16863
17032
  }
16864
17033
  function divider(width) {
16865
17034
  const w = Math.min(width ?? getTerminalWidth(), 60);
16866
- return pc.dim("─".repeat(w));
17035
+ return pc2.dim("─".repeat(w));
16867
17036
  }
16868
17037
  var init_box = __esm(() => {
16869
17038
  init_string_width();
@@ -16883,7 +17052,7 @@ async function withSpinner(message, fn) {
16883
17052
  }
16884
17053
  }
16885
17054
  function menuList(items) {
16886
- const lines = items.map((it, i) => ` ${pc.cyan(`[${i + 1}]`)} ${it.label}${it.url ? ` ${pc.dim(it.url)}` : ""}`);
17055
+ const lines = items.map((it, i) => ` ${pc2.cyan(`[${i + 1}]`)} ${it.label}${it.url ? ` ${pc2.dim(it.url)}` : ""}`);
16887
17056
  for (const l of box(lines, { width: 72 }))
16888
17057
  console.log(l);
16889
17058
  }
@@ -17018,15 +17187,15 @@ async function runSetup(externalRl) {
17018
17187
  }
17019
17188
  const connected = await withSpinner(t("setup.testing_spinner", { model }), () => testChat(apiBase, apiKey, model));
17020
17189
  if (connected) {
17021
- console.log(pc.green(t("setup.ok")));
17190
+ console.log(pc2.green(t("setup.ok")));
17022
17191
  } else {
17023
- console.log(pc.yellow(t("setup.warning")));
17192
+ console.log(pc2.yellow(t("setup.warning")));
17024
17193
  }
17025
17194
  console.log(t("setup.agent_settings"));
17026
17195
  const contextWindow = parseInt(await ask(rl, t("setup.context_window"), "32768"));
17027
17196
  const maxIterations = parseInt(await ask(rl, t("setup.max_iters"), "1000"));
17028
17197
  console.log(t("setup.security_header"));
17029
- console.log(pc.dim(t("setup.security_status_off")));
17198
+ console.log(pc2.dim(t("setup.security_status_off")));
17030
17199
  const configureSecurity = await ask(rl, t("setup.security_configure"), "n");
17031
17200
  let securityBashBlock = false;
17032
17201
  let securityFlagsBlock = false;
@@ -17050,7 +17219,7 @@ async function runSetup(externalRl) {
17050
17219
  securityFlagsBlock,
17051
17220
  securityPathsDeny
17052
17221
  };
17053
- console.log(pc.green(pc.bold(t("setup.complete"))));
17222
+ console.log(pc2.green(pc2.bold(t("setup.complete"))));
17054
17223
  const summary = renderTable([
17055
17224
  t("setup.summary_setting"),
17056
17225
  t("setup.summary_value"),
@@ -17110,9 +17279,9 @@ __export(exports_manifest, {
17110
17279
  getCertMark: () => getCertMark,
17111
17280
  MANIFEST_PATH: () => MANIFEST_PATH
17112
17281
  });
17113
- import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync15 } from "fs";
17282
+ import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "fs";
17114
17283
  import { homedir as homedir13 } from "os";
17115
- import { join as join28 } from "path";
17284
+ import { join as join29 } from "path";
17116
17285
  function readManifest(path = MANIFEST_PATH) {
17117
17286
  try {
17118
17287
  if (existsSync36(path)) {
@@ -17123,8 +17292,8 @@ function readManifest(path = MANIFEST_PATH) {
17123
17292
  return { version: 1, certifications: [] };
17124
17293
  }
17125
17294
  function saveManifest(m, path = MANIFEST_PATH) {
17126
- mkdirSync15(join28(homedir13(), ".mma"), { recursive: true });
17127
- writeFileSync15(path, JSON.stringify(m, null, 2), "utf-8");
17295
+ mkdirSync15(join29(homedir13(), ".mma"), { recursive: true });
17296
+ writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
17128
17297
  }
17129
17298
  function upsertCertification(entry, path = MANIFEST_PATH) {
17130
17299
  const m = readManifest(path);
@@ -17158,7 +17327,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
17158
17327
  }
17159
17328
  var MANIFEST_PATH;
17160
17329
  var init_manifest = __esm(() => {
17161
- MANIFEST_PATH = join28(homedir13(), ".mma", "certifications.json");
17330
+ MANIFEST_PATH = join29(homedir13(), ".mma", "certifications.json");
17162
17331
  });
17163
17332
 
17164
17333
  // node_modules/yaml/dist/nodes/identity.js
@@ -24282,7 +24451,7 @@ var init_scenarios = __esm(() => {
24282
24451
 
24283
24452
  // src/modules/certification/loader.ts
24284
24453
  import { existsSync as existsSync37, readdirSync as readdirSync10, readFileSync as readFileSync24 } from "fs";
24285
- import { join as join29 } from "path";
24454
+ import { join as join30 } from "path";
24286
24455
  function validateScenario(s) {
24287
24456
  const errors2 = [];
24288
24457
  const isSkip = s.mode === "skip";
@@ -24336,7 +24505,7 @@ function loadScenarios(userDir) {
24336
24505
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
24337
24506
  continue;
24338
24507
  try {
24339
- const raw = readFileSync24(join29(userDir, file), "utf-8");
24508
+ const raw = readFileSync24(join30(userDir, file), "utf-8");
24340
24509
  const data = $parse(raw);
24341
24510
  const parsed = normalizeScenario(data, file);
24342
24511
  const errs = validateScenario(parsed);
@@ -24390,7 +24559,7 @@ var init_loader3 = __esm(() => {
24390
24559
 
24391
24560
  // src/modules/certification/fact-checker.ts
24392
24561
  import { existsSync as existsSync38, readFileSync as readFileSync25, statSync as statSync7 } from "fs";
24393
- import { join as join30 } from "path";
24562
+ import { join as join31 } from "path";
24394
24563
  function checkSandbox(sandboxDir, checks, exitCode, output) {
24395
24564
  const failures = [];
24396
24565
  for (const check of checks) {
@@ -24407,13 +24576,13 @@ function runCheck(sandboxDir, check, exitCode, output) {
24407
24576
  case "outputContains":
24408
24577
  return output.includes(check.text);
24409
24578
  case "fileExists":
24410
- return isFile(join30(sandboxDir, check.path));
24579
+ return isFile(join31(sandboxDir, check.path));
24411
24580
  case "fileNotExists":
24412
- return !existsSync38(join30(sandboxDir, check.path));
24581
+ return !existsSync38(join31(sandboxDir, check.path));
24413
24582
  case "dirExists":
24414
- return isDir(join30(sandboxDir, check.path));
24583
+ return isDir(join31(sandboxDir, check.path));
24415
24584
  case "fileContent": {
24416
- const abs = join30(sandboxDir, check.path);
24585
+ const abs = join31(sandboxDir, check.path);
24417
24586
  if (!isFile(abs))
24418
24587
  return false;
24419
24588
  const content = readFileSync25(abs, "utf-8");
@@ -24424,7 +24593,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
24424
24593
  return false;
24425
24594
  }
24426
24595
  case "fileRegex": {
24427
- const abs = join30(sandboxDir, check.path);
24596
+ const abs = join31(sandboxDir, check.path);
24428
24597
  if (!isFile(abs))
24429
24598
  return false;
24430
24599
  return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
@@ -24475,7 +24644,7 @@ var init_fact_checker = () => {};
24475
24644
  import { spawn as spawn6 } from "child_process";
24476
24645
  import { existsSync as existsSync39, mkdirSync as mkdirSync16, rmSync as rmSync3, cpSync as cpSync2 } from "fs";
24477
24646
  import { platform as platform4 } from "os";
24478
- import { join as join31, resolve as resolve19, dirname as dirname9 } from "path";
24647
+ import { join as join32, resolve as resolve19, dirname as dirname9 } from "path";
24479
24648
  async function runScenario(scenario, opts) {
24480
24649
  if (scenario.mode === "skip") {
24481
24650
  return {
@@ -24494,7 +24663,7 @@ async function runScenario(scenario, opts) {
24494
24663
  let passed = 0;
24495
24664
  let firstError;
24496
24665
  for (let i = 1;i <= reps; i++) {
24497
- const sandbox = join31(opts.sandboxBase, `run-${scenario.id}-${i}`);
24666
+ const sandbox = join32(opts.sandboxBase, `run-${scenario.id}-${i}`);
24498
24667
  let failures = [];
24499
24668
  let exitCode = -1;
24500
24669
  let output = "";
@@ -24555,20 +24724,20 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
24555
24724
  rmSync3(sandbox, { recursive: true, force: true });
24556
24725
  mkdirSync16(sandbox, { recursive: true });
24557
24726
  for (const f of scenario.fixtures ?? []) {
24558
- const src = join31(mmaRoot, f.source);
24727
+ const src = join32(mmaRoot, f.source);
24559
24728
  if (!existsSync39(src)) {
24560
24729
  throw new Error(`fixture missing: ${f.source}`);
24561
24730
  }
24562
- const dest = join31(sandbox, f.dest);
24731
+ const dest = join32(sandbox, f.dest);
24563
24732
  mkdirSync16(dirname9(dest), { recursive: true });
24564
24733
  cpSync2(src, dest);
24565
24734
  }
24566
24735
  }
24567
24736
  function resolveMmaEntry(mmaRoot) {
24568
- const dev = join31(mmaRoot, "src", "cli", "main.ts");
24737
+ const dev = join32(mmaRoot, "src", "cli", "main.ts");
24569
24738
  if (existsSync39(dev))
24570
24739
  return dev;
24571
- return join31(mmaRoot, "dist", "main.js");
24740
+ return join32(mmaRoot, "dist", "main.js");
24572
24741
  }
24573
24742
  function findMmaRoot(fromDir) {
24574
24743
  const candidates = [
@@ -24576,7 +24745,7 @@ function findMmaRoot(fromDir) {
24576
24745
  resolve19(fromDir, "..")
24577
24746
  ];
24578
24747
  for (const c of candidates) {
24579
- if (existsSync39(join31(c, "package.json")))
24748
+ if (existsSync39(join32(c, "package.json")))
24580
24749
  return c;
24581
24750
  }
24582
24751
  return process.cwd();
@@ -24644,12 +24813,12 @@ __export(exports_cli, {
24644
24813
  });
24645
24814
  import { rmSync as rmSync4 } from "fs";
24646
24815
  import { homedir as homedir14 } from "os";
24647
- import { join as join32, dirname as dirname10 } from "path";
24816
+ import { join as join33, dirname as dirname10 } from "path";
24648
24817
  import { fileURLToPath } from "url";
24649
24818
  import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
24650
24819
  function readVersion() {
24651
24820
  const candidates = [
24652
- join32(MMA_ROOT, "package.json")
24821
+ join33(MMA_ROOT, "package.json")
24653
24822
  ];
24654
24823
  for (const p of candidates) {
24655
24824
  if (existsSync40(p)) {
@@ -24666,36 +24835,36 @@ function parseTags(s) {
24666
24835
  async function certify(opts) {
24667
24836
  const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
24668
24837
  if (opts.tags.includes("security") && !opts.config.security?.enabled) {
24669
- console.error(pc.red(t("cli.cert_security_required")));
24838
+ console.error(pc2.red(t("cli.cert_security_required")));
24670
24839
  process.exitCode = 1;
24671
24840
  return;
24672
24841
  }
24673
24842
  const { scenarios, errors: errors2 } = loadScenarios(USER_SCENARIO_DIR);
24674
24843
  for (const e of errors2)
24675
- console.error(pc.yellow(` ${e}`));
24844
+ console.error(pc2.yellow(` ${e}`));
24676
24845
  const selected = filterByTags(scenarios, opts.tags);
24677
24846
  if (selected.length === 0) {
24678
- console.error(pc.red(t("cli.cert_no_scenarios", { tags: opts.tags.join(",") })));
24847
+ console.error(pc2.red(t("cli.cert_no_scenarios", { tags: opts.tags.join(",") })));
24679
24848
  process.exitCode = 1;
24680
24849
  return;
24681
24850
  }
24682
24851
  const manifest = readManifest();
24683
24852
  const existing = manifest.certifications.find((e) => e.model === opts.name && e.providerUrl === providerUrl);
24684
24853
  if (existing && !opts.force) {
24685
- console.error(pc.yellow(t("cli.cert_exists", { model: opts.name })));
24686
- console.error(pc.yellow(t("cli.cert_exists_hint")));
24854
+ console.error(pc2.yellow(t("cli.cert_exists", { model: opts.name })));
24855
+ console.error(pc2.yellow(t("cli.cert_exists_hint")));
24687
24856
  process.exitCode = 1;
24688
24857
  return;
24689
24858
  }
24690
24859
  console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
24691
- const sandboxBase = join32(process.cwd(), ".mma", "certification");
24860
+ const sandboxBase = join33(process.cwd(), ".mma", "certification");
24692
24861
  const results = [];
24693
24862
  const total = selected.length;
24694
24863
  let idx = 0;
24695
24864
  for (const scenario of selected) {
24696
24865
  idx++;
24697
24866
  if (scenario.mode === "skip") {
24698
- console.log(pc.dim(`[${idx}/${total}] ${scenario.id} ... skipped`));
24867
+ console.log(pc2.dim(`[${idx}/${total}] ${scenario.id} ... skipped`));
24699
24868
  results.push({ id: scenario.id, title: scenario.title, status: "skipped", passed: 0, of: 0 });
24700
24869
  continue;
24701
24870
  }
@@ -24709,10 +24878,10 @@ async function certify(opts) {
24709
24878
  defaultReps: opts.reps,
24710
24879
  defaultThreshold: 2,
24711
24880
  onRep: (id, rep, reps, passed, failures) => {
24712
- const word = passed ? pc.green(t("cli.cert_rep_pass")) : pc.red(t("cli.cert_rep_fail"));
24881
+ const word = passed ? pc2.green(t("cli.cert_rep_pass")) : pc2.red(t("cli.cert_rep_fail"));
24713
24882
  console.log(`[${idx}/${total}] ${id} (${rep}/${reps})... ${word}`);
24714
24883
  if (!passed)
24715
- console.log(` ${pc.dim(failures.join("; "))}`);
24884
+ console.log(` ${pc2.dim(failures.join("; "))}`);
24716
24885
  }
24717
24886
  });
24718
24887
  results.push(res);
@@ -24760,7 +24929,7 @@ async function certList() {
24760
24929
  return;
24761
24930
  }
24762
24931
  for (const e of m.certifications) {
24763
- console.log(` ${pc.green("✔")} ${e.model} ${pc.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
24932
+ console.log(` ${pc2.green("✔")} ${e.model} ${pc2.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
24764
24933
  }
24765
24934
  }
24766
24935
  async function uncertify(name, config) {
@@ -24780,11 +24949,11 @@ function summarize(results) {
24780
24949
  }
24781
24950
  function printResults(results) {
24782
24951
  for (const r of results) {
24783
- const icon = r.status === "pass" ? pc.green("✔") : r.status === "fail" ? pc.red("✘") : r.status === "skipped" ? pc.dim("–") : pc.yellow("!");
24784
- const detail = r.status === "skipped" ? pc.dim(r.title) : `${r.passed}/${r.of}`;
24952
+ const icon = r.status === "pass" ? pc2.green("✔") : r.status === "fail" ? pc2.red("✘") : r.status === "skipped" ? pc2.dim("–") : pc2.yellow("!");
24953
+ const detail = r.status === "skipped" ? pc2.dim(r.title) : `${r.passed}/${r.of}`;
24785
24954
  console.log(` ${icon} ${r.id} ${detail}`);
24786
24955
  if (r.error)
24787
- console.log(` ${pc.dim(r.error)}`);
24956
+ console.log(` ${pc2.dim(r.error)}`);
24788
24957
  }
24789
24958
  }
24790
24959
  var HERE, MMA_ROOT, USER_SCENARIO_DIR;
@@ -24796,7 +24965,7 @@ var init_cli = __esm(() => {
24796
24965
  init_manifest();
24797
24966
  HERE = dirname10(fileURLToPath(import.meta.url));
24798
24967
  MMA_ROOT = findMmaRoot(HERE);
24799
- USER_SCENARIO_DIR = join32(homedir14(), ".mma", "certification", "scenarios");
24968
+ USER_SCENARIO_DIR = join33(homedir14(), ".mma", "certification", "scenarios");
24800
24969
  });
24801
24970
 
24802
24971
  // src/cli/repl-commands.ts
@@ -24805,15 +24974,15 @@ __export(exports_repl_commands, {
24805
24974
  registerAllCommands: () => registerAllCommands,
24806
24975
  COMMAND_GROUPS: () => COMMAND_GROUPS
24807
24976
  });
24808
- import { join as join34, dirname as dirname12 } from "path";
24977
+ import { join as join35, dirname as dirname12 } from "path";
24809
24978
  import { homedir as homedir16 } from "os";
24810
24979
  import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
24811
24980
  import { fileURLToPath as fileURLToPath3 } from "url";
24812
24981
  function readVersion3() {
24813
24982
  const here = dirname12(fileURLToPath3(import.meta.url));
24814
24983
  const candidates = [
24815
- join34(here, "..", "..", "package.json"),
24816
- join34(here, "..", "package.json")
24984
+ join35(here, "..", "..", "package.json"),
24985
+ join35(here, "..", "package.json")
24817
24986
  ];
24818
24987
  for (const p of candidates) {
24819
24988
  if (existsSync42(p)) {
@@ -24887,7 +25056,7 @@ function registerMmaCommands(ctx) {
24887
25056
  if (source.toLowerCase() === "clipboard") {
24888
25057
  const clipBuf = await readClipboardImage2();
24889
25058
  if (!clipBuf) {
24890
- console.log(pc.yellow(t("image.clipboard_empty")));
25059
+ console.log(pc2.yellow(t("image.clipboard_empty")));
24891
25060
  return;
24892
25061
  }
24893
25062
  const { bufferToDataUrl: bufferToDataUrl2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
@@ -24901,7 +25070,7 @@ function registerMmaCommands(ctx) {
24901
25070
  } else {
24902
25071
  const absPath = resolve20(process.cwd(), source);
24903
25072
  if (!existsSync43(absPath)) {
24904
- console.log(pc.red(t("image.not_found", { path: source })));
25073
+ console.log(pc2.red(t("image.not_found", { path: source })));
24905
25074
  return;
24906
25075
  }
24907
25076
  const result = await loadFileAsDataUrl2(absPath);
@@ -24910,7 +25079,7 @@ function registerMmaCommands(ctx) {
24910
25079
  }
24911
25080
  const contextManager = ctx.agent.contextManager;
24912
25081
  if (!contextManager) {
24913
- console.log(pc.red(t("image.no_context")));
25082
+ console.log(pc2.red(t("image.no_context")));
24914
25083
  return;
24915
25084
  }
24916
25085
  contextManager.addPendingImage({
@@ -24918,9 +25087,9 @@ function registerMmaCommands(ctx) {
24918
25087
  image_url: { url: dataUrl }
24919
25088
  });
24920
25089
  const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
24921
- console.log(pc.green(t("image.attached", { source: label, size: `${sizeKb} KB` })));
25090
+ console.log(pc2.green(t("image.attached", { source: label, size: `${sizeKb} KB` })));
24922
25091
  } catch (err) {
24923
- console.log(pc.red(t("image.error", { message: err.message })));
25092
+ console.log(pc2.red(t("image.error", { message: err.message })));
24924
25093
  }
24925
25094
  }
24926
25095
  });
@@ -24938,7 +25107,7 @@ function registerMmaCommands(ctx) {
24938
25107
  console.log(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
24939
25108
  console.log(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
24940
25109
  console.log(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
24941
- console.log(`${t("repl.reasoning_label")} ${cfg.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"))}`);
25110
+ console.log(`${t("repl.reasoning_label")} ${cfg.showReasoning ? pc2.green(t("repl.show")) : pc2.dim(t("repl.hide"))}`);
24942
25111
  console.log(`${t("repl.log_level")} ${cfg.logLevel}`);
24943
25112
  console.log(`${t("repl.locale")} ${cfg.locale}`);
24944
25113
  const meta = ctx.sessionManager?.getActiveMeta();
@@ -24953,7 +25122,7 @@ function registerMmaCommands(ctx) {
24953
25122
  usage: t("repl.reasoning_usage"),
24954
25123
  action: () => {
24955
25124
  ctx.config.showReasoning = !ctx.config.showReasoning;
24956
- const status = ctx.config.showReasoning ? pc.green(t("repl.show")) : pc.dim(t("repl.hide"));
25125
+ const status = ctx.config.showReasoning ? pc2.green(t("repl.show")) : pc2.dim(t("repl.hide"));
24957
25126
  console.log(t("repl.reasoning_status", { status }));
24958
25127
  }
24959
25128
  });
@@ -24976,10 +25145,10 @@ function registerMmaCommands(ctx) {
24976
25145
  aliases: ["setup"],
24977
25146
  usage: t("repl.wizard_usage"),
24978
25147
  action: async () => {
24979
- console.log(pc.yellow(t("repl.wizard_running")));
25148
+ console.log(pc2.yellow(t("repl.wizard_running")));
24980
25149
  await ctx.withExclusiveInput(async () => {
24981
25150
  const answers = await runSetup(ctx.rl);
24982
- const configPath = join34(homedir16(), ".mma", "config.json");
25151
+ const configPath = join35(homedir16(), ".mma", "config.json");
24983
25152
  ctx.config.provider.type = answers.provider;
24984
25153
  ctx.config.provider.baseUrl = answers.apiBase;
24985
25154
  ctx.config.provider.apiKey = answers.apiKey;
@@ -24989,7 +25158,7 @@ function registerMmaCommands(ctx) {
24989
25158
  ctx.config.locale = answers.locale;
24990
25159
  saveConfig(ctx.config, configPath);
24991
25160
  await ctx.agent.reconfigure(ctx.config);
24992
- console.log(pc.green(t("cli.config_saved")));
25161
+ console.log(pc2.green(t("cli.config_saved")));
24993
25162
  });
24994
25163
  }
24995
25164
  });
@@ -24999,18 +25168,18 @@ function registerMmaCommands(ctx) {
24999
25168
  usage: t("repl.sysprompt_desc"),
25000
25169
  action: () => {
25001
25170
  const info = ctx.agent.getSystemPromptInfo();
25002
- console.log(pc.bold(`System prompt (${info.tokenCount} tokens):`));
25003
- console.log(pc.dim("─".repeat(60)));
25171
+ console.log(pc2.bold(`System prompt (${info.tokenCount} tokens):`));
25172
+ console.log(pc2.dim("─".repeat(60)));
25004
25173
  for (const line of info.text.split(`
25005
25174
  `)) {
25006
25175
  console.log(line);
25007
25176
  }
25008
- console.log(pc.dim("─".repeat(60)));
25177
+ console.log(pc2.dim("─".repeat(60)));
25009
25178
  if (info.excluded.length > 0) {
25010
- console.log(pc.yellow(`
25179
+ console.log(pc2.yellow(`
25011
25180
  Excluded blocks: ${info.excluded.length}`));
25012
25181
  for (const e of info.excluded) {
25013
- console.log(pc.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
25182
+ console.log(pc2.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
25014
25183
  }
25015
25184
  }
25016
25185
  }
@@ -25033,10 +25202,10 @@ Excluded blocks: ${info.excluded.length}`));
25033
25202
  return;
25034
25203
  }
25035
25204
  ctx.config.provider.type = name;
25036
- const configPath = join34(homedir16(), ".mma", "config.json");
25205
+ const configPath = join35(homedir16(), ".mma", "config.json");
25037
25206
  saveConfig(ctx.config, configPath);
25038
25207
  await ctx.agent.reconfigure(ctx.config);
25039
- console.log(pc.green(t("repl.provider_set", { name })));
25208
+ console.log(pc2.green(t("repl.provider_set", { name })));
25040
25209
  return;
25041
25210
  }
25042
25211
  console.log(t("repl.provider_usage"));
@@ -25067,9 +25236,9 @@ Excluded blocks: ${info.excluded.length}`));
25067
25236
  console.log(t("cli.available_models"));
25068
25237
  const { getCertMark: getCertMark2 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
25069
25238
  for (const m of models) {
25070
- const marker = m === ctx.config.model ? pc.green("* ") : " ";
25239
+ const marker = m === ctx.config.model ? pc2.green("* ") : " ";
25071
25240
  const mark = getCertMark2(m, ctx.config.provider.baseUrl, version2);
25072
- const cert = mark === "certified" ? pc.green("✔") : mark === "stale" ? pc.yellow("○") : pc.dim("·");
25241
+ const cert = mark === "certified" ? pc2.green("✔") : mark === "stale" ? pc2.yellow("○") : pc2.dim("·");
25073
25242
  console.log(` ${marker}${cert} ${m}`);
25074
25243
  }
25075
25244
  } else {
@@ -25089,10 +25258,10 @@ Excluded blocks: ${info.excluded.length}`));
25089
25258
  return;
25090
25259
  }
25091
25260
  ctx.config.model = name;
25092
- const configPath = join34(homedir16(), ".mma", "config.json");
25261
+ const configPath = join35(homedir16(), ".mma", "config.json");
25093
25262
  saveConfig(ctx.config, configPath);
25094
25263
  await ctx.agent.reconfigure(ctx.config);
25095
- console.log(pc.green(t("repl.model_set", { name })));
25264
+ console.log(pc2.green(t("repl.model_set", { name })));
25096
25265
  return;
25097
25266
  }
25098
25267
  console.log(t("repl.model_usage"));
@@ -25114,10 +25283,10 @@ Excluded blocks: ${info.excluded.length}`));
25114
25283
  return;
25115
25284
  }
25116
25285
  ctx.config.contextWindow = size;
25117
- const configPath = join34(homedir16(), ".mma", "config.json");
25286
+ const configPath = join35(homedir16(), ".mma", "config.json");
25118
25287
  saveConfig(ctx.config, configPath);
25119
25288
  await ctx.agent.reconfigure(ctx.config);
25120
- console.log(pc.green(t("cli.context_set", { size })));
25289
+ console.log(pc2.green(t("cli.context_set", { size })));
25121
25290
  }
25122
25291
  });
25123
25292
  ctx.registerCommand({
@@ -25125,7 +25294,7 @@ Excluded blocks: ${info.excluded.length}`));
25125
25294
  description: t("repl.reload"),
25126
25295
  usage: t("repl.reload_usage"),
25127
25296
  action: async () => {
25128
- console.log(pc.yellow(t("repl.reloading")));
25297
+ console.log(pc2.yellow(t("repl.reloading")));
25129
25298
  if (ctx.sessionManager && ctx.config.session.autoSave) {
25130
25299
  const active = ctx.sessionManager.getActiveMeta();
25131
25300
  if (active) {}
@@ -25133,19 +25302,20 @@ Excluded blocks: ${info.excluded.length}`));
25133
25302
  ctx.agent.shutdown();
25134
25303
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
25135
25304
  const { homedir: homedir17 } = await import("os");
25136
- const { join: join35 } = await import("path");
25137
- const configDir = join35(homedir17(), ".mma");
25138
- const projectConfigPath = join35(process.cwd(), ".mmrc");
25305
+ const { join: join36 } = await import("path");
25306
+ const configDir = ctx.configDir;
25307
+ const baseDir = ctx.baseDir;
25308
+ const projectConfigPath = join36(baseDir, ".mmrc");
25139
25309
  const freshConfig = loadConfig2({ configDir, projectConfigPath });
25140
25310
  Object.assign(ctx.config, freshConfig);
25141
25311
  const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
25142
- const result = await bootstrap2(configDir, process.cwd(), false, false);
25312
+ const result = await bootstrap2(configDir, baseDir, false, false);
25143
25313
  ctx.agent = result.agent;
25144
25314
  ctx.sessionManager = result.sessionManager;
25145
25315
  ctx.skillsModule = result.skillsModule;
25146
25316
  ctx.pluginManager = result.pluginManager;
25147
25317
  ctx.setupCompleter();
25148
- console.log(pc.green(t("repl.reloaded")));
25318
+ console.log(pc2.green(t("repl.reloaded")));
25149
25319
  console.log(`${t("repl.model")} ${ctx.config.model}`);
25150
25320
  console.log(`${t("repl.context")} ${ctx.config.contextWindow}`);
25151
25321
  console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
@@ -25168,7 +25338,7 @@ function registerSessionCommands(ctx) {
25168
25338
  return;
25169
25339
  }
25170
25340
  const rows = sessions.map((s) => [
25171
- s.id === active ? pc.green("●") : "",
25341
+ s.id === active ? pc2.green("●") : "",
25172
25342
  s.id.slice(0, 12),
25173
25343
  s.name,
25174
25344
  s.updatedAt.slice(0, 19).replace("T", " "),
@@ -25183,7 +25353,7 @@ function registerSessionCommands(ctx) {
25183
25353
  ], rows)) {
25184
25354
  console.log(line);
25185
25355
  }
25186
- console.log(pc.dim(`
25356
+ console.log(pc2.dim(`
25187
25357
  ${t("repl.resume_hint")}`));
25188
25358
  }
25189
25359
  });
@@ -25197,8 +25367,8 @@ function registerSessionCommands(ctx) {
25197
25367
  const meta = ctx.sessionManager.create(name);
25198
25368
  ctx.agent.clearContext();
25199
25369
  console.clear();
25200
- console.log(`${t("session.created", { name: meta.name })} (${pc.dim(meta.id.slice(0, 12))})`);
25201
- console.log(pc.dim(` ${t("session.chat_cleared")}
25370
+ console.log(`${t("session.created", { name: meta.name })} (${pc2.dim(meta.id.slice(0, 12))})`);
25371
+ console.log(pc2.dim(` ${t("session.chat_cleared")}
25202
25372
  `));
25203
25373
  }
25204
25374
  });
@@ -25211,13 +25381,13 @@ function registerSessionCommands(ctx) {
25211
25381
  const query = args.join(" ");
25212
25382
  const sessions = ctx.sessionManager.list();
25213
25383
  if (!query) {
25214
- console.log(pc.dim(t("session.available")));
25384
+ console.log(pc2.dim(t("session.available")));
25215
25385
  const active = ctx.sessionManager.getActive();
25216
25386
  for (const s of sessions) {
25217
- const marker = s.id === active ? pc.green(" *") : " ";
25218
- console.log(pc.dim(` ${marker} ${s.id.slice(0, 12)} ${s.name}`));
25387
+ const marker = s.id === active ? pc2.green(" *") : " ";
25388
+ console.log(pc2.dim(` ${marker} ${s.id.slice(0, 12)} ${s.name}`));
25219
25389
  }
25220
- console.log(pc.dim(`
25390
+ console.log(pc2.dim(`
25221
25391
  ${t("repl.resume_usage")}`));
25222
25392
  return;
25223
25393
  }
@@ -25230,27 +25400,27 @@ function registerSessionCommands(ctx) {
25230
25400
  const history = ctx.sessionManager.loadHistory();
25231
25401
  ctx.agent.setContext(history);
25232
25402
  console.clear();
25233
- console.log(pc.bold(pc.green(t("session.resumed", { name: match.name }))) + " " + pc.dim(`(${match.id.slice(0, 12)})`) + " — " + match.messageCount + " msgs");
25234
- console.log(pc.dim("─".repeat(50)));
25403
+ console.log(pc2.bold(pc2.green(t("session.resumed", { name: match.name }))) + " " + pc2.dim(`(${match.id.slice(0, 12)})`) + " — " + match.messageCount + " msgs");
25404
+ console.log(pc2.dim("─".repeat(50)));
25235
25405
  if (history.length === 0) {
25236
- console.log(pc.dim(t("session.no_history")));
25406
+ console.log(pc2.dim(t("session.no_history")));
25237
25407
  } else {
25238
- console.log(pc.dim(t("session.chat_history")));
25408
+ console.log(pc2.dim(t("session.chat_history")));
25239
25409
  console.log();
25240
25410
  for (const msg of history) {
25241
25411
  if (msg.role === "user") {
25242
- console.log(pc.cyan(t("session.user_label") + ":"));
25412
+ console.log(pc2.cyan(t("session.user_label") + ":"));
25243
25413
  console.log(getMessageText(msg.content));
25244
25414
  console.log();
25245
25415
  } else if (msg.role === "assistant") {
25246
- console.log(pc.green(t("session.assistant_label") + ":"));
25416
+ console.log(pc2.green(t("session.assistant_label") + ":"));
25247
25417
  console.log(getMessageText(msg.content));
25248
25418
  console.log();
25249
25419
  }
25250
25420
  }
25251
25421
  }
25252
- console.log(pc.dim("─".repeat(50)));
25253
- console.log(pc.dim(` ${t("session.chat_loaded")}`));
25422
+ console.log(pc2.dim("─".repeat(50)));
25423
+ console.log(pc2.dim(` ${t("session.chat_loaded")}`));
25254
25424
  }
25255
25425
  });
25256
25426
  ctx.registerCommand({
@@ -25310,12 +25480,12 @@ function registerSkillCommands(ctx) {
25310
25480
  console.log(t("repl.no_skills"));
25311
25481
  return;
25312
25482
  }
25313
- console.log(pc.bold(t("repl.available_skills")));
25483
+ console.log(pc2.bold(t("repl.available_skills")));
25314
25484
  for (const skill of available) {
25315
25485
  const tokens = Math.ceil(skill.content.length / 4);
25316
25486
  const loaded = ctx.skillsModule.getLoaded().some((s) => s.name === skill.name);
25317
- const marker = loaded ? pc.green(" [loaded]") : "";
25318
- console.log(` ${pc.cyan(skill.name)}${marker} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25487
+ const marker = loaded ? pc2.green(" [loaded]") : "";
25488
+ console.log(` ${pc2.cyan(skill.name)}${marker} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25319
25489
  }
25320
25490
  return;
25321
25491
  }
@@ -25326,12 +25496,12 @@ function registerSkillCommands(ctx) {
25326
25496
  console.log(t("repl.no_loaded"));
25327
25497
  return;
25328
25498
  }
25329
- console.log(pc.bold(t("repl.loaded_skills")));
25499
+ console.log(pc2.bold(t("repl.loaded_skills")));
25330
25500
  for (const skill of loaded) {
25331
25501
  const tokens = Math.ceil(skill.content.length / 4);
25332
- console.log(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25502
+ console.log(` ${pc2.cyan(skill.name)} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25333
25503
  }
25334
- console.log(pc.dim(`
25504
+ console.log(pc2.dim(`
25335
25505
  ${t("repl.budget", { used: budget.used, total: budget.total, remaining: budget.remaining })}`));
25336
25506
  return;
25337
25507
  }
@@ -25342,9 +25512,9 @@ function registerSkillCommands(ctx) {
25342
25512
  }
25343
25513
  const result = ctx.skillsModule.loadByName(arg);
25344
25514
  if (result.success) {
25345
- console.log(pc.green(result.message));
25515
+ console.log(pc2.green(result.message));
25346
25516
  } else {
25347
- console.log(pc.red(result.message));
25517
+ console.log(pc2.red(result.message));
25348
25518
  }
25349
25519
  return;
25350
25520
  }
@@ -25354,9 +25524,9 @@ function registerSkillCommands(ctx) {
25354
25524
  return;
25355
25525
  }
25356
25526
  if (ctx.skillsModule.unload(arg)) {
25357
- console.log(pc.green(t("repl.skill_unloaded", { name: arg })));
25527
+ console.log(pc2.green(t("repl.skill_unloaded", { name: arg })));
25358
25528
  } else {
25359
- console.log(pc.red(t("repl.skill_not_loaded", { name: arg })));
25529
+ console.log(pc2.red(t("repl.skill_not_loaded", { name: arg })));
25360
25530
  }
25361
25531
  return;
25362
25532
  }
@@ -25370,14 +25540,14 @@ function registerSkillCommands(ctx) {
25370
25540
  console.log(t("repl.no_skill_match", { query: arg }));
25371
25541
  return;
25372
25542
  }
25373
- console.log(pc.bold(t("repl.skills_matching", { query: arg })));
25543
+ console.log(pc2.bold(t("repl.skills_matching", { query: arg })));
25374
25544
  for (const skill of results) {
25375
25545
  const tokens = Math.ceil(skill.content.length / 4);
25376
- console.log(` ${pc.cyan(skill.name)} ${pc.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25546
+ console.log(` ${pc2.cyan(skill.name)} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
25377
25547
  }
25378
25548
  return;
25379
25549
  }
25380
- console.log(pc.red(t("repl.skill_unknown_sub", { subcmd })));
25550
+ console.log(pc2.red(t("repl.skill_unknown_sub", { subcmd })));
25381
25551
  console.log(t("repl.skill_usage"));
25382
25552
  }
25383
25553
  });
@@ -25435,14 +25605,14 @@ init_bootstrap();
25435
25605
  init_config2();
25436
25606
  init_setup();
25437
25607
  init_i18n();
25438
- import { join as join33, dirname as dirname11 } from "path";
25608
+ import { join as join34, dirname as dirname11 } from "path";
25439
25609
  import { homedir as homedir15 } from "os";
25440
25610
  import { existsSync as existsSync41, readFileSync as readFileSync27 } from "fs";
25441
25611
 
25442
25612
  // src/cli/security-commands.ts
25443
25613
  init_bootstrap();
25444
25614
  init_config2();
25445
- import { join as join27 } from "path";
25615
+ import { join as join28 } from "path";
25446
25616
  import { homedir as homedir12 } from "os";
25447
25617
 
25448
25618
  // src/modules/security/security-policies.ts
@@ -25972,7 +26142,7 @@ function createSecurityCommand(program2) {
25972
26142
  }
25973
26143
  });
25974
26144
  securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
25975
- const configPath = join27(homedir12(), ".mma", "config.json");
26145
+ const configPath = join28(homedir12(), ".mma", "config.json");
25976
26146
  const { config: appConfig } = await bootstrap();
25977
26147
  const validPresets = ["strict", "balanced", "permissive"];
25978
26148
  if (!validPresets.includes(preset)) {
@@ -25987,7 +26157,7 @@ function createSecurityCommand(program2) {
25987
26157
  console.log(t("cli.security.policy_description", { description: policy.description }));
25988
26158
  });
25989
26159
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
25990
- const configPath = join27(homedir12(), ".mma", "config.json");
26160
+ const configPath = join28(homedir12(), ".mma", "config.json");
25991
26161
  const { config: appConfig } = await bootstrap();
25992
26162
  appConfig.security = appConfig.security || {};
25993
26163
  appConfig.security.sessionEncryption = {
@@ -25999,7 +26169,7 @@ function createSecurityCommand(program2) {
25999
26169
  console.log(t("cli.security.encryption_enabled"));
26000
26170
  });
26001
26171
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
26002
- const configPath = join27(homedir12(), ".mma", "config.json");
26172
+ const configPath = join28(homedir12(), ".mma", "config.json");
26003
26173
  const { config: appConfig } = await bootstrap();
26004
26174
  appConfig.security = appConfig.security || {};
26005
26175
  appConfig.security.sessionEncryption = {
@@ -26011,7 +26181,7 @@ function createSecurityCommand(program2) {
26011
26181
  console.log(t("cli.security.encryption_disabled"));
26012
26182
  });
26013
26183
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
26014
- const configPath = join27(homedir12(), ".mma", "config.json");
26184
+ const configPath = join28(homedir12(), ".mma", "config.json");
26015
26185
  const { config: appConfig } = await bootstrap();
26016
26186
  appConfig.security = appConfig.security || {};
26017
26187
  appConfig.security.auditNotifier = {
@@ -26025,7 +26195,7 @@ function createSecurityCommand(program2) {
26025
26195
  console.log(t("cli.security.audit_enabled"));
26026
26196
  });
26027
26197
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
26028
- const configPath = join27(homedir12(), ".mma", "config.json");
26198
+ const configPath = join28(homedir12(), ".mma", "config.json");
26029
26199
  const { config: appConfig } = await bootstrap();
26030
26200
  appConfig.security = appConfig.security || {};
26031
26201
  appConfig.security.auditNotifier = {
@@ -26061,8 +26231,8 @@ import { fileURLToPath as fileURLToPath2 } from "url";
26061
26231
  function readVersion2() {
26062
26232
  const here = dirname11(fileURLToPath2(import.meta.url));
26063
26233
  const candidates = [
26064
- join33(here, "..", "..", "package.json"),
26065
- join33(here, "..", "package.json")
26234
+ join34(here, "..", "..", "package.json"),
26235
+ join34(here, "..", "package.json")
26066
26236
  ];
26067
26237
  for (const p of candidates) {
26068
26238
  if (existsSync41(p)) {
@@ -26078,7 +26248,7 @@ function createProgram() {
26078
26248
  const program2 = new Command().name("mma").description(t("cli.description")).version(version).option("--no-agents-md", t("cli.no_agents_md")).option("-d, --dir <path>", t("cli.dir")).option("-e, --exit-on-complete", t("cli.exit_on_complete")).option("-j, --json", t("cli.json"));
26079
26249
  program2.command("init").description(t("cli.init")).action(async () => {
26080
26250
  const answers = await runSetup();
26081
- const configPath = join33(homedir15(), ".mma", "config.json");
26251
+ const configPath = join34(homedir15(), ".mma", "config.json");
26082
26252
  const { config } = await bootstrap();
26083
26253
  config.provider.type = answers.provider;
26084
26254
  config.provider.baseUrl = answers.apiBase;
@@ -26123,7 +26293,7 @@ function createProgram() {
26123
26293
  });
26124
26294
  const configCmd = program2.command("config").description(t("cli.manage_config"));
26125
26295
  configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
26126
- const configPath = join33(homedir15(), ".mma", "config.json");
26296
+ const configPath = join34(homedir15(), ".mma", "config.json");
26127
26297
  const { config } = await bootstrap();
26128
26298
  const keys = key.split(".");
26129
26299
  let obj = config;
@@ -26186,7 +26356,7 @@ function createProgram() {
26186
26356
  console.log(t("cli.model_hint"));
26187
26357
  });
26188
26358
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
26189
- const configPath = join33(homedir15(), ".mma", "config.json");
26359
+ const configPath = join34(homedir15(), ".mma", "config.json");
26190
26360
  const { config } = await bootstrap();
26191
26361
  config.model = name;
26192
26362
  saveConfig(config, configPath);
@@ -26222,7 +26392,7 @@ function createProgram() {
26222
26392
  await uncertify2(name, config);
26223
26393
  });
26224
26394
  program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
26225
- const configPath = join33(homedir15(), ".mma", "config.json");
26395
+ const configPath = join34(homedir15(), ".mma", "config.json");
26226
26396
  const { config } = await bootstrap();
26227
26397
  const contextWindow = parseInt(size, 10);
26228
26398
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -26240,7 +26410,7 @@ function createProgram() {
26240
26410
  console.log(t("cli.base_url"), config.provider.baseUrl);
26241
26411
  });
26242
26412
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
26243
- const configPath = join33(homedir15(), ".mma", "config.json");
26413
+ const configPath = join34(homedir15(), ".mma", "config.json");
26244
26414
  const { config } = await bootstrap();
26245
26415
  config.provider.type = name;
26246
26416
  saveConfig(config, configPath);
@@ -26292,8 +26462,8 @@ init_bootstrap();
26292
26462
  // src/cli/repl.ts
26293
26463
  init_colors();
26294
26464
  import * as readline2 from "readline";
26295
- import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as writeFileSync16 } from "fs";
26296
- import { join as join35, dirname as dirname13 } from "path";
26465
+ import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
26466
+ import { join as join36, dirname as dirname13 } from "path";
26297
26467
  import { homedir as homedir17 } from "os";
26298
26468
  import { fileURLToPath as fileURLToPath4 } from "url";
26299
26469
 
@@ -26411,24 +26581,24 @@ var TAG = /<\/?([A-Z][a-zA-Z0-9]*|[a-z][a-zA-Z0-9-]*)/g;
26411
26581
  var ATTR = /\b([a-zA-Z-]+=)"([^"]*)"/g;
26412
26582
  function highlight(code, lang) {
26413
26583
  if (lang === "html" || lang === "xml" || lang === "svg") {
26414
- code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
26415
- code = code.replace(ATTR, (_m, attr, val) => pc.yellow(attr) + "=" + pc.green('"' + val + '"'));
26416
- code = code.replace(TAG, (_m, tag) => "<" + pc.cyan(tag));
26584
+ code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
26585
+ code = code.replace(ATTR, (_m, attr, val) => pc2.yellow(attr) + "=" + pc2.green('"' + val + '"'));
26586
+ code = code.replace(TAG, (_m, tag) => "<" + pc2.cyan(tag));
26417
26587
  } else if (lang === "css" || lang === "scss" || lang === "less") {
26418
- code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
26419
- code = code.replace(STRING, (m) => pc.green(m));
26420
- code = code.replace(NUMBER, (m) => pc.yellow(m));
26588
+ code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
26589
+ code = code.replace(STRING, (m) => pc2.green(m));
26590
+ code = code.replace(NUMBER, (m) => pc2.yellow(m));
26421
26591
  } else if (lang === "bash" || lang === "sh" || lang === "shell" || lang === "zsh") {
26422
- code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
26423
- code = code.replace(STRING, (m) => pc.green(m));
26592
+ code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
26593
+ code = code.replace(STRING, (m) => pc2.green(m));
26424
26594
  } else if (lang === "json") {
26425
- code = code.replace(STRING, (m) => pc.green(m));
26426
- code = code.replace(NUMBER, (m) => pc.yellow(m));
26595
+ code = code.replace(STRING, (m) => pc2.green(m));
26596
+ code = code.replace(NUMBER, (m) => pc2.yellow(m));
26427
26597
  } else {
26428
- code = code.replace(COMMENT, (m) => pc.dim(pc.green(m)));
26429
- code = code.replace(STRING, (m) => pc.green(m));
26430
- code = code.replace(KW, (m) => pc.magenta(m));
26431
- code = code.replace(NUMBER, (m) => pc.yellow(m));
26598
+ code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
26599
+ code = code.replace(STRING, (m) => pc2.green(m));
26600
+ code = code.replace(KW, (m) => pc2.magenta(m));
26601
+ code = code.replace(NUMBER, (m) => pc2.yellow(m));
26432
26602
  }
26433
26603
  return code;
26434
26604
  }
@@ -26529,13 +26699,13 @@ class FormattingStream {
26529
26699
  `);
26530
26700
  const highlighted = highlight(code, this.codeLang);
26531
26701
  const lang = this.codeLang ? ` ${this.codeLang} ` : " ";
26532
- const top = pc.dim(`┌─${lang}${"─".repeat(Math.max(0, this.width - 3 - lang.length))}┐`);
26702
+ const top = pc2.dim(`┌─${lang}${"─".repeat(Math.max(0, this.width - 3 - lang.length))}┐`);
26533
26703
  this.onWrite(top);
26534
26704
  for (const l of highlighted.split(`
26535
26705
  `)) {
26536
- this.onWrite(pc.dim("│ ") + l);
26706
+ this.onWrite(pc2.dim("│ ") + l);
26537
26707
  }
26538
- this.onWrite(pc.dim(`└${"─".repeat(Math.max(0, this.width - 1))}┘`));
26708
+ this.onWrite(pc2.dim(`└${"─".repeat(Math.max(0, this.width - 1))}┘`));
26539
26709
  }
26540
26710
  this.codeLines = [];
26541
26711
  this.codeLang = "";
@@ -26547,47 +26717,47 @@ class FormattingStream {
26547
26717
  const level = heading[1].length;
26548
26718
  const content = this.formatInline(heading[2]);
26549
26719
  if (level === 1)
26550
- return pc.cyan(pc.bold(pc.underline(content)));
26551
- return pc.cyan(pc.bold(content));
26720
+ return pc2.cyan(pc2.bold(pc2.underline(content)));
26721
+ return pc2.cyan(pc2.bold(content));
26552
26722
  }
26553
26723
  if (isHorizontalRule(result)) {
26554
- return pc.dim("─".repeat(Math.max(0, Math.min(this.width, 60))));
26724
+ return pc2.dim("─".repeat(Math.max(0, Math.min(this.width, 60))));
26555
26725
  }
26556
26726
  const quote = result.match(/^(>+)\s?(.*)$/);
26557
26727
  if (quote) {
26558
26728
  const depth = Math.min(quote[1].length, 4);
26559
- const marker = pc.dim("▍".repeat(depth));
26729
+ const marker = pc2.dim("▍".repeat(depth));
26560
26730
  return `${marker} ${this.formatInline(quote[2])}`;
26561
26731
  }
26562
26732
  const checkbox = result.match(/^[-*]\s+\[([ xX])\]\s+(.+)$/);
26563
26733
  if (checkbox) {
26564
26734
  const checked = checkbox[1].toLowerCase() === "x";
26565
- const mark = checked ? pc.green("✓") : pc.dim("☐");
26735
+ const mark = checked ? pc2.green("✓") : pc2.dim("☐");
26566
26736
  return ` ${mark} ${this.formatInline(checkbox[2])}`;
26567
26737
  }
26568
26738
  const ordered = result.match(/^(\d+)[.)]\s+(.+)$/);
26569
26739
  if (ordered) {
26570
- return ` ${pc.yellow(ordered[1])}. ${this.formatInline(ordered[2])}`;
26740
+ return ` ${pc2.yellow(ordered[1])}. ${this.formatInline(ordered[2])}`;
26571
26741
  }
26572
26742
  const bullet = result.match(/^[-*]\s+(.+)$/);
26573
26743
  if (bullet) {
26574
- return ` ${pc.dim("•")} ${this.formatInline(bullet[1])}`;
26744
+ return ` ${pc2.dim("•")} ${this.formatInline(bullet[1])}`;
26575
26745
  }
26576
26746
  return this.formatInline(result);
26577
26747
  }
26578
26748
  formatInline(text) {
26579
26749
  const codeSpans = [];
26580
26750
  let result = text.replace(/`([^`]+)`/g, (_m, c) => {
26581
- codeSpans.push(pc.yellow(c));
26751
+ codeSpans.push(pc2.yellow(c));
26582
26752
  return `\x00${codeSpans.length - 1}\x00`;
26583
26753
  });
26584
- result = result.replace(/\*\*(.+?)\*\*/g, (_, s) => pc.bold(s));
26585
- result = result.replace(/~~(.+?)~~/g, (_, s) => pc.strikethrough(s));
26586
- result = result.replace(/\*([^*]+)\*/g, (_, s) => pc.italic(s));
26587
- result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre + pc.italic(s));
26754
+ result = result.replace(/\*\*(.+?)\*\*/g, (_, s) => pc2.bold(s));
26755
+ result = result.replace(/~~(.+?)~~/g, (_, s) => pc2.strikethrough(s));
26756
+ result = result.replace(/\*([^*]+)\*/g, (_, s) => pc2.italic(s));
26757
+ result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre + pc2.italic(s));
26588
26758
  result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
26589
26759
  const short = url.length > 80 ? url.slice(0, 77) + "…" : url;
26590
- return `${pc.cyan(label)} ${pc.dim(`(${short})`)}`;
26760
+ return `${pc2.cyan(label)} ${pc2.dim(`(${short})`)}`;
26591
26761
  });
26592
26762
  result = result.replace(/\u0000(\d+)\u0000/g, (_m, i) => codeSpans[Number(i)]);
26593
26763
  return result;
@@ -26702,7 +26872,7 @@ class Renderer {
26702
26872
  }
26703
26873
  reasoning(chunk) {
26704
26874
  this.spinner.stop();
26705
- this.out.write(pc.dim(chunk));
26875
+ this.out.write(pc2.dim(chunk));
26706
26876
  }
26707
26877
  thinkingStart() {
26708
26878
  this.spinner.start(t("ui.thinking"));
@@ -26716,7 +26886,7 @@ class Renderer {
26716
26886
  const summary = summarizeArgs2(args);
26717
26887
  if (!this.rich) {
26718
26888
  this.out.write(`
26719
- ${pc.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26889
+ ${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
26720
26890
  `);
26721
26891
  return;
26722
26892
  }
@@ -26724,18 +26894,18 @@ ${pc.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26724
26894
  if (this.toolStyle === "inline") {
26725
26895
  const marker = toolMarker(tool);
26726
26896
  this.out.write(`
26727
- ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26897
+ ${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
26728
26898
  `);
26729
26899
  return;
26730
26900
  }
26731
- this.spinner.start(`${pc.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}`);
26901
+ this.spinner.start(`${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}`);
26732
26902
  }
26733
26903
  toolEnd(_tool, duration, error, ctxDelta) {
26734
26904
  this.spinner.stop();
26735
26905
  if (!this.rich) {
26736
26906
  if (ctxDelta !== undefined && ctxDelta !== 0) {
26737
- const deltaStr = ctxDelta > 0 ? pc.green(`+${ctxDelta}`) : pc.yellow(`${ctxDelta} ↓`);
26738
- this.out.write(`${pc.dim("ctx")} ${deltaStr}
26907
+ const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
26908
+ this.out.write(`${pc2.dim("ctx")} ${deltaStr}
26739
26909
  `);
26740
26910
  }
26741
26911
  return;
@@ -26743,11 +26913,11 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26743
26913
  if (!this.card)
26744
26914
  return;
26745
26915
  const { tool, args, body } = this.card;
26746
- const marker = error ? pc.red("✗") : pc.green("✓");
26747
- let footer = `${marker} ${pc.dim(`${duration}ms`)}`;
26916
+ const marker = error ? pc2.red("✗") : pc2.green("✓");
26917
+ let footer = `${marker} ${pc2.dim(`${duration}ms`)}`;
26748
26918
  if (ctxDelta !== undefined && ctxDelta !== 0) {
26749
- const deltaStr = ctxDelta > 0 ? pc.green(`+${ctxDelta}`) : pc.yellow(`${ctxDelta} ↓`);
26750
- footer += ` ${pc.dim("ctx")} ${deltaStr}`;
26919
+ const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
26920
+ footer += ` ${pc2.dim("ctx")} ${deltaStr}`;
26751
26921
  }
26752
26922
  if (this.toolStyle === "inline") {
26753
26923
  this.out.write(`${GUTTER}${footer}
@@ -26760,7 +26930,7 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26760
26930
  const lines = [];
26761
26931
  const summary = summarizeArgs2(args);
26762
26932
  if (summary)
26763
- lines.push(pc.dim(summary));
26933
+ lines.push(pc2.dim(summary));
26764
26934
  for (const chunk of body) {
26765
26935
  for (const line of chunk.split(`
26766
26936
  `)) {
@@ -26784,7 +26954,7 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
26784
26954
  error(text) {
26785
26955
  this.endCard();
26786
26956
  this.spinner.stop();
26787
- this.err.write(`${pc.red(text)}
26957
+ this.err.write(`${pc2.red(text)}
26788
26958
  `);
26789
26959
  }
26790
26960
  flush() {
@@ -26807,8 +26977,8 @@ init_repl_commands();
26807
26977
  function readVersion4() {
26808
26978
  const here = dirname13(fileURLToPath4(import.meta.url));
26809
26979
  const candidates = [
26810
- join35(here, "..", "..", "package.json"),
26811
- join35(here, "..", "package.json")
26980
+ join36(here, "..", "..", "package.json"),
26981
+ join36(here, "..", "package.json")
26812
26982
  ];
26813
26983
  for (const p of candidates) {
26814
26984
  if (existsSync43(p)) {
@@ -26824,14 +26994,14 @@ function formatContextBar(used, limit, compactions, quality) {
26824
26994
  const pct = Math.min(100, Math.round(used / limit * 100));
26825
26995
  const barLen = 20;
26826
26996
  const filled = Math.round(pct / 100 * barLen);
26827
- const bar = pc.green("█".repeat(filled)) + pc.dim("░".repeat(barLen - filled));
26828
- const pctStr = pct >= 75 ? pc.yellow(`${pct}%`) : pc.dim(`${pct}%`);
26829
- let line = ` ${bar} ${pctStr} ${pc.dim(`(${used} / ${limit} tokens)`)}`;
26997
+ const bar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
26998
+ const pctStr = pct >= 75 ? pc2.yellow(`${pct}%`) : pc2.dim(`${pct}%`);
26999
+ let line = ` ${bar} ${pctStr} ${pc2.dim(`(${used} / ${limit} tokens)`)}`;
26830
27000
  if (compactions !== undefined) {
26831
- line += pc.dim(` compactions: ${compactions}`);
27001
+ line += pc2.dim(` compactions: ${compactions}`);
26832
27002
  }
26833
27003
  if (quality !== undefined) {
26834
- const qColor = quality >= 70 ? pc.green : quality >= 40 ? pc.yellow : pc.red;
27004
+ const qColor = quality >= 70 ? pc2.green : quality >= 40 ? pc2.yellow : pc2.red;
26835
27005
  line += ` ${qColor(`quality: ${quality}%`)}`;
26836
27006
  }
26837
27007
  return line;
@@ -26863,15 +27033,15 @@ class Repl {
26863
27033
  this.sessionManager = sessionManager;
26864
27034
  this.skillsModule = skillsModule;
26865
27035
  this.pluginManager = pluginManager;
26866
- this.configDir = configDir || join35(homedir17(), ".mma");
27036
+ this.configDir = configDir || join36(homedir17(), ".mma");
26867
27037
  this.baseDir = baseDir || process.cwd();
26868
27038
  this.noAgentsMd = noAgentsMd === true;
26869
- this.historyPath = join35(homedir17(), ".mma", "repl-history");
27039
+ this.historyPath = join36(homedir17(), ".mma", "repl-history");
26870
27040
  this.loadHistory();
26871
27041
  this.rl = readline2.createInterface({
26872
27042
  input: process.stdin,
26873
27043
  output: process.stdout,
26874
- prompt: pc.cyan("> "),
27044
+ prompt: pc2.cyan("> "),
26875
27045
  history: this.history,
26876
27046
  historySize: this.maxHistory,
26877
27047
  tabSize: 2,
@@ -26899,7 +27069,7 @@ class Repl {
26899
27069
  }
26900
27070
  saveHistory() {
26901
27071
  const allHistory = this.history.slice(-this.maxHistory);
26902
- writeFileSync16(this.historyPath, allHistory.join(`
27072
+ writeFileSync15(this.historyPath, allHistory.join(`
26903
27073
  `), "utf-8");
26904
27074
  }
26905
27075
  setupCompleter() {
@@ -26954,11 +27124,11 @@ class Repl {
26954
27124
  }
26955
27125
  }
26956
27126
  if (this.running) {
26957
- this.rl.setPrompt(pc.cyan("> "));
27127
+ this.rl.setPrompt(pc2.cyan("> "));
26958
27128
  this.rl.prompt();
26959
27129
  }
26960
27130
  } else {
26961
- this.rl.setPrompt(pc.cyan("... "));
27131
+ this.rl.setPrompt(pc2.cyan("... "));
26962
27132
  this.rl.prompt();
26963
27133
  }
26964
27134
  return;
@@ -26966,7 +27136,7 @@ class Repl {
26966
27136
  if (this.isMultiLineInput(trimmed)) {
26967
27137
  inMultiLine = true;
26968
27138
  multiLineBuffer = trimmed;
26969
- this.rl.setPrompt(pc.cyan("... "));
27139
+ this.rl.setPrompt(pc2.cyan("... "));
26970
27140
  this.rl.prompt();
26971
27141
  return;
26972
27142
  }
@@ -26997,7 +27167,7 @@ class Repl {
26997
27167
  if (escBytes >= 2 || withinWindow) {
26998
27168
  this.lastEscTime = 0;
26999
27169
  if (this.agentRunning) {
27000
- process.stdout.write(pc.yellow(`
27170
+ process.stdout.write(pc2.yellow(`
27001
27171
  ${t("repl.interrupt")}
27002
27172
  `));
27003
27173
  this.agent.shutdown();
@@ -27013,11 +27183,11 @@ ${t("repl.interrupt")}
27013
27183
  const { dataUrl } = await bufferToDataUrl2(clipBuf);
27014
27184
  this.pendingClipboardImage = dataUrl;
27015
27185
  const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
27016
- console.log(pc.green(`
27186
+ console.log(pc2.green(`
27017
27187
  ${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
27018
27188
  this.rl.prompt();
27019
27189
  } else {
27020
- console.log(pc.yellow(`
27190
+ console.log(pc2.yellow(`
27021
27191
  ${t("image.clipboard_empty")}`));
27022
27192
  this.rl.prompt();
27023
27193
  }
@@ -27025,13 +27195,16 @@ ${t("image.clipboard_empty")}`));
27025
27195
  }
27026
27196
  });
27027
27197
  }
27198
+ let forceExitTimer = null;
27028
27199
  process.on("SIGINT", () => {
27029
27200
  if (this.agentRunning) {
27030
- console.log(pc.yellow(`
27201
+ console.log(pc2.yellow(`
27031
27202
  [Ctrl+C] Остановка агента... (ещё раз — принудительно)`));
27032
27203
  this.agent.shutdown();
27033
27204
  this.agentRunning = false;
27034
- setTimeout(() => process.exit(1), 2000).unref();
27205
+ if (forceExitTimer)
27206
+ clearTimeout(forceExitTimer);
27207
+ forceExitTimer = setTimeout(() => process.exit(1), 2000).unref();
27035
27208
  } else {
27036
27209
  process.exit(0);
27037
27210
  }
@@ -27062,7 +27235,7 @@ ${t("image.clipboard_empty")}`));
27062
27235
  this.pendingClipboardImage = null;
27063
27236
  }
27064
27237
  process.stdout.write(`
27065
- ` + pc.green(t("repl.agent")));
27238
+ ` + pc2.green(t("repl.agent")));
27066
27239
  const renderer = new Renderer({
27067
27240
  spinner: this.config.ui?.spinner ?? true,
27068
27241
  toolStyle: this.config.ui?.toolStyle ?? "inline"
@@ -27084,7 +27257,7 @@ ${t("image.clipboard_empty")}`));
27084
27257
  process.stdout.write(`
27085
27258
  `);
27086
27259
  if (!result.success) {
27087
- console.error(pc.red(`${t("error.prefix")}${result.error}`));
27260
+ console.error(pc2.red(`${t("error.prefix")}${result.error}`));
27088
27261
  }
27089
27262
  this.showContextBar(result);
27090
27263
  } finally {
@@ -27114,13 +27287,13 @@ ${t("image.clipboard_empty")}`));
27114
27287
  const args = parts.slice(1);
27115
27288
  const cmd = this.commands.get(name);
27116
27289
  if (!cmd) {
27117
- console.log(pc.red(t("cli.unknown_cmd", { name })), t("cli.help_hint"));
27290
+ console.log(pc2.red(t("cli.unknown_cmd", { name })), t("cli.help_hint"));
27118
27291
  return;
27119
27292
  }
27120
27293
  try {
27121
27294
  await cmd.action(args);
27122
27295
  } catch (err) {
27123
- console.error(pc.red(t("error.command_error", {
27296
+ console.error(pc2.red(t("error.command_error", {
27124
27297
  message: err instanceof Error ? err.message : String(err)
27125
27298
  })));
27126
27299
  }
@@ -27144,12 +27317,12 @@ ${t("image.clipboard_empty")}`));
27144
27317
  }
27145
27318
  if (cmds.length === 0)
27146
27319
  continue;
27147
- console.log(pc.bold(t(`repl.group.${groupKey}`)));
27320
+ console.log(pc2.bold(t(`repl.group.${groupKey}`)));
27148
27321
  for (const cmd of cmds) {
27149
- const aliases = cmd.aliases?.length ? ` (${pc.dim(cmd.aliases.join(", "))})` : "";
27150
- console.log(` ${pc.cyan("/" + cmd.name)}${aliases} ${pc.dim(cmd.description)}`);
27322
+ const aliases = cmd.aliases?.length ? ` (${pc2.dim(cmd.aliases.join(", "))})` : "";
27323
+ console.log(` ${pc2.cyan("/" + cmd.name)}${aliases} ${pc2.dim(cmd.description)}`);
27151
27324
  if (cmd.usage) {
27152
- console.log(` ${pc.dim(cmd.usage)}`);
27325
+ console.log(` ${pc2.dim(cmd.usage)}`);
27153
27326
  }
27154
27327
  }
27155
27328
  console.log();
@@ -27161,7 +27334,7 @@ ${t("image.clipboard_empty")}`));
27161
27334
  const ctxLine = formatContextBar(result.contextUsed, result.contextLimit, result.compactionCount, result.contextQuality);
27162
27335
  console.log(ctxLine);
27163
27336
  if (result.totalTokens !== undefined && result.totalTokens > 0) {
27164
- const apiLine = pc.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
27337
+ const apiLine = pc2.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
27165
27338
  console.log(apiLine);
27166
27339
  }
27167
27340
  }
@@ -27170,57 +27343,57 @@ ${t("image.clipboard_empty")}`));
27170
27343
  this.running = true;
27171
27344
  const info = [];
27172
27345
  const row = (label, value) => {
27173
- info.push(` ${pc.yellow(label)} ${value}`);
27346
+ info.push(` ${pc2.yellow(label)} ${value}`);
27174
27347
  };
27175
27348
  const ctx = this.config.contextWindow;
27176
27349
  const sysBudget = Math.floor(ctx * this.config.contextBudget.systemPrompt);
27177
27350
  const resBudget = Math.floor(ctx * this.config.contextBudget.responseReserve);
27178
27351
  const histBudget = ctx - sysBudget - resBudget;
27179
- row(t("repl.model"), pc.white(this.config.model));
27180
- row(t("repl.provider"), `${this.config.provider.type} → ${pc.dim(this.config.provider.baseUrl)}`);
27181
- row(t("repl.context"), `${pc.white(String(ctx))} ${pc.dim(`(sys:${sysBudget} res:${resBudget} hist:${histBudget})`)}`);
27352
+ row(t("repl.model"), pc2.white(this.config.model));
27353
+ row(t("repl.provider"), `${this.config.provider.type} → ${pc2.dim(this.config.provider.baseUrl)}`);
27354
+ row(t("repl.context"), `${pc2.white(String(ctx))} ${pc2.dim(`(sys:${sysBudget} res:${resBudget} hist:${histBudget})`)}`);
27182
27355
  const si = this.agent.getSystemPromptInfo();
27183
- row(t("repl.sysprompt_label"), pc.dim(t("repl.sysprompt_size", { used: si.tokenCount, budget: sysBudget })));
27356
+ row(t("repl.sysprompt_label"), pc2.dim(t("repl.sysprompt_size", { used: si.tokenCount, budget: sysBudget })));
27184
27357
  if (this.skillsModule) {
27185
27358
  const budget = this.skillsModule.getBudget();
27186
- row(t("repl.skills_label"), `${pc.white(String(this.skillsModule.getAvailable().length))} available, ${pc.dim(`budget: ${budget.total} tokens`)}`);
27359
+ row(t("repl.skills_label"), `${pc2.white(String(this.skillsModule.getAvailable().length))} available, ${pc2.dim(`budget: ${budget.total} tokens`)}`);
27187
27360
  }
27188
27361
  if (this.pluginManager) {
27189
27362
  const plugins = this.pluginManager.getAllPlugins().filter((p) => !p.isBuiltin);
27190
27363
  if (plugins.length > 0) {
27191
27364
  const pluginNames = plugins.map((p) => p.name).join(", ");
27192
- row(t("repl.plugins_label"), `${pc.white(String(plugins.length))} active ${pc.dim(`(${pluginNames})`)}`);
27365
+ row(t("repl.plugins_label"), `${pc2.white(String(plugins.length))} active ${pc2.dim(`(${pluginNames})`)}`);
27193
27366
  }
27194
27367
  }
27195
27368
  const mcpServers = this.config.mcpServers || {};
27196
27369
  const enabledServers = Object.entries(mcpServers).filter(([, s]) => s.enabled !== false);
27197
27370
  if (enabledServers.length > 0) {
27198
27371
  const names = enabledServers.map(([name]) => name).join(", ");
27199
- row(t("repl.mcp_label"), `${pc.white(String(enabledServers.length))} ${pc.dim(`(${names})`)}`);
27372
+ row(t("repl.mcp_label"), `${pc2.white(String(enabledServers.length))} ${pc2.dim(`(${names})`)}`);
27200
27373
  }
27201
27374
  const cwd = process.cwd();
27202
- row(t("repl.work_dir"), pc.dim(cwd));
27375
+ row(t("repl.work_dir"), pc2.dim(cwd));
27203
27376
  if (this.noAgentsMd) {
27204
- row(t("repl.agents_label"), pc.red(t("repl.disabled")));
27377
+ row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
27205
27378
  } else {
27206
27379
  const agentsMdCandidates = [
27207
- join35(this.baseDir, "AGENTS.md"),
27208
- join35(this.baseDir, ".mma", "AGENTS.md"),
27209
- join35(this.configDir, "AGENTS.md")
27380
+ join36(this.baseDir, "AGENTS.md"),
27381
+ join36(this.baseDir, ".mma", "AGENTS.md"),
27382
+ join36(this.configDir, "AGENTS.md")
27210
27383
  ];
27211
27384
  const foundAgents = agentsMdCandidates.filter((p) => existsSync43(p));
27212
27385
  if (foundAgents.length > 0) {
27213
27386
  for (const p of foundAgents) {
27214
- row(t("repl.agents_label"), pc.dim(p));
27387
+ row(t("repl.agents_label"), pc2.dim(p));
27215
27388
  }
27216
27389
  } else {
27217
- row(t("repl.agents_label"), pc.dim(t("repl.not_found")));
27390
+ row(t("repl.agents_label"), pc2.dim(t("repl.not_found")));
27218
27391
  }
27219
27392
  }
27220
27393
  const meta = this.sessionManager?.getActiveMeta();
27221
27394
  if (meta) {
27222
- const sessionPath = join35(this.configDir, "sessions", meta.id);
27223
- row(t("repl.session_label"), `${pc.cyan(meta.name)} ${pc.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc.dim(sessionPath)}`);
27395
+ const sessionPath = join36(this.configDir, "sessions", meta.id);
27396
+ row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
27224
27397
  }
27225
27398
  const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
27226
27399
  for (const line of box(info, {
@@ -27246,7 +27419,7 @@ init_config2();
27246
27419
  init_i18n();
27247
27420
  init_colors();
27248
27421
  import { existsSync as existsSync44 } from "fs";
27249
- import { join as join36 } from "path";
27422
+ import { join as join37 } from "path";
27250
27423
  import { homedir as homedir18 } from "os";
27251
27424
  async function main() {
27252
27425
  const program2 = createProgram();
@@ -27302,7 +27475,7 @@ async function main() {
27302
27475
  renderer.flush();
27303
27476
  if (result.success) {
27304
27477
  if (!result.text) {
27305
- console.log(pc.yellow(t("cli.no_output")));
27478
+ console.log(pc2.yellow(t("cli.no_output")));
27306
27479
  }
27307
27480
  } else {
27308
27481
  console.error(`${t("error.prefix")}${result.error}`);
@@ -27313,13 +27486,16 @@ async function main() {
27313
27486
  }
27314
27487
  agent.shutdown();
27315
27488
  } else {
27316
- const configPath = join36(homedir18(), ".mma", "config.json");
27489
+ const configPath = join37(homedir18(), ".mma", "config.json");
27317
27490
  if (!existsSync44(configPath)) {
27318
- console.log(pc.yellow(`
27491
+ console.log(pc2.yellow(`
27319
27492
  ` + t("cli.first_run") + `
27320
27493
  `));
27321
27494
  const answers = await runSetup();
27322
- const { config: config2 } = await bootstrap(undefined, projectDir, noAgentsMd, exitOnComplete);
27495
+ const config2 = loadConfig({
27496
+ configDir: join37(homedir18(), ".mma"),
27497
+ projectConfigPath: projectDir ? join37(projectDir, ".mmrc") : join37(process.cwd(), ".mmrc")
27498
+ });
27323
27499
  config2.provider.type = answers.provider;
27324
27500
  config2.provider.baseUrl = answers.apiBase;
27325
27501
  config2.provider.apiKey = answers.apiKey;