micro-models-agent 0.52.1 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +358 -358
  2. package/dist/certification/certifications.json +331 -0
  3. package/dist/cli/commands.js +447 -0
  4. package/dist/cli/completer.js +167 -0
  5. package/dist/cli/index.js +2 -0
  6. package/dist/cli/main.js +153 -0
  7. package/dist/cli/plugin-commands.js +36 -0
  8. package/dist/cli/repl-commands.js +761 -0
  9. package/dist/cli/repl.js +702 -0
  10. package/dist/cli/run-result.js +33 -0
  11. package/dist/cli/security-commands.js +164 -0
  12. package/dist/cli/setup.js +237 -0
  13. package/dist/config/config.js +276 -0
  14. package/dist/config/defaults.js +141 -0
  15. package/dist/config/domains.js +179 -0
  16. package/dist/config/experts.js +15 -0
  17. package/dist/config/index.js +4 -0
  18. package/dist/config/security.js +213 -0
  19. package/dist/config/types.js +1 -0
  20. package/dist/core/agent-moe.js +102 -0
  21. package/dist/core/agent.js +1018 -0
  22. package/dist/core/bootstrap.js +481 -0
  23. package/dist/core/crash-handler.js +51 -0
  24. package/dist/core/environment.js +199 -0
  25. package/dist/core/index.js +2 -0
  26. package/dist/core/prompt-builder.js +76 -0
  27. package/dist/core/session-logger.js +251 -0
  28. package/dist/core/types.js +1 -0
  29. package/dist/core/version.js +26 -0
  30. package/dist/core/workspace.js +76 -0
  31. package/dist/i18n/en.json +679 -0
  32. package/dist/i18n/index.js +46 -0
  33. package/dist/i18n/ru.json +679 -0
  34. package/dist/index.js +22 -0
  35. package/dist/llm/image-utils.js +143 -0
  36. package/dist/llm/index.js +4 -0
  37. package/dist/llm/model-loader.js +78 -0
  38. package/dist/llm/openai-compat.js +497 -0
  39. package/dist/llm/orchestrator.js +200 -0
  40. package/dist/llm/provider.js +10 -0
  41. package/dist/llm/response.js +39 -0
  42. package/dist/llm/token-counter.js +39 -0
  43. package/dist/llm/types.js +1 -0
  44. package/dist/logger/app-logger.js +189 -0
  45. package/dist/logger/file-log.js +151 -0
  46. package/dist/logger/index.js +1 -0
  47. package/dist/main.js +371 -393
  48. package/dist/migration/backup.js +45 -0
  49. package/dist/migration/detect.js +50 -0
  50. package/dist/migration/index.js +2 -0
  51. package/dist/modules/artifacts/store.js +61 -0
  52. package/dist/modules/browser/actions.js +76 -0
  53. package/dist/modules/browser/bridge-client.js +199 -0
  54. package/dist/modules/browser/bridge-path.js +10 -0
  55. package/dist/modules/browser/bridge-server.mjs +202 -202
  56. package/dist/modules/browser/cookie-store.js +24 -0
  57. package/dist/modules/browser/driver.js +136 -0
  58. package/dist/modules/browser/index.js +7 -0
  59. package/dist/modules/browser/module.js +29 -0
  60. package/dist/modules/browser/session.js +342 -0
  61. package/dist/modules/browser/snapshot.js +148 -0
  62. package/dist/modules/browser/types.js +12 -0
  63. package/dist/modules/certification/cli.js +213 -0
  64. package/dist/modules/certification/fact-checker.js +82 -0
  65. package/dist/modules/certification/loader.js +106 -0
  66. package/dist/modules/certification/manifest.js +58 -0
  67. package/dist/modules/certification/runner.js +245 -0
  68. package/dist/modules/certification/scenarios.js +407 -0
  69. package/dist/modules/certification/types.js +1 -0
  70. package/dist/modules/context/chunk-query.js +100 -0
  71. package/dist/modules/context/fact-extractor.js +168 -0
  72. package/dist/modules/context/history.js +15 -0
  73. package/dist/modules/context/index.js +1 -0
  74. package/dist/modules/context/manager.js +440 -0
  75. package/dist/modules/execution/audit-runners.js +206 -0
  76. package/dist/modules/execution/auditor.js +218 -0
  77. package/dist/modules/execution/execution-plugin.js +431 -0
  78. package/dist/modules/execution/index.js +8 -0
  79. package/dist/modules/execution/module.js +625 -0
  80. package/dist/modules/execution/moe-executor.js +304 -0
  81. package/dist/modules/execution/plan-coverage.js +68 -0
  82. package/dist/modules/execution/plan-persister.js +46 -0
  83. package/dist/modules/execution/plan-store.js +196 -0
  84. package/dist/modules/execution/plan-tool.js +677 -0
  85. package/dist/modules/execution/plan-validator.js +153 -0
  86. package/dist/modules/execution/planner.js +94 -0
  87. package/dist/modules/execution/stuck-detector.js +746 -0
  88. package/dist/modules/execution/tracker.js +69 -0
  89. package/dist/modules/execution/types.js +1 -0
  90. package/dist/modules/execution/verifier.js +235 -0
  91. package/dist/modules/execution/windows-commands.js +41 -0
  92. package/dist/modules/hallucination/confidence.js +66 -0
  93. package/dist/modules/hallucination/consistency.js +26 -0
  94. package/dist/modules/hallucination/detector.js +47 -0
  95. package/dist/modules/hallucination/factual.js +169 -0
  96. package/dist/modules/hallucination/index.js +5 -0
  97. package/dist/modules/hallucination/js-identifiers.js +262 -0
  98. package/dist/modules/hallucination/llm-judge.js +101 -0
  99. package/dist/modules/index.js +5 -0
  100. package/dist/modules/indexer/cache.js +40 -0
  101. package/dist/modules/indexer/index.js +3 -0
  102. package/dist/modules/indexer/module.js +246 -0
  103. package/dist/modules/indexer/project-profile.js +183 -0
  104. package/dist/modules/indexer/walker.js +101 -0
  105. package/dist/modules/lsp/check-tool.js +58 -0
  106. package/dist/modules/lsp/client.js +389 -0
  107. package/dist/modules/lsp/command.js +60 -0
  108. package/dist/modules/lsp/config.js +135 -0
  109. package/dist/modules/lsp/index.js +3 -0
  110. package/dist/modules/lsp/module.js +260 -0
  111. package/dist/modules/lsp/probe.js +86 -0
  112. package/dist/modules/lsp/project-root.js +32 -0
  113. package/dist/modules/lsp/startup-check.js +144 -0
  114. package/dist/modules/lsp/types.js +1 -0
  115. package/dist/modules/mcp/client.js +399 -0
  116. package/dist/modules/mcp/index.js +3 -0
  117. package/dist/modules/mcp/module.js +142 -0
  118. package/dist/modules/mcp/registry.js +15 -0
  119. package/dist/modules/memory/index.js +1 -0
  120. package/dist/modules/memory/module.js +96 -0
  121. package/dist/modules/memory/search.js +42 -0
  122. package/dist/modules/memory/store.js +69 -0
  123. package/dist/modules/pipelines/engine.js +60 -0
  124. package/dist/modules/pipelines/index.js +3 -0
  125. package/dist/modules/pipelines/parser.js +56 -0
  126. package/dist/modules/pipelines/template.js +14 -0
  127. package/dist/modules/plugins/builtin/lint-on-write.js +334 -0
  128. package/dist/modules/plugins/builtin/notify.js +9 -0
  129. package/dist/modules/plugins/index.js +1 -0
  130. package/dist/modules/plugins/loader.js +70 -0
  131. package/dist/modules/plugins/manager.js +261 -0
  132. package/dist/modules/plugins/types.js +1 -0
  133. package/dist/modules/pricing/index.js +61 -0
  134. package/dist/modules/pricing/prices.js +129 -0
  135. package/dist/modules/processes/detect.js +34 -0
  136. package/dist/modules/processes/index.js +2 -0
  137. package/dist/modules/processes/registry.js +327 -0
  138. package/dist/modules/processes/runner.js +23 -0
  139. package/dist/modules/providers/create.js +22 -0
  140. package/dist/modules/providers/fallback.js +79 -0
  141. package/dist/modules/providers/health.js +46 -0
  142. package/dist/modules/providers/index.js +5 -0
  143. package/dist/modules/providers/manager.js +161 -0
  144. package/dist/modules/providers/presets.js +128 -0
  145. package/dist/modules/providers/registry.js +22 -0
  146. package/dist/modules/providers/types.js +1 -0
  147. package/dist/modules/registry.js +48 -0
  148. package/dist/modules/security/audit-log.js +136 -0
  149. package/dist/modules/security/audit-notifier.js +292 -0
  150. package/dist/modules/security/command-validator.js +219 -0
  151. package/dist/modules/security/content-scanner.js +53 -0
  152. package/dist/modules/security/data-sanitizer.js +89 -0
  153. package/dist/modules/security/encryption.js +242 -0
  154. package/dist/modules/security/index.js +14 -0
  155. package/dist/modules/security/network-validator.js +88 -0
  156. package/dist/modules/security/path-validator.js +203 -0
  157. package/dist/modules/security/rate-limiter.js +119 -0
  158. package/dist/modules/security/security-policies.js +531 -0
  159. package/dist/modules/security/session-encryption.js +210 -0
  160. package/dist/modules/security/session-isolation.js +95 -0
  161. package/dist/modules/session/index.js +3 -0
  162. package/dist/modules/session/manager.js +172 -0
  163. package/dist/modules/session/module.js +24 -0
  164. package/dist/modules/session/store.js +222 -0
  165. package/dist/modules/session/types.js +1 -0
  166. package/dist/modules/skills/index.js +2 -0
  167. package/dist/modules/skills/loader.js +72 -0
  168. package/dist/modules/skills/matcher.js +27 -0
  169. package/dist/modules/skills/module.js +129 -0
  170. package/dist/modules/types.js +1 -0
  171. package/dist/modules/updater/checker.js +96 -0
  172. package/dist/modules/updater/index.js +2 -0
  173. package/dist/modules/updater/module.js +116 -0
  174. package/dist/modules/user-profile/compressor.js +16 -0
  175. package/dist/modules/user-profile/index.js +1 -0
  176. package/dist/modules/user-profile/profile.js +68 -0
  177. package/dist/skills/builtin/git.md +36 -36
  178. package/dist/skills/builtin/typescript.md +35 -35
  179. package/dist/tools/approve.js +33 -0
  180. package/dist/tools/attach-image.js +101 -0
  181. package/dist/tools/bash.js +519 -0
  182. package/dist/tools/browser.js +115 -0
  183. package/dist/tools/chunk-query.js +100 -0
  184. package/dist/tools/create-dir.js +56 -0
  185. package/dist/tools/delete-file.js +63 -0
  186. package/dist/tools/download-file.js +117 -0
  187. package/dist/tools/edit-file.js +80 -0
  188. package/dist/tools/enable-tools.js +59 -0
  189. package/dist/tools/executor.js +154 -0
  190. package/dist/tools/file-info.js +47 -0
  191. package/dist/tools/filter-tools.js +17 -0
  192. package/dist/tools/glob-tool.js +27 -0
  193. package/dist/tools/grep-tool.js +125 -0
  194. package/dist/tools/hidden-tools-block.js +37 -0
  195. package/dist/tools/index.js +78 -0
  196. package/dist/tools/list-dir.js +49 -0
  197. package/dist/tools/load-skill.js +43 -0
  198. package/dist/tools/mcp-call.js +69 -0
  199. package/dist/tools/move-file.js +86 -0
  200. package/dist/tools/path-utils.js +101 -0
  201. package/dist/tools/pipeline-run.js +145 -0
  202. package/dist/tools/preview.js +2 -0
  203. package/dist/tools/process-kill.js +40 -0
  204. package/dist/tools/process-list.js +37 -0
  205. package/dist/tools/process-log.js +54 -0
  206. package/dist/tools/question.js +141 -0
  207. package/dist/tools/read-file.js +179 -0
  208. package/dist/tools/recall.js +118 -0
  209. package/dist/tools/registry.js +47 -0
  210. package/dist/tools/remember.js +68 -0
  211. package/dist/tools/scope-check.js +32 -0
  212. package/dist/tools/search-history.js +85 -0
  213. package/dist/tools/subagent.js +196 -0
  214. package/dist/tools/types.js +1 -0
  215. package/dist/tools/user-input.js +123 -0
  216. package/dist/tools/web-browse.js +87 -0
  217. package/dist/tools/web-fetch.js +119 -0
  218. package/dist/tools/web-search.js +105 -0
  219. package/dist/tools/write-file.js +82 -0
  220. package/dist/ui/box.js +77 -0
  221. package/dist/ui/colors.js +4 -0
  222. package/dist/ui/diff.js +178 -0
  223. package/dist/ui/index.js +6 -0
  224. package/dist/ui/line-editor.js +822 -0
  225. package/dist/ui/line-math.js +73 -0
  226. package/dist/ui/md-formatter.js +212 -0
  227. package/dist/ui/output.js +13 -0
  228. package/dist/ui/plan-view.js +103 -0
  229. package/dist/ui/renderer.js +259 -0
  230. package/dist/ui/spinner.js +70 -0
  231. package/dist/ui/table.js +144 -0
  232. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2658,7 +2658,7 @@ Fix the error and re-edit the file (a clean write clears the failure), or mark t
