micro-models-agent 0.46.1 → 0.46.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 (2) hide show
  1. package/dist/main.js +406 -139
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2400,6 +2400,12 @@ Use read_file on {path} to see the current content before editing — the target
2400
2400
  "error.no_response_body": "No response body stream",
2401
2401
  "error.llm_stream_idle": "LLM stream stalled — no data for {timeout}ms",
2402
2402
  "error.llm_timeout": "LLM request timed out ({timeout}ms)",
2403
+ "env.runtime_node": "Running under Node (v{version}) — clipboard image paste, subagent performance and LSP spawn on Windows degrade. Install Bun (https://bun.sh) for full features.",
2404
+ "env.runtime_old": "Runtime version {version} is below the required engines {engine}.",
2405
+ "env.tool_missing": "Tool not found on PATH: {tool}",
2406
+ "env.playwright_missing": "Playwright package is not installed — the browser tool will fail. Install with: bun add playwright",
2407
+ "env.playwright_browsers_missing": "Playwright browsers not downloaded ({dir}). The browser tool will fail. Install with: bunx playwright install chromium",
2408
+ "env.crash_stderr": "MMA crashed ({type}): {message} — crash report written to ~/.mma/logs/crash.jsonl",
2403
2409
  "session.started": "Session started: {id}",
2404
2410
  "session.ended": "Session ended: {id}",
2405
2411
  "session.not_found": "Session not found: {id}",
@@ -3078,6 +3084,12 @@ var init_ru = __esm(() => {
3078
3084
  "error.no_response_body": "Нет потока тела ответа",
3079
3085
  "error.llm_stream_idle": "Поток LLM завис — нет данных {timeout}мс",
3080
3086
  "error.llm_timeout": "Время запроса LLM истекло ({timeout}мс)",
3087
+ "env.runtime_node": "Запущено под Node (v{version}) — вставка изображений из буфера и LSP на Windows работают урезанно. Установите Bun (https://bun.sh) для полного функционала.",
3088
+ "env.runtime_old": "Версия рантайма {version} ниже требуемой engines {engine}.",
3089
+ "env.tool_missing": "Инструмент не найден в PATH: {tool}",
3090
+ "env.playwright_missing": "Пакет Playwright не установлен — браузерный инструмент не будет работать. Установите: bun add playwright",
3091
+ "env.playwright_browsers_missing": "Браузеры Playwright не скачаны ({dir}). Браузерный инструмент не будет работать. Установите: bunx playwright install chromium",
3092
+ "env.crash_stderr": "MMA упал ({type}): {message} — отчёт о падении записан в ~/.mma/logs/crash.jsonl",
3081
3093
  "session.started": "Сессия начата: {id}",
3082
3094
  "session.ended": "Сессия завершена: {id}",
3083
3095
  "session.not_found": "Сессия не найдена: {id}",
@@ -4628,6 +4640,20 @@ class Logger {
4628
4640
  }
4629
4641
  return sanitized;
4630
4642
  }
4643
+ logStructured(type, data) {
4644
+ const logTarget = this.sessionDir ?? this.logDir;
4645
+ if (!logTarget)
4646
+ return;
4647
+ try {
4648
+ appendFileSync2(join6(logTarget, "app.jsonl"), JSON.stringify({
4649
+ level: "info",
4650
+ ts: new Date().toISOString(),
4651
+ type,
4652
+ meta: this.sanitizeMeta(data)
4653
+ }) + `
4654
+ `, "utf-8");
4655
+ } catch {}
4656
+ }
4631
4657
  }
4632
4658
  var import_picocolors, LEVELS, LEVEL_COLORS;
