micro-models-agent 0.28.17 → 0.29.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 (94) hide show
  1. package/dist/cli/commands.js +3 -116
  2. package/dist/cli/main.js +8 -35
  3. package/dist/cli/repl.js +611 -110
  4. package/dist/cli/setup.js +12 -32
  5. package/dist/config/config.js +30 -46
  6. package/dist/config/defaults.js +1 -10
  7. package/dist/config/security.js +8 -15
  8. package/dist/core/agent-moe.js +12 -24
  9. package/dist/core/agent.js +47 -281
  10. package/dist/core/bootstrap.js +36 -52
  11. package/dist/core/session-logger.js +2 -35
  12. package/dist/i18n/en.json +15 -79
  13. package/dist/i18n/index.js +9 -12
  14. package/dist/i18n/ru.json +15 -79
  15. package/dist/index.js +13 -13
  16. package/dist/llm/openai-compat.js +10 -39
  17. package/dist/logger/app-logger.js +16 -83
  18. package/dist/main.js +624 -243
  19. package/dist/modules/browser/session.js +60 -108
  20. package/dist/modules/context/history.js +15 -0
  21. package/dist/modules/context/manager.js +10 -119
  22. package/dist/modules/execution/auditor.js +39 -33
  23. package/dist/modules/execution/index.js +6 -8
  24. package/dist/modules/execution/module.js +32 -474
  25. package/dist/modules/execution/moe-executor.js +40 -97
  26. package/dist/modules/execution/planner.js +13 -63
  27. package/dist/modules/execution/stuck-detector.js +39 -252
  28. package/dist/modules/execution/tracker.js +7 -21
  29. package/dist/modules/execution/verifier.js +17 -46
  30. package/dist/modules/hallucination/confidence.js +2 -7
  31. package/dist/modules/hallucination/consistency.js +42 -8
  32. package/dist/modules/hallucination/detector.js +21 -26
  33. package/dist/modules/hallucination/factual.js +150 -170
  34. package/dist/modules/hallucination/index.js +4 -5
  35. package/dist/modules/index.js +5 -5
  36. package/dist/modules/mcp/client.js +2 -8
  37. package/dist/modules/memory/store.js +0 -4
  38. package/dist/modules/plugins/builtin/lint-on-write.js +38 -143
  39. package/dist/modules/processes/detect.js +34 -0
  40. package/dist/modules/processes/index.js +2 -1
  41. package/dist/modules/processes/registry.js +35 -125
  42. package/dist/modules/processes/runner.js +110 -9
  43. package/dist/modules/security/audit-log.js +10 -30
  44. package/dist/modules/security/command-validator.js +16 -42
  45. package/dist/modules/security/content-scanner.js +8 -9
  46. package/dist/modules/security/network-validator.js +2 -2
  47. package/dist/modules/security/path-validator.js +10 -64
  48. package/dist/modules/security/security-policies.js +67 -221
  49. package/dist/modules/security/session-encryption.js +25 -42
  50. package/dist/modules/session/manager.js +10 -15
  51. package/dist/modules/session/store.js +8 -62
  52. package/dist/modules/skills/index.js +3 -2
  53. package/dist/modules/skills/matcher.js +27 -0
  54. package/dist/modules/skills/module.js +23 -10
  55. package/dist/tools/bash.js +90 -287
  56. package/dist/tools/create-dir.js +1 -0
  57. package/dist/tools/delete-file.js +1 -0
  58. package/dist/tools/edit-file.js +8 -10
  59. package/dist/tools/executor.js +7 -57
  60. package/dist/tools/grep-tool.js +29 -51
  61. package/dist/tools/index.js +40 -55
  62. package/dist/tools/load-skill.js +18 -14
  63. package/dist/tools/move-file.js +2 -3
  64. package/dist/tools/pipeline-run.js +1 -1
  65. package/dist/tools/read-file.js +5 -15
  66. package/dist/tools/search-history.js +22 -42
  67. package/dist/tools/subagent.js +12 -21
  68. package/dist/tools/web-browse.js +25 -54
  69. package/dist/tools/web-fetch.js +34 -60
  70. package/dist/tools/web-search.js +20 -39
  71. package/dist/tools/write-file.js +10 -13
  72. package/dist/ui/diff.js +16 -9
  73. package/dist/ui/renderer.js +6 -69
  74. package/package.json +1 -1
  75. package/dist/cli/repl-commands.js +0 -633
  76. package/dist/core/workspace.js +0 -76
  77. package/dist/logger/file-log.js +0 -151
  78. package/dist/modules/certification/cli.js +0 -176
  79. package/dist/modules/certification/fact-checker.js +0 -84
  80. package/dist/modules/certification/loader.js +0 -111
  81. package/dist/modules/certification/manifest.js +0 -50
  82. package/dist/modules/certification/runner.js +0 -162
  83. package/dist/modules/certification/scenarios.js +0 -124
  84. package/dist/modules/certification/types.js +0 -1
  85. package/dist/modules/execution/plan-coverage.js +0 -68
  86. package/dist/modules/execution/plan-persister.js +0 -46
  87. package/dist/modules/execution/plan-store.js +0 -159
  88. package/dist/modules/hallucination/js-identifiers.js +0 -72
  89. package/dist/modules/hallucination/llm-judge.js +0 -103
  90. package/dist/modules/lsp/client.js +0 -235
  91. package/dist/modules/lsp/config.js +0 -81
  92. package/dist/modules/lsp/index.js +0 -3
  93. package/dist/modules/lsp/module.js +0 -68
  94. package/dist/modules/lsp/types.js +0 -1
package/dist/main.js CHANGED
@@ -2256,6 +2256,13 @@ var init_defaults = __esm(() => {
2256
2256
  skills: {
2257
2257
  budget: 0.15
2258
2258
  },
2259
+ subagent: {
2260
+ resultMode: "text",
2261
+ maxSummaryChars: 2000,
2262
+ artifactsDir: ".mma/artifacts",
2263
+ stableSystemPrompt: true,
2264
+ maxParallelChunkQueries: 4
2265
+ },
2259
2266
  lsp: DEFAULT_LSP_CONFIG
2260
2267
  };
2261
2268
  });