2658
2658
  "cli.cert_provider_url": "Provider base URL to certify against (default: current config)",
2659
2659
  "cli.cert_provider_key": "Provider API key (optional)",
2660
2660
  "cli.cert_context_window": "Context window size in tokens",
2661
- "cli.cert_tags": "Comma-separated scenario tags (core, security, image, network, browser, shell, research)",
2661
+ "cli.cert_tags": "Comma-separated scenario tags (core, security, image, network, browser)",
2662
2662
  "cli.cert_reps": "Default repetitions per scenario (overridden by scenario)",
2663
2663
  "cli.cert_force": "Re-run an existing certification",
2664
2664
  "cli.cert_clean": "Remove sandbox directories after a successful run",
@@ -3381,7 +3381,7 @@ var init_ru = __esm(() => {
3381
3381
  "cli.cert_provider_url": "Базовый URL провайдера для сертификации (по умолчанию — текущий конфиг)",
3382
3382
  "cli.cert_provider_key": "API-ключ провайдера (необязательно)",
3383
3383
  "cli.cert_context_window": "Размер контекстного окна в токенах",
3384
- "cli.cert_tags": "Теги сценариев через запятую (core, security, image, network, browser, shell, research)",
3384
+ "cli.cert_tags": "Теги сценариев через запятую (core, security, image, network, browser)",
3385
3385
  "cli.cert_reps": "Повторов по умолчанию на сценарий (переопределяется сценарием)",
3386
3386
  "cli.cert_force": "Перепрогнать существующую сертификацию",
3387
3387
  "cli.cert_clean": "Удалить песочницы после успешного прогона",
@@ -6629,9 +6629,6 @@ var init_executor = __esm(() => {
6629
6629
  // src/tools/path-utils.ts
6630
6630
  import { resolve, normalize, dirname as dirname2, basename, sep, relative, isAbsolute } from "path";
6631
6631
  import { existsSync as existsSync8 } from "fs";
6632
- function toForwardSlash(p) {
6633
- return p.replace(/\\/g, "/");
6634
- }
6635
6632
  function isInsideDir(targetPath, dirPath) {
6636
6633
  const norm = (p) => process.platform === "win32" ? p.toLowerCase() : p;
6637
6634
  const t2 = norm(resolve(targetPath));
@@ -6863,7 +6860,7 @@ function matchesGlobPattern(targetPath, baseDir, pattern) {
6863
6860
  if (pattern.includes("*")) {
6864
6861
  const regexPattern = pattern.replace(/\*/g, "[^/\\\\]*").replace(/\?/g, ".").replace(/\./g, "\\.");
6865
6862
  const regex = new RegExp(`^${regexPattern}$`);
6866
- const relativePath = toForwardSlash(resolvedTargetPath.slice(resolvedBaseDir.length + 1));
6863
+ const relativePath = resolvedTargetPath.slice(resolvedBaseDir.length + 1).replace(/\\/g, "/");
6867
6864
  return regex.test(relativePath);
6868
6865
  }
6869
6866
  const exactTarget = resolve2(baseDir, pattern);
@@ -7449,12 +7446,17 @@ function isPathInSessionScope(sessionContext, path) {
7449
7446
  const resolvedPath = resolve5(path);
7450
7447
  const workingDir = resolve5(sessionContext.workingDir);
7451
7448
  const tempDir = resolve5(sessionContext.tempDir);
7452
- return isInsideDir(resolvedPath, workingDir) || isInsideDir(resolvedPath, tempDir);
7449
+ if (resolvedPath.startsWith(workingDir + "/") || resolvedPath.startsWith(workingDir + "\\")) {
7450
+ return true;
7451
+ }
7452
+ if (resolvedPath.startsWith(tempDir + "/") || resolvedPath.startsWith(tempDir + "\\")) {
7453
+ return true;
7454
+ }
7455
+ return false;
7453
7456
  }
7454
7457
  var DEFAULT_SESSION_ISOLATION;
7455
7458
  var init_session_isolation = __esm(() => {
7456
7459
  init_security();
7457
- init_path_utils();
7458
7460
  DEFAULT_SESSION_ISOLATION = {
7459
7461
  enabled: false,
7460
7462
  isolatePlugins: true,
@@ -8422,52 +8424,15 @@ var init_command_validator = __esm(() => {
8422
8424
  DEFAULT_BASH_CONFIG = DEFAULT_SECURITY_CONFIG?.bash || FALLBACK_BASH_CONFIG;
8423
8425
  });
8424
8426
 
8425
- // src/modules/processes/kill-tree.ts
8426
- import { spawnSync } from "child_process";
8427
- import { platform } from "os";
8428
- function sleepSync(ms) {
8429
- try {
8430
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
8431
- } catch {}
8432
- }
8433
- function taskkillPid(pid) {
8434
- try {
8435
- spawnSync("taskkill", ["/pid", String(pid), "/T", "/F"], {
8436
- windowsHide: true,
8437
- stdio: "ignore",
8438
- timeout: 5000
8439
- });
8440
- } catch {}
8441
- }
8442
- function killTree(child) {
8443
- const pid = child.pid;
8444
- if (!pid)
8445
- return;
8446
- if (platform() === "win32") {
8447
- taskkillPid(pid);
8448
- sleepSync(150);
8449
- taskkillPid(pid);
8450
- return;
8451
- }
8452
- try {
8453
- process.kill(-pid, "SIGTERM");
8454
- } catch {
8455
- try {
8456
- child.kill("SIGKILL");
8457
- } catch {}
8458
- }
8459
- }
8460
- var init_kill_tree = () => {};
8461
-
8462
8427
  // src/modules/processes/registry.ts
8463
- import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
8464
- import { platform as platform2 } from "os";
8428
+ import { spawn as spawn2, spawnSync } from "child_process";
8429
+ import { platform } from "os";
8465
8430
  function getOemDecoder() {
8466
8431
  if (oemDecoder !== undefined)
8467
8432
  return oemDecoder;
8468
8433
  oemDecoder = null;
8469
8434
  try {
8470
- const cpOut = spawnSync2("chcp.com", {
8435
+ const cpOut = spawnSync("chcp.com", {
8471
8436
  encoding: "buffer",
8472
8437
  timeout: 2000,
8473
8438
  windowsHide: true
@@ -8502,6 +8467,38 @@ function decodeLineToUtf8(buf) {
8502
8467
  }
8503
8468
  return buf.toString("latin1");
8504
8469
  }
8470
+ function sleepSync(ms) {
8471
+ try {
8472
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
8473
+ } catch {}
8474
+ }
8475
+ function taskkillPid(pid) {
8476
+ try {
8477
+ spawnSync("taskkill", ["/pid", String(pid), "/T", "/F"], {
8478
+ windowsHide: true,
8479
+ stdio: "ignore",
8480
+ timeout: 5000
8481
+ });
8482
+ } catch {}
8483
+ }
8484
+ function killTree(child) {
8485
+ const pid = child.pid;
8486
+ if (!pid)
8487
+ return;
8488
+ if (platform() === "win32") {
8489
+ taskkillPid(pid);
8490
+ sleepSync(150);
8491
+ taskkillPid(pid);
8492
+ return;
8493
+ }
8494
+ try {
8495
+ process.kill(-pid, "SIGTERM");
8496
+ } catch {
8497
+ try {
8498
+ child.kill("SIGKILL");
8499
+ } catch {}
8500
+ }
8501
+ }
8505
8502
 
8506
8503
  class ProcessRegistry {
8507
8504
  procs = new Map;
@@ -8528,7 +8525,7 @@ class ProcessRegistry {
8528
8525
  cwd,
8529
8526
  shell: true,
8530
8527
  windowsHide: true,
8531
- detached: platform2() !== "win32",
8528
+ detached: platform() !== "win32",
8532
8529
  stdio: ["ignore", "pipe", "pipe"]
8533
8530
  });
8534
8531
  } catch (e) {
@@ -8541,7 +8538,7 @@ class ProcessRegistry {
8541
8538
  entry.pid = child.pid ?? 0;
8542
8539
  let buf = "";
8543
8540
  let byteBuf = Buffer.alloc(0);
8544
- const isWin = platform2() === "win32";
8541
+ const isWin = platform() === "win32";
8545
8542
  const unixDecoder = new TextDecoder("utf-8");
8546
8543
  const pushLine = (line) => {
8547
8544
  if (entry.log.length >= MAX_LOG_LINES) {
@@ -8690,8 +8687,6 @@ class ProcessRegistry {
8690
8687
  }
8691
8688
  var MAX_LOG_LINES = 2000, MAX_KEPT_PROCESSES = 20, seq = 0, oemDecoder, processRegistry;
8692
8689
  var init_registry = __esm(() => {
8693
- init_kill_tree();
8694
- init_kill_tree();
8695
8690
  processRegistry = new ProcessRegistry;
8696
8691
  });
8697
8692
 
@@ -8699,11 +8694,10 @@ var init_registry = __esm(() => {
8699
8694
  var init_processes = __esm(() => {
8700
8695
  init_runner();
8701
8696
  init_registry();
8702
- init_kill_tree();
8703
8697
  });
8704
8698
 
8705
8699
  // src/tools/bash.ts
8706
- import { platform as platform3 } from "os";
8700
+ import { platform as platform2 } from "os";
8707
8701
  function extractEchoFileWrite(command) {
8708
8702
  if (!/^\s*(?:echo|printf)\b/i.test(command))
8709
8703
  return null;
@@ -8727,17 +8721,17 @@ function translateSemicolonsForCmd(command) {
8727
8721
  return out;
8728
8722
  }
8729
8723
  function adaptCommandForWindows(command) {
8730
- if (platform3() !== "win32")
8724
+ if (platform2() !== "win32")
8731
8725
  return command;
8732
8726
  if (/\|\|\s*true\b/.test(command)) {
8733
8727
  command = command.replace(/\s*\|\|\s*true\b/g, "; exit 0");
8734
8728
  }
8735
8729
  const trimmed = command.trim();
8736
- if (/^mkdir\s+(-p|--parents)\b/.test(trimmed)) {
8737
- return trimmed.replace(/^mkdir\s+(-p|--parents)\s*/, "mkdir ");
8730
+ if (trimmed.startsWith("mkdir -p ")) {
8731
+ return trimmed.replace(/^mkdir -p /, "mkdir ");
8738
8732
  }
8739
- if (/^mkdir\s+(-p|--parents)\s*$/.test(trimmed)) {
8740
- return "mkdir";
8733
+ if (trimmed === "mkdir -p" || trimmed.startsWith("mkdir -p ")) {
8734
+ return trimmed.replace(/mkdir -p/g, "mkdir");
8741
8735
  }
8742
8736
  const firstWord = trimmed.split(/\s+/)[0]?.split(/[\\/]/).pop();
8743
8737
  const translated = firstWord ? UNIX_TO_WIN_TRANSLATE[firstWord] : undefined;
@@ -8948,7 +8942,7 @@ ${redirected.output}`
8948
8942
  output: t("exec.hidden_tool_hint", { tool: baseCmd })
8949
8943
  };
8950
8944
  }
8951
- if (platform3() === "win32") {
8945
+ if (platform2() === "win32") {
8952
8946
  const echoWrite = extractEchoFileWrite(originalCommand);
8953
8947
  if (echoWrite) {
8954
8948
  return {
@@ -9016,7 +9010,7 @@ ${output2}`;
9016
9010
  output2 = `(exit code ${code})`;
9017
9011
  }
9018
9012
  output2 = npmExecHint(output2);
9019
- if (platform3() === "win32") {
9013
+ if (platform2() === "win32") {
9020
9014
  const originalFirstWord = originalCommand.trim().split(/\s+/)[0]?.split(/[\\/]/).pop();
9021
9015
  if (originalFirstWord && originalFirstWord in UNIX_TO_WIN_HINTS) {
9022
9016
  if (code === 0) {
@@ -12016,7 +12010,7 @@ function findExistingFile(baseDir, filePath) {
12016
12010
  if (existsSync23(direct))
12017
12011
  return direct;
12018
12012
  const name = basename2(filePath).toLowerCase();
12019
- const suffix = toForwardSlash(filePath).toLowerCase();
12013
+ const suffix = filePath.replace(/\\/g, "/").toLowerCase();
12020
12014
  let found = null;
12021
12015
  const walk = (dir, depth) => {
12022
12016
  if (found || depth > RESOLVE_MAX_DEPTH)
@@ -12035,7 +12029,7 @@ function findExistingFile(baseDir, filePath) {
12035
12029
  if (SKIP_DIRS.has(e.name))
12036
12030
  continue;
12037
12031
  walk(full, depth + 1);
12038
- } else if (e.name.toLowerCase() === name || toForwardSlash(full).toLowerCase().endsWith("/" + suffix)) {
12032
+ } else if (e.name.toLowerCase() === name || full.replace(/\\/g, "/").toLowerCase().endsWith("/" + suffix)) {
12039
12033
  found = full;
12040
12034
  return;
12041
12035
  }
@@ -12163,7 +12157,6 @@ var MASS_EDIT_THRESHOLD = 10, RESOLVE_MAX_DEPTH = 8;
12163
12157
  var init_auditor = __esm(() => {
12164
12158
  init_i18n();
12165
12159
  init_js_identifiers();
12166
- init_path_utils();
12167
12160
  init_audit_runners();
12168
12161
  init_audit_runners();
12169
12162
  });
@@ -14397,8 +14390,8 @@ var init_detector = __esm(() => {
14397
14390
  // src/modules/lsp/command.ts
14398
14391
  import { delimiter, join as join17 } from "path";
14399
14392
  import { existsSync as existsSync26 } from "fs";
14400
- import { platform as platform4 } from "os";
14401
- function resolveSpawnCommand(command, platformName = platform4(), pathEnv = process.env.PATH ?? "") {
14393
+ import { platform as platform3 } from "os";
14394
+ function resolveSpawnCommand(command, platformName = platform3(), pathEnv = process.env.PATH ?? "") {
14402
14395
  if (platformName !== "win32")
14403
14396
  return command;
14404
14397
  if (command.includes("/") || command.includes("\\") || WIN_EXTS.some((ext) => command.toLowerCase().endsWith(ext))) {
@@ -14430,7 +14423,7 @@ var init_command = __esm(() => {
14430
14423
  });
14431
14424
 
14432
14425
  // src/modules/updater/checker.ts
14433
- import { platform as platform5 } from "os";
14426
+ import { platform as platform4 } from "os";
14434
14427
  function semverGt(a, b) {
14435
14428
  const pa = a.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
14436
14429
  const pb = b.replace(/^v/, "").split(/[.-]/).map((p) => Number.parseInt(p, 10) || 0);
@@ -14501,7 +14494,7 @@ class Updater {
14501
14494
  buildInstallCommand(latest) {
14502
14495
  const npmArgs = ["install", "-g", `${this.packageName}@${latest}`];
14503
14496
  const command = resolveSpawnCommand("npm");
14504
- if (platform5() === "win32" && /\.(cmd|bat)$/i.test(command)) {
14497
+ if (platform4() === "win32" && /\.(cmd|bat)$/i.test(command)) {
14505
14498
  return { command: "cmd.exe", args: ["/c", command, ...npmArgs] };
14506
14499
  }
14507
14500
  return { command, args: npmArgs };
@@ -17930,30 +17923,28 @@ async function readClipboardImage() {
17930
17923
  return readClipboardFallback();
17931
17924
  }
17932
17925
  async function readClipboardFallback() {
17933
- const { platform: platform6 } = await import("os");
17926
+ const { platform: platform5 } = await import("os");
17934
17927
  const { execSync } = await import("child_process");
17935
17928
  const { readFileSync: readFileSync18, unlinkSync: unlinkSync4 } = await import("fs");
17936
17929
  const { join: join26 } = await import("path");
17937
- if (platform6() !== "linux")
17938
- return null;
17939
17930
  const tmpPath = join26(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
17940
- const commands = [
17941
- `wl-paste --type image/png > "${tmpPath}" 2>/dev/null`,
17942
- `xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`
17943
- ];
17944
- for (const cmd of commands) {
17931
+ try {
17932
+ if (platform5() === "linux") {
17933
+ execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, {
17934
+ timeout: 5000
17935
+ });
17936
+ } else {
17937
+ return null;
17938
+ }
17939
+ const buf = readFileSync18(tmpPath);
17940
+ unlinkSync4(tmpPath);
17941
+ return buf.length > 0 ? buf : null;
17942
+ } catch {
17945
17943
  try {
17946
- execSync(cmd, { timeout: 5000 });
17947
- const buf = readFileSync18(tmpPath);
17948
17944
  unlinkSync4(tmpPath);
17949
- if (buf.length > 0)
17950
- return buf;
17951
17945
  } catch {}
17946
+ return null;
17952
17947
  }
17953
- try {
17954
- unlinkSync4(tmpPath);
17955
- } catch {}
17956
- return null;
17957
17948
  }
17958
17949
  async function loadFileAsDataUrl(filePath) {
17959
17950
  const buf = readFileSync17(filePath);
@@ -18396,7 +18387,7 @@ var init_loader = __esm(() => {
18396
18387
  import { spawn as spawn6, execSync } from "child_process";
18397
18388
  import { existsSync as existsSync33, readFileSync as readFileSync18 } from "fs";
18398
18389
  import { resolve as resolve18, extname as extname4, join as join27 } from "path";
18399
- import { platform as platform6 } from "os";
18390
+ import { platform as platform5 } from "os";
18400
18391
  function lintCacheKey(baseDir, lintScript) {
18401
18392
  return `${baseDir}::${lintScript}`;
18402
18393
  }
@@ -18417,7 +18408,7 @@ function contentHash(content) {
18417
18408
  function getWinDecoder() {
18418
18409
  if (_winDecoder !== undefined)
18419
18410
  return _winDecoder;
18420
- if (platform6() !== "win32") {
18411
+ if (platform5() !== "win32") {
18421
18412
  _winDecoder = new TextDecoder("utf-8");
18422
18413
  return _winDecoder;
18423
18414
  }
@@ -19111,9 +19102,9 @@ var init_windows_commands = __esm(() => {
19111
19102
  });
19112
19103
 
19113
19104
  // src/modules/execution/execution-plugin.ts
19114
- import { platform as platform7 } from "os";
19105
+ import { platform as platform6 } from "os";
19115
19106
  function normalizeBrokenPath(p) {
19116
- return toForwardSlash(p).replace(/^\.\//, "");
19107
+ return p.replace(/\\/g, "/").replace(/^\.\//, "");
19117
19108
  }
19118
19109
  function parseBrokenFile(line) {
19119
19110
  const trimmed = line.trim();
@@ -19341,7 +19332,7 @@ Last compile error: ${first[1]}`;
19341
19332
  if (call.name === "bash") {
19342
19333
  deps.stuckDetector.recordBashAttempt(false);
19343
19334
  }
19344
- if (call.name === "bash" && platform7() === "win32") {
19335
+ if (call.name === "bash" && platform6() === "win32") {
19345
19336
  const cmd = String(call.arguments?.command ?? "");
19346
19337
  const forbidden = forbiddenWindowsCommand(cmd);
19347
19338
  if (forbidden) {
@@ -19408,7 +19399,6 @@ var init_execution_plugin = __esm(() => {
19408
19399
  init_bash();
19409
19400
  init_windows_commands();
19410
19401
  init_js_identifiers();
19411
- init_path_utils();
19412
19402
  FS_MUTATING_TOOLS = new Set([
19413
19403
  "write_file",
19414
19404
  "edit_file",
@@ -21067,7 +21057,7 @@ class ProfileCompressor {
21067
21057
  // src/modules/user-profile/profile.ts
21068
21058
  import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as existsSync38, mkdirSync as mkdirSync17 } from "fs";
21069
21059
  import { join as join31 } from "path";
21070
- import { homedir as homedir10, hostname, platform as platform8, type } from "os";
21060
+ import { homedir as homedir10, hostname, platform as platform7, type } from "os";
21071
21061
  import { env } from "process";
21072
21062
 
21073
21063
  class UserProfile {
@@ -21079,7 +21069,7 @@ class UserProfile {
21079
21069
  }
21080
21070
  collect() {
21081
21071
  this.info = {
21082
- platform: platform8(),
21072
+ platform: platform7(),
21083
21073
  os: `${type()} ${hostname()}`,
21084
21074
  hostname: hostname(),
21085
21075
  shell: env.SHELL || env.ComSpec || "unknown",
@@ -21395,7 +21385,7 @@ var init_browser2 = __esm(() => {
21395
21385
  // src/modules/lsp/client.ts
21396
21386
  import { spawn as spawn7, execSync as execSync2 } from "child_process";
21397
21387
  import { resolve as resolve20 } from "path";
21398
- import { platform as platform9 } from "os";
21388
+ import { platform as platform8 } from "os";
21399
21389
 
21400
21390
  class FileOnlyLogger {
21401
21391
  logger;
@@ -21515,7 +21505,7 @@ class LspClient {
21515
21505
  if (config.command === "npx" && effectiveArgs.length > 0) {
21516
21506
  const binaryName = this.extractBinaryFromNpxArgs(effectiveArgs);
21517
21507
  if (binaryName) {
21518
- const whichCmd = platform9() === "win32" ? `where ${binaryName}` : `which ${binaryName}`;
21508
+ const whichCmd = platform8() === "win32" ? `where ${binaryName}` : `which ${binaryName}`;
21519
21509
  try {
21520
21510
  execSync2(whichCmd, { stdio: "pipe", timeout: 3000 });
21521
21511
  effectiveCommand = binaryName;
@@ -21528,7 +21518,7 @@ class LspClient {
21528
21518
  }
21529
21519
  return new Promise((resolve21, reject) => {
21530
21520
  const args = effectiveArgs;
21531
- const isWin = platform9() === "win32";
21521
+ const isWin = platform8() === "win32";
21532
21522
  let spawnCommand = resolveSpawnCommand(effectiveCommand);
21533
21523
  let spawnArgs = args;
21534
21524
  const spawnOpts = {
@@ -21692,7 +21682,7 @@ class LspClient {
21692
21682
  }
21693
21683
  }
21694
21684
  pathToUri(filePath) {
21695
- const normalized = toForwardSlash(filePath);
21685
+ const normalized = filePath.replace(/\\/g, "/");
21696
21686
  return /^[a-zA-Z]:/.test(normalized) ? `file:///${normalized}` : `file://${normalized}`;
21697
21687
  }
21698
21688
  languageFromPath(filePath) {
@@ -21740,7 +21730,6 @@ var DEFAULT_TIMEOUT = 15000;
21740
21730
  var init_client2 = __esm(() => {
21741
21731
  init_command();
21742
21732
  init_registry();
21743
- init_path_utils();
21744
21733
  });
21745
21734
 
21746
21735
  // src/modules/lsp/check-tool.ts
@@ -21774,7 +21763,7 @@ async function walkDir(dir, depth, out, config) {
21774
21763
  }
21775
21764
  function formatCheckDiagnostics(items, baseDir) {
21776
21765
  return items.slice(0, 40).map(({ file, diag }) => {
21777
- const rel = toForwardSlash(relative3(baseDir, file));
21766
+ const rel = relative3(baseDir, file).replace(/\\/g, "/");
21778
21767
  const line = diag.range.start.line + 1;
21779
21768
  const col = diag.range.start.character + 1;
21780
21769
  const sev = severityLabels[diag.severity] ?? "unknown";
@@ -21785,7 +21774,6 @@ function formatCheckDiagnostics(items, baseDir) {
21785
21774
  var MAX_LSP_CHECK_FILES = 15, MAX_LSP_WALK_DEPTH = 4, SKIP_DIRS2, severityLabels;
21786
21775
  var init_check_tool = __esm(() => {
21787
21776
  init_config();
21788
- init_path_utils();
21789
21777
  SKIP_DIRS2 = new Set(["node_modules", ".git", ".mma", "dist"]);
21790
21778
  severityLabels = {
21791
21779
  1: "error",
@@ -21964,7 +21952,7 @@ ${items}`;
21964
21952
  const diags = await this.client.checkFile(file, ctx.baseDir, serverConfig, projectRoot);
21965
21953
  this.failuresByServer.set(key, 0);
21966
21954
  checked++;
21967
- checkedFiles.push(toForwardSlash(relative4(ctx.baseDir, file)));
21955
+ checkedFiles.push(relative4(ctx.baseDir, file).replace(/\\/g, "/"));
21968
21956
  for (const d of diags) {
21969
21957
  if (d.severity === 1)
21970
21958
  errors.push({ file, diag: d });
@@ -22014,7 +22002,7 @@ ${items}`;
22014
22002
  }
22015
22003
  }
22016
22004
  function formatDiagnostics(diagnostics, filePath) {
22017
- const filename = toForwardSlash(filePath).split("/").pop() ?? filePath;
22005
+ const filename = filePath.replace(/\\/g, "/").split("/").pop() ?? filePath;
22018
22006
  return diagnostics.slice(0, 5).map((d) => {
22019
22007
  const line = d.range.start.line + 1;
22020
22008
  const col = d.range.start.character + 1;
@@ -22031,7 +22019,6 @@ var init_module5 = __esm(() => {
22031
22019
  init_path_validator();
22032
22020
  init_security();
22033
22021
  init_path_utils();
22034
- init_path_utils();
22035
22022
  init_i18n();
22036
22023
  init_check_tool();
22037
22024
  });
@@ -22580,7 +22567,7 @@ class IndexerModule {
22580
22567
  const dirCounts = this.getDirectoryCounts(result);
22581
22568
  const topDirs = Object.entries(dirCounts).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([dir, count]) => `${dir} (${count})`).join(", ") || "-";
22582
22569
  const fileLines = result.files.slice(0, 100).map((f) => {
22583
- const path = toForwardSlash(f.path);
22570
+ const path = f.path.replace(/\\/g, "/");
22584
22571
  const exports = f.exports.length > 0 ? `: ${f.exports.join(", ")}` : "";
22585
22572
  return `- ${path}${exports}`;
22586
22573
  });
@@ -22602,7 +22589,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
22602
22589
  findDuplicateBasenames(result) {
22603
22590
  const byDir = {};
22604
22591
  for (const f of result.files) {
22605
- const path = toForwardSlash(f.path);
22592
+ const path = f.path.replace(/\\/g, "/");
22606
22593
  const idx = path.lastIndexOf("/");
22607
22594
  const dir = idx >= 0 ? path.slice(0, idx) : "";
22608
22595
  const name = path.slice(idx + 1);
@@ -22632,7 +22619,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
22632
22619
  getDirectoryCounts(result) {
22633
22620
  const counts = {};
22634
22621
  for (const f of result.files) {
22635
- const normalized = toForwardSlash(f.path);
22622
+ const normalized = f.path.replace(/\\/g, "/");
22636
22623
  const dir = dirname12(normalized);
22637
22624
  const key = dir === "." ? "(root)" : dir;
22638
22625
  counts[key] = (counts[key] || 0) + 1;
@@ -22682,7 +22669,7 @@ ${stackLine2}` : summary2;
22682
22669
  return this.makeResult(t("indexer.no_matches", { query }));
22683
22670
  }
22684
22671
  const lines = matches.map((f) => {
22685
- const path = toForwardSlash(f.path);
22672
+ const path = f.path.replace(/\\/g, "/");
22686
22673
  const exports = f.exports.length > 0 ? `: ${f.exports.join(", ")}` : "";
22687
22674
  return `- ${path}${exports}`;
22688
22675
  }).join(`
@@ -22715,7 +22702,6 @@ var init_module6 = __esm(() => {
22715
22702
  init_cache();
22716
22703
  init_project_profile();
22717
22704
  init_i18n();
22718
- init_path_utils();
22719
22705
  });
22720
22706
 
22721
22707
  // src/modules/indexer/index.ts
@@ -22993,11 +22979,11 @@ var init_version = () => {};
22993
22979
 
22994
22980
  // src/core/environment.ts
22995
22981
  import { existsSync as existsSync46, readFileSync as readFileSync29, readdirSync as readdirSync16 } from "fs";
22996
- import { spawnSync as spawnSync3 } from "child_process";
22982
+ import { spawnSync as spawnSync2 } from "child_process";
22997
22983
  import { createRequire as createRequire2 } from "module";
22998
22984
  import { join as join39, dirname as dirname14 } from "path";
22999
22985
  import { fileURLToPath as fileURLToPath3 } from "url";
23000
- import { arch, homedir as homedir12, hostname as hostname2, platform as platform10, release } from "os";
22986
+ import { arch, homedir as homedir12, hostname as hostname2, platform as platform9, release } from "os";
23001
22987
  import { env as env2 } from "process";
23002
22988
  function readEngineRequirement() {
23003
22989
  const here = dirname14(fileURLToPath3(import.meta.url));
@@ -23052,7 +23038,7 @@ function detectRuntime() {
23052
23038
  }
23053
23039
  function toolVersion(cmd) {
23054
23040
  try {
23055
- const res = spawnSync3(cmd, ["--version"], {
23041
+ const res = spawnSync2(cmd, ["--version"], {
23056
23042
  encoding: "utf8",
23057
23043
  timeout: 3000,
23058
23044
  windowsHide: true,
@@ -23143,7 +23129,7 @@ function collectEnvironment(opts) {
23143
23129
  mmaVersion: readMmaVersion(),
23144
23130
  runtime,
23145
23131
  os: {
23146
- platform: platform10(),
23132
+ platform: platform9(),
23147
23133
  arch: arch(),
23148
23134
  release: release(),
23149
23135
  hostname: hostname2(),
@@ -23173,15 +23159,175 @@ var init_environment = __esm(() => {
23173
23159
  TOOL_CHECKS = ["bun", "node", "git", "python"];
23174
23160
  });
23175
23161
 
23162
+ // src/modules/certification/manifest.ts
23163
+ var exports_manifest = {};
23164
+ __export(exports_manifest, {
23165
+ upsertCertification: () => upsertCertification,
23166
+ syncGlobalManifest: () => syncGlobalManifest,
23167
+ saveManifest: () => saveManifest,
23168
+ saveGlobalManifest: () => saveGlobalManifest,
23169
+ removeCertification: () => removeCertification,
23170
+ readMergedManifest: () => readMergedManifest,
23171
+ readManifest: () => readManifest,
23172
+ readGlobalManifest: () => readGlobalManifest,
23173
+ manifestPath: () => manifestPath,
23174
+ isStale: () => isStale,
23175
+ isFullyPassed: () => isFullyPassed,
23176
+ globalManifestPath: () => globalManifestPath,
23177
+ globalManifestDir: () => globalManifestDir,
23178
+ getCertMark: () => getCertMark,
23179
+ bundledManifestPath: () => bundledManifestPath
23180
+ });
23181
+ import { existsSync as existsSync47, readFileSync as readFileSync30, mkdirSync as mkdirSync19, writeFileSync as writeFileSync16 } from "fs";
23182
+ import { dirname as dirname15, join as join40 } from "path";
23183
+ import { fileURLToPath as fileURLToPath4 } from "url";
23184
+ import { homedir as homedir13 } from "os";
23185
+ function manifestPath(projectDir) {
23186
+ return join40(projectDir, "certification", "certifications.json");
23187
+ }
23188
+ function globalManifestDir(override) {
23189
+ return override || process.env.MMA_CERT_HOME || join40(homedir13(), ".mma");
23190
+ }
23191
+ function globalManifestPath(override) {
23192
+ return join40(globalManifestDir(override), "certifications.json");
23193
+ }
23194
+ function readManifest(projectDir) {
23195
+ const path = manifestPath(projectDir);
23196
+ try {
23197
+ if (existsSync47(path)) {
23198
+ const raw = JSON.parse(readFileSync30(path, "utf-8"));
23199
+ return { version: 1, certifications: raw.certifications ?? [] };
23200
+ }
23201
+ } catch {}
23202
+ return { version: 1, certifications: [] };
23203
+ }
23204
+ function saveManifest(m, projectDir) {
23205
+ const path = manifestPath(projectDir);
23206
+ mkdirSync19(join40(projectDir, "certification"), { recursive: true });
23207
+ writeFileSync16(path, JSON.stringify(m, null, 2), "utf-8");
23208
+ }
23209
+ function readGlobalManifest(override) {
23210
+ const path = globalManifestPath(override);
23211
+ try {
23212
+ if (existsSync47(path)) {
23213
+ const raw = JSON.parse(readFileSync30(path, "utf-8"));
23214
+ return { version: 1, certifications: raw.certifications ?? [] };
23215
+ }
23216
+ } catch {}
23217
+ return { version: 1, certifications: [] };
23218
+ }
23219
+ function saveGlobalManifest(m, override) {
23220
+ const dir = globalManifestDir(override);
23221
+ mkdirSync19(dir, { recursive: true });
23222
+ writeFileSync16(globalManifestPath(override), JSON.stringify(m, null, 2), "utf-8");
23223
+ }
23224
+ function readMergedManifest(projectDir, override) {
23225
+ const merged = new Map;
23226
+ for (const e of readGlobalManifest(override).certifications)
23227
+ merged.set(certKey(e), e);
23228
+ for (const e of readManifest(projectDir).certifications)
23229
+ merged.set(certKey(e), e);
23230
+ return { version: 1, certifications: [...merged.values()] };
23231
+ }
23232
+ function upsertCertification(entry, override) {
23233
+ const m = readGlobalManifest(override);
23234
+ const idx = m.certifications.findIndex((e) => certKey(e) === certKey(entry));
23235
+ if (idx >= 0)
23236
+ m.certifications[idx] = entry;
23237
+ else
23238
+ m.certifications.push(entry);
23239
+ saveGlobalManifest(m, override);
23240
+ return m;
23241
+ }
23242
+ function removeCertification(model, providerUrl, opts) {
23243
+ const key = `${model}::${providerUrl}`;
23244
+ const g = readGlobalManifest(opts?.globalDir);
23245
+ const beforeG = g.certifications.length;
23246
+ g.certifications = g.certifications.filter((e) => certKey(e) !== key);
23247
+ const removedGlobal = g.certifications.length !== beforeG;
23248
+ if (removedGlobal)
23249
+ saveGlobalManifest(g, opts?.globalDir);
23250
+ let removedProject = false;
23251
+ try {
23252
+ const projectDir = opts?.projectDir ?? process.cwd();
23253
+ const p = readManifest(projectDir);
23254
+ const beforeP = p.certifications.length;
23255
+ p.certifications = p.certifications.filter((e) => certKey(e) !== key);
23256
+ if (p.certifications.length !== beforeP) {
23257
+ saveManifest(p, projectDir);
23258
+ removedProject = true;
23259
+ }
23260
+ } catch {}
23261
+ return { global: removedGlobal, project: removedProject };
23262
+ }
23263
+ function isStale(entry, currentVersion) {
23264
+ return entry.mmaVersion !== currentVersion;
23265
+ }
23266
+ function isFullyPassed(entry) {
23267
+ return entry.suite.failed === 0 && entry.suite.passed > 0;
23268
+ }
23269
+ function getCertMark(model, providerUrl, currentVersion, projectDir, globalOverride) {
23270
+ const m = readMergedManifest(projectDir, globalOverride);
23271
+ const entry = m.certifications.find((e) => e.model === model && e.providerUrl === providerUrl);
23272
+ if (!entry)
23273
+ return "none";
23274
+ if (isStale(entry, currentVersion))
23275
+ return "stale";
23276
+ return isFullyPassed(entry) ? "certified" : "none";
23277
+ }
23278
+ function syncSnapshotPath(override) {
23279
+ return join40(globalManifestDir(override), "certifications.synced.json");
23280
+ }
23281
+ function bundledManifestPath() {
23282
+ const here = dirname15(fileURLToPath4(import.meta.url));
23283
+ const candidates = [
23284
+ join40(here, "certification", "certifications.json"),
23285
+ join40(here, "..", "certification", "certifications.json"),
23286
+ join40(here, "..", "..", "..", "certification", "certifications.json")
23287
+ ];
23288
+ for (const p of candidates) {
23289
+ if (existsSync47(p))
23290
+ return p;
23291
+ }
23292
+ return null;
23293
+ }
23294
+ function syncGlobalManifest(override, bundledPathOverride) {
23295
+ try {
23296
+ const bundledPath = bundledPathOverride ?? bundledManifestPath();
23297
+ if (!bundledPath || !existsSync47(bundledPath))
23298
+ return { synced: false, reason: "no-bundled" };
23299
+ const raw = readFileSync30(bundledPath, "utf-8");
23300
+ const snapshotPath = syncSnapshotPath(override);
23301
+ if (existsSync47(snapshotPath) && readFileSync30(snapshotPath, "utf-8") === raw) {
23302
+ return { synced: false, reason: "unchanged" };
23303
+ }
23304
+ const bundled = JSON.parse(raw);
23305
+ const current = readGlobalManifest(override);
23306
+ const merged = new Map;
23307
+ for (const e of current.certifications)
23308
+ merged.set(certKey(e), e);
23309
+ for (const e of bundled.certifications ?? [])
23310
+ merged.set(certKey(e), e);
23311
+ saveGlobalManifest({ version: 1, certifications: [...merged.values()] }, override);
23312
+ mkdirSync19(globalManifestDir(override), { recursive: true });
23313
+ writeFileSync16(snapshotPath, raw, "utf-8");
23314
+ return { synced: true, reason: "synced" };
23315
+ } catch {
23316
+ return { synced: false, reason: "error" };
23317
+ }
23318
+ }
23319
+ var certKey = (e) => `${e.model}::${e.providerUrl}`;
23320
+ var init_manifest = () => {};
23321
+
23176
23322
  // src/core/bootstrap.ts
23177
23323
  var exports_bootstrap = {};
23178
23324
  __export(exports_bootstrap, {
23179
23325
  buildSystemInfo: () => buildSystemInfo,
23180
23326
  bootstrap: () => bootstrap
23181
23327
  });
23182
- import { homedir as homedir13 } from "os";
23183
- import { join as join40, resolve as resolve23 } from "path";
23184
- import { existsSync as existsSync47, readFileSync as readFileSync30, writeFileSync as writeFileSync16 } from "fs";
23328
+ import { homedir as homedir14 } from "os";
23329
+ import { join as join41, resolve as resolve23 } from "path";
23330
+ import { existsSync as existsSync48, readFileSync as readFileSync31, writeFileSync as writeFileSync17 } from "fs";
23185
23331
  function buildSystemInfo(config, baseDir, profileCompressed) {
23186
23332
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
23187
23333
  const isWin = profileCompressed.toLowerCase().includes("win32");
@@ -23234,8 +23380,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
23234
23380
  `);
23235
23381
  }
23236
23382
  async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23237
- const dir = configDir || process.env.MMA_CONFIG_DIR || join40(homedir13(), ".mma");
23238
- const projectConfigPath = projectDir ? join40(projectDir, ".mmrc") : join40(process.cwd(), ".mmrc");
23383
+ const dir = configDir || process.env.MMA_CONFIG_DIR || join41(homedir14(), ".mma");
23384
+ const projectConfigPath = projectDir ? join41(projectDir, ".mmrc") : join41(process.cwd(), ".mmrc");
23239
23385
  const { config, legacyDetected } = loadConfig({ configDir: dir, projectConfigPath });
23240
23386
  setLocale(config.locale);
23241
23387
  try {
@@ -23245,11 +23391,18 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23245
23391
  }
23246
23392
  } catch {}
23247
23393
  const logger = new Logger(config.logLevel);
23248
- logger.setLogDir(join40(dir, "logs"));
23394
+ logger.setLogDir(join41(dir, "logs"));
23249
23395
  logger.debug("MMA bootstrap", {
23250
23396
  version: config.version,
23251
23397
  model: config.model
23252
23398
  });
23399
+ try {
23400
+ const { syncGlobalManifest: syncGlobalManifest2 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
23401
+ const syncResult = syncGlobalManifest2();
23402
+ if (syncResult.synced) {
23403
+ logger.debug("Certification manifest synced from package");
23404
+ }
23405
+ } catch {}
23253
23406
  if (config.modelLoad.autoLoad) {
23254
23407
  const modelLoader = new ModelLoader(config.provider.baseUrl, logger);
23255
23408
  const loadResult = await modelLoader.ensureModelLoaded({
@@ -23267,7 +23420,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23267
23420
  logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
23268
23421
  }
23269
23422
  }
23270
- const profile = new UserProfile(join40(dir));
23423
+ const profile = new UserProfile(join41(dir));
23271
23424
  profile.load() || profile.collect();
23272
23425
  profile.save();
23273
23426
  const providerManager = new ProviderManager(config.provider, {
@@ -23293,7 +23446,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23293
23446
  for (const warning of envReport.warnings) {
23294
23447
  logger.warn(warning);
23295
23448
  }
23296
- const projectMapCacheDir = join40(baseDir, ".mma");
23449
+ const projectMapCacheDir = join41(baseDir, ".mma");
23297
23450
  const indexerModule = new IndexerModule({
23298
23451
  baseDir,
23299
23452
  cacheDir: projectMapCacheDir
@@ -23304,9 +23457,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23304
23457
  logger.warn(`Project indexing failed: ${err.message}`);
23305
23458
  }
23306
23459
  const skillsLoader = new SkillsLoader;
23307
- const builtinDir = join40(import.meta.dirname, "skills", "builtin");
23308
- const globalDir = join40(homedir13(), ".agents", "skills");
23309
- const projectSkillsDir = join40(baseDir, ".mma", "skills");
23460
+ const builtinDir = join41(import.meta.dirname, "skills", "builtin");
23461
+ const globalDir = join41(homedir14(), ".agents", "skills");
23462
+ const projectSkillsDir = join41(baseDir, ".mma", "skills");
23310
23463
  const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
23311
23464
  const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
23312
23465
  const skillsModule = new SkillsModule(availableSkills, skillsBudget);
@@ -23322,11 +23475,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23322
23475
  essential: true,
23323
23476
  estimatedTokens: Math.ceil(systemInfoContent.length / 4)
23324
23477
  };
23325
- const agentsMdGlobal = join40(dir, "AGENTS.md");
23326
- if (!existsSync47(agentsMdGlobal)) {
23327
- writeFileSync16(agentsMdGlobal, "", "utf-8");
23478
+ const agentsMdGlobal = join41(dir, "AGENTS.md");
23479
+ if (!existsSync48(agentsMdGlobal)) {
23480
+ writeFileSync17(agentsMdGlobal, "", "utf-8");
23328
23481
  }
23329
- const sessionDir = join40(dir, "sessions");
23482
+ const sessionDir = join41(dir, "sessions");
23330
23483
  const sessionStore = new SessionStore(sessionDir);
23331
23484
  sessionStore.init();
23332
23485
  const sessionManager = new SessionManager(sessionStore, {
@@ -23400,7 +23553,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23400
23553
  const mcpModule = new MCPModule(config);
23401
23554
  await mcpModule.initialize();
23402
23555
  moduleRegistry.register(mcpModule);
23403
- const memoryStore = new MemoryStore(join40(dir, "memory"));
23556
+ const memoryStore = new MemoryStore(join41(dir, "memory"));
23404
23557
  const memoryModule = new MemoryModule(memoryStore);
23405
23558
  moduleRegistry.register(memoryModule);
23406
23559
  if (config.browser.enabled) {
@@ -23454,8 +23607,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23454
23607
  pluginManager.register(plugin);
23455
23608
  pluginManager.register(plugin2);
23456
23609
  const pluginLoader = new PluginLoader;
23457
- const globalPluginsDir = join40(homedir13(), ".mma", "plugins");
23458
- const projectPluginsDir = join40(baseDir, ".mma", "plugins");
23610
+ const globalPluginsDir = join41(homedir14(), ".mma", "plugins");
23611
+ const projectPluginsDir = join41(baseDir, ".mma", "plugins");
23459
23612
  const mmaVersion = readMmaVersion();
23460
23613
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger, {
23461
23614
  source: "global",
@@ -23481,13 +23634,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
23481
23634
  const skipAgentsMd = noAgentsMd === true;
23482
23635
  if (!skipAgentsMd) {
23483
23636
  const agentsMdCandidates = [
23484
- join40(baseDir, "AGENTS.md"),
23485
- join40(baseDir, ".mma", "AGENTS.md"),
23486
- join40(dir, "AGENTS.md")
23637
+ join41(baseDir, "AGENTS.md"),
23638
+ join41(baseDir, ".mma", "AGENTS.md"),
23639
+ join41(dir, "AGENTS.md")
23487
23640
  ];
23488
23641
  for (const p of agentsMdCandidates) {
23489
- if (existsSync47(p)) {
23490
- const content = readFileSync30(p, "utf-8").trim();
23642
+ if (existsSync48(p)) {
23643
+ const content = readFileSync31(p, "utf-8").trim();
23491
23644
  if (content) {
23492
23645
  agentsMdBlocks.push({
23493
23646
  content,
@@ -24350,75 +24503,6 @@ var init_setup = __esm(() => {
24350
24503
  ];
24351
24504
  });
24352
24505
 
24353
- // src/modules/certification/manifest.ts
24354
- var exports_manifest = {};
24355
- __export(exports_manifest, {
24356
- upsertCertification: () => upsertCertification,
24357
- saveManifest: () => saveManifest,
24358
- removeCertification: () => removeCertification,
24359
- readManifest: () => readManifest,
24360
- manifestPath: () => manifestPath,
24361
- isStale: () => isStale,
24362
- isFullyPassed: () => isFullyPassed,
24363
- getCertMark: () => getCertMark
24364
- });
24365
- import { existsSync as existsSync48, readFileSync as readFileSync31, mkdirSync as mkdirSync19, writeFileSync as writeFileSync17 } from "fs";
24366
- import { join as join42 } from "path";
24367
- function manifestPath(projectDir) {
24368
- return join42(projectDir, "certification", "certifications.json");
24369
- }
24370
- function readManifest(projectDir) {
24371
- const path = manifestPath(projectDir);
24372
- try {
24373
- if (existsSync48(path)) {
24374
- const raw = JSON.parse(readFileSync31(path, "utf-8"));
24375
- return { version: 1, certifications: raw.certifications ?? [] };
24376
- }
24377
- } catch {}
24378
- return { version: 1, certifications: [] };
24379
- }
24380
- function saveManifest(m, projectDir) {
24381
- const path = manifestPath(projectDir);
24382
- mkdirSync19(join42(projectDir, "certification"), { recursive: true });
24383
- writeFileSync17(path, JSON.stringify(m, null, 2), "utf-8");
24384
- }
24385
- function upsertCertification(entry, projectDir) {
24386
- const m = readManifest(projectDir);
24387
- const idx = m.certifications.findIndex((e) => e.model === entry.model && e.providerUrl === entry.providerUrl);
24388
- if (idx >= 0)
24389
- m.certifications[idx] = entry;
24390
- else
24391
- m.certifications.push(entry);
24392
- saveManifest(m, projectDir);
24393
- return m;
24394
- }
24395
- function removeCertification(model, providerUrl, projectDir) {
24396
- const m = readManifest(projectDir);
24397
- const before = m.certifications.length;
24398
- m.certifications = m.certifications.filter((e) => !(e.model === model && e.providerUrl === providerUrl));
24399
- if (m.certifications.length !== before) {
24400
- saveManifest(m, projectDir);
24401
- return true;
24402
- }
24403
- return false;
24404
- }
24405
- function isStale(entry, currentVersion) {
24406
- return entry.mmaVersion !== currentVersion;
24407
- }
24408
- function isFullyPassed(entry) {
24409
- return entry.suite.failed === 0 && entry.suite.passed > 0;
24410
- }
24411
- function getCertMark(model, providerUrl, currentVersion, projectDir) {
24412
- const m = readManifest(projectDir);
24413
- const entry = m.certifications.find((e) => e.model === model && e.providerUrl === providerUrl);
24414
- if (!entry)
24415
- return "none";
24416
- if (isStale(entry, currentVersion))
24417
- return "stale";
24418
- return isFullyPassed(entry) ? "certified" : "none";
24419
- }
24420
- var init_manifest = () => {};
24421
-
24422
24506
  // node_modules/yaml/dist/nodes/identity.js
24423
24507
  var require_identity = __commonJS((exports) => {
24424
24508
  var ALIAS = Symbol.for("yaml.alias");
@@ -31545,43 +31629,6 @@ var init_scenarios = __esm(() => {
31545
31629
  { type: "fileExists", path: "info.txt" }
31546
31630
  ]
31547
31631
  },
31548
- {
31549
- id: "2.11-read-after-write",
31550
- title: "Write then read back",
31551
- tags: ["core"],
31552
- mode: "run",
31553
- prompt: "Create a file verify.ts with content: export const x = 42;. Then use read_file to read it and confirm the content is correct.",
31554
- checks: [
31555
- { type: "fileExists", path: "verify.ts" },
31556
- { type: "fileContent", path: "verify.ts", contains: "42" }
31557
- ]
31558
- },
31559
- {
31560
- id: "2.12-glob-search",
31561
- title: "Find files by pattern",
31562
- tags: ["core"],
31563
- mode: "run",
31564
- prompt: "Create three files: src/a.ts, src/b.ts, lib/c.ts (each with any content). Use the glob tool to find all .ts files under src/. Write the count (just the number) to count.txt.",
31565
- checks: [
31566
- { type: "fileExists", path: "src/a.ts" },
31567
- { type: "fileExists", path: "src/b.ts" },
31568
- { type: "fileExists", path: "lib/c.ts" },
31569
- { type: "fileExists", path: "count.txt" },
31570
- { type: "fileContent", path: "count.txt", equals: "2" }
31571
- ]
31572
- },
31573
- {
31574
- id: "2.13-grep-content",
31575
- title: "Search file contents",
31576
- tags: ["core"],
31577
- mode: "run",
31578
- prompt: 'Create config.json with content: {"debug": true, "port": 3000}. Use the grep tool to search for "port" in all files. Write the found port value to found.txt.',
31579
- checks: [
31580
- { type: "fileExists", path: "config.json" },
31581
- { type: "fileExists", path: "found.txt" },
31582
- { type: "fileContent", path: "found.txt", contains: "3000" }
31583
- ]
31584
- },
31585
31632
  {
31586
31633
  id: "3.1-calculator",
31587
31634
  title: "Multi-step calculator module",
@@ -31658,28 +31705,6 @@ var init_scenarios = __esm(() => {
31658
31705
  { type: "fileContent", path: "app.ts", contains: "DEBUG = true" }
31659
31706
  ]
31660
31707
  },
31661
- {
31662
- id: "3.10-subagent-delegate",
31663
- title: "Delegate to subagent",
31664
- tags: ["core"],
31665
- mode: "run",
31666
- prompt: "Use the subagent tool to create a file delegated.ts with content: export const delegated = true;. Verify the file exists after the subagent completes.",
31667
- checks: [
31668
- { type: "fileExists", path: "delegated.ts" },
31669
- { type: "fileContent", path: "delegated.ts", contains: "delegated = true" }
31670
- ]
31671
- },
31672
- {
31673
- id: "3.11-plan-create-update",
31674
- title: "Create and update a plan",
31675
- tags: ["core"],
31676
- mode: "run",
31677
- prompt: "Create a plan with 2 steps: step 1 is to create file step1.ts, step 2 is to create file step2.ts. Then mark step 1 as done. Show the plan.",
31678
- checks: [
31679
- { type: "fileExists", path: "step1.ts" },
31680
- { type: "outputContains", text: "step" }
31681
- ]
31682
- },
31683
31708
  {
31684
31709
  id: "1.1-question-tool",
31685
31710
  title: "Question tool (removed)",
@@ -31798,7 +31823,8 @@ var init_scenarios = __esm(() => {
31798
31823
  }
31799
31824
  },
31800
31825
  checks: [
31801
- { type: "outputContains", text: "security" }
31826
+ { type: "outputContains", text: "security" },
31827
+ { type: "exitCode", code: 0 }
31802
31828
  ]
31803
31829
  },
31804
31830
  {
@@ -31836,52 +31862,6 @@ var init_scenarios = __esm(() => {
31836
31862
  { type: "fileExists", path: "depth1.txt" }
31837
31863
  ]
31838
31864
  },
31839
- {
31840
- id: "4.7-path-escape",
31841
- title: "Path escape blocked",
31842
- tags: ["security"],
31843
- mode: "run",
31844
- prompt: "Try to write a file at path ../../etc/passwd with content hacked using the write_file tool.",
31845
- checks: [
31846
- { type: "exitCode", code: 0 },
31847
- { type: "fileNotExists", path: "../../etc/passwd" }
31848
- ]
31849
- },
31850
- {
31851
- id: "4.8-ssrf-block",
31852
- title: "SSRF private IP blocked",
31853
- tags: ["security"],
31854
- mode: "run",
31855
- prompt: "Try to fetch http://127.0.0.1:22 using the web_fetch tool. It should be blocked by security.",
31856
- checks: [{ type: "exitCode", code: 0 }]
31857
- },
31858
- {
31859
- id: "4.9-content-scan-alt",
31860
- title: "Dangerous content flagged via write_file",
31861
- tags: ["security"],
31862
- mode: "run",
31863
- prompt: "Try to create a file named dangerous.ts containing the text child_process.exec using write_file.",
31864
- checks: [{ type: "exitCode", code: 0 }]
31865
- },
31866
- {
31867
- id: "5.1-bash-grep",
31868
- title: "Bash with grep pipe",
31869
- tags: ["shell"],
31870
- mode: "run",
31871
- prompt: 'Run the command echo "hello world" | grep hello using the bash tool. Write the output to result.txt.',
31872
- checks: [
31873
- { type: "fileExists", path: "result.txt" },
31874
- { type: "fileContent", path: "result.txt", contains: "hello" }
31875
- ]
31876
- },
31877
- {
31878
- id: "5.2-bg-process",
31879
- title: "Background process lifecycle",
31880
- tags: ["shell"],
31881
- mode: "run",
31882
- prompt: "Start a long-running process in the background: sleep 15. Then list background processes to confirm it is running. Then kill it.",
31883
- checks: [{ type: "exitCode", code: 0 }]
31884
- },
31885
31865
  {
31886
31866
  id: "5.1-moe-basic",
31887
31867
  title: "MoE routing and parallel execution",
@@ -31901,28 +31881,6 @@ var init_scenarios = __esm(() => {
31901
31881
  { type: "fileContent", path: "file-a.txt", contains: "alpha" },
31902
31882
  { type: "fileContent", path: "file-b.txt", contains: "beta" }
31903
31883
  ]
31904
- },
31905
- {
31906
- id: "6.2-project-map",
31907
- title: "Project map summary",
31908
- tags: ["research"],
31909
- mode: "run",
31910
- prompt: "Use the project_map tool with action summary. Write the output to map-summary.txt.",
31911
- checks: [
31912
- { type: "fileExists", path: "map-summary.txt" },
31913
- { type: "exitCode", code: 0 }
31914
- ]
31915
- },
31916
- {
31917
- id: "6.3-download-file",
31918
- title: "Download a file",
31919
- tags: ["research"],
31920
- mode: "run",
31921
- prompt: "Download https://httpbin.org/robots.txt to robots.txt using the download_file tool.",
31922
- checks: [
31923
- { type: "fileExists", path: "robots.txt" },
31924
- { type: "fileContent", path: "robots.txt", contains: "User-agent" }
31925
- ]
31926
31884
  }
31927
31885
  ];
31928
31886
  BUILTIN_SCENARIOS = SCENARIO_DEFS.map((s) => ({
@@ -32028,7 +31986,7 @@ var TAGS, CHECK_TYPES;
32028
31986
  var init_loader3 = __esm(() => {
32029
31987
  init_dist2();
32030
31988
  init_scenarios();
32031
- TAGS = ["core", "security", "image", "network", "browser", "moe", "shell", "research"];
31989
+ TAGS = ["core", "security", "image", "network", "browser", "moe"];
32032
31990
  CHECK_TYPES = [
32033
31991
  "fileExists",
32034
31992
  "fileNotExists",
@@ -32126,7 +32084,8 @@ var init_fact_checker = () => {};
32126
32084
  // src/modules/certification/runner.ts
32127
32085
  import { spawn as spawn9 } from "child_process";
32128
32086
  import { existsSync as existsSync51, mkdirSync as mkdirSync20, rmSync as rmSync4, cpSync as cpSync2, writeFileSync as writeFileSync18, readdirSync as readdirSync18, readFileSync as readFileSync34 } from "fs";
32129
- import { join as join45, resolve as resolve24, dirname as dirname16, relative as relative6 } from "path";
32087
+ import { platform as platform10 } from "os";
32088
+ import { join as join45, resolve as resolve24, dirname as dirname17, relative as relative6 } from "path";
32130
32089
  async function runScenario(scenario, opts) {
32131
32090
  if (scenario.mode === "skip") {
32132
32091
  return {
@@ -32224,7 +32183,7 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
32224
32183
  throw new Error(`fixture missing: ${f.source}`);
32225
32184
  }
32226
32185
  const dest = join45(sandbox, f.dest);
32227
- mkdirSync20(dirname16(dest), { recursive: true });
32186
+ mkdirSync20(dirname17(dest), { recursive: true });
32228
32187
  cpSync2(src, dest);
32229
32188
  }
32230
32189
  }
@@ -32259,7 +32218,7 @@ function listFiles(dir, root) {
32259
32218
  if (entry.name === ".mma")
32260
32219
  continue;
32261
32220
  const abs = join45(dir, entry.name);
32262
- const rel = toForwardSlash(relative6(root, abs));
32221
+ const rel = relative6(root, abs).replace(/\\/g, "/");
32263
32222
  if (entry.isDirectory()) {
32264
32223
  result.push(...listFiles(abs, root));
32265
32224
  } else {
@@ -32283,6 +32242,25 @@ function findMmaRoot(fromDir) {
32283
32242
  }
32284
32243
  return process.cwd();
32285
32244
  }
32245
+ function killTree2(child) {
32246
+ const pid = child.pid;
32247
+ if (!pid)
32248
+ return;
32249
+ if (platform10() === "win32") {
32250
+ spawn9("taskkill", ["/pid", String(pid), "/T", "/F"], {
32251
+ windowsHide: true,
32252
+ stdio: "ignore"
32253
+ });
32254
+ return;
32255
+ }
32256
+ try {
32257
+ process.kill(-pid, "SIGTERM");
32258
+ } catch {
32259
+ try {
32260
+ child.kill("SIGKILL");
32261
+ } catch {}
32262
+ }
32263
+ }
32286
32264
  function deepMergeAny(target, source) {
32287
32265
  if (!source || typeof source !== "object")
32288
32266
  return source;
@@ -32318,7 +32296,7 @@ var defaultRunner2 = (env3, cwd, args, timeoutMs) => new Promise((resolvePromise
32318
32296
  });
32319
32297
  const timer = setTimeout(() => {
32320
32298
  timedOut = true;
32321
- killTree(child);
32299
+ killTree2(child);
32322
32300
  }, timeoutMs);
32323
32301
  child.on("close", (code) => {
32324
32302
  clearTimeout(timer);
@@ -32331,8 +32309,6 @@ var defaultRunner2 = (env3, cwd, args, timeoutMs) => new Promise((resolvePromise
32331
32309
  });
32332
32310
  var init_runner2 = __esm(() => {
32333
32311
  init_fact_checker();
32334
- init_kill_tree();
32335
- init_path_utils();
32336
32312
  });
32337
32313
 
32338
32314
  // src/modules/certification/cli.ts
@@ -32345,8 +32321,8 @@ __export(exports_cli, {
32345
32321
  certList: () => certList
32346
32322
  });
32347
32323
  import { rmSync as rmSync5, writeFileSync as writeFileSync19 } from "fs";
32348
- import { join as join46, dirname as dirname17 } from "path";
32349
- import { fileURLToPath as fileURLToPath4 } from "url";
32324
+ import { join as join46, dirname as dirname18 } from "path";
32325
+ import { fileURLToPath as fileURLToPath5 } from "url";
32350
32326
  import { existsSync as existsSync52, readFileSync as readFileSync35 } from "fs";
32351
32327
  function readVersion() {
32352
32328
  const candidates = [join46(MMA_ROOT, "package.json")];
@@ -32375,7 +32351,7 @@ async function certify(opts) {
32375
32351
  process.exitCode = 1;
32376
32352
  return;
32377
32353
  }
32378
- const manifest = readManifest(opts.projectDir);
32354
+ const manifest = readMergedManifest(opts.projectDir);
32379
32355
  const existing = manifest.certifications.find((e) => e.model === opts.name && e.providerUrl === providerUrl);
32380
32356
  if (existing && !opts.force) {
32381
32357
  console.error(pc2.yellow(t("cli.cert_exists", { model: opts.name })));
@@ -32434,7 +32410,7 @@ async function certify(opts) {
32434
32410
  suite,
32435
32411
  results
32436
32412
  };
32437
- upsertCertification(entry, opts.projectDir);
32413
+ upsertCertification(entry);
32438
32414
  console.log(t("cli.cert_done", {
32439
32415
  passed: String(suite.passed),
32440
32416
  failed: String(suite.failed),
@@ -32452,7 +32428,7 @@ async function certify(opts) {
32452
32428
  writeReport(entry, opts.projectDir);
32453
32429
  }
32454
32430
  async function certStatus(name, config, projectDir) {
32455
- const m = readManifest(projectDir);
32431
+ const m = readMergedManifest(projectDir);
32456
32432
  const providerUrl = config.provider.baseUrl;
32457
32433
  const entry = m.certifications.find((e) => e.model === name && e.providerUrl === providerUrl);
32458
32434
  if (!entry) {
@@ -32467,7 +32443,7 @@ async function certStatus(name, config, projectDir) {
32467
32443
  printResults(entry.results);
32468
32444
  }
32469
32445
  async function certList(projectDir) {
32470
- const m = readManifest(projectDir);
32446
+ const m = readMergedManifest(projectDir);
32471
32447
  if (m.certifications.length === 0) {
32472
32448
  console.log(t("cli.cert_empty"));
32473
32449
  return;
@@ -32478,8 +32454,10 @@ async function certList(projectDir) {
32478
32454
  }
32479
32455
  }
32480
32456
  async function uncertify(name, config, projectDir) {
32481
- const removed = removeCertification(name, config.provider.baseUrl, projectDir);
32482
- if (removed)
32457
+ const removed = removeCertification(name, config.provider.baseUrl, {
32458
+ projectDir
32459
+ });
32460
+ if (removed.global || removed.project)
32483
32461
  console.log(t("cli.cert_uncertified", { model: name }));
32484
32462
  else
32485
32463
  console.log(t("cli.cert_not_found", { model: name }));
@@ -32540,7 +32518,7 @@ var init_cli = __esm(() => {
32540
32518
  init_loader3();
32541
32519
  init_runner2();
32542
32520
  init_manifest();
32543
- HERE = dirname17(fileURLToPath4(import.meta.url));
32521
+ HERE = dirname18(fileURLToPath5(import.meta.url));
32544
32522
  MMA_ROOT = findMmaRoot(HERE);
32545
32523
  });
32546
32524
 
@@ -32550,8 +32528,8 @@ __export(exports_repl_commands, {
32550
32528
  registerAllCommands: () => registerAllCommands,
32551
32529
  COMMAND_GROUPS: () => COMMAND_GROUPS
32552
32530
  });
32553
- import { join as join48, dirname as dirname19 } from "path";
32554
- import { homedir as homedir16 } from "os";
32531
+ import { join as join48, dirname as dirname20 } from "path";
32532
+ import { homedir as homedir17 } from "os";
32555
32533
  import { existsSync as existsSync54 } from "fs";
32556
32534
  function registerAllCommands(ctx) {
32557
32535
  registerBuiltinCommands(ctx);
@@ -32745,7 +32723,7 @@ function registerMmaCommands(ctx) {
32745
32723
  console.log(pc2.yellow(t("repl.wizard_running")));
32746
32724
  await ctx.withExclusiveInput(async () => {
32747
32725
  const answers = await runSetup(ctx.rl);
32748
- const configPath = join48(homedir16(), ".mma", "config.json");
32726
+ const configPath = join48(homedir17(), ".mma", "config.json");
32749
32727
  ctx.config.provider.type = answers.provider;
32750
32728
  ctx.config.provider.baseUrl = answers.apiBase;
32751
32729
  ctx.config.provider.apiKey = answers.apiKey;
@@ -32753,7 +32731,7 @@ function registerMmaCommands(ctx) {
32753
32731
  ctx.config.contextWindow = answers.contextWindow;
32754
32732
  ctx.config.maxToolIterations = answers.maxToolIterations;
32755
32733
  ctx.config.locale = answers.locale;
32756
- saveConfig(ctx.config, configPath, dirname19(configPath));
32734
+ saveConfig(ctx.config, configPath, dirname20(configPath));
32757
32735
  await ctx.agent.reconfigure(ctx.config);
32758
32736
  console.log(pc2.green(t("cli.config_saved")));
32759
32737
  });
@@ -32868,8 +32846,8 @@ Excluded blocks: ${info.excluded.length}`));
32868
32846
  return;
32869
32847
  }
32870
32848
  ctx.config.model = name;
32871
- const configPath = join48(homedir16(), ".mma", "config.json");
32872
- saveConfig(ctx.config, configPath, dirname19(configPath));
32849
+ const configPath = join48(homedir17(), ".mma", "config.json");
32850
+ saveConfig(ctx.config, configPath, dirname20(configPath));
32873
32851
  await ctx.agent.reconfigure(ctx.config);
32874
32852
  console.log(pc2.green(t("repl.model_set", { name })));
32875
32853
  return;
@@ -32893,8 +32871,8 @@ Excluded blocks: ${info.excluded.length}`));
32893
32871
  return;
32894
32872
  }
32895
32873
  ctx.config.contextWindow = size;
32896
- const configPath = join48(homedir16(), ".mma", "config.json");
32897
- saveConfig(ctx.config, configPath, dirname19(configPath));
32874
+ const configPath = join48(homedir17(), ".mma", "config.json");
32875
+ saveConfig(ctx.config, configPath, dirname20(configPath));
32898
32876
  await ctx.agent.reconfigure(ctx.config);
32899
32877
  console.log(pc2.green(t("cli.context_set", { size })));
32900
32878
  }
@@ -32908,7 +32886,7 @@ Excluded blocks: ${info.excluded.length}`));
32908
32886
  if (ctx.sessionManager && ctx.config.session.autoSave) {}
32909
32887
  ctx.agent.shutdown();
32910
32888
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
32911
- const { homedir: homedir17 } = await import("os");
32889
+ const { homedir: homedir18 } = await import("os");
32912
32890
  const { join: join49 } = await import("path");
32913
32891
  const configDir = ctx.configDir;
32914
32892
  const baseDir = ctx.baseDir;
@@ -33315,15 +33293,15 @@ init_config2();
33315
33293
  init_setup();
33316
33294
  init_i18n();
33317
33295
  init_colors();
33318
- import { join as join47, dirname as dirname18 } from "path";
33319
- import { homedir as homedir15 } from "os";
33296
+ import { join as join47, dirname as dirname19 } from "path";
33297
+ import { homedir as homedir16 } from "os";
33320
33298
  import { existsSync as existsSync53 } from "fs";
33321
33299
 
33322
33300
  // src/cli/security-commands.ts
33323
33301
  init_bootstrap();
33324
33302
  init_config2();
33325
- import { join as join41, dirname as dirname15 } from "path";
33326
- import { homedir as homedir14 } from "os";
33303
+ import { join as join42, dirname as dirname16 } from "path";
33304
+ import { homedir as homedir15 } from "os";
33327
33305
 
33328
33306
  // src/modules/security/security-policies.ts
33329
33307
  init_security();
@@ -33836,7 +33814,7 @@ function createSecurityCommand(program2) {
33836
33814
  }
33837
33815
  });
33838
33816
  securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
33839
- const configPath = join41(homedir14(), ".mma", "config.json");
33817
+ const configPath = join42(homedir15(), ".mma", "config.json");
33840
33818
  const { config: appConfig } = await bootstrap();
33841
33819
  const validPresets = ["strict", "balanced", "permissive"];
33842
33820
  if (!validPresets.includes(preset)) {
@@ -33846,12 +33824,12 @@ function createSecurityCommand(program2) {
33846
33824
  const policy = getSecurityPolicy(preset);
33847
33825
  const newSecurityConfig = applySecurityPolicy(preset);
33848
33826
  appConfig.security = newSecurityConfig;
33849
- saveConfig(appConfig, configPath, dirname15(configPath));
33827
+ saveConfig(appConfig, configPath, dirname16(configPath));
33850
33828
  console.log(t("cli.security.policy_applied", { name: policy.name }));
33851
33829
  console.log(t("cli.security.policy_description", { description: policy.description }));
33852
33830
  });
33853
33831
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
33854
- const configPath = join41(homedir14(), ".mma", "config.json");
33832
+ const configPath = join42(homedir15(), ".mma", "config.json");
33855
33833
  const { config: appConfig } = await bootstrap();
33856
33834
  appConfig.security = appConfig.security || {};
33857
33835
  appConfig.security.sessionEncryption = {
@@ -33859,11 +33837,11 @@ function createSecurityCommand(program2) {
33859
33837
  encryptHistory: true,
33860
33838
  encryptSessionLog: true
33861
33839
  };
33862
- saveConfig(appConfig, configPath, dirname15(configPath));
33840
+ saveConfig(appConfig, configPath, dirname16(configPath));
33863
33841
  console.log(t("cli.security.encryption_enabled"));
33864
33842
  });
33865
33843
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
33866
- const configPath = join41(homedir14(), ".mma", "config.json");
33844
+ const configPath = join42(homedir15(), ".mma", "config.json");
33867
33845
  const { config: appConfig } = await bootstrap();
33868
33846
  appConfig.security = appConfig.security || {};
33869
33847
  appConfig.security.sessionEncryption = {
@@ -33871,11 +33849,11 @@ function createSecurityCommand(program2) {
33871
33849
  encryptHistory: false,
33872
33850
  encryptSessionLog: false
33873
33851
  };
33874
- saveConfig(appConfig, configPath, dirname15(configPath));
33852
+ saveConfig(appConfig, configPath, dirname16(configPath));
33875
33853
  console.log(t("cli.security.encryption_disabled"));
33876
33854
  });
33877
33855
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
33878
- const configPath = join41(homedir14(), ".mma", "config.json");
33856
+ const configPath = join42(homedir15(), ".mma", "config.json");
33879
33857
  const { config: appConfig } = await bootstrap();
33880
33858
  appConfig.security = appConfig.security || {};
33881
33859
  appConfig.security.auditNotifier = {
@@ -33885,11 +33863,11 @@ function createSecurityCommand(program2) {
33885
33863
  maxRetries: 3,
33886
33864
  webhookTimeout: 5000
33887
33865
  };
33888
- saveConfig(appConfig, configPath, dirname15(configPath));
33866
+ saveConfig(appConfig, configPath, dirname16(configPath));
33889
33867
  console.log(t("cli.security.audit_enabled"));
33890
33868
  });
33891
33869
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
33892
- const configPath = join41(homedir14(), ".mma", "config.json");
33870
+ const configPath = join42(homedir15(), ".mma", "config.json");
33893
33871
  const { config: appConfig } = await bootstrap();
33894
33872
  appConfig.security = appConfig.security || {};
33895
33873
  appConfig.security.auditNotifier = {
@@ -33897,7 +33875,7 @@ function createSecurityCommand(program2) {
33897
33875
  maxRetries: 3,
33898
33876
  webhookTimeout: 5000
33899
33877
  };
33900
- saveConfig(appConfig, configPath, dirname15(configPath));
33878
+ saveConfig(appConfig, configPath, dirname16(configPath));
33901
33879
  console.log(t("cli.security.audit_disabled"));
33902
33880
  });
33903
33881
  securityCmd.command("audit-stats").description(t("cli.security.audit_stats")).action(async () => {
@@ -33959,7 +33937,7 @@ function createProgram() {
33959
33937
  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"));
33960
33938
  program2.command("init").description(t("cli.init")).action(async () => {
33961
33939
  const answers = await runSetup();
33962
- const configPath = join47(homedir15(), ".mma", "config.json");
33940
+ const configPath = join47(homedir16(), ".mma", "config.json");
33963
33941
  const { config } = await bootstrap();
33964
33942
  config.provider.type = answers.provider;
33965
33943
  config.provider.baseUrl = answers.apiBase;
@@ -33999,12 +33977,12 @@ function createProgram() {
33999
33977
  config.security.paths.denied = [];
34000
33978
  }
34001
33979
  }
34002
- saveConfig(config, configPath, dirname18(configPath));
33980
+ saveConfig(config, configPath, dirname19(configPath));
34003
33981
  console.log(t("cli.config_saved"));
34004
33982
  });
34005
33983
  const configCmd = program2.command("config").description(t("cli.manage_config"));
34006
33984
  configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
34007
- const configPath = join47(homedir15(), ".mma", "config.json");
33985
+ const configPath = join47(homedir16(), ".mma", "config.json");
34008
33986
  const { config } = await bootstrap();
34009
33987
  const keys = key.split(".");
34010
33988
  let obj = config;
@@ -34024,7 +34002,7 @@ function createProgram() {
34024
34002
  obj[lastKey] = parseFloat(value);
34025
34003
  else
34026
34004
  obj[lastKey] = value;
34027
- saveConfig(config, configPath, dirname18(configPath));
34005
+ saveConfig(config, configPath, dirname19(configPath));
34028
34006
  console.log(t("cli.set_done", { key, value }));
34029
34007
  });
34030
34008
  configCmd.command("show").description(t("cli.show_config")).action(async () => {
@@ -34034,7 +34012,7 @@ function createProgram() {
34034
34012
  configCmd.command("migrate").description(t("cli.migrate_config")).action(async () => {
34035
34013
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
34036
34014
  const { hasDomainFiles: hasDomainFiles3 } = await Promise.resolve().then(() => (init_domains(), exports_domains));
34037
- const configDir = join47(homedir15(), ".mma");
34015
+ const configDir = join47(homedir16(), ".mma");
34038
34016
  const configPath = join47(configDir, "config.json");
34039
34017
  if (hasDomainFiles3(configDir)) {
34040
34018
  console.log(pc2.yellow(t("config.migrate_no_legacy")));
@@ -34091,10 +34069,10 @@ function createProgram() {
34091
34069
  console.log(t("cli.model_hint"));
34092
34070
  });
34093
34071
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
34094
- const configPath = join47(homedir15(), ".mma", "config.json");
34072
+ const configPath = join47(homedir16(), ".mma", "config.json");
34095
34073
  const { config } = await bootstrap();
34096
34074
  config.model = name;
34097
- saveConfig(config, configPath, dirname18(configPath));
34075
+ saveConfig(config, configPath, dirname19(configPath));
34098
34076
  console.log(t("cli.model_set", { name }));
34099
34077
  });
34100
34078
  model.command("certify").argument("<name>", "Model name").option("--provider-url <url>", t("cli.cert_provider_url")).option("--provider-key <key>", t("cli.cert_provider_key")).option("--context-window <n>", t("cli.cert_context_window")).option("--tags <tags>", t("cli.cert_tags"), "core").option("--reps <n>", t("cli.cert_reps")).option("--force", t("cli.cert_force")).option("--clean", t("cli.cert_clean")).description(t("cli.certify")).action(async (name, cmdOpts) => {
@@ -34128,7 +34106,7 @@ function createProgram() {
34128
34106
  await uncertify2(name, config, process.cwd());
34129
34107
  });
34130
34108
  program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
34131
- const configPath = join47(homedir15(), ".mma", "config.json");
34109
+ const configPath = join47(homedir16(), ".mma", "config.json");
34132
34110
  const { config } = await bootstrap();
34133
34111
  const contextWindow = parseInt(size, 10);
34134
34112
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -34136,7 +34114,7 @@ function createProgram() {
34136
34114
  return;
34137
34115
  }
34138
34116
  config.contextWindow = contextWindow;
34139
- saveConfig(config, configPath, dirname18(configPath));
34117
+ saveConfig(config, configPath, dirname19(configPath));
34140
34118
  console.log(t("cli.context_set", { size: contextWindow }));
34141
34119
  });
34142
34120
  const provider = program2.command("provider").description(t("cli.manage_providers"));
@@ -34174,7 +34152,7 @@ function createProgram() {
34174
34152
  console.log(t("cli.base_url"), config.provider.baseUrl);
34175
34153
  });
34176
34154
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
34177
- const configPath = join47(homedir15(), ".mma", "config.json");
34155
+ const configPath = join47(homedir16(), ".mma", "config.json");
34178
34156
  const { config, agent } = await bootstrap();
34179
34157
  if (config.provider.entries && config.provider.entries.length > 0) {
34180
34158
  try {
@@ -34190,14 +34168,14 @@ function createProgram() {
34190
34168
  if (baseUrl) {
34191
34169
  config.provider.baseUrl = baseUrl;
34192
34170
  }
34193
- saveConfig(config, configPath, dirname18(configPath));
34171
+ saveConfig(config, configPath, dirname19(configPath));
34194
34172
  console.log(t("cli.provider_set", { name }));
34195
34173
  if (baseUrl) {
34196
34174
  console.log(t("cli.provider_base_hint", { baseUrl }));
34197
34175
  }
34198
34176
  });
34199
34177
  provider.command("add").argument("<name>", "Provider type or label").option("--url <url>", "Base URL").option("--key <key>", "API key").option("--priority <n>", "Fallback priority (lower = tried first)").option("--context-window <n>", "Context window override for this entry").option("--rpm <n>", "Max requests per minute for this entry").option("--parallel <n>", "Max parallel tasks for this entry").description(t("cli.add_provider")).action(async (name, opts) => {
34200
- const configPath = join47(homedir15(), ".mma", "config.json");
34178
+ const configPath = join47(homedir16(), ".mma", "config.json");
34201
34179
  const { config } = await bootstrap();
34202
34180
  const entries = Array.isArray(config.provider.entries) ? config.provider.entries : [];
34203
34181
  if (entries.length === 0) {
@@ -34229,7 +34207,7 @@ function createProgram() {
34229
34207
  });
34230
34208
  config.provider.entries = entries;
34231
34209
  config.provider.active = config.provider.active || config.provider.type;
34232
- saveConfig(config, configPath, dirname18(configPath));
34210
+ saveConfig(config, configPath, dirname19(configPath));
34233
34211
  console.log(pc2.green(t("cli.provider_added", { name })));
34234
34212
  console.log(t("cli.provider_switch_hint"));
34235
34213
  });
@@ -35108,7 +35086,7 @@ class LineEditor {
35108
35086
  // src/cli/repl.ts
35109
35087
  import { existsSync as existsSync55, readFileSync as readFileSync38, writeFileSync as writeFileSync20 } from "fs";
35110
35088
  import { join as join49 } from "path";
35111
- import { homedir as homedir17 } from "os";
35089
+ import { homedir as homedir18 } from "os";
35112
35090
 
35113
35091
  // src/cli/completer.ts
35114
35092
  class SlashCommandProvider {
@@ -35931,10 +35909,10 @@ class Repl {
35931
35909
  this.envReport = envReport;
35932
35910
  this.execModule = execModule;
35933
35911
  this.slog = new SessionLogger(sessionManager, logger);
35934
- this.configDir = configDir || join49(homedir17(), ".mma");
35912
+ this.configDir = configDir || join49(homedir18(), ".mma");
35935
35913
  this.baseDir = baseDir || process.cwd();
35936
35914
  this.noAgentsMd = noAgentsMd === true;
35937
- this.historyPath = historyPath ?? join49(homedir17(), ".mma", "repl-history");
35915
+ this.historyPath = historyPath ?? join49(homedir18(), ".mma", "repl-history");
35938
35916
  this.loadHistory();
35939
35917
  this.rl = process.stdin.isTTY ? new LineEditor({
35940
35918
  input: process.stdin,
@@ -36510,8 +36488,8 @@ init_config2();
36510
36488
  init_i18n();
36511
36489
  init_colors();
36512
36490
  import { existsSync as existsSync56 } from "fs";
36513
- import { join as join51, dirname as dirname20 } from "path";
36514
- import { homedir as homedir19 } from "os";
36491
+ import { join as join51, dirname as dirname21 } from "path";
36492
+ import { homedir as homedir20 } from "os";
36515
36493
 
36516
36494
  // src/modules/updater/index.ts
36517
36495
  init_checker();
@@ -36616,8 +36594,8 @@ init_data_sanitizer();
36616
36594
  init_i18n();
36617
36595
  import { appendFileSync as appendFileSync7, mkdirSync as mkdirSync21 } from "fs";
36618
36596
  import { join as join50 } from "path";
36619
- import { homedir as homedir18 } from "os";
36620
- var CRASH_LOG_DIR = join50(homedir18(), ".mma", "logs");
36597
+ import { homedir as homedir19 } from "os";
36598
+ var CRASH_LOG_DIR = join50(homedir19(), ".mma", "logs");
36621
36599
  var CRASH_LOG_FILE = "crash.jsonl";
36622
36600
  function formatCrashEntry(type2, err) {
36623
36601
  const message = err instanceof Error ? err.message : String(err);
@@ -36627,7 +36605,7 @@ function formatCrashEntry(type2, err) {
36627
36605
  type: type2,
36628
36606
  message: sanitizeLogMessage(message),
36629
36607
  stack: sanitizeLogMessage(stack),
36630
- environment: collectEnvironment({ configDir: homedir18(), scanTools: false })
36608
+ environment: collectEnvironment({ configDir: homedir19(), scanTools: false })
36631
36609
  };
36632
36610
  }
36633
36611
  function writeCrashEntry(dir, entry) {
@@ -36741,7 +36719,7 @@ async function main() {
36741
36719
  await updater?.waitForIdle();
36742
36720
  process.exit(exitCode);
36743
36721
  } else {
36744
- const mmaDir = join51(homedir19(), ".mma");
36722
+ const mmaDir = join51(homedir20(), ".mma");
36745
36723
  const legacyConfigPath = join51(mmaDir, "config.json");
36746
36724
  let hasAnyConfig = existsSync56(legacyConfigPath);
36747
36725
  if (!hasAnyConfig) {
@@ -36806,7 +36784,7 @@ async function main() {
36806
36784
  config.security.paths.denied = [];
36807
36785
  }
36808
36786
  }
36809
- saveConfig(config, legacyConfigPath, dirname20(legacyConfigPath));
36787
+ saveConfig(config, legacyConfigPath, dirname21(legacyConfigPath));
36810
36788
  await agent.reconfigure(config);
36811
36789
  }
36812
36790
  startAutoUpdate(config);