4633
4659
  var init_app_logger = __esm(() => {
@@ -21574,15 +21600,197 @@ function readMmaVersion() {
21574
21600
  }
21575
21601
  var init_version = () => {};
21576
21602
 
21603
+ // src/core/environment.ts
21604
+ import { existsSync as existsSync44, readFileSync as readFileSync27, readdirSync as readdirSync15 } from "fs";
21605
+ import { spawnSync as spawnSync2 } from "child_process";
21606
+ import { createRequire as createRequire2 } from "module";
21607
+ import { join as join37, dirname as dirname14 } from "path";
21608
+ import { fileURLToPath as fileURLToPath3 } from "url";
21609
+ import { arch, homedir as homedir11, hostname as hostname2, platform as platform9, release } from "os";
21610
+ import { env as env2 } from "process";
21611
+ function readEngineRequirement() {
21612
+ const here = dirname14(fileURLToPath3(import.meta.url));
21613
+ const candidates = [join37(here, "..", "..", "package.json"), join37(here, "..", "package.json")];
21614
+ for (const p of candidates) {
21615
+ if (!existsSync44(p))
21616
+ continue;
21617
+ try {
21618
+ const raw = JSON.parse(readFileSync27(p, "utf8"));
21619
+ if (raw.engines?.node)
21620
+ return String(raw.engines.node);
21621
+ } catch {}
21622
+ }
21623
+ return ">=20";
21624
+ }
21625
+ function satisfiesMinimum(version, requirement) {
21626
+ const minMatch = requirement.match(/(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
21627
+ if (!minMatch)
21628
+ return true;
21629
+ const min = [
21630
+ parseInt(minMatch[1], 10),
21631
+ minMatch[2] ? parseInt(minMatch[2], 10) : 0,
21632
+ minMatch[3] ? parseInt(minMatch[3], 10) : 0
21633
+ ];
21634
+ const parts = version.replace(/^v/i, "").split(".");
21635
+ const got = [
21636
+ parts[0] ? parseInt(parts[0], 10) : 0,
21637
+ parts[1] ? parseInt(parts[1], 10) : 0,
21638
+ parts[2] ? parseInt(parts[2], 10) : 0
21639
+ ];
21640
+ for (let i = 0;i < 3; i++) {
21641
+ if (got[i] > min[i])
21642
+ return true;
21643
+ if (got[i] < min[i])
21644
+ return false;
21645
+ }
21646
+ return true;
21647
+ }
21648
+ function detectRuntime() {
21649
+ const bun = globalThis.Bun;
21650
+ const isBun = typeof bun !== "undefined" && typeof bun?.version !== "undefined";
21651
+ const engine2 = readEngineRequirement();
21652
+ const runtime = isBun ? "bun" : "node";
21653
+ const runtimeVersion = isBun ? String(bun.version) : process.version;
21654
+ return {
21655
+ runtime,
21656
+ runtimeVersion,
21657
+ nodeVersion: process.version,
21658
+ engine: engine2,
21659
+ engineOk: satisfiesMinimum(process.version, engine2)
21660
+ };
21661
+ }
21662
+ function toolVersion(cmd) {
21663
+ try {
21664
+ const res = spawnSync2(cmd, ["--version"], {
21665
+ encoding: "utf8",
21666
+ timeout: 3000,
21667
+ windowsHide: true,
21668
+ stdio: ["ignore", "pipe", "pipe"]
21669
+ });
21670
+ if (res.error || res.status !== 0)
21671
+ return "missing";
21672
+ const out = ((res.stdout || "") + (res.stderr || "")).trim();
21673
+ return out.split(/\r?\n/)[0].slice(0, 40) || "ok";
21674
+ } catch {
21675
+ return "missing";
21676
+ }
21677
+ }
21678
+ function playwrightBrowsersDir() {
21679
+ if (process.env.PLAYWRIGHT_BROWSERS_PATH)
21680
+ return process.env.PLAYWRIGHT_BROWSERS_PATH;
21681
+ return process.platform === "win32" ? join37(homedir11(), "AppData", "Local", "ms-playwright") : join37(homedir11(), ".cache", "ms-playwright");
21682
+ }
21683
+ function playwrightInfo() {
21684
+ let installed = false;
21685
+ let version = "";
21686
+ const browsersDir = playwrightBrowsersDir();
21687
+ try {
21688
+ const require2 = createRequire2(import.meta.url);
21689
+ const pkgPath = require2.resolve("playwright/package.json");
21690
+ installed = existsSync44(pkgPath);
21691
+ version = JSON.parse(readFileSync27(pkgPath, "utf8")).version || "";
21692
+ } catch {
21693
+ installed = false;
21694
+ }
21695
+ let browsersInstalled = false;
21696
+ try {
21697
+ if (existsSync44(browsersDir)) {
21698
+ browsersInstalled = readdirSync15(browsersDir).some((d) => /chrom/i.test(d));
21699
+ }
21700
+ } catch {
21701
+ browsersInstalled = false;
21702
+ }
21703
+ return { installed, version, browsersDir, browsersInstalled };
21704
+ }
21705
+ function checkEnvironmentRequirements(report) {
21706
+ const warnings = [];
21707
+ if (report.runtime.runtime === "node") {
21708
+ warnings.push(t("env.runtime_node", { version: report.runtime.nodeVersion }));
21709
+ }
21710
+ if (!report.runtime.engineOk) {
21711
+ warnings.push(t("env.runtime_old", {
21712
+ version: report.runtime.nodeVersion,
21713
+ engine: report.runtime.engine
21714
+ }));
21715
+ }
21716
+ if (report.tools.bun === "missing") {
21717
+ warnings.push(t("env.tool_missing", { tool: "bun" }));
21718
+ }
21719
+ if (report.tools.git === "missing") {
21720
+ warnings.push(t("env.tool_missing", { tool: "git" }));
21721
+ }
21722
+ if (report.features.browser && report.playwright) {
21723
+ if (!report.playwright.installed) {
21724
+ warnings.push(t("env.playwright_missing"));
21725
+ } else if (!report.playwright.browsersInstalled) {
21726
+ warnings.push(t("env.playwright_browsers_missing", { dir: report.playwright.browsersDir }));
21727
+ }
21728
+ }
21729
+ return warnings;
21730
+ }
21731
+ function collectEnvironment(opts) {
21732
+ const runtime = detectRuntime();
21733
+ const tools = {};
21734
+ if (opts.scanTools) {
21735
+ for (const tool of TOOL_CHECKS)
21736
+ tools[tool] = toolVersion(tool);
21737
+ }
21738
+ const provider = opts.config ? {
21739
+ model: opts.config.model,
21740
+ baseUrl: sanitizeUrl(opts.config.provider?.baseUrl || ""),
21741
+ contextWindow: opts.config.contextWindow,
21742
+ retry: {
21743
+ maxRetries: opts.config.retry?.maxRetries ?? 0,
21744
+ baseDelay: opts.config.retry?.baseDelay ?? 0,
21745
+ maxDelay: opts.config.retry?.maxDelay ?? 0,
21746
+ maxStreamRetries: opts.config.retry?.maxStreamRetries ?? 0,
21747
+ noDataTimeoutMs: opts.config.retry?.noDataTimeoutMs ?? 0
21748
+ }
21749
+ } : null;
21750
+ const report = {
21751
+ ts: new Date().toISOString(),
21752
+ mmaVersion: readMmaVersion(),
21753
+ runtime,
21754
+ os: {
21755
+ platform: platform9(),
21756
+ arch: arch(),
21757
+ release: release(),
21758
+ hostname: hostname2(),
21759
+ shell: env2.SHELL || env2.ComSpec || "unknown",
21760
+ home: homedir11(),
21761
+ cwd: process.cwd()
21762
+ },
21763
+ paths: { configDir: opts.configDir, baseDir: opts.baseDir || process.cwd() },
21764
+ tools,
21765
+ provider,
21766
+ features: { browser: Boolean(opts.config?.browser?.enabled) },
21767
+ playwright: playwrightInfo(),
21768
+ warnings: []
21769
+ };
21770
+ report.warnings = checkEnvironmentRequirements(report);
21771
+ return report;
21772
+ }
21773
+ function logEnvironment(report, logger) {
21774
+ logger.info(`Environment: ${report.os.platform} ${report.os.arch} | ${report.runtime.runtime} ${report.runtime.runtimeVersion} (node ${report.runtime.nodeVersion}) | mma ${report.mmaVersion} | ${report.provider?.model ?? "no provider"}`);
21775
+ logger.logStructured("environment", report);
21776
+ }
21777
+ var TOOL_CHECKS;
21778
+ var init_environment = __esm(() => {
21779
+ init_version();
21780
+ init_network_validator();
21781
+ init_i18n();
21782
+ TOOL_CHECKS = ["bun", "node", "git", "python"];
21783
+ });
21784
+
21577
21785
  // src/core/bootstrap.ts
21578
21786
  var exports_bootstrap = {};
21579
21787
  __export(exports_bootstrap, {
21580
21788
  buildSystemInfo: () => buildSystemInfo,
21581
21789
  bootstrap: () => bootstrap
21582
21790
  });
21583
- import { homedir as homedir11 } from "os";
21584
- import { join as join37, resolve as resolve23 } from "path";
21585
- import { existsSync as existsSync44, readFileSync as readFileSync27, writeFileSync as writeFileSync15 } from "fs";
21791
+ import { homedir as homedir12 } from "os";
21792
+ import { join as join38, resolve as resolve23 } from "path";
21793
+ import { existsSync as existsSync45, readFileSync as readFileSync28, writeFileSync as writeFileSync15 } from "fs";
21586
21794
  function buildSystemInfo(config, baseDir, profileCompressed) {
21587
21795
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
21588
21796
  const isWin = profileCompressed.toLowerCase().includes("win32");
@@ -21608,8 +21816,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
21608
21816
  `);
21609
21817
  }
21610
21818
  async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21611
- const dir = configDir || join37(homedir11(), ".mma");
21612
- const projectConfigPath = projectDir ? join37(projectDir, ".mmrc") : join37(process.cwd(), ".mmrc");
21819
+ const dir = configDir || join38(homedir12(), ".mma");
21820
+ const projectConfigPath = projectDir ? join38(projectDir, ".mmrc") : join38(process.cwd(), ".mmrc");
21613
21821
  const config = loadConfig({ configDir: dir, projectConfigPath });
21614
21822
  setLocale(config.locale);
21615
21823
  try {
@@ -21619,7 +21827,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21619
21827
  }
21620
21828
  } catch {}
21621
21829
  const logger = new Logger(config.logLevel);
21622
- logger.setLogDir(join37(dir, "logs"));
21830
+ logger.setLogDir(join38(dir, "logs"));
21623
21831
  logger.debug("MMA bootstrap", {
21624
21832
  version: config.version,
21625
21833
  model: config.model
@@ -21641,7 +21849,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21641
21849
  logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
21642
21850
  }
21643
21851
  }
21644
- const profile = new UserProfile(join37(dir));
21852
+ const profile = new UserProfile(join38(dir));
21645
21853
  profile.load() || profile.collect();
21646
21854
  profile.save();
21647
21855
  const llmProvider = new OpenAICompatProvider({
@@ -21653,7 +21861,17 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21653
21861
  rateLimits: config.security?.rateLimits
21654
21862
  });
21655
21863
  const baseDir = projectDir ? resolve23(projectDir) : process.cwd();
21656
- const projectMapCacheDir = join37(baseDir, ".mma");
21864
+ const envReport = collectEnvironment({
21865
+ configDir: dir,
21866
+ baseDir,
21867
+ config,
21868
+ scanTools: true
21869
+ });
21870
+ logEnvironment(envReport, logger);
21871
+ for (const warning of envReport.warnings) {
21872
+ logger.warn(warning);
21873
+ }
21874
+ const projectMapCacheDir = join38(baseDir, ".mma");
21657
21875
  const indexerModule = new IndexerModule({
21658
21876
  baseDir,
21659
21877
  cacheDir: projectMapCacheDir
@@ -21664,9 +21882,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21664
21882
  logger.warn(`Project indexing failed: ${err.message}`);
21665
21883
  }
21666
21884
  const skillsLoader = new SkillsLoader;
21667
- const builtinDir = join37(import.meta.dirname, "skills", "builtin");
21668
- const globalDir = join37(homedir11(), ".agents", "skills");
21669
- const projectSkillsDir = join37(baseDir, ".mma", "skills");
21885
+ const builtinDir = join38(import.meta.dirname, "skills", "builtin");
21886
+ const globalDir = join38(homedir12(), ".agents", "skills");
21887
+ const projectSkillsDir = join38(baseDir, ".mma", "skills");
21670
21888
  const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
21671
21889
  const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
21672
21890
  const skillsModule = new SkillsModule(availableSkills, skillsBudget);
@@ -21682,11 +21900,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21682
21900
  essential: true,
21683
21901
  estimatedTokens: Math.ceil(systemInfoContent.length / 4)
21684
21902
  };
21685
- const agentsMdGlobal = join37(dir, "AGENTS.md");
21686
- if (!existsSync44(agentsMdGlobal)) {
21903
+ const agentsMdGlobal = join38(dir, "AGENTS.md");
21904
+ if (!existsSync45(agentsMdGlobal)) {
21687
21905
  writeFileSync15(agentsMdGlobal, "", "utf-8");
21688
21906
  }
21689
- const sessionDir = join37(dir, "sessions");
21907
+ const sessionDir = join38(dir, "sessions");
21690
21908
  const sessionStore = new SessionStore(sessionDir);
21691
21909
  sessionStore.init();
21692
21910
  const sessionManager = new SessionManager(sessionStore, {
@@ -21763,7 +21981,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21763
21981
  const mcpModule = new MCPModule(config);
21764
21982
  await mcpModule.initialize();
21765
21983
  moduleRegistry.register(mcpModule);
21766
- const memoryStore = new MemoryStore(join37(dir, "memory"));
21984
+ const memoryStore = new MemoryStore(join38(dir, "memory"));
21767
21985
  const memoryModule = new MemoryModule(memoryStore);
21768
21986
  moduleRegistry.register(memoryModule);
21769
21987
  if (config.browser.enabled) {
@@ -21816,8 +22034,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21816
22034
  pluginManager.register(plugin);
21817
22035
  pluginManager.register(plugin2);
21818
22036
  const pluginLoader = new PluginLoader;
21819
- const globalPluginsDir = join37(homedir11(), ".mma", "plugins");
21820
- const projectPluginsDir = join37(baseDir, ".mma", "plugins");
22037
+ const globalPluginsDir = join38(homedir12(), ".mma", "plugins");
22038
+ const projectPluginsDir = join38(baseDir, ".mma", "plugins");
21821
22039
  const mmaVersion = readMmaVersion();
21822
22040
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger, {
21823
22041
  source: "global",
@@ -21843,13 +22061,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
21843
22061
  const skipAgentsMd = noAgentsMd === true;
21844
22062
  if (!skipAgentsMd) {
21845
22063
  const agentsMdCandidates = [
21846
- join37(baseDir, "AGENTS.md"),
21847
- join37(baseDir, ".mma", "AGENTS.md"),
21848
- join37(dir, "AGENTS.md")
22064
+ join38(baseDir, "AGENTS.md"),
22065
+ join38(baseDir, ".mma", "AGENTS.md"),
22066
+ join38(dir, "AGENTS.md")
21849
22067
  ];
21850
22068
  for (const p of agentsMdCandidates) {
21851
- if (existsSync44(p)) {
21852
- const content = readFileSync27(p, "utf-8").trim();
22069
+ if (existsSync45(p)) {
22070
+ const content = readFileSync28(p, "utf-8").trim();
21853
22071
  if (content) {
21854
22072
  agentsMdBlocks.push({
21855
22073
  content,
@@ -21952,6 +22170,7 @@ var init_bootstrap = __esm(() => {
21952
22170
  init_i18n();
21953
22171
  init_agent();
21954
22172
  init_version();
22173
+ init_environment();
21955
22174
  });
21956
22175
 
21957
22176
  // node_modules/ansi-regex/index.js
@@ -22720,20 +22939,20 @@ __export(exports_manifest, {
22720
22939
  getCertMark: () => getCertMark,
22721
22940
  MANIFEST_PATH: () => MANIFEST_PATH
22722
22941
  });
22723
- import { existsSync as existsSync45, readFileSync as readFileSync28, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
22724
- import { homedir as homedir13 } from "os";
22725
- import { join as join39 } from "path";
22942
+ import { existsSync as existsSync46, readFileSync as readFileSync29, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
22943
+ import { homedir as homedir14 } from "os";
22944
+ import { join as join40 } from "path";
22726
22945
  function readManifest(path = MANIFEST_PATH) {
22727
22946
  try {
22728
- if (existsSync45(path)) {
22729
- const raw = JSON.parse(readFileSync28(path, "utf-8"));
22947
+ if (existsSync46(path)) {
22948
+ const raw = JSON.parse(readFileSync29(path, "utf-8"));
22730
22949
  return { version: 1, certifications: raw.certifications ?? [] };
22731
22950
  }
22732
22951
  } catch {}
22733
22952
  return { version: 1, certifications: [] };
22734
22953
  }
22735
22954
  function saveManifest(m, path = MANIFEST_PATH) {
22736
- mkdirSync18(join39(homedir13(), ".mma"), { recursive: true });
22955
+ mkdirSync18(join40(homedir14(), ".mma"), { recursive: true });
22737
22956
  writeFileSync16(path, JSON.stringify(m, null, 2), "utf-8");
22738
22957
  }
22739
22958
  function upsertCertification(entry, path = MANIFEST_PATH) {
@@ -22768,7 +22987,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
22768
22987
  }
22769
22988
  var MANIFEST_PATH;
22770
22989
  var init_manifest = __esm(() => {
22771
- MANIFEST_PATH = join39(homedir13(), ".mma", "certifications.json");
22990
+ MANIFEST_PATH = join40(homedir14(), ".mma", "certifications.json");
22772
22991
  });
22773
22992
 
22774
22993
  // node_modules/yaml/dist/nodes/identity.js
@@ -29891,8 +30110,8 @@ var init_scenarios = __esm(() => {
29891
30110
  });
29892
30111
 
29893
30112
  // src/modules/certification/loader.ts
29894
- import { existsSync as existsSync46, readdirSync as readdirSync15, readFileSync as readFileSync29 } from "fs";
29895
- import { join as join40 } from "path";
30113
+ import { existsSync as existsSync47, readdirSync as readdirSync16, readFileSync as readFileSync30 } from "fs";
30114
+ import { join as join41 } from "path";
29896
30115
  function validateScenario(s) {
29897
30116
  const errors2 = [];
29898
30117
  const isSkip = s.mode === "skip";
@@ -29941,12 +30160,12 @@ function loadScenarios(userDir) {
29941
30160
  else
29942
30161
  scenarios.push(s);
29943
30162
  }
29944
- if (userDir && existsSync46(userDir)) {
29945
- for (const file of readdirSync15(userDir)) {
30163
+ if (userDir && existsSync47(userDir)) {
30164
+ for (const file of readdirSync16(userDir)) {
29946
30165
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
29947
30166
  continue;
29948
30167
  try {
29949
- const raw = readFileSync29(join40(userDir, file), "utf-8");
30168
+ const raw = readFileSync30(join41(userDir, file), "utf-8");
29950
30169
  const data = $parse(raw);
29951
30170
  const parsed = normalizeScenario(data, file);
29952
30171
  const errs = validateScenario(parsed);
@@ -29999,8 +30218,8 @@ var init_loader3 = __esm(() => {
29999
30218
  });
30000
30219
 
30001
30220
  // src/modules/certification/fact-checker.ts
30002
- import { existsSync as existsSync47, readFileSync as readFileSync30, statSync as statSync8 } from "fs";
30003
- import { join as join41 } from "path";
30221
+ import { existsSync as existsSync48, readFileSync as readFileSync31, statSync as statSync8 } from "fs";
30222
+ import { join as join42 } from "path";
30004
30223
  function checkSandbox(sandboxDir, checks, exitCode, output) {
30005
30224
  const failures = [];
30006
30225
  for (const check of checks) {
@@ -30017,16 +30236,16 @@ function runCheck2(sandboxDir, check, exitCode, output) {
30017
30236
  case "outputContains":
30018
30237
  return output.includes(check.text);
30019
30238
  case "fileExists":
30020
- return isFile(join41(sandboxDir, check.path));
30239
+ return isFile(join42(sandboxDir, check.path));
30021
30240
  case "fileNotExists":
30022
- return !existsSync47(join41(sandboxDir, check.path));
30241
+ return !existsSync48(join42(sandboxDir, check.path));
30023
30242
  case "dirExists":
30024
- return isDir(join41(sandboxDir, check.path));
30243
+ return isDir(join42(sandboxDir, check.path));
30025
30244
  case "fileContent": {
30026
- const abs = join41(sandboxDir, check.path);
30245
+ const abs = join42(sandboxDir, check.path);
30027
30246
  if (!isFile(abs))
30028
30247
  return false;
30029
- const content = readFileSync30(abs, "utf-8");
30248
+ const content = readFileSync31(abs, "utf-8");
30030
30249
  if (check.contains !== undefined)
30031
30250
  return content.includes(check.contains);
30032
30251
  if (check.equals !== undefined)
@@ -30034,10 +30253,10 @@ function runCheck2(sandboxDir, check, exitCode, output) {
30034
30253
  return false;
30035
30254
  }
30036
30255
  case "fileRegex": {
30037
- const abs = join41(sandboxDir, check.path);
30256
+ const abs = join42(sandboxDir, check.path);
30038
30257
  if (!isFile(abs))
30039
30258
  return false;
30040
- return new RegExp(check.pattern).test(readFileSync30(abs, "utf-8"));
30259
+ return new RegExp(check.pattern).test(readFileSync31(abs, "utf-8"));
30041
30260
  }
30042
30261
  default:
30043
30262
  return false;
@@ -30045,14 +30264,14 @@ function runCheck2(sandboxDir, check, exitCode, output) {
30045
30264
  }
30046
30265
  function isFile(p) {
30047
30266
  try {
30048
- return existsSync47(p) && statSync8(p).isFile();
30267
+ return existsSync48(p) && statSync8(p).isFile();
30049
30268
  } catch {
30050
30269
  return false;
30051
30270
  }
30052
30271
  }
30053
30272
  function isDir(p) {
30054
30273
  try {
30055
- return existsSync47(p) && statSync8(p).isDirectory();
30274
+ return existsSync48(p) && statSync8(p).isDirectory();
30056
30275
  } catch {
30057
30276
  return false;
30058
30277
  }
@@ -30083,9 +30302,9 @@ var init_fact_checker = () => {};
30083
30302
 
30084
30303
  // src/modules/certification/runner.ts
30085
30304
  import { spawn as spawn8 } from "child_process";
30086
- import { existsSync as existsSync48, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
30087
- import { platform as platform9 } from "os";
30088
- import { join as join42, resolve as resolve24, dirname as dirname14 } from "path";
30305
+ import { existsSync as existsSync49, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
30306
+ import { platform as platform10 } from "os";
30307
+ import { join as join43, resolve as resolve24, dirname as dirname15 } from "path";
30089
30308
  async function runScenario(scenario, opts) {
30090
30309
  if (scenario.mode === "skip") {
30091
30310
  return {
@@ -30104,7 +30323,7 @@ async function runScenario(scenario, opts) {
30104
30323
  let passed = 0;
30105
30324
  let firstError;
30106
30325
  for (let i = 1;i <= reps; i++) {
30107
- const sandbox = join42(opts.sandboxBase, `run-${scenario.id}-${i}`);
30326
+ const sandbox = join43(opts.sandboxBase, `run-${scenario.id}-${i}`);
30108
30327
  let failures = [];
30109
30328
  let exitCode = -1;
30110
30329
  let output = "";
@@ -30118,15 +30337,15 @@ async function runScenario(scenario, opts) {
30118
30337
  sandbox,
30119
30338
  scenario.prompt
30120
30339
  ];
30121
- const env2 = {
30340
+ const env3 = {
30122
30341
  ...process.env,
30123
30342
  MMA_MODEL: opts.model,
30124
30343
  MMA_PROVIDER_BASEURL: opts.providerUrl,
30125
30344
  MMA_CONTEXT_WINDOW: String(opts.contextWindow ?? 32000)
30126
30345
  };
30127
30346
  if (opts.providerKey)
30128
- env2.MMA_PROVIDER_APIKEY = opts.providerKey;
30129
- const res = await runner(env2, opts.mmaRoot, args, timeoutMs);
30347
+ env3.MMA_PROVIDER_APIKEY = opts.providerKey;
30348
+ const res = await runner(env3, opts.mmaRoot, args, timeoutMs);
30130
30349
  output = `${res.stdout}
30131
30350
  ${res.stderr}`;
30132
30351
  exitCode = res.code ?? -1;
@@ -30165,25 +30384,25 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
30165
30384
  rmSync4(sandbox, { recursive: true, force: true });
30166
30385
  mkdirSync19(sandbox, { recursive: true });
30167
30386
  for (const f of scenario.fixtures ?? []) {
30168
- const src = join42(mmaRoot, f.source);
30169
- if (!existsSync48(src)) {
30387
+ const src = join43(mmaRoot, f.source);
30388
+ if (!existsSync49(src)) {
30170
30389
  throw new Error(`fixture missing: ${f.source}`);
30171
30390
  }
30172
- const dest = join42(sandbox, f.dest);
30173
- mkdirSync19(dirname14(dest), { recursive: true });
30391
+ const dest = join43(sandbox, f.dest);
30392
+ mkdirSync19(dirname15(dest), { recursive: true });
30174
30393
  cpSync2(src, dest);
30175
30394
  }
30176
30395
  }
30177
30396
  function resolveMmaEntry(mmaRoot) {
30178
- const dev = join42(mmaRoot, "src", "cli", "main.ts");
30179
- if (existsSync48(dev))
30397
+ const dev = join43(mmaRoot, "src", "cli", "main.ts");
30398
+ if (existsSync49(dev))
30180
30399
  return dev;
30181
- return join42(mmaRoot, "dist", "main.js");
30400
+ return join43(mmaRoot, "dist", "main.js");
30182
30401
  }
30183
30402
  function findMmaRoot(fromDir) {
30184
30403
  const candidates = [resolve24(fromDir, "..", "..", ".."), resolve24(fromDir, "..")];
30185
30404
  for (const c of candidates) {
30186
- if (existsSync48(join42(c, "package.json")))
30405
+ if (existsSync49(join43(c, "package.json")))
30187
30406
  return c;
30188
30407
  }
30189
30408
  return process.cwd();
@@ -30192,7 +30411,7 @@ function killTree2(child) {
30192
30411
  const pid = child.pid;
30193
30412
  if (!pid)
30194
30413
  return;
30195
- if (platform9() === "win32") {
30414
+ if (platform10() === "win32") {
30196
30415
  spawn8("taskkill", ["/pid", String(pid), "/T", "/F"], {
30197
30416
  windowsHide: true,
30198
30417
  stdio: "ignore"
@@ -30207,10 +30426,10 @@ function killTree2(child) {
30207
30426
  } catch {}
30208
30427
  }
30209
30428
  }
30210
- var defaultRunner2 = (env2, cwd, args, timeoutMs) => new Promise((resolvePromise) => {
30429
+ var defaultRunner2 = (env3, cwd, args, timeoutMs) => new Promise((resolvePromise) => {
30211
30430
  const child = spawn8(process.execPath, args, {
30212
30431
  cwd,
30213
- env: env2,
30432
+ env: env3,
30214
30433
  windowsHide: true,
30215
30434
  stdio: ["ignore", "pipe", "pipe"]
30216
30435
  });
@@ -30250,16 +30469,16 @@ __export(exports_cli, {
30250
30469
  certList: () => certList
30251
30470
  });
30252
30471
  import { rmSync as rmSync5 } from "fs";
30253
- import { homedir as homedir14 } from "os";
30254
- import { join as join43, dirname as dirname15 } from "path";
30255
- import { fileURLToPath as fileURLToPath3 } from "url";
30256
- import { existsSync as existsSync49, readFileSync as readFileSync31 } from "fs";
30472
+ import { homedir as homedir15 } from "os";
30473
+ import { join as join44, dirname as dirname16 } from "path";
30474
+ import { fileURLToPath as fileURLToPath4 } from "url";
30475
+ import { existsSync as existsSync50, readFileSync as readFileSync32 } from "fs";
30257
30476
  function readVersion() {
30258
- const candidates = [join43(MMA_ROOT, "package.json")];
30477
+ const candidates = [join44(MMA_ROOT, "package.json")];
30259
30478
  for (const p of candidates) {
30260
- if (existsSync49(p)) {
30479
+ if (existsSync50(p)) {
30261
30480
  try {
30262
- const raw = JSON.parse(readFileSync31(p, "utf-8"));
30481
+ const raw = JSON.parse(readFileSync32(p, "utf-8"));
30263
30482
  if (raw.version)
30264
30483
  return raw.version;
30265
30484
  } catch {}
@@ -30295,7 +30514,7 @@ async function certify(opts) {
30295
30514
  return;
30296
30515
  }
30297
30516
  console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
30298
- const sandboxBase = join43(process.cwd(), ".mma", "certification");
30517
+ const sandboxBase = join44(process.cwd(), ".mma", "certification");
30299
30518
  const results = [];
30300
30519
  const total = selected.length;
30301
30520
  let idx = 0;
@@ -30407,9 +30626,9 @@ var init_cli = __esm(() => {
30407
30626
  init_loader3();
30408
30627
  init_runner2();
30409
30628
  init_manifest();
30410
- HERE = dirname15(fileURLToPath3(import.meta.url));
30629
+ HERE = dirname16(fileURLToPath4(import.meta.url));
30411
30630
  MMA_ROOT = findMmaRoot(HERE);
30412
- USER_SCENARIO_DIR = join43(homedir14(), ".mma", "certification", "scenarios");
30631
+ USER_SCENARIO_DIR = join44(homedir15(), ".mma", "certification", "scenarios");
30413
30632
  });
30414
30633
 
30415
30634
  // src/cli/repl-commands.ts
@@ -30418,17 +30637,17 @@ __export(exports_repl_commands, {
30418
30637
  registerAllCommands: () => registerAllCommands,
30419
30638
  COMMAND_GROUPS: () => COMMAND_GROUPS
30420
30639
  });
30421
- import { join as join45, dirname as dirname17 } from "path";
30422
- import { homedir as homedir16 } from "os";
30423
- import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
30424
- import { fileURLToPath as fileURLToPath5 } from "url";
30640
+ import { join as join46, dirname as dirname18 } from "path";
30641
+ import { homedir as homedir17 } from "os";
30642
+ import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
30643
+ import { fileURLToPath as fileURLToPath6 } from "url";
30425
30644
  function readVersion3() {
30426
- const here = dirname17(fileURLToPath5(import.meta.url));
30427
- const candidates = [join45(here, "..", "..", "package.json"), join45(here, "..", "package.json")];
30645
+ const here = dirname18(fileURLToPath6(import.meta.url));
30646
+ const candidates = [join46(here, "..", "..", "package.json"), join46(here, "..", "package.json")];
30428
30647
  for (const p of candidates) {
30429
- if (existsSync51(p)) {
30648
+ if (existsSync52(p)) {
30430
30649
  try {
30431
- const raw = JSON.parse(readFileSync33(p, "utf8"));
30650
+ const raw = JSON.parse(readFileSync34(p, "utf8"));
30432
30651
  if (raw.version)
30433
30652
  return raw.version;
30434
30653
  } catch {}
@@ -30492,7 +30711,7 @@ function registerMmaCommands(ctx) {
30492
30711
  }
30493
30712
  try {
30494
30713
  const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
30495
- const { existsSync: existsSync52 } = await import("fs");
30714
+ const { existsSync: existsSync53 } = await import("fs");
30496
30715
  const { resolve: resolve25 } = await import("path");
30497
30716
  let dataUrl;
30498
30717
  let label;
@@ -30512,7 +30731,7 @@ function registerMmaCommands(ctx) {
30512
30731
  label = source;
30513
30732
  } else {
30514
30733
  const absPath = resolve25(process.cwd(), source);
30515
- if (!existsSync52(absPath)) {
30734
+ if (!existsSync53(absPath)) {
30516
30735
  console.log(pc2.red(t("image.not_found", { path: source })));
30517
30736
  return;
30518
30737
  }
@@ -30591,7 +30810,7 @@ function registerMmaCommands(ctx) {
30591
30810
  console.log(pc2.yellow(t("repl.wizard_running")));
30592
30811
  await ctx.withExclusiveInput(async () => {
30593
30812
  const answers = await runSetup(ctx.rl);
30594
- const configPath = join45(homedir16(), ".mma", "config.json");
30813
+ const configPath = join46(homedir17(), ".mma", "config.json");
30595
30814
  ctx.config.provider.type = answers.provider;
30596
30815
  ctx.config.provider.baseUrl = answers.apiBase;
30597
30816
  ctx.config.provider.apiKey = answers.apiKey;
@@ -30645,7 +30864,7 @@ Excluded blocks: ${info.excluded.length}`));
30645
30864
  return;
30646
30865
  }
30647
30866
  ctx.config.provider.type = name;
30648
- const configPath = join45(homedir16(), ".mma", "config.json");
30867
+ const configPath = join46(homedir17(), ".mma", "config.json");
30649
30868
  saveConfig(ctx.config, configPath);
30650
30869
  await ctx.agent.reconfigure(ctx.config);
30651
30870
  console.log(pc2.green(t("repl.provider_set", { name })));
@@ -30701,7 +30920,7 @@ Excluded blocks: ${info.excluded.length}`));
30701
30920
  return;
30702
30921
  }
30703
30922
  ctx.config.model = name;
30704
- const configPath = join45(homedir16(), ".mma", "config.json");
30923
+ const configPath = join46(homedir17(), ".mma", "config.json");
30705
30924
  saveConfig(ctx.config, configPath);
30706
30925
  await ctx.agent.reconfigure(ctx.config);
30707
30926
  console.log(pc2.green(t("repl.model_set", { name })));
@@ -30726,7 +30945,7 @@ Excluded blocks: ${info.excluded.length}`));
30726
30945
  return;