@@ -2367,6 +2374,10 @@ var init_en = __esm(() => {
2367
2374
  "tool.friendly.mcp_call": "MCP call",
2368
2375
  "tool.truncated": "[Truncated: {tokens} tokens removed]",
2369
2376
  "tool.subagent_queued": "Sub-agent task queued: {task}",
2377
+ "tool.subagent_artifact": `Sub-agent completed. Full result saved to artifact: {path}
2378
+ Iterations: {iterations}
2379
+ Summary:
2380
+ {summary}`,
2370
2381
  "tool.pipeline_started": 'Pipeline "{name}" execution started. Pipeline engine is a stub — run dispatched.',
2371
2382
  "tool.mcp_call": "MCP call: {server}/{tool} with {args}",
2372
2383
  "tool.action_required": "Action is required.",
@@ -2387,6 +2398,8 @@ var init_en = __esm(() => {
2387
2398
  "tool.question.unanswered": "Unanswered",
2388
2399
  "tool.question.answered": "User has answered your questions: {formatted}. You can now continue with the user's answers in mind.",
2389
2400
  "tool.name_or_task": 'Provide either "name" or "task" parameter',
2401
+ "tool.chunk_query_no_query": "chunk_query: a query string is required.",
2402
+ "tool.chunk_query_no_input": "chunk_query: provide input_path or text.",
2390
2403
  "tool.invalid_params": "Invalid parameters",
2391
2404
  "tool.skill_budget": 'Skill "{name}" loaded ({tokens} tokens, {remaining} remaining in skills budget). Skill content is now in system prompt — no need to reload after context compaction.',
2392
2405
  "tool.skill_available_hint": "Available skills",
@@ -2926,6 +2939,10 @@ var init_ru = __esm(() => {
2926
2939
  "tool.friendly.mcp_call": "MCP вызов",
2927
2940
  "tool.truncated": "[Обрезано: удалено {tokens} токенов]",
2928
2941
  "tool.subagent_queued": "Задача подагенту добавлена: {task}",
2942
+ "tool.subagent_artifact": `Суб-агент завершён. Полный результат сохранён в артефакт: {path}
2943
+ Итераций: {iterations}
2944
+ Сводка:
2945
+ {summary}`,
2929
2946
  "tool.pipeline_started": 'Пайплайн "{name}" запущен. Движок пайплайнов — заглушка, задача отправлена.',
2930
2947
  "tool.mcp_call": "MCP вызов: {server}/{tool} с {args}",
2931
2948
  "tool.action_required": "Требуется действие.",
@@ -2946,6 +2963,8 @@ var init_ru = __esm(() => {
2946
2963
  "tool.question.unanswered": "Без ответа",
2947
2964
  "tool.question.answered": "Пользователь ответил на ваши вопросы: {formatted}. Теперь продолжайте с учётом ответов.",
2948
2965
  "tool.name_or_task": 'Укажите параметр "name" или "task"',
2966
+ "tool.chunk_query_no_query": "chunk_query: требуется строка запроса.",
2967
+ "tool.chunk_query_no_input": "chunk_query: укажите input_path или text.",
2949
2968
  "tool.invalid_params": "Неверные параметры",
2950
2969
  "tool.skill_budget": 'Скилл "{name}" загружен ({tokens} токенов, осталось {remaining} в бюджете скиллов). Контент скилла теперь в системном промпте — перезагрузка после компрессии не нужна.',
2951
2970
  "tool.skill_available_hint": "Доступные скиллы",
@@ -4832,12 +4851,12 @@ class OpenAICompatProvider {
4832
4851
  };
4833
4852
  this.rateLimiter = createRateLimiter(config.rateLimits);
4834
4853
  }
4835
- async* chat(messages, tools, signal) {
4854
+ async* chat(messages, tools, signal, options) {
4836
4855
  if (!this.rateLimiter.canMakeRequest()) {
4837
4856
  throw new Error(`Rate limit exceeded: ${this.rateLimiter.getConfig().maxRequestsPerMinute} requests per minute`);
4838
4857
  }
4839
4858
  this.rateLimiter.recordRequest();
4840
- const streamResult = this.doStream(messages, tools, signal);
4859
+ const streamResult = this.doStream(messages, tools, signal, options);
4841
4860
  let hasToolCall = false;
4842
4861
  let hasText = false;
4843
4862
  let reasoningAcc = "";
@@ -4852,19 +4871,22 @@ class OpenAICompatProvider {
4852
4871
  yield chunk;
4853
4872
  }
4854
4873
  if (!hasToolCall && !hasText) {
4855
- const fallback = await this.doNonStreaming(messages, tools, signal);
4874
+ const fallback = await this.doNonStreaming(messages, tools, signal, options);
4856
4875
  for (const chunk of fallback) {
4857
4876
  yield chunk;
4858
4877
  }
4859
4878
  }
4860
4879
  }
4861
- async* doStream(messages, tools, signal) {
4880
+ async* doStream(messages, tools, signal, options) {
4862
4881
  const body = {
4863
4882
  model: this.model,
4864
4883
  messages,
4865
4884
  stream: true,
4866
- max_tokens: this.config.maxCompletionTokens ?? 4096
4885
+ max_tokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096
4867
4886
  };
4887
+ if (options?.reasoningEffort) {
4888
+ body.reasoning_effort = options.reasoningEffort;
4889
+ }
4868
4890
  if (tools && tools.length > 0) {
4869
4891
  body.tools = tools.map((t2) => ({
4870
4892
  type: "function",
@@ -5000,13 +5022,16 @@ class OpenAICompatProvider {
5000
5022
  reader.releaseLock();
5001
5023
  }
5002
5024
  }
5003
- async doNonStreaming(messages, tools, signal) {
5025
+ async doNonStreaming(messages, tools, signal, options) {
5004
5026
  const body = {
5005
5027
  model: this.model,
5006
5028
  messages,
5007
5029
  stream: false,
5008
- max_tokens: this.config.maxCompletionTokens ?? 4096
5030
+ max_tokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096
5009
5031
  };
5032
+ if (options?.reasoningEffort) {
5033
+ body.reasoning_effort = options.reasoningEffort;
5034
+ }
5010
5035
  if (tools && tools.length > 0) {
5011
5036
  body.tools = tools.map((t2) => ({
5012
5037
  type: "function",
@@ -5354,14 +5379,15 @@ class ToolExecutor {
5354
5379
  if (tool.interactive) {
5355
5380
  result = await tool.handler(this.ctx, call.arguments);
5356
5381
  } else {
5382
+ const timeoutMs = tool.timeoutMs ?? TOOL_EXECUTION_TIMEOUT_MS;
5357
5383
  const timeoutPromise = new Promise((_, reject) => {
5358
5384
  setTimeout(() => {
5359
5385
  killByCallId(call.id);
5360
5386
  reject(new Error(t("tool.timeout", {
5361
5387
  name: call.name,
5362
- seconds: TOOL_EXECUTION_TIMEOUT_MS / 1000
5388
+ seconds: Math.round(timeoutMs / 1000)
5363
5389
  })));
5364
- }, TOOL_EXECUTION_TIMEOUT_MS);
5390
+ }, timeoutMs);
5365
5391
  });
5366
5392
  const racePromises = [
5367
5393
  tool.handler(this.ctx, call.arguments),
@@ -7084,18 +7110,28 @@ function decodeLineToUtf8(buf) {
7084
7110
  }
7085
7111
  return buf.toString("latin1");
7086
7112
  }
7113
+ function sleepSync(ms) {
7114
+ try {
7115
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
7116
+ } catch {}
7117
+ }
7118
+ function taskkillPid(pid) {
7119
+ try {
7120
+ spawnSync("taskkill", ["/pid", String(pid), "/T", "/F"], {
7121
+ windowsHide: true,
7122
+ stdio: "ignore",
7123
+ timeout: 5000
7124
+ });
7125
+ } catch {}
7126
+ }
7087
7127
  function killTree(child) {
7088
7128
  const pid = child.pid;
7089
7129
  if (!pid)
7090
7130
  return;
7091
7131
  if (platform() === "win32") {
7092
- try {
7093
- spawnSync("taskkill", ["/pid", String(pid), "/T", "/F"], {
7094
- windowsHide: true,
7095
- stdio: "ignore",
7096
- timeout: 3000
7097
- });
7098
- } catch {}
7132
+ taskkillPid(pid);
7133
+ sleepSync(150);
7134
+ taskkillPid(pid);
7099
7135
  return;
7100
7136
  }
7101
7137
  try {
@@ -9424,6 +9460,59 @@ var init_stuck_detector = __esm(() => {
9424
9460
  init_i18n();
9425
9461
  });
9426
9462
 
9463
+ // src/modules/artifacts/store.ts
9464
+ import { existsSync as existsSync18, mkdirSync as mkdirSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
9465
+ import { resolve as resolve10, relative, isAbsolute } from "node:path";
9466
+
9467
+ class ArtifactStore {
9468
+ root;
9469
+ constructor(opts) {
9470
+ const artifactsDir = opts.artifactsDir || ".mma/artifacts";
9471
+ this.root = resolve10(opts.baseDir, artifactsDir, opts.sessionId);
9472
+ }
9473
+ static sanitizeName(name) {
9474
+ const stripped = name.replace(/^(\.\.?[\\/])+/g, "").replace(/^\.{1,2}$/, "");
9475
+ const cleaned = stripped.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/_{2,}/g, "_").replace(/^_+|_+$/g, "");
9476
+ if (cleaned === "" || cleaned === "." || cleaned === "..") {
9477
+ return "artifact";
9478
+ }
9479
+ return cleaned;
9480
+ }
9481
+ static isInside(root, candidate) {
9482
+ const rel = relative(root, candidate);
9483
+ if (rel === "")
9484
+ return true;
9485
+ return !rel.startsWith("..") && !isAbsolute(rel);
9486
+ }
9487
+ save(name, content, ext = "md") {
9488
+ const safe = ArtifactStore.sanitizeName(name);
9489
+ const dir = resolve10(this.root);
9490
+ mkdirSync11(dir, { recursive: true });
9491
+ const abs = resolve10(dir, `${safe}.${ext}`);
9492
+ if (!ArtifactStore.isInside(dir, abs)) {
9493
+ throw new Error(`Artifact path escapes root: ${abs}`);
9494
+ }
9495
+ writeFileSync7(abs, content, "utf8");
9496
+ return abs;
9497
+ }
9498
+ read(path) {
9499
+ const abs = resolve10(this.root, path);
9500
+ if (!ArtifactStore.isInside(this.root, abs))
9501
+ return null;
9502
+ if (!existsSync18(abs))
9503
+ return null;
9504
+ return readFileSync9(abs, "utf8");
9505
+ }
9506
+ summary(content, maxChars) {
9507
+ if (content.length <= maxChars)
9508
+ return content;
9509
+ const head = content.slice(0, maxChars).trimEnd();
9510
+ return `${head}
9511
+ …[truncated: ${content.length - maxChars} chars]`;
9512
+ }
9513
+ }
9514
+ var init_store = () => {};
9515
+
9427
9516
  // src/modules/execution/moe-executor.ts
9428
9517
  function isTransientError(error) {
9429
9518
  return TRANSIENT_ERROR_PATTERNS.some((p) => error.includes(p));
@@ -9515,14 +9604,38 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
9515
9604
  read_only_files: readOnlyFiles,
9516
9605
  tool_tags: expertConfig.tool_tags
9517
9606
  };
9607
+ if (deps.config.subagent?.resultMode === "file") {
9608
+ subagentArgs.result_mode = "file";
9609
+ subagentArgs.artifact_name = subtask.id;
9610
+ }
9518
9611
  const result = await subagentTool.handler({
9519
9612
  config: deps.config,
9520
9613
  baseDir: deps.baseDir,
9521
9614
  logger: deps.logger,
9522
9615
  llmProvider: deps.llmProvider,
9523
- toolExecutor: deps.toolExecutor
9616
+ toolExecutor: deps.toolExecutor,
9617
+ sessionId: "moe"
9524
9618
  }, subagentArgs);
9525
9619
  if (result.success) {
9620
+ if (deps.config.subagent?.resultMode === "file") {
9621
+ const pathMatch = result.output.match(/saved to artifact: (.+)/);
9622
+ const abs = pathMatch ? pathMatch[1].trim() : "";
9623
+ if (abs) {
9624
+ const store = new ArtifactStore({
9625
+ baseDir: deps.baseDir,
9626
+ sessionId: "moe"
9627
+ });
9628
+ const full = store.read(abs.split(/[\\/]/).pop() || "");
9629
+ deps.logger.debug(`MoE subtask "${subtask.id}" attached artifact ${abs} (${full?.length ?? 0} chars) to Router`);
9630
+ return {
9631
+ subtaskId: subtask.id,
9632
+ success: true,
9633
+ summary: `Artifact: ${abs}`,
9634
+ result: full ?? result.output,
9635
+ durationMs: Date.now() - startTime
9636
+ };
9637
+ }
9638
+ }
9526
9639
  return {
9527
9640
  subtaskId: subtask.id,
9528
9641
  success: true,
@@ -9682,6 +9795,7 @@ var TRANSIENT_ERROR_PATTERNS;
9682
9795
  var init_moe_executor = __esm(() => {
9683
9796
  init_stuck_detector();
9684
9797
  init_i18n();
9798
+ init_store();
9685
9799
  TRANSIENT_ERROR_PATTERNS = [
9686
9800
  "timeout",
9687
9801
  "Timeout",
@@ -9701,8 +9815,8 @@ var init_moe_executor = __esm(() => {
9701
9815
  });
9702
9816
 
9703
9817
  // src/modules/execution/verifier.ts
9704
- import { existsSync as existsSync18 } from "fs";
9705
- import { resolve as resolve10, extname as extname2 } from "path";
9818
+ import { existsSync as existsSync19 } from "fs";
9819
+ import { resolve as resolve11, extname as extname2 } from "path";
9706
9820
  import { spawn as spawn2 } from "child_process";
9707
9821
 
9708
9822
  class StepVerifier {
@@ -9711,8 +9825,8 @@ class StepVerifier {
9711
9825
  this.baseDir = baseDir;
9712
9826
  }
9713
9827
  async checkFileExists(path) {
9714
- const resolved = resolve10(this.baseDir, path);
9715
- const exists = existsSync18(resolved);
9828
+ const resolved = resolve11(this.baseDir, path);
9829
+ const exists = existsSync19(resolved);
9716
9830
  return {
9717
9831
  passed: exists,
9718
9832
  message: exists ? t("verify.file_exists", { path }) : t("verify.file_not_found", { path })
@@ -9727,8 +9841,8 @@ class StepVerifier {
9727
9841
  }
9728
9842
  }
9729
9843
  async runTypeCheck() {
9730
- const tsconfigPath = resolve10(this.baseDir, "tsconfig.json");
9731
- if (!existsSync18(tsconfigPath)) {
9844
+ const tsconfigPath = resolve11(this.baseDir, "tsconfig.json");
9845
+ if (!existsSync19(tsconfigPath)) {
9732
9846
  return { passed: true, message: "No tsconfig.json found — skipping type check" };
9733
9847
  }
9734
9848
  try {
@@ -9740,8 +9854,8 @@ class StepVerifier {
9740
9854
  }
9741
9855
  }
9742
9856
  async runTests() {
9743
- const pkgPath = resolve10(this.baseDir, "package.json");
9744
- if (!existsSync18(pkgPath)) {
9857
+ const pkgPath = resolve11(this.baseDir, "package.json");
9858
+ if (!existsSync19(pkgPath)) {
9745
9859
  return { passed: true, message: "No package.json found — skipping tests" };
9746
9860
  }
9747
9861
  try {
@@ -9793,7 +9907,7 @@ class StepVerifier {
9793
9907
  const result = await this.checkFileExists(filePath);
9794
9908
  results.push(result);
9795
9909
  if (result.passed) {
9796
- const fullPath = resolve10(this.baseDir, filePath);
9910
+ const fullPath = resolve11(this.baseDir, filePath);
9797
9911
  if (!await this.validateSyntax(fullPath)) {
9798
9912
  syntaxValid = false;
9799
9913
  results.push({ passed: false, message: t("verify.syntax_error", { path: filePath }) });
@@ -9834,7 +9948,7 @@ class StepVerifier {
9834
9948
  return true;
9835
9949
  }
9836
9950
  runAsync(command, cwd, timeoutMs) {
9837
- return new Promise((resolve11, reject) => {
9951
+ return new Promise((resolve12, reject) => {
9838
9952
  const child = spawn2(command, {
9839
9953
  cwd,
9840
9954
  shell: true,
@@ -9860,7 +9974,7 @@ class StepVerifier {
9860
9974
  child.on("close", (code) => {
9861
9975
  clearTimeout(timer);
9862
9976
  if (code === 0) {
9863
- resolve11({ stdout, stderr });
9977
+ resolve12({ stdout, stderr });
9864
9978
  } else {
9865
9979
  const err = new Error(`Command failed with exit code ${code}`);
9866
9980
  err.stdout = stdout;
@@ -9991,7 +10105,7 @@ var init_agent_moe = __esm(() => {
9991
10105
  });
9992
10106
 
9993
10107
  // src/modules/memory/search.ts
9994
- import { readFileSync as readFileSync9, existsSync as existsSync19 } from "fs";
10108
+ import { readFileSync as readFileSync10, existsSync as existsSync20 } from "fs";
9995
10109
  import { join as join10 } from "path";
9996
10110
 
9997
10111
  class MemorySearch {
@@ -10004,9 +10118,9 @@ class MemorySearch {
10004
10118
  const lowerQuery = query.toLowerCase();
10005
10119
  for (const name of MEMORY_FILES) {
10006
10120
  const path = join10(this.memoryDir, `${name}.md`);
10007
- if (!existsSync19(path))
10121
+ if (!existsSync20(path))
10008
10122
  continue;
10009
- const content = readFileSync9(path, "utf-8");
10123
+ const content = readFileSync10(path, "utf-8");
10010
10124
  const lines = content.split(`
10011
10125
  `);
10012
10126
  for (const line of lines) {
@@ -10016,9 +10130,9 @@ class MemorySearch {
10016
10130
  }
10017
10131
  }
10018
10132
  const prefsPath = join10(this.memoryDir, "preferences.json");
10019
- if (existsSync19(prefsPath)) {
10133
+ if (existsSync20(prefsPath)) {
10020
10134
  try {
10021
- const prefs = JSON.parse(readFileSync9(prefsPath, "utf-8"));
10135
+ const prefs = JSON.parse(readFileSync10(prefsPath, "utf-8"));
10022
10136
  for (const [key, value] of Object.entries(prefs)) {
10023
10137
  const searchStr = `${key}=${value}`;
10024
10138
  if (searchStr.toLowerCase().includes(lowerQuery)) {
@@ -10036,7 +10150,7 @@ var init_search = __esm(() => {
10036
10150
  });
10037
10151
 
10038
10152
  // src/modules/memory/store.ts
10039
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, appendFileSync as appendFileSync5, existsSync as existsSync20, mkdirSync as mkdirSync11 } from "fs";
10153
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, appendFileSync as appendFileSync5, existsSync as existsSync21, mkdirSync as mkdirSync12 } from "fs";
10040
10154
  import { join as join11 } from "path";
10041
10155
 
10042
10156
  class MemoryStore {
@@ -10046,23 +10160,23 @@ class MemoryStore {
10046
10160
  this.ensureDir();
10047
10161
  for (const name of MEMORY_FILES2) {
10048
10162
  const path = join11(this.memoryDir, `${name}.md`);
10049
- if (!existsSync20(path)) {
10050
- writeFileSync7(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
10163
+ if (!existsSync21(path)) {
10164
+ writeFileSync8(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
10051
10165
 
10052
10166
  `, "utf-8");
10053
10167
  }
10054
10168
  }
10055
10169
  }
10056
10170
  ensureDir() {
10057
- if (!existsSync20(this.memoryDir)) {
10058
- mkdirSync11(this.memoryDir, { recursive: true });
10171
+ if (!existsSync21(this.memoryDir)) {
10172
+ mkdirSync12(this.memoryDir, { recursive: true });
10059
10173
  }
10060
10174
  }
10061
10175
  read(name) {
10062
10176
  const path = join11(this.memoryDir, `${name}.md`);
10063
- if (!existsSync20(path))
10177
+ if (!existsSync21(path))
10064
10178
  return "";
10065
- return readFileSync10(path, "utf-8");
10179
+ return readFileSync11(path, "utf-8");
10066
10180
  }
10067
10181
  append(name, entry) {
10068
10182
  const path = join11(this.memoryDir, `${name}.md`);
@@ -10080,10 +10194,10 @@ class MemoryStore {
10080
10194
  }
10081
10195
  getPreferences() {
10082
10196
  const path = this.prefsPath();
10083
- if (!existsSync20(path))
10197
+ if (!existsSync21(path))
10084
10198
  return {};
10085
10199
  try {
10086
- return JSON.parse(readFileSync10(path, "utf-8"));
10200
+ return JSON.parse(readFileSync11(path, "utf-8"));
10087
10201
  } catch {
10088
10202
  return {};
10089
10203
  }
@@ -10091,14 +10205,14 @@ class MemoryStore {
10091
10205
  setPreference(key, value) {
10092
10206
  const prefs = this.getPreferences();
10093
10207
  prefs[key] = value;
10094
- writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
10208
+ writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
10095
10209
  }
10096
10210
  deletePreference(key) {
10097
10211
  const prefs = this.getPreferences();
10098
10212
  if (!(key in prefs))
10099
10213
  return false;
10100
10214
  delete prefs[key];
10101
- writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
10215
+ writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
10102
10216
  return true;
10103
10217
  }
10104
10218
  appendRule(category, pattern, cause, solution) {
@@ -10109,7 +10223,7 @@ class MemoryStore {
10109
10223
  }
10110
10224
  }
10111
10225
  var MEMORY_FILES2;
10112
- var init_store = __esm(() => {
10226
+ var init_store2 = __esm(() => {
10113
10227
  init_search();
10114
10228
  MEMORY_FILES2 = ["conventions", "decisions", "errors", "facts"];
10115
10229
  });
@@ -10784,7 +10898,7 @@ var init_agent = __esm(() => {
10784
10898
  init_processes();
10785
10899
  init_session_logger();
10786
10900
  init_agent_moe();
10787
- init_store();
10901
+ init_store2();
10788
10902
  init_verifier();
10789
10903
  });
10790
10904
 
@@ -11244,8 +11358,8 @@ var init_js_identifiers = __esm(() => {
11244
11358
  });
11245
11359
 
11246
11360
  // src/modules/hallucination/factual.ts
11247
- import { existsSync as existsSync21, readdirSync as readdirSync5 } from "fs";
11248
- import { resolve as resolve11, isAbsolute, join as join13 } from "path";
11361
+ import { existsSync as existsSync22, readdirSync as readdirSync5 } from "fs";
11362
+ import { resolve as resolve12, isAbsolute as isAbsolute2, join as join13 } from "path";
11249
11363
  function looksLikeFilePath(s) {
11250
11364
  const lower = s.toLowerCase();
11251
11365
  if (TECH_NAMES.has(lower))
@@ -11290,15 +11404,15 @@ class FactualCheck {
11290
11404
  return { status: "pass" };
11291
11405
  }
11292
11406
  pathExists(fp) {
11293
- if (isAbsolute(fp))
11294
- return existsSync21(fp);
11407
+ if (isAbsolute2(fp))
11408
+ return existsSync22(fp);
11295
11409
  if (!fp.includes("/") && !fp.includes("\\")) {
11296
11410
  return this.bareNameExists(fp);
11297
11411
  }
11298
- return existsSync21(resolve11(this.baseDir, fp));
11412
+ return existsSync22(resolve12(this.baseDir, fp));
11299
11413
  }
11300
11414
  bareNameExists(name) {
11301
- if (existsSync21(resolve11(this.baseDir, name)))
11415
+ if (existsSync22(resolve12(this.baseDir, name)))
11302
11416
  return true;
11303
11417
  if (this.indexHas(name))
11304
11418
  return true;
@@ -11692,7 +11806,18 @@ class PluginManager {
11692
11806
  }
11693
11807
 
11694
11808
  // src/tools/subagent.ts
11695
- var subagentTool;
11809
+ function buildSubagentSystemPrompt(context, stable) {
11810
+ if (stable)
11811
+ return SUBAGENT_SYSTEM_PROMPT_TEMPLATE;
11812
+ return `You are a sub-agent working on a specific task. ${context ? `Context: ${context}` : ""}`;
11813
+ }
11814
+ var SUBAGENT_SYSTEM_PROMPT_TEMPLATE = `You are a sub-agent working on a specific task. You have your own context window and tool set.
11815
+
11816
+ Workflow rules:
11817
+ - Prefer small, focused steps. Verify your own work (typecheck/tests) before finishing.
11818
+ - For large outputs, write the result to a file with write_file instead of reproducing it in your answer.
11819
+ - If the task is big and decomposable, delegate parts to the subagent tool instead of doing everything in one context.
11820
+ - When you finish, return a concise final answer; do not repeat file contents verbatim if you already wrote them to disk.`, subagentTool;
11696
11821
  var init_subagent = __esm(() => {
11697
11822
  init_i18n();
11698
11823
  init_agent();
@@ -11700,6 +11825,7 @@ var init_subagent = __esm(() => {
11700
11825
  init_detector();
11701
11826
  init_audit_log();
11702
11827
  init_session_isolation();
11828
+ init_store();
11703
11829
  subagentTool = {
11704
11830
  name: "subagent",
11705
11831
  description: "Spawn an isolated sub-agent to work on a task independently. The sub-agent has its own context and executes autonomously. Use for parallel work or complex sub-tasks.",
@@ -11741,6 +11867,15 @@ var init_subagent = __esm(() => {
11741
11867
  type: "array",
11742
11868
  items: { type: "string" },
11743
11869
  description: "Tool tags to expose to the sub-agent"
11870
+ },
11871
+ result_mode: {
11872
+ type: "string",
11873
+ enum: ["text", "file"],
11874
+ description: '"file": persist the full result to an artifact and return a path + summary (pass-by-reference). "text" (default): return the full text into context.'
11875
+ },
11876
+ artifact_name: {
11877
+ type: "string",
11878
+ description: "Artifact file name (sanitized). Default: subagent-<timestamp>."
11744
11879
  }
11745
11880
  },
11746
11881
  required: ["task"]
@@ -11788,10 +11923,10 @@ var init_subagent = __esm(() => {
11788
11923
  const parentScope = ctx.scope;
11789
11924
  ctx.toolExecutor.setScope(scope || { allowed_files: [], read_only_files: [] });
11790
11925
  const systemPrompt = {
11791
- content: `You are a sub-agent working on a specific task. ${context ? `Context: ${context}` : ""}`,
11926
+ content: buildSubagentSystemPrompt(context, ctx.config.subagent?.stableSystemPrompt !== false),
11792
11927
  priority: "critical",
11793
11928
  essential: true,
11794
- estimatedTokens: 100
11929
+ estimatedTokens: 150
11795
11930
  };
11796
11931
  const subDeps = {
11797
11932
  config: ctx.config,
@@ -11814,16 +11949,38 @@ Context: ${context}` : task;
11814
11949
  let scopeRestored = false;
11815
11950
  try {
11816
11951
  const result = await subAgent.run(fullTask);
11817
- return result.success ? {
11952
+ if (!result.success) {
11953
+ return {
11954
+ success: false,
11955
+ output: `Sub-agent failed: ${result.error}
11956
+ Partial output: ${result.text}`
11957
+ };
11958
+ }
11959
+ const resultMode = args.result_mode || ctx.config.subagent?.resultMode || "text";
11960
+ if (resultMode === "file") {
11961
+ const store = new ArtifactStore({
11962
+ baseDir: ctx.baseDir,
11963
+ sessionId: ctx.sessionId || "default",
11964
+ artifactsDir: ctx.config.subagent?.artifactsDir
11965
+ });
11966
+ const abs = store.save(args.artifact_name || `subagent-${Date.now()}`, result.text, "md");
11967
+ const summary = store.summary(result.text, ctx.config.subagent?.maxSummaryChars ?? 2000);
11968
+ ctx.logger.debug(`subagent result persisted to artifact ${abs} (${result.text.length} chars, ${result.iterationCount} iterations)`);
11969
+ return {
11970
+ success: true,
11971
+ output: t("tool.subagent_artifact", {
11972
+ path: abs,
11973
+ iterations: String(result.iterationCount),
11974
+ summary
11975
+ })
11976
+ };
11977
+ }
11978
+ return {
11818
11979
  success: true,
11819
11980
  output: `Sub-agent completed:
11820
11981
  ${result.text}
11821
11982
 
11822
11983
  Iterations: ${result.iterationCount}`
11823
- } : {
11824
- success: false,
11825
- output: `Sub-agent failed: ${result.error}
11826
- Partial output: ${result.text}`
11827
11984
  };
11828
11985
  } finally {
11829
11986
  if (!scopeRestored) {
@@ -11837,6 +11994,228 @@ Partial output: ${result.text}`
11837
11994
  };
11838
11995
  });
11839
11996
 
11997
+ // src/tools/scope-check.ts
11998
+ import { resolve as resolve13, normalize as normalize4 } from "path";
11999
+ function isPathInScope2(baseDir, targetPath, scope) {
12000
+ const baseResolved = resolve13(baseDir);
12001
+ const targetResolved = resolve13(baseDir, normalize4(targetPath));
12002
+ if (!targetResolved.startsWith(baseResolved)) {
12003
+ return { allowed: false, reason: "Path is outside the base working directory" };
12004
+ }
12005
+ if (!scope)
12006
+ return { allowed: true };
12007
+ const isRead = scope.read_only_files.some((f) => targetResolved.startsWith(resolve13(baseDir, f)));
12008
+ const isWrite = scope.allowed_files.some((f) => targetResolved.startsWith(resolve13(baseDir, f)));
12009
+ if (isWrite)
12010
+ return { allowed: true };
12011
+ if (isRead)
12012
+ return { allowed: true, reason: "Read-only file" };
12013
+ return { allowed: false, reason: "Path is not within the allowed scope for this sub-agent" };
12014
+ }
12015
+ var init_scope_check = () => {};
12016
+
12017
+ // src/modules/context/chunk-query.ts
12018
+ function splitTextIntoChunks(text, chunkChars) {
12019
+ if (chunkChars <= 0)
12020
+ throw new Error("chunkChars must be > 0");
12021
+ if (text.length <= chunkChars)
12022
+ return [text];
12023
+ const lines = text.split(`
12024
+ `);
12025
+ const chunks = [];
12026
+ let current = [];
12027
+ let size = 0;
12028
+ for (const line of lines) {
12029
+ if (current.length > 0 && size + line.length + 1 > chunkChars) {
12030
+ chunks.push(current.join(`
12031
+ `));
12032
+ current = [];
12033
+ size = 0;
12034
+ }
12035
+ current.push(line);
12036
+ size += line.length + 1;
12037
+ }
12038
+ if (current.length > 0)
12039
+ chunks.push(current.join(`
12040
+ `));
12041
+ return chunks;
12042
+ }
12043
+ async function chatText(provider, messages, maxTokens, reasoningEffort) {
12044
+ let out = "";
12045
+ for await (const chunk of provider.chat(messages, undefined, undefined, {
12046
+ maxTokens,
12047
+ reasoningEffort
12048
+ })) {
12049
+ if (chunk.type === "text" && chunk.content)
12050
+ out += chunk.content;
12051
+ }
12052
+ return out;
12053
+ }
12054
+ async function runChunkQuery(provider, text, query, opts = {}) {
12055
+ const chunkChars = opts.chunkChars ?? 12000;
12056
+ const maxParallel = Math.max(1, opts.maxParallel ?? 4);
12057
+ const maxChunkTokens = opts.maxChunkTokens ?? 1024;
12058
+ const maxSynthesisTokens = opts.maxSynthesisTokens ?? 2048;
12059
+ const reasoningEffort = opts.reasoningEffort ?? "none";
12060
+ const chunks = splitTextIntoChunks(text, chunkChars);
12061
+ const answers = new Array(chunks.length);
12062
+ const chunkSystem = opts.querySystemPrompt ?? DEFAULT_CHUNK_SYSTEM_PROMPT;
12063
+ const logger = opts.logger;
12064
+ if (chunks.length === 1) {
12065
+ logger?.debug(`runChunkQuery: single chunk (${text.length} chars), no chunking needed`);
12066
+ } else {
12067
+ logger?.debug(`runChunkQuery: ${chunks.length} chunks over ${text.length} chars (chunkChars=${chunkChars}, maxParallel=${maxParallel})`);
12068
+ }
12069
+ let cursor = 0;
12070
+ let inFlight = 0;
12071
+ let maxParallelObserved = 0;
12072
+ const workers = Array.from({ length: Math.min(maxParallel, chunks.length) }, async () => {
12073
+ while (cursor < chunks.length) {
12074
+ const idx = cursor++;
12075
+ inFlight++;
12076
+ maxParallelObserved = Math.max(maxParallelObserved, inFlight);
12077
+ try {
12078
+ answers[idx] = await chatText(provider, [
12079
+ { role: "system", content: chunkSystem },
12080
+ { role: "user", content: `Query: ${query}
12081
+
12082
+ Text:
12083
+ ${chunks[idx]}` }
12084
+ ], maxChunkTokens, reasoningEffort);
12085
+ } finally {
12086
+ inFlight--;
12087
+ }
12088
+ }
12089
+ });
12090
+ await Promise.all(workers);
12091
+ let synthesis = "";
12092
+ if (opts.synthesize !== false && chunks.length > 0) {
12093
+ const joined = answers.map((a, i) => `--- Chunk ${i + 1}/${chunks.length} ---
12094
+ ${a}`).join(`
12095
+
12096
+ `);
12097
+ logger?.debug(`runChunkQuery: synthesis pass over ${chunks.length} answers`);
12098
+ synthesis = await chatText(provider, [
12099
+ {
12100
+ role: "system",
12101
+ content: opts.synthesisSystemPrompt ?? DEFAULT_SYNTHESIS_SYSTEM_PROMPT
12102
+ },
12103
+ { role: "user", content: `Query: ${query}
12104
+
12105
+ Chunk answers:
12106
+ ${joined}` }
12107
+ ], maxSynthesisTokens, reasoningEffort);
12108
+ }
12109
+ logger?.debug(`runChunkQuery: done, ${chunks.length} chunks, max parallel observed ${maxParallelObserved}, synthesis ${synthesis.length} chars`);
12110
+ return {
12111
+ chunks: chunks.length,
12112
+ answers,
12113
+ synthesis,
12114
+ totalChars: text.length,
12115
+ maxParallelObserved
12116
+ };
12117
+ }
12118
+ var DEFAULT_CHUNK_SYSTEM_PROMPT = 'Answer the query using ONLY the provided text. Be concise. If the text does not contain the answer, say "NO_EVIDENCE".', DEFAULT_SYNTHESIS_SYSTEM_PROMPT = "You are given a query and per-chunk answers over a large text. Produce the final answer to the query, combining evidence from the chunks. If no chunk had evidence, say so.";
12119
+
12120
+ // src/tools/chunk-query.ts
12121
+ import { readFileSync as readFileSync12 } from "node:fs";
12122
+ var chunkQueryTool;
12123
+ var init_chunk_query = __esm(() => {
12124
+ init_i18n();
12125
+ init_scope_check();
12126
+ chunkQueryTool = {
12127
+ name: "chunk_query",
12128
+ description: "Answer a query over a large text (file or inline) by splitting it into chunks and querying the model per chunk in parallel, then optionally synthesizing a final answer. Use when the input is too large for the context window.",
12129
+ tags: ["research", "code"],
12130
+ timeoutMs: 300000,
12131
+ parameters: {
12132
+ type: "object",
12133
+ properties: {
12134
+ query: {
12135
+ type: "string",
12136
+ description: "The question to answer over the text."
12137
+ },
12138
+ input_path: {
12139
+ type: "string",
12140
+ description: "Path to the large text file (scope-checked). Preferred over text."
12141
+ },
12142
+ text: {
12143
+ type: "string",
12144
+ description: "Inline text. Use only when a file path is not available."
12145
+ },
12146
+ chunk_chars: {
12147
+ type: "number",
12148
+ description: "Approximate chunk size in chars (default 12000)."
12149
+ },
12150
+ max_parallel: {
12151
+ type: "number",
12152
+ description: "Max parallel chunk queries (default from config.subagent.maxParallelChunkQueries)."
12153
+ },
12154
+ max_chunk_tokens: {
12155
+ type: "number",
12156
+ description: "Cap on generated tokens per chunk call (default 1024)."
12157
+ },
12158
+ max_synthesis_tokens: {
12159
+ type: "number",
12160
+ description: "Cap on generated tokens for the synthesis call (default 2048)."
12161
+ },
12162
+ reasoning_effort: {
12163
+ type: "string",
12164
+ enum: ["none", "low", "medium", "high"],
12165
+ description: 'Reasoning effort for chunk/synthesis calls (default "none"). "none" prevents long thinking chains from eating the token budget on reasoning models.'
12166
+ },
12167
+ synthesize: {
12168
+ type: "boolean",
12169
+ description: "Run a final synthesis call over chunk answers (default true)."
12170
+ }
12171
+ },
12172
+ required: ["query"]
12173
+ },
12174
+ handler: async (ctx, args) => {
12175
+ const query = String(args.query || "");
12176
+ const inputPath = args.input_path ? String(args.input_path) : undefined;
12177
+ const text = args.text ? String(args.text) : undefined;
12178
+ if (!query)
12179
+ return { success: false, output: t("tool.chunk_query_no_query") };
12180
+ if (!inputPath && !text)
12181
+ return { success: false, output: t("tool.chunk_query_no_input") };
12182
+ let content = text || "";
12183
+ if (inputPath) {
12184
+ const check = isPathInScope2(ctx.baseDir, inputPath, ctx.scope);
12185
+ if (!check.allowed) {
12186
+ return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
12187
+ }
12188
+ try {
12189
+ content = readFileSync12(inputPath, "utf8");
12190
+ } catch (e) {
12191
+ return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
12192
+ }
12193
+ }
12194
+ if (!ctx.llmProvider) {
12195
+ return { success: false, output: "chunk_query: missing llmProvider in context" };
12196
+ }
12197
+ const maxParallel = typeof args.max_parallel === "number" ? args.max_parallel : ctx.config.subagent?.maxParallelChunkQueries ?? 4;
12198
+ const res = await runChunkQuery(ctx.llmProvider, content, query, {
12199
+ chunkChars: typeof args.chunk_chars === "number" ? args.chunk_chars : undefined,
12200
+ maxParallel,
12201
+ synthesize: typeof args.synthesize === "boolean" ? args.synthesize : undefined,
12202
+ maxChunkTokens: typeof args.max_chunk_tokens === "number" ? args.max_chunk_tokens : undefined,
12203
+ maxSynthesisTokens: typeof args.max_synthesis_tokens === "number" ? args.max_synthesis_tokens : undefined,
12204
+ reasoningEffort: ["none", "low", "medium", "high"].includes(args.reasoning_effort) ? args.reasoning_effort : undefined,
12205
+ logger: ctx.logger
12206
+ });
12207
+ ctx.logger.debug(`chunk_query: ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}`);
12208
+ return {
12209
+ success: true,
12210
+ output: `[chunk_query] ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}
12211
+
12212
+ ${res.synthesis || res.answers.join(`
12213
+ `)}`
12214
+ };
12215
+ }
12216
+ };
12217
+ });
12218
+
11840
12219
  // src/modules/security/network-validator.ts
11841
12220
  function isUrlAllowed(url, securityConfig) {
11842
12221
  if (!securityConfig?.enabled) {
@@ -12586,7 +12965,7 @@ class MCPClient {
12586
12965
  }
12587
12966
  }
12588
12967
  connectStdio() {
12589
- return new Promise((resolve12, reject) => {
12968
+ return new Promise((resolve14, reject) => {
12590
12969
  const child = spawn3(this.config.command, this.config.args || [], {
12591
12970
  env: { ...process.env, ...this.config.env },
12592
12971
  stdio: ["pipe", "pipe", "pipe"]
@@ -12610,7 +12989,7 @@ class MCPClient {
12610
12989
  this._connected = true;
12611
12990
  this.process = child;
12612
12991
  _resolved = true;
12613
- resolve12();
12992
+ resolve14();
12614
12993
  });
12615
12994
  });
12616
12995
  }
@@ -12679,7 +13058,7 @@ class MCPClient {
12679
13058
  if (!this.process) {
12680
13059
  throw new Error("Not connected to MCP server");
12681
13060
  }
12682
- return new Promise((resolve12, reject) => {
13061
+ return new Promise((resolve14, reject) => {
12683
13062
  const request = {
12684
13063
  jsonrpc: "2.0",
12685
13064
  id: Date.now(),
@@ -12703,7 +13082,7 @@ class MCPClient {
12703
13082
  if (response.error) {
12704
13083
  reject(new Error(response.error.message));
12705
13084
  } else {
12706
- resolve12(response.result?.tools || []);
13085
+ resolve14(response.result?.tools || []);
12707
13086
  }
12708
13087
  return;
12709
13088
  }
@@ -12785,8 +13164,8 @@ class MCPClient {
12785
13164
  arguments: args
12786
13165
  }
12787
13166
  };
12788
- return new Promise((resolve12, reject) => {
12789
- this.pendingResolve = resolve12;
13167
+ return new Promise((resolve14, reject) => {
13168
+ this.pendingResolve = resolve14;
12790
13169
  this.pendingReject = reject;
12791
13170
  const timeout = this.config.timeout || 30000;
12792
13171
  const timer = setTimeout(() => {
@@ -12813,7 +13192,7 @@ class MCPClient {
12813
13192
  if (result.error) {
12814
13193
  reject(new Error(result.error.message));
12815
13194
  } else {
12816
- resolve12(result.result || result);
13195
+ resolve14(result.result || result);
12817
13196
  }
12818
13197
  }).catch((err) => {
12819
13198
  clearTimeout(timer);
@@ -12827,7 +13206,7 @@ class MCPClient {
12827
13206
  if (!this.process) {
12828
13207
  throw new Error("Not connected to MCP server");
12829
13208
  }
12830
- return new Promise((resolve12, reject) => {
13209
+ return new Promise((resolve14, reject) => {
12831
13210
  const request = {
12832
13211
  jsonrpc: "2.0",
12833
13212
  id: Date.now(),
@@ -12855,7 +13234,7 @@ class MCPClient {
12855
13234
  if (response.error) {
12856
13235
  reject(new Error(response.error.message));
12857
13236
  } else {
12858
- resolve12(response.result);
13237
+ resolve14(response.result);
12859
13238
  }
12860
13239
  return;
12861
13240
  }
@@ -13057,7 +13436,7 @@ import { join as join15 } from "path";
13057
13436
  var CATEGORIES, rememberTool;
13058
13437
  var init_remember = __esm(() => {
13059
13438
  init_i18n();
13060
- init_store();
13439
+ init_store2();
13061
13440
  CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
13062
13441
  rememberTool = {
13063
13442
  name: "remember",
@@ -13184,7 +13563,7 @@ function searchCategory(store, category, query) {
13184
13563
  var CATEGORIES2, recallTool;
13185
13564
  var init_recall = __esm(() => {
13186
13565
  init_i18n();
13187
- init_store();
13566
+ init_store2();
13188
13567
  CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
13189
13568
  recallTool = {
13190
13569
  name: "recall",
@@ -13883,7 +14262,7 @@ __export(exports_image_utils, {
13883
14262
  detectMime: () => detectMime,
13884
14263
  bufferToDataUrl: () => bufferToDataUrl
13885
14264
  });
13886
- import { readFileSync as readFileSync12 } from "fs";
14265
+ import { readFileSync as readFileSync14 } from "fs";
13887
14266
  import { extname as extname3 } from "path";
13888
14267
  function detectMime(filePath) {
13889
14268
  const ext = extname3(filePath).toLowerCase();
@@ -13904,7 +14283,7 @@ async function readClipboardImage() {
13904
14283
  async function readClipboardFallback() {
13905
14284
  const { platform: platform3 } = await import("os");
13906
14285
  const { execSync } = await import("child_process");
13907
- const { readFileSync: readFileSync13, unlinkSync: unlinkSync4 } = await import("fs");
14286
+ const { readFileSync: readFileSync15, unlinkSync: unlinkSync4 } = await import("fs");
13908
14287
  const { join: join19 } = await import("path");
13909
14288
  const tmpPath = join19(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13910
14289
  try {
@@ -13913,7 +14292,7 @@ async function readClipboardFallback() {
13913
14292
  } else {
13914
14293
  return null;
13915
14294
  }
13916
- const buf = readFileSync13(tmpPath);
14295
+ const buf = readFileSync15(tmpPath);
13917
14296
  unlinkSync4(tmpPath);
13918
14297
  return buf.length > 0 ? buf : null;
13919
14298
  } catch {
@@ -13924,7 +14303,7 @@ async function readClipboardFallback() {
13924
14303
  }
13925
14304
  }
13926
14305
  async function loadFileAsDataUrl(filePath) {
13927
- const buf = readFileSync12(filePath);
14306
+ const buf = readFileSync14(filePath);
13928
14307
  if (typeof Bun !== "undefined" && typeof Bun.Image !== "undefined") {
13929
14308
  try {
13930
14309
  const img = new Bun.Image(buf);
@@ -13984,8 +14363,8 @@ var init_image_utils = __esm(() => {
13984
14363
  });
13985
14364
 
13986
14365
  // src/tools/attach-image.ts
13987
- import { existsSync as existsSync23 } from "fs";
13988
- import { resolve as resolve12 } from "path";
14366
+ import { existsSync as existsSync24 } from "fs";
14367
+ import { resolve as resolve14 } from "path";
13989
14368
  var attachImageTool;
13990
14369
  var init_attach_image = __esm(() => {
13991
14370
  init_i18n();
@@ -14026,16 +14405,16 @@ var init_attach_image = __esm(() => {
14026
14405
  const result = await loadUrlAsDataUrl(source);
14027
14406
  dataUrl = result.dataUrl;
14028
14407
  } else {
14029
- const absPath = resolve12(ctx.baseDir, source);
14030
- if (!existsSync23(absPath)) {
14408
+ const absPath = resolve14(ctx.baseDir, source);
14409
+ if (!existsSync24(absPath)) {
14031
14410
  return {
14032
14411
  success: false,
14033
14412
  output: t("image.not_found", { path: source })
14034
14413
  };
14035
14414
  }
14036
14415
  if (ctx.scope) {
14037
- const { isPathInScope: isPathInScope2 } = await Promise.resolve().then(() => (init_path_validator(), exports_path_validator));
14038
- const validation = isPathInScope2(ctx.baseDir, absPath, ctx.scope);
14416
+ const { isPathInScope: isPathInScope3 } = await Promise.resolve().then(() => (init_path_validator(), exports_path_validator));
14417
+ const validation = isPathInScope3(ctx.baseDir, absPath, ctx.scope);
14039
14418
  if (!validation.allowed) {
14040
14419
  logSecurityBlock(ctx.sessionId, "file_read", validation.reason ?? "attach_image out of scope", absPath);
14041
14420
  return {
@@ -14087,6 +14466,7 @@ function registerAllTools(registry2, skillsModule) {
14087
14466
  fileInfoTool,
14088
14467
  bashTool,
14089
14468
  subagentTool,
14469
+ chunkQueryTool,
14090
14470
  processListTool,
14091
14471
  processLogTool,
14092
14472
  processKillTool,
@@ -14122,6 +14502,7 @@ var init_tools = __esm(() => {
14122
14502
  init_process_log();
14123
14503
  init_process_kill();
14124
14504
  init_subagent();
14505
+ init_chunk_query();
14125
14506
  init_web_search();
14126
14507
  init_web_fetch();
14127
14508
  init_web_browse();
@@ -14183,12 +14564,12 @@ class ModuleRegistry {
14183
14564
  }
14184
14565
 
14185
14566
  // src/modules/plugins/loader.ts
14186
- import { readdirSync as readdirSync7, existsSync as existsSync24, statSync as statSync5 } from "fs";
14567
+ import { readdirSync as readdirSync7, existsSync as existsSync25, statSync as statSync5 } from "fs";
14187
14568
  import { join as join19 } from "path";
14188
14569
 
14189
14570
  class PluginLoader {
14190
14571
  loadFromDir(dirPath, pluginManager, logger) {
14191
- if (!existsSync24(dirPath))
14572
+ if (!existsSync25(dirPath))
14192
14573
  return;
14193
14574
  const entries = readdirSync7(dirPath);
14194
14575
  for (const entry of entries) {
@@ -14216,8 +14597,8 @@ var init_loader = __esm(() => {
14216
14597
 
14217
14598
  // src/modules/plugins/builtin/lint-on-write.ts
14218
14599
  import { spawn as spawn4, execSync } from "child_process";
14219
- import { existsSync as existsSync25, readFileSync as readFileSync13 } from "fs";
14220
- import { resolve as resolve13, extname as extname4, join as join20 } from "path";
14600
+ import { existsSync as existsSync26, readFileSync as readFileSync15 } from "fs";
14601
+ import { resolve as resolve15, extname as extname4, join as join20 } from "path";
14221
14602
  import { platform as platform3 } from "os";
14222
14603
  function contentHash(content) {
14223
14604
  let h = 5381;
@@ -14262,8 +14643,8 @@ class LintOnWritePlugin {
14262
14643
  const path = String(call.arguments.path || "");
14263
14644
  if (!path)
14264
14645
  return;
14265
- const fullPath = resolve13(ctx.baseDir, path);
14266
- if (!existsSync25(fullPath))
14646
+ const fullPath = resolve15(ctx.baseDir, path);
14647
+ if (!existsSync26(fullPath))
14267
14648
  return;
14268
14649
  const ext = extname4(fullPath);
14269
14650
  const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir);
@@ -14280,7 +14661,7 @@ class LintOnWritePlugin {
14280
14661
  if (ext === ".ts" || ext === ".tsx") {
14281
14662
  let content = "";
14282
14663
  try {
14283
- content = readFileSync13(filePath, "utf-8");
14664
+ content = readFileSync15(filePath, "utf-8");
14284
14665
  } catch {
14285
14666
  return null;
14286
14667
  }
@@ -14320,10 +14701,10 @@ class LintOnWritePlugin {
14320
14701
  async runProjectLint(ctx, result) {
14321
14702
  try {
14322
14703
  const packageJsonPath = join20(ctx.baseDir, "package.json");
14323
- if (!existsSync25(packageJsonPath)) {
14704
+ if (!existsSync26(packageJsonPath)) {
14324
14705
  return;
14325
14706
  }
14326
- const packageJson = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
14707
+ const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
14327
14708
  const lintScript = packageJson.scripts?.lint;
14328
14709
  if (!lintScript) {
14329
14710
  return;
@@ -14340,7 +14721,7 @@ class LintOnWritePlugin {
14340
14721
  }
14341
14722
  async runProjectTypeCheck(ctx, result) {
14342
14723
  const tsconfigPath = join20(ctx.baseDir, "tsconfig.json");
14343
- if (!existsSync25(tsconfigPath)) {
14724
+ if (!existsSync26(tsconfigPath)) {
14344
14725
  return;
14345
14726
  }
14346
14727
  const now = Date.now();
@@ -14381,7 +14762,7 @@ class LintOnWritePlugin {
14381
14762
  }
14382
14763
  }
14383
14764
  function runAsync(command, cwd, timeoutMs) {
14384
- return new Promise((resolve14, reject) => {
14765
+ return new Promise((resolve16, reject) => {
14385
14766
  const child = spawn4(command, {
14386
14767
  cwd,
14387
14768
  shell: true,
@@ -14410,7 +14791,7 @@ function runAsync(command, cwd, timeoutMs) {
14410
14791
  stdout += decoder.decode();
14411
14792
  stderr += decoder.decode();
14412
14793
  if (code === 0) {
14413
- resolve14({ stdout, stderr });
14794
+ resolve16({ stdout, stderr });
14414
14795
  } else {
14415
14796
  const err = new Error(`Command failed with exit code ${code}`);
14416
14797
  err.stdout = stdout;
@@ -14582,8 +14963,8 @@ class PlanTracker {
14582
14963
  var init_tracker = () => {};
14583
14964
 
14584
14965
  // src/modules/execution/auditor.ts
14585
- import { existsSync as existsSync26, readdirSync as readdirSync8 } from "fs";
14586
- import { resolve as resolve14, join as join21 } from "path";
14966
+ import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
14967
+ import { resolve as resolve16, join as join21 } from "path";
14587
14968
  function findTestFile(dir, depth = 0) {
14588
14969
  if (depth > 5)
14589
14970
  return null;
@@ -14673,8 +15054,8 @@ class Auditor {
14673
15054
  const missingFiles = [];
14674
15055
  const existingFiles = [];
14675
15056
  for (const filePath of uniqueFiles) {
14676
- const resolved = resolve14(this.baseDir, filePath);
14677
- if (existsSync26(resolved)) {
15057
+ const resolved = resolve16(this.baseDir, filePath);
15058
+ if (existsSync27(resolved)) {
14678
15059
  existingFiles.push(filePath);
14679
15060
  } else {
14680
15061
  missingFiles.push(filePath);
@@ -14753,11 +15134,11 @@ var init_auditor = __esm(() => {
14753
15134
  });
14754
15135
 
14755
15136
  // src/modules/execution/plan-store.ts
14756
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync12, existsSync as existsSync27, readdirSync as readdirSync9, rmSync } from "fs";
15137
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync13, existsSync as existsSync28, readdirSync as readdirSync9, rmSync } from "fs";
14757
15138
  import { join as join22 } from "path";
14758
15139
  function readPlanFile(path, fallbackBaseDir) {
14759
15140
  try {
14760
- const raw = readFileSync14(path, "utf-8");
15141
+ const raw = readFileSync16(path, "utf-8");
14761
15142
  if (!raw.trim())
14762
15143
  return null;
14763
15144
  const parsed = JSON.parse(raw);
@@ -14776,10 +15157,10 @@ function readPlanFile(path, fallbackBaseDir) {
14776
15157
  }
14777
15158
  }
14778
15159
  function writePlanFile(path, plan) {
14779
- writeFileSync8(path, JSON.stringify(plan, null, 2), "utf-8");
15160
+ writeFileSync9(path, JSON.stringify(plan, null, 2), "utf-8");
14780
15161
  }
14781
15162
  function listDir(dir, baseDir) {
14782
- if (!existsSync27(dir))
15163
+ if (!existsSync28(dir))
14783
15164
  return [];
14784
15165
  const files = readdirSync9(dir).filter((f) => f.endsWith(".json"));
14785
15166
  return files.map((f) => readPlanFile(join22(dir, f), baseDir)).filter((p) => p !== null);
@@ -14804,16 +15185,16 @@ class PlanStore {
14804
15185
  legacyPath;
14805
15186
  constructor(baseDir) {
14806
15187
  const mmaDir = join22(baseDir, ".mma");
14807
- if (!existsSync27(mmaDir))
14808
- mkdirSync12(mmaDir, { recursive: true });
15188
+ if (!existsSync28(mmaDir))
15189
+ mkdirSync13(mmaDir, { recursive: true });
14809
15190
  this.baseDir = baseDir;
14810
15191
  this.plansDir = join22(mmaDir, "plans");
14811
15192
  this.draftsDir = join22(this.plansDir, "drafts");
14812
15193
  this.archiveDir = join22(this.plansDir, "archive");
14813
15194
  this.legacyPath = join22(mmaDir, LEGACY_FILE);
14814
15195
  for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
14815
- if (!existsSync27(dir))
14816
- mkdirSync12(dir, { recursive: true });
15196
+ if (!existsSync28(dir))
15197
+ mkdirSync13(dir, { recursive: true });
14817
15198
  }
14818
15199
  }
14819
15200
  activePath() {
@@ -14824,12 +15205,12 @@ class PlanStore {
14824
15205
  }
14825
15206
  loadActive() {
14826
15207
  const activePath = this.activePath();
14827
- if (existsSync27(activePath)) {
15208
+ if (existsSync28(activePath)) {
14828
15209
  const plan = readPlanFile(activePath, this.baseDir);
14829
15210
  if (plan)
14830
15211
  return plan;
14831
15212
  }
14832
- if (existsSync27(this.legacyPath)) {
15213
+ if (existsSync28(this.legacyPath)) {
14833
15214
  const legacy = readPlanFile(this.legacyPath, this.baseDir);
14834
15215
  if (legacy) {
14835
15216
  this.saveActive(legacy);
@@ -14843,7 +15224,7 @@ class PlanStore {
14843
15224
  }
14844
15225
  clearActive() {
14845
15226
  const p = this.activePath();
14846
- if (existsSync27(p))
15227
+ if (existsSync28(p))
14847
15228
  rmSync(p, { force: true });
14848
15229
  }
14849
15230
  saveDraft(plan) {
@@ -14851,11 +15232,11 @@ class PlanStore {
14851
15232
  }
14852
15233
  loadDraft(id) {
14853
15234
  const p = join22(this.draftsDir, `${id}.json`);
14854
- return existsSync27(p) ? readPlanFile(p, this.baseDir) : null;
15235
+ return existsSync28(p) ? readPlanFile(p, this.baseDir) : null;
14855
15236
  }
14856
15237
  removeDraft(id) {
14857
15238
  const p = join22(this.draftsDir, `${id}.json`);
14858
- if (existsSync27(p))
15239
+ if (existsSync28(p))
14859
15240
  rmSync(p, { force: true });
14860
15241
  }
14861
15242
  listDrafts() {
@@ -14874,7 +15255,7 @@ class PlanStore {
14874
15255
  }
14875
15256
  removeArchived(id) {
14876
15257
  const p = join22(this.archiveDir, `${id}.json`);
14877
- if (existsSync27(p))
15258
+ if (existsSync28(p))
14878
15259
  rmSync(p, { force: true });
14879
15260
  }
14880
15261
  listAll() {
@@ -14968,8 +15349,8 @@ var init_plan_coverage = __esm(() => {
14968
15349
  });
14969
15350
 
14970
15351
  // src/modules/execution/module.ts
14971
- import { existsSync as existsSync28, readFileSync as readFileSync15 } from "fs";
14972
- import { resolve as resolve15 } from "path";
15352
+ import { existsSync as existsSync29, readFileSync as readFileSync17 } from "fs";
15353
+ import { resolve as resolve17 } from "path";
14973
15354
 
14974
15355
  class ExecutionModule {
14975
15356
  name = "execution";
@@ -15624,7 +16005,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
15624
16005
  "poetry.lock",
15625
16006
  "requirements.txt"
15626
16007
  ];
15627
- const hasLockFile = lockFiles.some((f) => existsSync28(resolve15(this.baseDir, f)));
16008
+ const hasLockFile = lockFiles.some((f) => existsSync29(resolve17(this.baseDir, f)));
15628
16009
  if (!hasLockFile) {
15629
16010
  if (contextManager) {
15630
16011
  const hints = this.depsGateHints.get(step.id) || 0;
@@ -15644,13 +16025,13 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
15644
16025
  }
15645
16026
  if (stepPaths.length === 0)
15646
16027
  return;
15647
- const allExist = stepPaths.every((p) => existsSync28(resolve15(this.baseDir, p)));
16028
+ const allExist = stepPaths.every((p) => existsSync29(resolve17(this.baseDir, p)));
15648
16029
  if (!allExist)
15649
16030
  return;
15650
16031
  const emptyFiles = [];
15651
16032
  for (const p of stepPaths) {
15652
16033
  try {
15653
- const content = readFileSync15(resolve15(this.baseDir, p), "utf-8");
16034
+ const content = readFileSync17(resolve17(this.baseDir, p), "utf-8");
15654
16035
  if (content.trim().length < 10) {
15655
16036
  emptyFiles.push(p);
15656
16037
  }
@@ -15707,9 +16088,9 @@ var init_module = __esm(() => {
15707
16088
 
15708
16089
  // src/modules/security/session-encryption.ts
15709
16090
  import {
15710
- readFileSync as readFileSync16,
15711
- writeFileSync as writeFileSync9,
15712
- existsSync as existsSync29,
16091
+ readFileSync as readFileSync18,
16092
+ writeFileSync as writeFileSync10,
16093
+ existsSync as existsSync30,
15713
16094
  readdirSync as readdirSync10,
15714
16095
  unlinkSync as unlinkSync4
15715
16096
  } from "fs";
@@ -15767,23 +16148,23 @@ class SessionFileEncryptor {
15767
16148
  return lines.map((line) => this.decryptFileContent(line));
15768
16149
  }
15769
16150
  readSessionFile(filePath) {
15770
- const content = readFileSync16(filePath, "utf8");
16151
+ const content = readFileSync18(filePath, "utf8");
15771
16152
  return this.decryptFileContent(content);
15772
16153
  }
15773
16154
  writeSessionFile(filePath, content) {
15774
16155
  const encrypted = this.encryptFileContent(content);
15775
- writeFileSync9(filePath, encrypted, "utf8");
16156
+ writeFileSync10(filePath, encrypted, "utf8");
15776
16157
  }
15777
16158
  readSessionJSON(filePath) {
15778
- const content = readFileSync16(filePath, "utf8");
16159
+ const content = readFileSync18(filePath, "utf8");
15779
16160
  return this.decryptJSON(content);
15780
16161
  }
15781
16162
  writeSessionJSON(filePath, obj) {
15782
16163
  const content = this.encryptJSON(obj);
15783
- writeFileSync9(filePath, content, "utf8");
16164
+ writeFileSync10(filePath, content, "utf8");
15784
16165
  }
15785
16166
  readSessionJSONL(filePath) {
15786
- const content = readFileSync16(filePath, "utf8");
16167
+ const content = readFileSync18(filePath, "utf8");
15787
16168
  const lines = content.split(`
15788
16169
  `).filter((line) => line.trim());
15789
16170
  const decryptedLines = this.decryptJSONL(lines);
@@ -15797,7 +16178,7 @@ class SessionFileEncryptor {
15797
16178
  }
15798
16179
  appendToSessionJSONL(filePath, obj) {
15799
16180
  const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
15800
- writeFileSync9(filePath, encryptedLine + `
16181
+ writeFileSync10(filePath, encryptedLine + `
15801
16182
  `, {
15802
16183
  flag: "a",
15803
16184
  encoding: "utf8"
@@ -15809,11 +16190,11 @@ class SessionFileEncryptor {
15809
16190
  const files = readdirSync10(sessionDir);
15810
16191
  for (const file of files) {
15811
16192
  const filePath = join23(sessionDir, file);
15812
- if (existsSync29(filePath) && !file.endsWith(".enc")) {
16193
+ if (existsSync30(filePath) && !file.endsWith(".enc")) {
15813
16194
  try {
15814
- const content = readFileSync16(filePath, "utf8");
16195
+ const content = readFileSync18(filePath, "utf8");
15815
16196
  const encrypted = this.encryptFileContent(content);
15816
- writeFileSync9(filePath + ".enc", encrypted, "utf8");
16197
+ writeFileSync10(filePath + ".enc", encrypted, "utf8");
15817
16198
  unlinkSync4(filePath);
15818
16199
  } catch {}
15819
16200
  }
@@ -15828,9 +16209,9 @@ class SessionFileEncryptor {
15828
16209
  const encFilePath = join23(sessionDir, file);
15829
16210
  const decFilePath = encFilePath.slice(0, -4);
15830
16211
  try {
15831
- const content = readFileSync16(encFilePath, "utf8");
16212
+ const content = readFileSync18(encFilePath, "utf8");
15832
16213
  const decrypted = this.decryptFileContent(content);
15833
- writeFileSync9(decFilePath, decrypted, "utf8");
16214
+ writeFileSync10(decFilePath, decrypted, "utf8");
15834
16215
  unlinkSync4(encFilePath);
15835
16216
  } catch {}
15836
16217
  }
@@ -15850,12 +16231,12 @@ var init_session_encryption = __esm(() => {
15850
16231
 
15851
16232
  // src/modules/session/store.ts
15852
16233
  import {
15853
- existsSync as existsSync30,
15854
- mkdirSync as mkdirSync13,
16234
+ existsSync as existsSync31,
16235
+ mkdirSync as mkdirSync14,
15855
16236
  readdirSync as readdirSync11,
15856
- readFileSync as readFileSync17,
16237
+ readFileSync as readFileSync19,
15857
16238
  rmSync as rmSync2,
15858
- writeFileSync as writeFileSync10,
16239
+ writeFileSync as writeFileSync11,
15859
16240
  appendFileSync as appendFileSync6
15860
16241
  } from "fs";
15861
16242
  import { join as join24 } from "path";
@@ -15885,7 +16266,7 @@ class SessionStore {
15885
16266
  return this.encryptor?.isEnabled() ?? false;
15886
16267
  }
15887
16268
  init() {
15888
- mkdirSync13(this.baseDir, { recursive: true });
16269
+ mkdirSync14(this.baseDir, { recursive: true });
15889
16270
  }
15890
16271
  sessionDir(id) {
15891
16272
  return join24(this.baseDir, id);
@@ -15900,17 +16281,17 @@ class SessionStore {
15900
16281
  return join24(this.sessionDir(id), "session.jsonl");
15901
16282
  }
15902
16283
  sessionExists(id) {
15903
- return existsSync30(this.metaPath(id));
16284
+ return existsSync31(this.metaPath(id));
15904
16285
  }
15905
16286
  saveMeta(id, meta) {
15906
16287
  this._metaCache.set(id, meta);
15907
16288
  const dir = this.sessionDir(id);
15908
- mkdirSync13(dir, { recursive: true });
16289
+ mkdirSync14(dir, { recursive: true });
15909
16290
  const content = JSON.stringify(meta, null, 2);
15910
16291
  if (this.encryptor) {
15911
- writeFileSync10(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
16292
+ writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
15912
16293
  } else {
15913
- writeFileSync10(this.metaPath(id), content, "utf-8");
16294
+ writeFileSync11(this.metaPath(id), content, "utf-8");
15914
16295
  }
15915
16296
  }
15916
16297
  loadMeta(id) {
@@ -15918,10 +16299,10 @@ class SessionStore {
15918
16299
  if (cached)
15919
16300
  return cached;
15920
16301
  const path = this.metaPath(id);
15921
- if (!existsSync30(path))
16302
+ if (!existsSync31(path))
15922
16303
  return null;
15923
16304
  try {
15924
- const raw = readFileSync17(path, "utf-8");
16305
+ const raw = readFileSync19(path, "utf-8");
15925
16306
  const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
15926
16307
  const meta = JSON.parse(content);
15927
16308
  this._metaCache.set(id, meta);
@@ -15932,7 +16313,7 @@ class SessionStore {
15932
16313
  }
15933
16314
  appendMessage(id, msg) {
15934
16315
  const dir = this.sessionDir(id);
15935
- mkdirSync13(dir, { recursive: true });
16316
+ mkdirSync14(dir, { recursive: true });
15936
16317
  const line = JSON.stringify(msg);
15937
16318
  if (this.encryptor?.isEnabled()) {
15938
16319
  appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
@@ -15950,10 +16331,10 @@ class SessionStore {
15950
16331
  }
15951
16332
  loadHistory(id) {
15952
16333
  const path = this.historyPath(id);
15953
- if (!existsSync30(path))
16334
+ if (!existsSync31(path))
15954
16335
  return [];
15955
16336
  try {
15956
- const raw = readFileSync17(path, "utf-8");
16337
+ const raw = readFileSync19(path, "utf-8");
15957
16338
  const lines = raw.split(`
15958
16339
  `).filter(Boolean);
15959
16340
  const parseLine = (line) => {
@@ -15979,7 +16360,7 @@ class SessionStore {
15979
16360
  }
15980
16361
  appendSessionLog(id, entry) {
15981
16362
  const dir = this.sessionDir(id);
15982
- mkdirSync13(dir, { recursive: true });
16363
+ mkdirSync14(dir, { recursive: true });
15983
16364
  const line = JSON.stringify(entry);
15984
16365
  if (this.encryptor?.isEnabled()) {
15985
16366
  appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
@@ -15991,10 +16372,10 @@ class SessionStore {
15991
16372
  }
15992
16373
  loadSessionLog(id) {
15993
16374
  const path = this.sessionLogPath(id);
15994
- if (!existsSync30(path))
16375
+ if (!existsSync31(path))
15995
16376
  return [];
15996
16377
  try {
15997
- const raw = readFileSync17(path, "utf-8");
16378
+ const raw = readFileSync19(path, "utf-8");
15998
16379
  const lines = raw.split(`
15999
16380
  `).filter(Boolean);
16000
16381
  const parseLine = (line) => {
@@ -16019,7 +16400,7 @@ class SessionStore {
16019
16400
  }
16020
16401
  }
16021
16402
  listSessions() {
16022
- if (!existsSync30(this.baseDir))
16403
+ if (!existsSync31(this.baseDir))
16023
16404
  return [];
16024
16405
  const entries = readdirSync11(this.baseDir, { withFileTypes: true });
16025
16406
  const sessions = [];
@@ -16036,7 +16417,7 @@ class SessionStore {
16036
16417
  deleteSession(id) {
16037
16418
  this._metaCache.delete(id);
16038
16419
  const dir = this.sessionDir(id);
16039
- if (existsSync30(dir)) {
16420
+ if (existsSync31(dir)) {
16040
16421
  rmSync2(dir, { recursive: true, force: true });
16041
16422
  }
16042
16423
  }
@@ -16048,18 +16429,18 @@ class SessionStore {
16048
16429
  const updatedAt = new Date(session2.updatedAt);
16049
16430
  if (updatedAt < thirtyDaysAgo) {
16050
16431
  const historyPath = this.historyPath(session2.id);
16051
- if (existsSync30(historyPath)) {
16052
- const content = readFileSync17(historyPath, "utf-8");
16432
+ if (existsSync31(historyPath)) {
16433
+ const content = readFileSync19(historyPath, "utf-8");
16053
16434
  const compressed = gzipSync(content);
16054
16435
  const gzPath = join24(this.baseDir, `${session2.id}.jsonl.gz`);
16055
- writeFileSync10(gzPath, compressed);
16436
+ writeFileSync11(gzPath, compressed);
16056
16437
  rmSync2(historyPath);
16057
16438
  }
16058
16439
  }
16059
16440
  }
16060
16441
  }
16061
16442
  }
16062
- var init_store2 = __esm(() => {
16443
+ var init_store3 = __esm(() => {
16063
16444
  init_session_encryption();
16064
16445
  });
16065
16446
 
@@ -16239,7 +16620,7 @@ var init_module2 = __esm(() => {
16239
16620
 
16240
16621
  // src/modules/session/index.ts
16241
16622
  var init_session2 = __esm(() => {
16242
- init_store2();
16623
+ init_store3();
16243
16624
  init_manager2();
16244
16625
  init_module2();
16245
16626
  });
@@ -16261,7 +16642,7 @@ class ProfileCompressor {
16261
16642
  }
16262
16643
 
16263
16644
  // src/modules/user-profile/profile.ts
16264
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync31, mkdirSync as mkdirSync14 } from "fs";
16645
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync12, existsSync as existsSync32, mkdirSync as mkdirSync15 } from "fs";
16265
16646
  import { join as join25 } from "path";
16266
16647
  import { homedir as homedir9, hostname, platform as platform4, type } from "os";
16267
16648
  import { env } from "process";
@@ -16286,17 +16667,17 @@ class UserProfile {
16286
16667
  return this.info;
16287
16668
  }
16288
16669
  save() {
16289
- if (!existsSync31(this.profileDir)) {
16290
- mkdirSync14(this.profileDir, { recursive: true });
16670
+ if (!existsSync32(this.profileDir)) {
16671
+ mkdirSync15(this.profileDir, { recursive: true });
16291
16672
  }
16292
- writeFileSync11(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
16673
+ writeFileSync12(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
16293
16674
  }
16294
16675
  load() {
16295
16676
  const path = join25(this.profileDir, "profile.json");
16296
- if (!existsSync31(path))
16677
+ if (!existsSync32(path))
16297
16678
  return null;
16298
16679
  try {
16299
- const data = JSON.parse(readFileSync18(path, "utf-8"));
16680
+ const data = JSON.parse(readFileSync20(path, "utf-8"));
16300
16681
  this.info = {
16301
16682
  platform: data.platform,
16302
16683
  os: data.os,
@@ -16331,12 +16712,12 @@ class UserProfile {
16331
16712
  var init_profile = () => {};
16332
16713
 
16333
16714
  // src/modules/skills/loader.ts
16334
- import { readdirSync as readdirSync12, readFileSync as readFileSync19, existsSync as existsSync32, statSync as statSync6 } from "fs";
16715
+ import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync33, statSync as statSync6 } from "fs";
16335
16716
  import { join as join26 } from "path";
16336
16717
 
16337
16718
  class SkillsLoader {
16338
16719
  loadFromDir(dirPath) {
16339
- if (!existsSync32(dirPath))
16720
+ if (!existsSync33(dirPath))
16340
16721
  return [];
16341
16722
  const skills = [];
16342
16723
  this.scanDir(dirPath, skills);
@@ -16353,7 +16734,7 @@ class SkillsLoader {
16353
16734
  }
16354
16735
  if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
16355
16736
  continue;
16356
- const content = readFileSync19(fullPath, "utf-8");
16737
+ const content = readFileSync21(fullPath, "utf-8");
16357
16738
  const parsed = this.parseSkillFile(content, fullPath);
16358
16739
  if (parsed)
16359
16740
  skills.push(parsed);
@@ -16587,7 +16968,7 @@ var init_browser2 = __esm(() => {
16587
16968
 
16588
16969
  // src/modules/lsp/client.ts
16589
16970
  import { spawn as spawn5, execSync as execSync2 } from "child_process";
16590
- import { resolve as resolve16 } from "path";
16971
+ import { resolve as resolve18 } from "path";
16591
16972
 
16592
16973
  class LspClient {
16593
16974
  process = null;
@@ -16603,7 +16984,7 @@ class LspClient {
16603
16984
  const timeout = config.timeout ?? DEFAULT_TIMEOUT;
16604
16985
  try {
16605
16986
  await this.startServer(config, baseDir);
16606
- const rootUri = this.pathToUri(resolve16(baseDir));
16987
+ const rootUri = this.pathToUri(resolve18(baseDir));
16607
16988
  const initResult = await this.sendRequest("initialize", {
16608
16989
  processId: process.pid,
16609
16990
  rootUri,
@@ -16612,11 +16993,11 @@ class LspClient {
16612
16993
  }, timeout);
16613
16994
  this.initialized = true;
16614
16995
  this.sendNotification("initialized", {});
16615
- const uri = this.pathToUri(resolve16(filePath));
16996
+ const uri = this.pathToUri(resolve18(filePath));
16616
16997
  const fs2 = await import("fs");
16617
16998
  const content = fs2.readFileSync(filePath, "utf-8");
16618
- const diagPromise = new Promise((resolve17) => {
16619
- this.diagnosticsResolve = resolve17;
16999
+ const diagPromise = new Promise((resolve19) => {
17000
+ this.diagnosticsResolve = resolve19;
16620
17001
  this.diagnostics = [];
16621
17002
  this.diagnosticsTimer = setTimeout(() => {
16622
17003
  if (this.diagnosticsResolve) {
@@ -16648,7 +17029,7 @@ class LspClient {
16648
17029
  throw new Error(`${config.command} not found in PATH`);
16649
17030
  }
16650
17031
  }
16651
- return new Promise((resolve17, reject) => {
17032
+ return new Promise((resolve19, reject) => {
16652
17033
  const args = config.args ?? [];
16653
17034
  const proc = spawn5(config.command, args, {
16654
17035
  stdio: ["pipe", "pipe", "pipe"],
@@ -16661,7 +17042,7 @@ class LspClient {
16661
17042
  });
16662
17043
  proc.stderr.on("data", () => {});
16663
17044
  proc.once("spawn", () => {
16664
- resolve17();
17045
+ resolve19();
16665
17046
  });
16666
17047
  this.process = proc;
16667
17048
  setTimeout(() => {
@@ -16738,9 +17119,9 @@ class LspClient {
16738
17119
  }
16739
17120
  }
16740
17121
  sendRequest(method, params, timeout) {
16741
- return new Promise((resolve17, reject) => {
17122
+ return new Promise((resolve19, reject) => {
16742
17123
  const id = ++this.requestId;
16743
- this.pending.set(id, { resolve: resolve17, reject });
17124
+ this.pending.set(id, { resolve: resolve19, reject });
16744
17125
  const message = JSON.stringify({ jsonrpc: "2.0", id, method, params });
16745
17126
  this.write(message);
16746
17127
  setTimeout(() => {
@@ -16818,8 +17199,8 @@ var DEFAULT_TIMEOUT = 15000;
16818
17199
  var init_client2 = () => {};
16819
17200
 
16820
17201
  // src/modules/lsp/module.ts
16821
- import { existsSync as existsSync33 } from "fs";
16822
- import { resolve as resolve17 } from "path";
17202
+ import { existsSync as existsSync34 } from "fs";
17203
+ import { resolve as resolve19 } from "path";
16823
17204
 
16824
17205
  class LspModule {
16825
17206
  name = "lsp";
@@ -16843,8 +17224,8 @@ class LspModule {
16843
17224
  const filePath = String(call.arguments.path ?? "");
16844
17225
  if (!filePath)
16845
17226
  return;
16846
- const fullPath = resolve17(_ctx.baseDir, filePath);
16847
- if (!existsSync33(fullPath))
17227
+ const fullPath = resolve19(_ctx.baseDir, filePath);
17228
+ if (!existsSync34(fullPath))
16848
17229
  return;
16849
17230
  const serverConfig = getServerForFile(fullPath, self.config);
16850
17231
  if (!serverConfig)
@@ -16902,8 +17283,8 @@ var init_lsp = __esm(() => {
16902
17283
  });
16903
17284
 
16904
17285
  // src/modules/indexer/walker.ts
16905
- import { readdirSync as readdirSync13, readFileSync as readFileSync20, statSync as statSync7, existsSync as existsSync34, watch } from "fs";
16906
- import { join as join27, relative, extname as extname5 } from "path";
17286
+ import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync35, watch } from "fs";
17287
+ import { join as join27, relative as relative2, extname as extname5 } from "path";
16907
17288
 
16908
17289
  class Indexer {
16909
17290
  baseDir;
@@ -16930,7 +17311,7 @@ class Indexer {
16930
17311
  let totalSize = 0;
16931
17312
  let count = 0;
16932
17313
  const walkDir = (dir) => {
16933
- if (!existsSync34(dir))
17314
+ if (!existsSync35(dir))
16934
17315
  return;
16935
17316
  let entries;
16936
17317
  try {
@@ -16942,7 +17323,7 @@ class Indexer {
16942
17323
  if (count >= this.MAX_FILES)
16943
17324
  return;
16944
17325
  const fullPath = join27(dir, entry);
16945
- const relPath = relative(this.baseDir, fullPath);
17326
+ const relPath = relative2(this.baseDir, fullPath);
16946
17327
  const stat = statSync7(fullPath);
16947
17328
  if (stat.isDirectory()) {
16948
17329
  if (!IGNORE_DIRS.has(entry)) {
@@ -16952,7 +17333,7 @@ class Indexer {
16952
17333
  const ext = extname5(entry).toLowerCase();
16953
17334
  const language = LANGUAGES[ext];
16954
17335
  if (language) {
16955
- const content = readFileSync20(fullPath, "utf-8");
17336
+ const content = readFileSync22(fullPath, "utf-8");
16956
17337
  const exports = this.extractExports(content, language);
16957
17338
  files.push({ path: relPath, language, exports, size: stat.size });
16958
17339
  totalSize += stat.size;
@@ -17004,7 +17385,7 @@ var init_walker = __esm(() => {
17004
17385
  });
17005
17386
 
17006
17387
  // src/modules/indexer/cache.ts
17007
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, existsSync as existsSync35, mkdirSync as mkdirSync15, rmSync as rmSync3 } from "fs";
17388
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync13, existsSync as existsSync36, mkdirSync as mkdirSync16, rmSync as rmSync3 } from "fs";
17008
17389
  import { join as join28 } from "path";
17009
17390
 
17010
17391
  class IndexCache {
@@ -17016,10 +17397,10 @@ class IndexCache {
17016
17397
  load() {
17017
17398
  if (this.cache)
17018
17399
  return this.cache;
17019
- if (!existsSync35(this.cachePath))
17400
+ if (!existsSync36(this.cachePath))
17020
17401
  return null;
17021
17402
  try {
17022
- this.cache = JSON.parse(readFileSync21(this.cachePath, "utf-8"));
17403
+ this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
17023
17404
  return this.cache;
17024
17405
  } catch {
17025
17406
  return null;
@@ -17028,13 +17409,13 @@ class IndexCache {
17028
17409
  save(result) {
17029
17410
  this.cache = result;
17030
17411
  const dir = join28(this.cachePath, "..");
17031
- if (!existsSync35(dir))
17032
- mkdirSync15(dir, { recursive: true });
17033
- writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
17412
+ if (!existsSync36(dir))
17413
+ mkdirSync16(dir, { recursive: true });
17414
+ writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
17034
17415
  }
17035
17416
  invalidate() {
17036
17417
  this.cache = null;
17037
- if (existsSync35(this.cachePath)) {
17418
+ if (existsSync36(this.cachePath)) {
17038
17419
  try {
17039
17420
  rmSync3(this.cachePath);
17040
17421
  } catch {}
@@ -17434,7 +17815,7 @@ class MemoryModule {
17434
17815
  }
17435
17816
  }
17436
17817
  var init_module8 = __esm(() => {
17437
- init_store();
17818
+ init_store2();
17438
17819
  init_remember();
17439
17820
  init_recall();
17440
17821
  });
@@ -17446,8 +17827,8 @@ __export(exports_bootstrap, {
17446
17827
  bootstrap: () => bootstrap
17447
17828
  });
17448
17829
  import { homedir as homedir11 } from "os";
17449
- import { join as join30, resolve as resolve18 } from "path";
17450
- import { existsSync as existsSync36, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
17830
+ import { join as join30, resolve as resolve20 } from "path";
17831
+ import { existsSync as existsSync37, readFileSync as readFileSync24, writeFileSync as writeFileSync14 } from "fs";
17451
17832
  function buildSystemInfo(config, baseDir, profileCompressed) {
17452
17833
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
17453
17834
  const isWin = profileCompressed.toLowerCase().includes("win32");
@@ -17516,7 +17897,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17516
17897
  retry: config.retry,
17517
17898
  rateLimits: config.security?.rateLimits
17518
17899
  });
17519
- const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
17900
+ const baseDir = projectDir ? resolve20(projectDir) : process.cwd();
17520
17901
  const projectMapCacheDir = join30(baseDir, ".mma");
17521
17902
  const indexerModule = new IndexerModule({
17522
17903
  baseDir,
@@ -17545,8 +17926,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17545
17926
  estimatedTokens: Math.ceil(systemInfoContent.length / 4)
17546
17927
  };
17547
17928
  const agentsMdGlobal = join30(dir, "AGENTS.md");
17548
- if (!existsSync36(agentsMdGlobal)) {
17549
- writeFileSync13(agentsMdGlobal, "", "utf-8");
17929
+ if (!existsSync37(agentsMdGlobal)) {
17930
+ writeFileSync14(agentsMdGlobal, "", "utf-8");
17550
17931
  }
17551
17932
  const sessionDir = join30(dir, "sessions");
17552
17933
  const sessionStore = new SessionStore(sessionDir);
@@ -17689,8 +18070,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17689
18070
  join30(dir, "AGENTS.md")
17690
18071
  ];
17691
18072
  for (const p of agentsMdCandidates) {
17692
- if (existsSync36(p)) {
17693
- const content = readFileSync22(p, "utf-8").trim();
18073
+ if (existsSync37(p)) {
18074
+ const content = readFileSync24(p, "utf-8").trim();
17694
18075
  if (content) {
17695
18076
  agentsMdBlocks.push({
17696
18077
  content,
@@ -18317,10 +18698,10 @@ function menuList(items) {
18317
18698
  console.log(l);
18318
18699
  }
18319
18700
  function ask(rl, question, defaultValue) {
18320
- return new Promise((resolve19) => {
18701
+ return new Promise((resolve21) => {
18321
18702
  const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
18322
18703
  rl.question(prompt, (answer) => {
18323
- resolve19(answer.trim() || defaultValue || "");
18704
+ resolve21(answer.trim() || defaultValue || "");
18324
18705
  });
18325
18706
  });
18326
18707
  }
@@ -18539,21 +18920,21 @@ __export(exports_manifest, {
18539
18920
  getCertMark: () => getCertMark,
18540
18921
  MANIFEST_PATH: () => MANIFEST_PATH
18541
18922
  });
18542
- import { existsSync as existsSync37, readFileSync as readFileSync23, mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
18923
+ import { existsSync as existsSync38, readFileSync as readFileSync25, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
18543
18924
  import { homedir as homedir13 } from "os";
18544
18925
  import { join as join32 } from "path";
18545
18926
  function readManifest(path = MANIFEST_PATH) {
18546
18927
  try {
18547
- if (existsSync37(path)) {
18548
- const raw = JSON.parse(readFileSync23(path, "utf-8"));
18928
+ if (existsSync38(path)) {
18929
+ const raw = JSON.parse(readFileSync25(path, "utf-8"));
18549
18930
  return { version: 1, certifications: raw.certifications ?? [] };
18550
18931
  }
18551
18932
  } catch {}
18552
18933
  return { version: 1, certifications: [] };
18553
18934
  }
18554
18935
  function saveManifest(m, path = MANIFEST_PATH) {
18555
- mkdirSync16(join32(homedir13(), ".mma"), { recursive: true });
18556
- writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
18936
+ mkdirSync17(join32(homedir13(), ".mma"), { recursive: true });
18937
+ writeFileSync15(path, JSON.stringify(m, null, 2), "utf-8");
18557
18938
  }
18558
18939
  function upsertCertification(entry, path = MANIFEST_PATH) {
18559
18940
  const m = readManifest(path);
@@ -25710,7 +26091,7 @@ var init_scenarios = __esm(() => {
25710
26091
  });
25711
26092
 
25712
26093
  // src/modules/certification/loader.ts
25713
- import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync24 } from "fs";
26094
+ import { existsSync as existsSync39, readdirSync as readdirSync14, readFileSync as readFileSync26 } from "fs";
25714
26095
  import { join as join33 } from "path";
25715
26096
  function validateScenario(s) {
25716
26097
  const errors2 = [];
@@ -25760,12 +26141,12 @@ function loadScenarios(userDir) {
25760
26141
  else
25761
26142
  scenarios.push(s);
25762
26143
  }
25763
- if (userDir && existsSync38(userDir)) {
26144
+ if (userDir && existsSync39(userDir)) {
25764
26145
  for (const file of readdirSync14(userDir)) {
25765
26146
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
25766
26147
  continue;
25767
26148
  try {
25768
- const raw = readFileSync24(join33(userDir, file), "utf-8");
26149
+ const raw = readFileSync26(join33(userDir, file), "utf-8");
25769
26150
  const data = $parse(raw);
25770
26151
  const parsed = normalizeScenario(data, file);
25771
26152
  const errs = validateScenario(parsed);
@@ -25818,7 +26199,7 @@ var init_loader3 = __esm(() => {
25818
26199
  });
25819
26200
 
25820
26201
  // src/modules/certification/fact-checker.ts
25821
- import { existsSync as existsSync39, readFileSync as readFileSync25, statSync as statSync8 } from "fs";
26202
+ import { existsSync as existsSync40, readFileSync as readFileSync27, statSync as statSync8 } from "fs";
25822
26203
  import { join as join34 } from "path";
25823
26204
  function checkSandbox(sandboxDir, checks, exitCode, output) {
25824
26205
  const failures = [];
@@ -25838,14 +26219,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
25838
26219
  case "fileExists":
25839
26220
  return isFile(join34(sandboxDir, check.path));
25840
26221
  case "fileNotExists":
25841
- return !existsSync39(join34(sandboxDir, check.path));
26222
+ return !existsSync40(join34(sandboxDir, check.path));
25842
26223
  case "dirExists":
25843
26224
  return isDir(join34(sandboxDir, check.path));
25844
26225
  case "fileContent": {
25845
26226
  const abs = join34(sandboxDir, check.path);
25846
26227
  if (!isFile(abs))
25847
26228
  return false;
25848
- const content = readFileSync25(abs, "utf-8");
26229
+ const content = readFileSync27(abs, "utf-8");
25849
26230
  if (check.contains !== undefined)
25850
26231
  return content.includes(check.contains);
25851
26232
  if (check.equals !== undefined)
@@ -25856,7 +26237,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
25856
26237
  const abs = join34(sandboxDir, check.path);
25857
26238
  if (!isFile(abs))
25858
26239
  return false;
25859
- return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
26240
+ return new RegExp(check.pattern).test(readFileSync27(abs, "utf-8"));
25860
26241
  }
25861
26242
  default:
25862
26243
  return false;
@@ -25864,14 +26245,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
25864
26245
  }
25865
26246
  function isFile(p) {
25866
26247
  try {
25867
- return existsSync39(p) && statSync8(p).isFile();
26248
+ return existsSync40(p) && statSync8(p).isFile();
25868
26249
  } catch {
25869
26250
  return false;
25870
26251
  }
25871
26252
  }
25872
26253
  function isDir(p) {
25873
26254
  try {
25874
- return existsSync39(p) && statSync8(p).isDirectory();
26255
+ return existsSync40(p) && statSync8(p).isDirectory();
25875
26256
  } catch {
25876
26257
  return false;
25877
26258
  }
@@ -25902,9 +26283,9 @@ var init_fact_checker = () => {};
25902
26283
 
25903
26284
  // src/modules/certification/runner.ts
25904
26285
  import { spawn as spawn6 } from "child_process";
25905
- import { existsSync as existsSync40, mkdirSync as mkdirSync17, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
26286
+ import { existsSync as existsSync41, mkdirSync as mkdirSync18, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
25906
26287
  import { platform as platform5 } from "os";
25907
- import { join as join35, resolve as resolve19, dirname as dirname8 } from "path";
26288
+ import { join as join35, resolve as resolve21, dirname as dirname8 } from "path";
25908
26289
  async function runScenario(scenario, opts) {
25909
26290
  if (scenario.mode === "skip") {
25910
26291
  return {
@@ -25982,30 +26363,30 @@ ${res.stderr}`;
25982
26363
  }
25983
26364
  function prepareSandbox(sandbox, scenario, mmaRoot) {
25984
26365
  rmSync4(sandbox, { recursive: true, force: true });
25985
- mkdirSync17(sandbox, { recursive: true });
26366
+ mkdirSync18(sandbox, { recursive: true });
25986
26367
  for (const f of scenario.fixtures ?? []) {
25987
26368
  const src = join35(mmaRoot, f.source);
25988
- if (!existsSync40(src)) {
26369
+ if (!existsSync41(src)) {
25989
26370
  throw new Error(`fixture missing: ${f.source}`);
25990
26371
  }
25991
26372
  const dest = join35(sandbox, f.dest);
25992
- mkdirSync17(dirname8(dest), { recursive: true });
26373
+ mkdirSync18(dirname8(dest), { recursive: true });
25993
26374
  cpSync2(src, dest);
25994
26375
  }
25995
26376
  }
25996
26377
  function resolveMmaEntry(mmaRoot) {
25997
26378
  const dev = join35(mmaRoot, "src", "cli", "main.ts");
25998
- if (existsSync40(dev))
26379
+ if (existsSync41(dev))
25999
26380
  return dev;
26000
26381
  return join35(mmaRoot, "dist", "main.js");
26001
26382
  }
26002
26383
  function findMmaRoot(fromDir) {
26003
26384
  const candidates = [
26004
- resolve19(fromDir, "..", "..", ".."),
26005
- resolve19(fromDir, "..")
26385
+ resolve21(fromDir, "..", "..", ".."),
26386
+ resolve21(fromDir, "..")
26006
26387
  ];
26007
26388
  for (const c of candidates) {
26008
- if (existsSync40(join35(c, "package.json")))
26389
+ if (existsSync41(join35(c, "package.json")))
26009
26390
  return c;
26010
26391
  }
26011
26392
  return process.cwd();
@@ -26075,13 +26456,13 @@ import { rmSync as rmSync5 } from "fs";
26075
26456
  import { homedir as homedir14 } from "os";
26076
26457
  import { join as join36, dirname as dirname9 } from "path";
26077
26458
  import { fileURLToPath } from "url";
26078
- import { existsSync as existsSync41, readFileSync as readFileSync26 } from "fs";
26459
+ import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
26079
26460
  function readVersion() {
26080
26461
  const candidates = [join36(MMA_ROOT, "package.json")];
26081
26462
  for (const p of candidates) {
26082
- if (existsSync41(p)) {
26463
+ if (existsSync42(p)) {
26083
26464
  try {
26084
- const raw = JSON.parse(readFileSync26(p, "utf-8"));
26465
+ const raw = JSON.parse(readFileSync28(p, "utf-8"));
26085
26466
  if (raw.version)
26086
26467
  return raw.version;
26087
26468
  } catch {}
@@ -26242,7 +26623,7 @@ __export(exports_repl_commands, {
26242
26623
  });
26243
26624
  import { join as join38, dirname as dirname11 } from "path";
26244
26625
  import { homedir as homedir16 } from "os";
26245
- import { existsSync as existsSync43, readFileSync as readFileSync28 } from "fs";
26626
+ import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
26246
26627
  import { fileURLToPath as fileURLToPath3 } from "url";
26247
26628
  function readVersion3() {
26248
26629
  const here = dirname11(fileURLToPath3(import.meta.url));
@@ -26251,9 +26632,9 @@ function readVersion3() {
26251
26632
  join38(here, "..", "package.json")
26252
26633
  ];
26253
26634
  for (const p of candidates) {
26254
- if (existsSync43(p)) {
26635
+ if (existsSync44(p)) {
26255
26636
  try {
26256
- const raw = JSON.parse(readFileSync28(p, "utf8"));
26637
+ const raw = JSON.parse(readFileSync30(p, "utf8"));
26257
26638
  if (raw.version)
26258
26639
  return raw.version;
26259
26640
  } catch {}
@@ -26317,8 +26698,8 @@ function registerMmaCommands(ctx) {
26317
26698
  }
26318
26699
  try {
26319
26700
  const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
26320
- const { existsSync: existsSync44 } = await import("fs");
26321
- const { resolve: resolve20 } = await import("path");
26701
+ const { existsSync: existsSync45 } = await import("fs");
26702
+ const { resolve: resolve22 } = await import("path");
26322
26703
  let dataUrl;
26323
26704
  let label;
26324
26705
  if (source.toLowerCase() === "clipboard") {
@@ -26336,8 +26717,8 @@ function registerMmaCommands(ctx) {
26336
26717
  dataUrl = result.dataUrl;
26337
26718
  label = source;
26338
26719
  } else {
26339
- const absPath = resolve20(process.cwd(), source);
26340
- if (!existsSync44(absPath)) {
26720
+ const absPath = resolve22(process.cwd(), source);
26721
+ if (!existsSync45(absPath)) {
26341
26722
  console.log(pc2.red(t("image.not_found", { path: source })));
26342
26723
  return;
26343
26724
  }
@@ -26875,7 +27256,7 @@ init_setup();
26875
27256
  init_i18n();
26876
27257
  import { join as join37, dirname as dirname10 } from "path";
26877
27258
  import { homedir as homedir15 } from "os";
26878
- import { existsSync as existsSync42, readFileSync as readFileSync27 } from "fs";
27259
+ import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
26879
27260
 
26880
27261
  // src/cli/security-commands.ts
26881
27262
  init_bootstrap();
@@ -27503,9 +27884,9 @@ function readVersion2() {
27503
27884
  join37(here, "..", "package.json")
27504
27885
  ];
27505
27886
  for (const p of candidates) {
27506
- if (existsSync42(p)) {
27887
+ if (existsSync43(p)) {
27507
27888
  try {
27508
- const raw = JSON.parse(readFileSync27(p, "utf8"));
27889
+ const raw = JSON.parse(readFileSync29(p, "utf8"));
27509
27890
  if (raw.version)
27510
27891
  return raw.version;
27511
27892
  } catch {}
@@ -27732,7 +28113,7 @@ init_bootstrap();
27732
28113
  // src/cli/repl.ts
27733
28114
  init_colors();
27734
28115
  import * as readline2 from "readline";
27735
- import { existsSync as existsSync44, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
28116
+ import { existsSync as existsSync45, readFileSync as readFileSync31, writeFileSync as writeFileSync16 } from "fs";
27736
28117
  import { join as join39, dirname as dirname12 } from "path";
27737
28118
  import { homedir as homedir17 } from "os";
27738
28119
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -28251,9 +28632,9 @@ function readVersion4() {
28251
28632
  join39(here, "..", "package.json")
28252
28633
  ];
28253
28634
  for (const p of candidates) {
28254
- if (existsSync44(p)) {
28635
+ if (existsSync45(p)) {
28255
28636
  try {
28256
- const raw = JSON.parse(readFileSync29(p, "utf8"));
28637
+ const raw = JSON.parse(readFileSync31(p, "utf8"));
28257
28638
  if (raw.version)
28258
28639
  return raw.version;
28259
28640
  } catch {}
@@ -28331,9 +28712,9 @@ class Repl {
28331
28712
  this.setupListeners();
28332
28713
  }
28333
28714
  loadHistory() {
28334
- if (existsSync44(this.historyPath)) {
28715
+ if (existsSync45(this.historyPath)) {
28335
28716
  try {
28336
- const raw = readFileSync29(this.historyPath, "utf-8");
28717
+ const raw = readFileSync31(this.historyPath, "utf-8");
28337
28718
  this.history = raw.split(`
28338
28719
  `).filter(Boolean).slice(-this.maxHistory);
28339
28720
  } catch {
@@ -28343,7 +28724,7 @@ class Repl {
28343
28724
  }
28344
28725
  saveHistory() {
28345
28726
  const allHistory = this.history.slice(-this.maxHistory);
28346
- writeFileSync15(this.historyPath, allHistory.join(`
28727
+ writeFileSync16(this.historyPath, allHistory.join(`
28347
28728
  `), "utf-8");
28348
28729
  }
28349
28730
  setupCompleter() {
@@ -28668,7 +29049,7 @@ ${t("image.clipboard_empty")}`));
28668
29049
  join39(this.baseDir, ".mma", "AGENTS.md"),
28669
29050
  join39(this.configDir, "AGENTS.md")
28670
29051
  ];
28671
- const foundAgents = agentsMdCandidates.filter((p) => existsSync44(p));
29052
+ const foundAgents = agentsMdCandidates.filter((p) => existsSync45(p));
28672
29053
  if (foundAgents.length > 0) {
28673
29054
  for (const p of foundAgents) {
28674
29055
  row(t("repl.agents_label"), pc2.dim(p));
@@ -28705,7 +29086,7 @@ init_setup();
28705
29086
  init_config2();
28706
29087
  init_i18n();
28707
29088
  init_colors();
28708
- import { existsSync as existsSync45 } from "fs";
29089
+ import { existsSync as existsSync46 } from "fs";
28709
29090
  import { join as join40 } from "path";
28710
29091
  import { homedir as homedir18 } from "os";
28711
29092
  async function main() {
@@ -28774,7 +29155,7 @@ async function main() {
28774
29155
  agent.shutdown();
28775
29156
  } else {
28776
29157
  const configPath = join40(homedir18(), ".mma", "config.json");
28777
- if (!existsSync45(configPath)) {
29158
+ if (!existsSync46(configPath)) {
28778
29159
  console.log(pc2.yellow(`
28779
29160
  ` + t("cli.first_run") + `
28780
29161
  `));