30727
30946
  }
30728
30947
  ctx.config.contextWindow = size;
30729
- const configPath = join45(homedir16(), ".mma", "config.json");
30948
+ const configPath = join46(homedir17(), ".mma", "config.json");
30730
30949
  saveConfig(ctx.config, configPath);
30731
30950
  await ctx.agent.reconfigure(ctx.config);
30732
30951
  console.log(pc2.green(t("cli.context_set", { size })));
@@ -30744,11 +30963,11 @@ Excluded blocks: ${info.excluded.length}`));
30744
30963
  }
30745
30964
  ctx.agent.shutdown();
30746
30965
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
30747
- const { homedir: homedir17 } = await import("os");
30748
- const { join: join46 } = await import("path");
30966
+ const { homedir: homedir18 } = await import("os");
30967
+ const { join: join47 } = await import("path");
30749
30968
  const configDir = ctx.configDir;
30750
30969
  const baseDir = ctx.baseDir;
30751
- const projectConfigPath = join46(baseDir, ".mmrc");
30970
+ const projectConfigPath = join47(baseDir, ".mmrc");
30752
30971
  const freshConfig = loadConfig2({ configDir, projectConfigPath });
30753
30972
  Object.assign(ctx.config, freshConfig);
30754
30973
  const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
@@ -31149,15 +31368,15 @@ init_bootstrap();
31149
31368
  init_config2();
31150
31369
  init_setup();
31151
31370
  init_i18n();
31152
- import { join as join44, dirname as dirname16 } from "path";
31153
- import { homedir as homedir15 } from "os";
31154
- import { existsSync as existsSync50, readFileSync as readFileSync32 } from "fs";
31371
+ import { join as join45, dirname as dirname17 } from "path";
31372
+ import { homedir as homedir16 } from "os";
31373
+ import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
31155
31374
 
31156
31375
  // src/cli/security-commands.ts
31157
31376
  init_bootstrap();
31158
31377
  init_config2();
31159
- import { join as join38 } from "path";
31160
- import { homedir as homedir12 } from "os";
31378
+ import { join as join39 } from "path";
31379
+ import { homedir as homedir13 } from "os";
31161
31380
 
31162
31381
  // src/modules/security/security-policies.ts
31163
31382
  init_security();
@@ -31670,7 +31889,7 @@ function createSecurityCommand(program2) {
31670
31889
  }
31671
31890
  });
31672
31891
  securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
31673
- const configPath = join38(homedir12(), ".mma", "config.json");
31892
+ const configPath = join39(homedir13(), ".mma", "config.json");
31674
31893
  const { config: appConfig } = await bootstrap();
31675
31894
  const validPresets = ["strict", "balanced", "permissive"];
31676
31895
  if (!validPresets.includes(preset)) {
@@ -31685,7 +31904,7 @@ function createSecurityCommand(program2) {
31685
31904
  console.log(t("cli.security.policy_description", { description: policy.description }));
31686
31905
  });
31687
31906
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
31688
- const configPath = join38(homedir12(), ".mma", "config.json");
31907
+ const configPath = join39(homedir13(), ".mma", "config.json");
31689
31908
  const { config: appConfig } = await bootstrap();
31690
31909
  appConfig.security = appConfig.security || {};
31691
31910
  appConfig.security.sessionEncryption = {
@@ -31697,7 +31916,7 @@ function createSecurityCommand(program2) {
31697
31916
  console.log(t("cli.security.encryption_enabled"));
31698
31917
  });
31699
31918
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
31700
- const configPath = join38(homedir12(), ".mma", "config.json");
31919
+ const configPath = join39(homedir13(), ".mma", "config.json");
31701
31920
  const { config: appConfig } = await bootstrap();
31702
31921
  appConfig.security = appConfig.security || {};
31703
31922
  appConfig.security.sessionEncryption = {
@@ -31709,7 +31928,7 @@ function createSecurityCommand(program2) {
31709
31928
  console.log(t("cli.security.encryption_disabled"));
31710
31929
  });
31711
31930
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
31712
- const configPath = join38(homedir12(), ".mma", "config.json");
31931
+ const configPath = join39(homedir13(), ".mma", "config.json");
31713
31932
  const { config: appConfig } = await bootstrap();
31714
31933
  appConfig.security = appConfig.security || {};
31715
31934
  appConfig.security.auditNotifier = {
@@ -31723,7 +31942,7 @@ function createSecurityCommand(program2) {
31723
31942
  console.log(t("cli.security.audit_enabled"));
31724
31943
  });
31725
31944
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
31726
- const configPath = join38(homedir12(), ".mma", "config.json");
31945
+ const configPath = join39(homedir13(), ".mma", "config.json");
31727
31946
  const { config: appConfig } = await bootstrap();
31728
31947
  appConfig.security = appConfig.security || {};
31729
31948
  appConfig.security.auditNotifier = {
@@ -31787,14 +32006,14 @@ function createPluginCommand(program2) {
31787
32006
 
31788
32007
  // src/cli/commands.ts
31789
32008
  init_setup();
31790
- import { fileURLToPath as fileURLToPath4 } from "url";
32009
+ import { fileURLToPath as fileURLToPath5 } from "url";
31791
32010
  function readVersion2() {
31792
- const here = dirname16(fileURLToPath4(import.meta.url));
31793
- const candidates = [join44(here, "..", "..", "package.json"), join44(here, "..", "package.json")];
32011
+ const here = dirname17(fileURLToPath5(import.meta.url));
32012
+ const candidates = [join45(here, "..", "..", "package.json"), join45(here, "..", "package.json")];
31794
32013
  for (const p of candidates) {
31795
- if (existsSync50(p)) {
32014
+ if (existsSync51(p)) {
31796
32015
  try {
31797
- const raw = JSON.parse(readFileSync32(p, "utf8"));
32016
+ const raw = JSON.parse(readFileSync33(p, "utf8"));
31798
32017
  if (raw.version)
31799
32018
  return raw.version;
31800
32019
  } catch {}
@@ -31807,7 +32026,7 @@ function createProgram() {
31807
32026
  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"));
31808
32027
  program2.command("init").description(t("cli.init")).action(async () => {
31809
32028
  const answers = await runSetup();
31810
- const configPath = join44(homedir15(), ".mma", "config.json");
32029
+ const configPath = join45(homedir16(), ".mma", "config.json");
31811
32030
  const { config } = await bootstrap();
31812
32031
  config.provider.type = answers.provider;
31813
32032
  config.provider.baseUrl = answers.apiBase;
@@ -31852,7 +32071,7 @@ function createProgram() {
31852
32071
  });
31853
32072
  const configCmd = program2.command("config").description(t("cli.manage_config"));
31854
32073
  configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
31855
- const configPath = join44(homedir15(), ".mma", "config.json");
32074
+ const configPath = join45(homedir16(), ".mma", "config.json");
31856
32075
  const { config } = await bootstrap();
31857
32076
  const keys = key.split(".");
31858
32077
  let obj = config;
@@ -31915,7 +32134,7 @@ function createProgram() {
31915
32134
  console.log(t("cli.model_hint"));
31916
32135
  });
31917
32136
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
31918
- const configPath = join44(homedir15(), ".mma", "config.json");
32137
+ const configPath = join45(homedir16(), ".mma", "config.json");
31919
32138
  const { config } = await bootstrap();
31920
32139
  config.model = name;
31921
32140
  saveConfig(config, configPath);
@@ -31951,7 +32170,7 @@ function createProgram() {
31951
32170
  await uncertify2(name, config);
31952
32171
  });
31953
32172
  program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
31954
- const configPath = join44(homedir15(), ".mma", "config.json");
32173
+ const configPath = join45(homedir16(), ".mma", "config.json");
31955
32174
  const { config } = await bootstrap();
31956
32175
  const contextWindow = parseInt(size, 10);
31957
32176
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -31969,7 +32188,7 @@ function createProgram() {
31969
32188
  console.log(t("cli.base_url"), config.provider.baseUrl);
31970
32189
  });
31971
32190
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
31972
- const configPath = join44(homedir15(), ".mma", "config.json");
32191
+ const configPath = join45(homedir16(), ".mma", "config.json");
31973
32192
  const { config } = await bootstrap();
31974
32193
  config.provider.type = name;
31975
32194
  const baseUrl = HOSTED_BASE_URLS[name];
@@ -32784,9 +33003,9 @@ class LineEditor {
32784
33003
  }
32785
33004
 
32786
33005
  // src/cli/repl.ts
32787
- import { existsSync as existsSync53, readFileSync as readFileSync35, writeFileSync as writeFileSync17 } from "fs";
32788
- import { join as join47 } from "path";
32789
- import { homedir as homedir17 } from "os";
33006
+ import { existsSync as existsSync54, readFileSync as readFileSync36, writeFileSync as writeFileSync17 } from "fs";
33007
+ import { join as join48 } from "path";
33008
+ import { homedir as homedir18 } from "os";
32790
33009
 
32791
33010
  // src/cli/completer.ts
32792
33011
  class SlashCommandProvider {
@@ -33393,14 +33612,14 @@ init_config();
33393
33612
  init_colors();
33394
33613
  init_js_identifiers();
33395
33614
  init_i18n();
33396
- import { existsSync as existsSync52, readFileSync as readFileSync34 } from "fs";
33397
- import { join as join46 } from "path";
33615
+ import { existsSync as existsSync53, readFileSync as readFileSync35 } from "fs";
33616
+ import { join as join47 } from "path";
33398
33617
  function readActivePlan(baseDir) {
33399
- const p = join46(baseDir, ".mma", "plans", "active.json");
33400
- if (!existsSync52(p))
33618
+ const p = join47(baseDir, ".mma", "plans", "active.json");
33619
+ if (!existsSync53(p))
33401
33620
  return null;
33402
33621
  try {
33403
- const raw = readFileSync34(p, "utf-8");
33622
+ const raw = readFileSync35(p, "utf-8");
33404
33623
  if (!raw.trim())
33405
33624
  return null;
33406
33625
  const parsed = JSON.parse(raw);
@@ -33543,10 +33762,10 @@ class Repl {
33543
33762
  this.skillsModule = skillsModule;
33544
33763
  this.pluginManager = pluginManager;
33545
33764
  this.logger = logger;
33546
- this.configDir = configDir || join47(homedir17(), ".mma");
33765
+ this.configDir = configDir || join48(homedir18(), ".mma");
33547
33766
  this.baseDir = baseDir || process.cwd();
33548
33767
  this.noAgentsMd = noAgentsMd === true;
33549
- this.historyPath = join47(homedir17(), ".mma", "repl-history");
33768
+ this.historyPath = join48(homedir18(), ".mma", "repl-history");
33550
33769
  this.loadHistory();
33551
33770
  this.rl = process.stdin.isTTY ? new LineEditor({
33552
33771
  input: process.stdin,
@@ -33579,9 +33798,9 @@ class Repl {
33579
33798
  this.setupListeners();
33580
33799
  }
33581
33800
  loadHistory() {
33582
- if (existsSync53(this.historyPath)) {
33801
+ if (existsSync54(this.historyPath)) {
33583
33802
  try {
33584
- const raw = readFileSync35(this.historyPath, "utf-8");
33803
+ const raw = readFileSync36(this.historyPath, "utf-8");
33585
33804
  this.history = raw.split(`
33586
33805
  `).filter(Boolean).slice(-this.maxHistory);
33587
33806
  } catch {
@@ -33959,11 +34178,11 @@ ${t("image.clipboard_empty")}`));
33959
34178
  row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
33960
34179
  } else {
33961
34180
  const agentsMdCandidates = [
33962
- join47(this.baseDir, "AGENTS.md"),
33963
- join47(this.baseDir, ".mma", "AGENTS.md"),
33964
- join47(this.configDir, "AGENTS.md")
34181
+ join48(this.baseDir, "AGENTS.md"),
34182
+ join48(this.baseDir, ".mma", "AGENTS.md"),
34183
+ join48(this.configDir, "AGENTS.md")
33965
34184
  ];
33966
- const foundAgents = agentsMdCandidates.filter((p) => existsSync53(p));
34185
+ const foundAgents = agentsMdCandidates.filter((p) => existsSync54(p));
33967
34186
  if (foundAgents.length > 0) {
33968
34187
  for (const p of foundAgents) {
33969
34188
  row(t("repl.agents_label"), pc2.dim(p));
@@ -33974,7 +34193,7 @@ ${t("image.clipboard_empty")}`));
33974
34193
  }
33975
34194
  const meta = this.sessionManager?.getActiveMeta();
33976
34195
  if (meta) {
33977
- const sessionPath = join47(this.configDir, "sessions", meta.id);
34196
+ const sessionPath = join48(this.configDir, "sessions", meta.id);
33978
34197
  row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
33979
34198
  }
33980
34199
  const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
@@ -34060,10 +34279,10 @@ init_setup();
34060
34279
  init_config2();
34061
34280
  init_i18n();
34062
34281
  init_colors();
34063
- import { existsSync as existsSync54, readFileSync as readFileSync36 } from "fs";
34064
- import { join as join48, dirname as dirname18 } from "path";
34065
- import { homedir as homedir18 } from "os";
34066
- import { fileURLToPath as fileURLToPath6 } from "url";
34282
+ import { existsSync as existsSync55, readFileSync as readFileSync37 } from "fs";
34283
+ import { join as join50, dirname as dirname19 } from "path";
34284
+ import { homedir as homedir20 } from "os";
34285
+ import { fileURLToPath as fileURLToPath7 } from "url";
34067
34286
 
34068
34287
  // src/modules/updater/index.ts
34069
34288
  init_checker();
@@ -34162,14 +34381,61 @@ class UpdaterModule {
34162
34381
  await this.runOnce();
34163
34382
  }
34164
34383
  }
34384
+ // src/core/crash-handler.ts
34385
+ init_environment();
34386
+ init_data_sanitizer();
34387
+ init_i18n();
34388
+ import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync20 } from "fs";
34389
+ import { join as join49 } from "path";
34390
+ import { homedir as homedir19 } from "os";
34391
+ var CRASH_LOG_DIR = join49(homedir19(), ".mma", "logs");
34392
+ var CRASH_LOG_FILE = "crash.jsonl";
34393
+ function formatCrashEntry(type2, err) {
34394
+ const message = err instanceof Error ? err.message : String(err);
34395
+ const stack = err instanceof Error && err.stack ? err.stack : message;
34396
+ return {
34397
+ ts: new Date().toISOString(),
34398
+ type: type2,
34399
+ message: sanitizeLogMessage(message),
34400
+ stack: sanitizeLogMessage(stack),
34401
+ environment: collectEnvironment({ configDir: homedir19(), scanTools: false })
34402
+ };
34403
+ }
34404
+ function writeCrashEntry(dir, entry) {
34405
+ try {
34406
+ mkdirSync20(dir, { recursive: true });
34407
+ appendFileSync7(join49(dir, CRASH_LOG_FILE), JSON.stringify(entry) + `
34408
+ `, "utf-8");
34409
+ } catch {}
34410
+ }
34411
+ var installed = false;
34412
+ function installCrashHandlers() {
34413
+ if (installed)
34414
+ return;
34415
+ installed = true;
34416
+ process.on("uncaughtException", (err) => {
34417
+ const entry = formatCrashEntry("uncaughtException", err);
34418
+ writeCrashEntry(CRASH_LOG_DIR, entry);
34419
+ process.stderr.write(`${t("env.crash_stderr", { type: entry.type, message: entry.message })}
34420
+ `);
34421
+ process.exit(1);
34422
+ });
34423
+ process.on("unhandledRejection", (reason) => {
34424
+ const entry = formatCrashEntry("unhandledRejection", reason);
34425
+ writeCrashEntry(CRASH_LOG_DIR, entry);
34426
+ process.stderr.write(`${t("env.crash_stderr", { type: entry.type, message: entry.message })}
34427
+ `);
34428
+ });
34429
+ }
34430
+
34165
34431
  // src/cli/main.ts
34166
34432
  function readVersion4() {
34167
- const here = dirname18(fileURLToPath6(import.meta.url));
34168
- const candidates = [join48(here, "..", "..", "package.json"), join48(here, "..", "package.json")];
34433
+ const here = dirname19(fileURLToPath7(import.meta.url));
34434
+ const candidates = [join50(here, "..", "..", "package.json"), join50(here, "..", "package.json")];
34169
34435
  for (const p of candidates) {
34170
- if (existsSync54(p)) {
34436
+ if (existsSync55(p)) {
34171
34437
  try {
34172
- const raw = JSON.parse(readFileSync36(p, "utf8"));
34438
+ const raw = JSON.parse(readFileSync37(p, "utf8"));
34173
34439
  if (raw.version)
34174
34440
  return raw.version;
34175
34441
  } catch {}
@@ -34194,6 +34460,7 @@ function startAutoUpdate(config) {
34194
34460
  }
34195
34461
  }
34196
34462
  async function main() {
34463
+ installCrashHandlers();
34197
34464
  const program2 = createProgram();
34198
34465
  program2.parse(process.argv);
34199
34466
  const cmdNames = new Set(program2.commands.map((c) => c.name()));
@@ -34253,15 +34520,15 @@ async function main() {
34253
34520
  await updater?.waitForIdle();
34254
34521
  process.exit(exitCode);
34255
34522
  } else {
34256
- const configPath = join48(homedir18(), ".mma", "config.json");
34257
- if (!existsSync54(configPath)) {
34523
+ const configPath = join50(homedir20(), ".mma", "config.json");
34524
+ if (!existsSync55(configPath)) {
34258
34525
  console.log(pc2.yellow(`
34259
34526
  ` + t("cli.first_run") + `
34260
34527
  `));
34261
34528
  const answers = await runSetup();
34262
34529
  const config2 = loadConfig({
34263
- configDir: join48(homedir18(), ".mma"),
34264
- projectConfigPath: projectDir ? join48(projectDir, ".mmrc") : join48(process.cwd(), ".mmrc")
34530
+ configDir: join50(homedir20(), ".mma"),
34531
+ projectConfigPath: projectDir ? join50(projectDir, ".mmrc") : join50(process.cwd(), ".mmrc")
34265
34532
  });
34266
34533
  config2.provider.type = answers.provider;
34267
34534
  config2.provider.baseUrl = answers.apiBase;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "micro-models-agent",
3
- "version": "0.46.1",
3
+ "version": "0.46.2",
4
4
  "description": "Micro Models Agent (MMA) — LLM agent harness for small models (Qwen3.5-9B, 32K-64K context)",
5
5
  "type": "module",
6
6
  "bin": {