micro-models-agent 0.28.17 → 0.29.1

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 +625 -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,229 @@ 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
+ import { resolve as resolve14 } from "node:path";
12123
+ var chunkQueryTool;
12124
+ var init_chunk_query = __esm(() => {
12125
+ init_i18n();
12126
+ init_scope_check();
12127
+ chunkQueryTool = {
12128
+ name: "chunk_query",
12129
+ 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.",
12130
+ tags: ["research", "code"],
12131
+ timeoutMs: 300000,
12132
+ parameters: {
12133
+ type: "object",
12134
+ properties: {
12135
+ query: {
12136
+ type: "string",
12137
+ description: "The question to answer over the text."
12138
+ },
12139
+ input_path: {
12140
+ type: "string",
12141
+ description: "Path to the large text file (scope-checked). Preferred over text."
12142
+ },
12143
+ text: {
12144
+ type: "string",
12145
+ description: "Inline text. Use only when a file path is not available."
12146
+ },
12147
+ chunk_chars: {
12148
+ type: "number",
12149
+ description: "Approximate chunk size in chars (default 12000)."
12150
+ },
12151
+ max_parallel: {
12152
+ type: "number",
12153
+ description: "Max parallel chunk queries (default from config.subagent.maxParallelChunkQueries)."
12154
+ },
12155
+ max_chunk_tokens: {
12156
+ type: "number",
12157
+ description: "Cap on generated tokens per chunk call (default 1024)."
12158
+ },
12159
+ max_synthesis_tokens: {
12160
+ type: "number",
12161
+ description: "Cap on generated tokens for the synthesis call (default 2048)."
12162
+ },
12163
+ reasoning_effort: {
12164
+ type: "string",
12165
+ enum: ["none", "low", "medium", "high"],
12166
+ description: 'Reasoning effort for chunk/synthesis calls (default "none"). "none" prevents long thinking chains from eating the token budget on reasoning models.'
12167
+ },
12168
+ synthesize: {
12169
+ type: "boolean",
12170
+ description: "Run a final synthesis call over chunk answers (default true)."
12171
+ }
12172
+ },
12173
+ required: ["query"]
12174
+ },
12175
+ handler: async (ctx, args) => {
12176
+ const query = String(args.query || "");
12177
+ const inputPath = args.input_path ? String(args.input_path) : undefined;
12178
+ const text = args.text ? String(args.text) : undefined;
12179
+ if (!query)
12180
+ return { success: false, output: t("tool.chunk_query_no_query") };
12181
+ if (!inputPath && !text)
12182
+ return { success: false, output: t("tool.chunk_query_no_input") };
12183
+ let content = text || "";
12184
+ if (inputPath) {
12185
+ const check = isPathInScope2(ctx.baseDir, inputPath, ctx.scope);
12186
+ if (!check.allowed) {
12187
+ return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
12188
+ }
12189
+ try {
12190
+ content = readFileSync12(resolve14(ctx.baseDir, inputPath), "utf8");
12191
+ } catch (e) {
12192
+ return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
12193
+ }
12194
+ }
12195
+ if (!ctx.llmProvider) {
12196
+ return { success: false, output: "chunk_query: missing llmProvider in context" };
12197
+ }
12198
+ const maxParallel = typeof args.max_parallel === "number" ? args.max_parallel : ctx.config.subagent?.maxParallelChunkQueries ?? 4;
12199
+ const res = await runChunkQuery(ctx.llmProvider, content, query, {
12200
+ chunkChars: typeof args.chunk_chars === "number" ? args.chunk_chars : undefined,
12201
+ maxParallel,
12202
+ synthesize: typeof args.synthesize === "boolean" ? args.synthesize : undefined,
12203
+ maxChunkTokens: typeof args.max_chunk_tokens === "number" ? args.max_chunk_tokens : undefined,
12204
+ maxSynthesisTokens: typeof args.max_synthesis_tokens === "number" ? args.max_synthesis_tokens : undefined,
12205
+ reasoningEffort: ["none", "low", "medium", "high"].includes(args.reasoning_effort) ? args.reasoning_effort : undefined,
12206
+ logger: ctx.logger
12207
+ });
12208
+ ctx.logger.debug(`chunk_query: ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}`);
12209
+ return {
12210
+ success: true,
12211
+ output: `[chunk_query] ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}
12212
+
12213
+ ${res.synthesis || res.answers.join(`
12214
+ `)}`
12215
+ };
12216
+ }
12217
+ };
12218
+ });
12219
+
11840
12220
  // src/modules/security/network-validator.ts
11841
12221
  function isUrlAllowed(url, securityConfig) {
11842
12222
  if (!securityConfig?.enabled) {
@@ -12586,7 +12966,7 @@ class MCPClient {
12586
12966
  }
12587
12967
  }
12588
12968
  connectStdio() {
12589
- return new Promise((resolve12, reject) => {
12969
+ return new Promise((resolve15, reject) => {
12590
12970
  const child = spawn3(this.config.command, this.config.args || [], {
12591
12971
  env: { ...process.env, ...this.config.env },
12592
12972
  stdio: ["pipe", "pipe", "pipe"]
@@ -12610,7 +12990,7 @@ class MCPClient {
12610
12990
  this._connected = true;
12611
12991
  this.process = child;
12612
12992
  _resolved = true;
12613
- resolve12();
12993
+ resolve15();
12614
12994
  });
12615
12995
  });
12616
12996
  }
@@ -12679,7 +13059,7 @@ class MCPClient {
12679
13059
  if (!this.process) {
12680
13060
  throw new Error("Not connected to MCP server");
12681
13061
  }
12682
- return new Promise((resolve12, reject) => {
13062
+ return new Promise((resolve15, reject) => {
12683
13063
  const request = {
12684
13064
  jsonrpc: "2.0",
12685
13065
  id: Date.now(),
@@ -12703,7 +13083,7 @@ class MCPClient {
12703
13083
  if (response.error) {
12704
13084
  reject(new Error(response.error.message));
12705
13085
  } else {
12706
- resolve12(response.result?.tools || []);
13086
+ resolve15(response.result?.tools || []);
12707
13087
  }
12708
13088
  return;
12709
13089
  }
@@ -12785,8 +13165,8 @@ class MCPClient {
12785
13165
  arguments: args
12786
13166
  }
12787
13167
  };
12788
- return new Promise((resolve12, reject) => {
12789
- this.pendingResolve = resolve12;
13168
+ return new Promise((resolve15, reject) => {
13169
+ this.pendingResolve = resolve15;
12790
13170
  this.pendingReject = reject;
12791
13171
  const timeout = this.config.timeout || 30000;
12792
13172
  const timer = setTimeout(() => {
@@ -12813,7 +13193,7 @@ class MCPClient {
12813
13193
  if (result.error) {
12814
13194
  reject(new Error(result.error.message));
12815
13195
  } else {
12816
- resolve12(result.result || result);
13196
+ resolve15(result.result || result);
12817
13197
  }
12818
13198
  }).catch((err) => {
12819
13199
  clearTimeout(timer);
@@ -12827,7 +13207,7 @@ class MCPClient {
12827
13207
  if (!this.process) {
12828
13208
  throw new Error("Not connected to MCP server");
12829
13209
  }
12830
- return new Promise((resolve12, reject) => {
13210
+ return new Promise((resolve15, reject) => {
12831
13211
  const request = {
12832
13212
  jsonrpc: "2.0",
12833
13213
  id: Date.now(),
@@ -12855,7 +13235,7 @@ class MCPClient {
12855
13235
  if (response.error) {
12856
13236
  reject(new Error(response.error.message));
12857
13237
  } else {
12858
- resolve12(response.result);
13238
+ resolve15(response.result);
12859
13239
  }
12860
13240
  return;
12861
13241
  }
@@ -13057,7 +13437,7 @@ import { join as join15 } from "path";
13057
13437
  var CATEGORIES, rememberTool;
13058
13438
  var init_remember = __esm(() => {
13059
13439
  init_i18n();
13060
- init_store();
13440
+ init_store2();
13061
13441
  CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
13062
13442
  rememberTool = {
13063
13443
  name: "remember",
@@ -13184,7 +13564,7 @@ function searchCategory(store, category, query) {
13184
13564
  var CATEGORIES2, recallTool;
13185
13565
  var init_recall = __esm(() => {
13186
13566
  init_i18n();
13187
- init_store();
13567
+ init_store2();
13188
13568
  CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
13189
13569
  recallTool = {
13190
13570
  name: "recall",
@@ -13883,7 +14263,7 @@ __export(exports_image_utils, {
13883
14263
  detectMime: () => detectMime,
13884
14264
  bufferToDataUrl: () => bufferToDataUrl
13885
14265
  });
13886
- import { readFileSync as readFileSync12 } from "fs";
14266
+ import { readFileSync as readFileSync14 } from "fs";
13887
14267
  import { extname as extname3 } from "path";
13888
14268
  function detectMime(filePath) {
13889
14269
  const ext = extname3(filePath).toLowerCase();
@@ -13904,7 +14284,7 @@ async function readClipboardImage() {
13904
14284
  async function readClipboardFallback() {
13905
14285
  const { platform: platform3 } = await import("os");
13906
14286
  const { execSync } = await import("child_process");
13907
- const { readFileSync: readFileSync13, unlinkSync: unlinkSync4 } = await import("fs");
14287
+ const { readFileSync: readFileSync15, unlinkSync: unlinkSync4 } = await import("fs");
13908
14288
  const { join: join19 } = await import("path");
13909
14289
  const tmpPath = join19(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13910
14290
  try {
@@ -13913,7 +14293,7 @@ async function readClipboardFallback() {
13913
14293
  } else {
13914
14294
  return null;
13915
14295
  }
13916
- const buf = readFileSync13(tmpPath);
14296
+ const buf = readFileSync15(tmpPath);
13917
14297
  unlinkSync4(tmpPath);
13918
14298
  return buf.length > 0 ? buf : null;
13919
14299
  } catch {
@@ -13924,7 +14304,7 @@ async function readClipboardFallback() {
13924
14304
  }
13925
14305
  }
13926
14306
  async function loadFileAsDataUrl(filePath) {
13927
- const buf = readFileSync12(filePath);
14307
+ const buf = readFileSync14(filePath);
13928
14308
  if (typeof Bun !== "undefined" && typeof Bun.Image !== "undefined") {
13929
14309
  try {
13930
14310
  const img = new Bun.Image(buf);
@@ -13984,8 +14364,8 @@ var init_image_utils = __esm(() => {
13984
14364
  });
13985
14365
 
13986
14366
  // src/tools/attach-image.ts
13987
- import { existsSync as existsSync23 } from "fs";
13988
- import { resolve as resolve12 } from "path";
14367
+ import { existsSync as existsSync24 } from "fs";
14368
+ import { resolve as resolve15 } from "path";
13989
14369
  var attachImageTool;
13990
14370
  var init_attach_image = __esm(() => {
13991
14371
  init_i18n();
@@ -14026,16 +14406,16 @@ var init_attach_image = __esm(() => {
14026
14406
  const result = await loadUrlAsDataUrl(source);
14027
14407
  dataUrl = result.dataUrl;
14028
14408
  } else {
14029
- const absPath = resolve12(ctx.baseDir, source);
14030
- if (!existsSync23(absPath)) {
14409
+ const absPath = resolve15(ctx.baseDir, source);
14410
+ if (!existsSync24(absPath)) {
14031
14411
  return {
14032
14412
  success: false,
14033
14413
  output: t("image.not_found", { path: source })
14034
14414
  };
14035
14415
  }
14036
14416
  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);
14417
+ const { isPathInScope: isPathInScope3 } = await Promise.resolve().then(() => (init_path_validator(), exports_path_validator));
14418
+ const validation = isPathInScope3(ctx.baseDir, absPath, ctx.scope);
14039
14419
  if (!validation.allowed) {
14040
14420
  logSecurityBlock(ctx.sessionId, "file_read", validation.reason ?? "attach_image out of scope", absPath);
14041
14421
  return {
@@ -14087,6 +14467,7 @@ function registerAllTools(registry2, skillsModule) {
14087
14467
  fileInfoTool,
14088
14468
  bashTool,
14089
14469
  subagentTool,
14470
+ chunkQueryTool,
14090
14471
  processListTool,
14091
14472
  processLogTool,
14092
14473
  processKillTool,
@@ -14122,6 +14503,7 @@ var init_tools = __esm(() => {
14122
14503
  init_process_log();
14123
14504
  init_process_kill();
14124
14505
  init_subagent();
14506
+ init_chunk_query();
14125
14507
  init_web_search();
14126
14508
  init_web_fetch();
14127
14509
  init_web_browse();
@@ -14183,12 +14565,12 @@ class ModuleRegistry {
14183
14565
  }
14184
14566
 
14185
14567
  // src/modules/plugins/loader.ts
14186
- import { readdirSync as readdirSync7, existsSync as existsSync24, statSync as statSync5 } from "fs";
14568
+ import { readdirSync as readdirSync7, existsSync as existsSync25, statSync as statSync5 } from "fs";
14187
14569
  import { join as join19 } from "path";
14188
14570
 
14189
14571
  class PluginLoader {
14190
14572
  loadFromDir(dirPath, pluginManager, logger) {
14191
- if (!existsSync24(dirPath))
14573
+ if (!existsSync25(dirPath))
14192
14574
  return;
14193
14575
  const entries = readdirSync7(dirPath);
14194
14576
  for (const entry of entries) {
@@ -14216,8 +14598,8 @@ var init_loader = __esm(() => {
14216
14598
 
14217
14599
  // src/modules/plugins/builtin/lint-on-write.ts
14218
14600
  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";
14601
+ import { existsSync as existsSync26, readFileSync as readFileSync15 } from "fs";
14602
+ import { resolve as resolve16, extname as extname4, join as join20 } from "path";
14221
14603
  import { platform as platform3 } from "os";
14222
14604
  function contentHash(content) {
14223
14605
  let h = 5381;
@@ -14262,8 +14644,8 @@ class LintOnWritePlugin {
14262
14644
  const path = String(call.arguments.path || "");
14263
14645
  if (!path)
14264
14646
  return;
14265
- const fullPath = resolve13(ctx.baseDir, path);
14266
- if (!existsSync25(fullPath))
14647
+ const fullPath = resolve16(ctx.baseDir, path);
14648
+ if (!existsSync26(fullPath))
14267
14649
  return;
14268
14650
  const ext = extname4(fullPath);
14269
14651
  const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir);
@@ -14280,7 +14662,7 @@ class LintOnWritePlugin {
14280
14662
  if (ext === ".ts" || ext === ".tsx") {
14281
14663
  let content = "";
14282
14664
  try {
14283
- content = readFileSync13(filePath, "utf-8");
14665
+ content = readFileSync15(filePath, "utf-8");
14284
14666
  } catch {
14285
14667
  return null;
14286
14668
  }
@@ -14320,10 +14702,10 @@ class LintOnWritePlugin {
14320
14702
  async runProjectLint(ctx, result) {
14321
14703
  try {
14322
14704
  const packageJsonPath = join20(ctx.baseDir, "package.json");
14323
- if (!existsSync25(packageJsonPath)) {
14705
+ if (!existsSync26(packageJsonPath)) {
14324
14706
  return;
14325
14707
  }
14326
- const packageJson = JSON.parse(readFileSync13(packageJsonPath, "utf-8"));
14708
+ const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
14327
14709
  const lintScript = packageJson.scripts?.lint;
14328
14710
  if (!lintScript) {
14329
14711
  return;
@@ -14340,7 +14722,7 @@ class LintOnWritePlugin {
14340
14722
  }
14341
14723
  async runProjectTypeCheck(ctx, result) {
14342
14724
  const tsconfigPath = join20(ctx.baseDir, "tsconfig.json");
14343
- if (!existsSync25(tsconfigPath)) {
14725
+ if (!existsSync26(tsconfigPath)) {
14344
14726
  return;
14345
14727
  }
14346
14728
  const now = Date.now();
@@ -14381,7 +14763,7 @@ class LintOnWritePlugin {
14381
14763
  }
14382
14764
  }
14383
14765
  function runAsync(command, cwd, timeoutMs) {
14384
- return new Promise((resolve14, reject) => {
14766
+ return new Promise((resolve17, reject) => {
14385
14767
  const child = spawn4(command, {
14386
14768
  cwd,
14387
14769
  shell: true,
@@ -14410,7 +14792,7 @@ function runAsync(command, cwd, timeoutMs) {
14410
14792
  stdout += decoder.decode();
14411
14793
  stderr += decoder.decode();
14412
14794
  if (code === 0) {
14413
- resolve14({ stdout, stderr });
14795
+ resolve17({ stdout, stderr });
14414
14796
  } else {
14415
14797
  const err = new Error(`Command failed with exit code ${code}`);
14416
14798
  err.stdout = stdout;
@@ -14582,8 +14964,8 @@ class PlanTracker {
14582
14964
  var init_tracker = () => {};
14583
14965
 
14584
14966
  // 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";
14967
+ import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
14968
+ import { resolve as resolve17, join as join21 } from "path";
14587
14969
  function findTestFile(dir, depth = 0) {
14588
14970
  if (depth > 5)
14589
14971
  return null;
@@ -14673,8 +15055,8 @@ class Auditor {
14673
15055
  const missingFiles = [];
14674
15056
  const existingFiles = [];
14675
15057
  for (const filePath of uniqueFiles) {
14676
- const resolved = resolve14(this.baseDir, filePath);
14677
- if (existsSync26(resolved)) {
15058
+ const resolved = resolve17(this.baseDir, filePath);
15059
+ if (existsSync27(resolved)) {
14678
15060
  existingFiles.push(filePath);
14679
15061
  } else {
14680
15062
  missingFiles.push(filePath);
@@ -14753,11 +15135,11 @@ var init_auditor = __esm(() => {
14753
15135
  });
14754
15136
 
14755
15137
  // 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";
15138
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync13, existsSync as existsSync28, readdirSync as readdirSync9, rmSync } from "fs";
14757
15139
  import { join as join22 } from "path";
14758
15140
  function readPlanFile(path, fallbackBaseDir) {
14759
15141
  try {
14760
- const raw = readFileSync14(path, "utf-8");
15142
+ const raw = readFileSync16(path, "utf-8");
14761
15143
  if (!raw.trim())
14762
15144
  return null;
14763
15145
  const parsed = JSON.parse(raw);
@@ -14776,10 +15158,10 @@ function readPlanFile(path, fallbackBaseDir) {
14776
15158
  }
14777
15159
  }
14778
15160
  function writePlanFile(path, plan) {
14779
- writeFileSync8(path, JSON.stringify(plan, null, 2), "utf-8");
15161
+ writeFileSync9(path, JSON.stringify(plan, null, 2), "utf-8");
14780
15162
  }
14781
15163
  function listDir(dir, baseDir) {
14782
- if (!existsSync27(dir))
15164
+ if (!existsSync28(dir))
14783
15165
  return [];
14784
15166
  const files = readdirSync9(dir).filter((f) => f.endsWith(".json"));
14785
15167
  return files.map((f) => readPlanFile(join22(dir, f), baseDir)).filter((p) => p !== null);
@@ -14804,16 +15186,16 @@ class PlanStore {
14804
15186
  legacyPath;
14805
15187
  constructor(baseDir) {
14806
15188
  const mmaDir = join22(baseDir, ".mma");
14807
- if (!existsSync27(mmaDir))
14808
- mkdirSync12(mmaDir, { recursive: true });
15189
+ if (!existsSync28(mmaDir))
15190
+ mkdirSync13(mmaDir, { recursive: true });
14809
15191
  this.baseDir = baseDir;
14810
15192
  this.plansDir = join22(mmaDir, "plans");
14811
15193
  this.draftsDir = join22(this.plansDir, "drafts");
14812
15194
  this.archiveDir = join22(this.plansDir, "archive");
14813
15195
  this.legacyPath = join22(mmaDir, LEGACY_FILE);
14814
15196
  for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
14815
- if (!existsSync27(dir))
14816
- mkdirSync12(dir, { recursive: true });
15197
+ if (!existsSync28(dir))
15198
+ mkdirSync13(dir, { recursive: true });
14817
15199
  }
14818
15200
  }
14819
15201
  activePath() {
@@ -14824,12 +15206,12 @@ class PlanStore {
14824
15206
  }
14825
15207
  loadActive() {
14826
15208
  const activePath = this.activePath();
14827
- if (existsSync27(activePath)) {
15209
+ if (existsSync28(activePath)) {
14828
15210
  const plan = readPlanFile(activePath, this.baseDir);
14829
15211
  if (plan)
14830
15212
  return plan;
14831
15213
  }
14832
- if (existsSync27(this.legacyPath)) {
15214
+ if (existsSync28(this.legacyPath)) {
14833
15215
  const legacy = readPlanFile(this.legacyPath, this.baseDir);
14834
15216
  if (legacy) {
14835
15217
  this.saveActive(legacy);
@@ -14843,7 +15225,7 @@ class PlanStore {
14843
15225
  }
14844
15226
  clearActive() {
14845
15227
  const p = this.activePath();
14846
- if (existsSync27(p))
15228
+ if (existsSync28(p))
14847
15229
  rmSync(p, { force: true });
14848
15230
  }
14849
15231
  saveDraft(plan) {
@@ -14851,11 +15233,11 @@ class PlanStore {
14851
15233
  }
14852
15234
  loadDraft(id) {
14853
15235
  const p = join22(this.draftsDir, `${id}.json`);
14854
- return existsSync27(p) ? readPlanFile(p, this.baseDir) : null;
15236
+ return existsSync28(p) ? readPlanFile(p, this.baseDir) : null;
14855
15237
  }
14856
15238
  removeDraft(id) {
14857
15239
  const p = join22(this.draftsDir, `${id}.json`);
14858
- if (existsSync27(p))
15240
+ if (existsSync28(p))
14859
15241
  rmSync(p, { force: true });
14860
15242
  }
14861
15243
  listDrafts() {
@@ -14874,7 +15256,7 @@ class PlanStore {
14874
15256
  }
14875
15257
  removeArchived(id) {
14876
15258
  const p = join22(this.archiveDir, `${id}.json`);
14877
- if (existsSync27(p))
15259
+ if (existsSync28(p))
14878
15260
  rmSync(p, { force: true });
14879
15261
  }
14880
15262
  listAll() {
@@ -14968,8 +15350,8 @@ var init_plan_coverage = __esm(() => {
14968
15350
  });
14969
15351
 
14970
15352
  // src/modules/execution/module.ts
14971
- import { existsSync as existsSync28, readFileSync as readFileSync15 } from "fs";
14972
- import { resolve as resolve15 } from "path";
15353
+ import { existsSync as existsSync29, readFileSync as readFileSync17 } from "fs";
15354
+ import { resolve as resolve18 } from "path";
14973
15355
 
14974
15356
  class ExecutionModule {
14975
15357
  name = "execution";
@@ -15624,7 +16006,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
15624
16006
  "poetry.lock",
15625
16007
  "requirements.txt"
15626
16008
  ];
15627
- const hasLockFile = lockFiles.some((f) => existsSync28(resolve15(this.baseDir, f)));
16009
+ const hasLockFile = lockFiles.some((f) => existsSync29(resolve18(this.baseDir, f)));
15628
16010
  if (!hasLockFile) {
15629
16011
  if (contextManager) {
15630
16012
  const hints = this.depsGateHints.get(step.id) || 0;
@@ -15644,13 +16026,13 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
15644
16026
  }
15645
16027
  if (stepPaths.length === 0)
15646
16028
  return;
15647
- const allExist = stepPaths.every((p) => existsSync28(resolve15(this.baseDir, p)));
16029
+ const allExist = stepPaths.every((p) => existsSync29(resolve18(this.baseDir, p)));
15648
16030
  if (!allExist)
15649
16031
  return;
15650
16032
  const emptyFiles = [];
15651
16033
  for (const p of stepPaths) {
15652
16034
  try {
15653
- const content = readFileSync15(resolve15(this.baseDir, p), "utf-8");
16035
+ const content = readFileSync17(resolve18(this.baseDir, p), "utf-8");
15654
16036
  if (content.trim().length < 10) {
15655
16037
  emptyFiles.push(p);
15656
16038
  }
@@ -15707,9 +16089,9 @@ var init_module = __esm(() => {
15707
16089
 
15708
16090
  // src/modules/security/session-encryption.ts
15709
16091
  import {
15710
- readFileSync as readFileSync16,
15711
- writeFileSync as writeFileSync9,
15712
- existsSync as existsSync29,
16092
+ readFileSync as readFileSync18,
16093
+ writeFileSync as writeFileSync10,
16094
+ existsSync as existsSync30,
15713
16095
  readdirSync as readdirSync10,
15714
16096
  unlinkSync as unlinkSync4
15715
16097
  } from "fs";
@@ -15767,23 +16149,23 @@ class SessionFileEncryptor {
15767
16149
  return lines.map((line) => this.decryptFileContent(line));
15768
16150
  }
15769
16151
  readSessionFile(filePath) {
15770
- const content = readFileSync16(filePath, "utf8");
16152
+ const content = readFileSync18(filePath, "utf8");
15771
16153
  return this.decryptFileContent(content);
15772
16154
  }
15773
16155
  writeSessionFile(filePath, content) {
15774
16156
  const encrypted = this.encryptFileContent(content);
15775
- writeFileSync9(filePath, encrypted, "utf8");
16157
+ writeFileSync10(filePath, encrypted, "utf8");
15776
16158
  }
15777
16159
  readSessionJSON(filePath) {
15778
- const content = readFileSync16(filePath, "utf8");
16160
+ const content = readFileSync18(filePath, "utf8");
15779
16161
  return this.decryptJSON(content);
15780
16162
  }
15781
16163
  writeSessionJSON(filePath, obj) {
15782
16164
  const content = this.encryptJSON(obj);
15783
- writeFileSync9(filePath, content, "utf8");
16165
+ writeFileSync10(filePath, content, "utf8");
15784
16166
  }
15785
16167
  readSessionJSONL(filePath) {
15786
- const content = readFileSync16(filePath, "utf8");
16168
+ const content = readFileSync18(filePath, "utf8");
15787
16169
  const lines = content.split(`
15788
16170
  `).filter((line) => line.trim());
15789
16171
  const decryptedLines = this.decryptJSONL(lines);
@@ -15797,7 +16179,7 @@ class SessionFileEncryptor {
15797
16179
  }
15798
16180
  appendToSessionJSONL(filePath, obj) {
15799
16181
  const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
15800
- writeFileSync9(filePath, encryptedLine + `
16182
+ writeFileSync10(filePath, encryptedLine + `
15801
16183
  `, {
15802
16184
  flag: "a",
15803
16185
  encoding: "utf8"
@@ -15809,11 +16191,11 @@ class SessionFileEncryptor {
15809
16191
  const files = readdirSync10(sessionDir);
15810
16192
  for (const file of files) {
15811
16193
  const filePath = join23(sessionDir, file);
15812
- if (existsSync29(filePath) && !file.endsWith(".enc")) {
16194
+ if (existsSync30(filePath) && !file.endsWith(".enc")) {
15813
16195
  try {
15814
- const content = readFileSync16(filePath, "utf8");
16196
+ const content = readFileSync18(filePath, "utf8");
15815
16197
  const encrypted = this.encryptFileContent(content);
15816
- writeFileSync9(filePath + ".enc", encrypted, "utf8");
16198
+ writeFileSync10(filePath + ".enc", encrypted, "utf8");
15817
16199
  unlinkSync4(filePath);
15818
16200
  } catch {}
15819
16201
  }
@@ -15828,9 +16210,9 @@ class SessionFileEncryptor {
15828
16210
  const encFilePath = join23(sessionDir, file);
15829
16211
  const decFilePath = encFilePath.slice(0, -4);
15830
16212
  try {
15831
- const content = readFileSync16(encFilePath, "utf8");
16213
+ const content = readFileSync18(encFilePath, "utf8");
15832
16214
  const decrypted = this.decryptFileContent(content);
15833
- writeFileSync9(decFilePath, decrypted, "utf8");
16215
+ writeFileSync10(decFilePath, decrypted, "utf8");
15834
16216
  unlinkSync4(encFilePath);
15835
16217
  } catch {}
15836
16218
  }
@@ -15850,12 +16232,12 @@ var init_session_encryption = __esm(() => {
15850
16232
 
15851
16233
  // src/modules/session/store.ts
15852
16234
  import {
15853
- existsSync as existsSync30,
15854
- mkdirSync as mkdirSync13,
16235
+ existsSync as existsSync31,
16236
+ mkdirSync as mkdirSync14,
15855
16237
  readdirSync as readdirSync11,
15856
- readFileSync as readFileSync17,
16238
+ readFileSync as readFileSync19,
15857
16239
  rmSync as rmSync2,
15858
- writeFileSync as writeFileSync10,
16240
+ writeFileSync as writeFileSync11,
15859
16241
  appendFileSync as appendFileSync6
15860
16242
  } from "fs";
15861
16243
  import { join as join24 } from "path";
@@ -15885,7 +16267,7 @@ class SessionStore {
15885
16267
  return this.encryptor?.isEnabled() ?? false;
15886
16268
  }
15887
16269
  init() {
15888
- mkdirSync13(this.baseDir, { recursive: true });
16270
+ mkdirSync14(this.baseDir, { recursive: true });
15889
16271
  }
15890
16272
  sessionDir(id) {
15891
16273
  return join24(this.baseDir, id);
@@ -15900,17 +16282,17 @@ class SessionStore {
15900
16282
  return join24(this.sessionDir(id), "session.jsonl");
15901
16283
  }
15902
16284
  sessionExists(id) {
15903
- return existsSync30(this.metaPath(id));
16285
+ return existsSync31(this.metaPath(id));
15904
16286
  }
15905
16287
  saveMeta(id, meta) {
15906
16288
  this._metaCache.set(id, meta);
15907
16289
  const dir = this.sessionDir(id);
15908
- mkdirSync13(dir, { recursive: true });
16290
+ mkdirSync14(dir, { recursive: true });
15909
16291
  const content = JSON.stringify(meta, null, 2);
15910
16292
  if (this.encryptor) {
15911
- writeFileSync10(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
16293
+ writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
15912
16294
  } else {
15913
- writeFileSync10(this.metaPath(id), content, "utf-8");
16295
+ writeFileSync11(this.metaPath(id), content, "utf-8");
15914
16296
  }
15915
16297
  }
15916
16298
  loadMeta(id) {
@@ -15918,10 +16300,10 @@ class SessionStore {
15918
16300
  if (cached)
15919
16301
  return cached;
15920
16302
  const path = this.metaPath(id);
15921
- if (!existsSync30(path))
16303
+ if (!existsSync31(path))
15922
16304
  return null;
15923
16305
  try {
15924
- const raw = readFileSync17(path, "utf-8");
16306
+ const raw = readFileSync19(path, "utf-8");
15925
16307
  const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
15926
16308
  const meta = JSON.parse(content);
15927
16309
  this._metaCache.set(id, meta);
@@ -15932,7 +16314,7 @@ class SessionStore {
15932
16314
  }
15933
16315
  appendMessage(id, msg) {
15934
16316
  const dir = this.sessionDir(id);
15935
- mkdirSync13(dir, { recursive: true });
16317
+ mkdirSync14(dir, { recursive: true });
15936
16318
  const line = JSON.stringify(msg);
15937
16319
  if (this.encryptor?.isEnabled()) {
15938
16320
  appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
@@ -15950,10 +16332,10 @@ class SessionStore {
15950
16332
  }
15951
16333
  loadHistory(id) {
15952
16334
  const path = this.historyPath(id);
15953
- if (!existsSync30(path))
16335
+ if (!existsSync31(path))
15954
16336
  return [];
15955
16337
  try {
15956
- const raw = readFileSync17(path, "utf-8");
16338
+ const raw = readFileSync19(path, "utf-8");
15957
16339
  const lines = raw.split(`
15958
16340
  `).filter(Boolean);
15959
16341
  const parseLine = (line) => {
@@ -15979,7 +16361,7 @@ class SessionStore {
15979
16361
  }
15980
16362
  appendSessionLog(id, entry) {
15981
16363
  const dir = this.sessionDir(id);
15982
- mkdirSync13(dir, { recursive: true });
16364
+ mkdirSync14(dir, { recursive: true });
15983
16365
  const line = JSON.stringify(entry);
15984
16366
  if (this.encryptor?.isEnabled()) {
15985
16367
  appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
@@ -15991,10 +16373,10 @@ class SessionStore {
15991
16373
  }
15992
16374
  loadSessionLog(id) {
15993
16375
  const path = this.sessionLogPath(id);
15994
- if (!existsSync30(path))
16376
+ if (!existsSync31(path))
15995
16377
  return [];
15996
16378
  try {
15997
- const raw = readFileSync17(path, "utf-8");
16379
+ const raw = readFileSync19(path, "utf-8");
15998
16380
  const lines = raw.split(`
15999
16381
  `).filter(Boolean);
16000
16382
  const parseLine = (line) => {
@@ -16019,7 +16401,7 @@ class SessionStore {
16019
16401
  }
16020
16402
  }
16021
16403
  listSessions() {
16022
- if (!existsSync30(this.baseDir))
16404
+ if (!existsSync31(this.baseDir))
16023
16405
  return [];
16024
16406
  const entries = readdirSync11(this.baseDir, { withFileTypes: true });
16025
16407
  const sessions = [];
@@ -16036,7 +16418,7 @@ class SessionStore {
16036
16418
  deleteSession(id) {
16037
16419
  this._metaCache.delete(id);
16038
16420
  const dir = this.sessionDir(id);
16039
- if (existsSync30(dir)) {
16421
+ if (existsSync31(dir)) {
16040
16422
  rmSync2(dir, { recursive: true, force: true });
16041
16423
  }
16042
16424
  }
@@ -16048,18 +16430,18 @@ class SessionStore {
16048
16430
  const updatedAt = new Date(session2.updatedAt);
16049
16431
  if (updatedAt < thirtyDaysAgo) {
16050
16432
  const historyPath = this.historyPath(session2.id);
16051
- if (existsSync30(historyPath)) {
16052
- const content = readFileSync17(historyPath, "utf-8");
16433
+ if (existsSync31(historyPath)) {
16434
+ const content = readFileSync19(historyPath, "utf-8");
16053
16435
  const compressed = gzipSync(content);
16054
16436
  const gzPath = join24(this.baseDir, `${session2.id}.jsonl.gz`);
16055
- writeFileSync10(gzPath, compressed);
16437
+ writeFileSync11(gzPath, compressed);
16056
16438
  rmSync2(historyPath);
16057
16439
  }
16058
16440
  }
16059
16441
  }
16060
16442
  }
16061
16443
  }
16062
- var init_store2 = __esm(() => {
16444
+ var init_store3 = __esm(() => {
16063
16445
  init_session_encryption();
16064
16446
  });
16065
16447
 
@@ -16239,7 +16621,7 @@ var init_module2 = __esm(() => {
16239
16621
 
16240
16622
  // src/modules/session/index.ts
16241
16623
  var init_session2 = __esm(() => {
16242
- init_store2();
16624
+ init_store3();
16243
16625
  init_manager2();
16244
16626
  init_module2();
16245
16627
  });
@@ -16261,7 +16643,7 @@ class ProfileCompressor {
16261
16643
  }
16262
16644
 
16263
16645
  // src/modules/user-profile/profile.ts
16264
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync31, mkdirSync as mkdirSync14 } from "fs";
16646
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync12, existsSync as existsSync32, mkdirSync as mkdirSync15 } from "fs";
16265
16647
  import { join as join25 } from "path";
16266
16648
  import { homedir as homedir9, hostname, platform as platform4, type } from "os";
16267
16649
  import { env } from "process";
@@ -16286,17 +16668,17 @@ class UserProfile {
16286
16668
  return this.info;
16287
16669
  }
16288
16670
  save() {
16289
- if (!existsSync31(this.profileDir)) {
16290
- mkdirSync14(this.profileDir, { recursive: true });
16671
+ if (!existsSync32(this.profileDir)) {
16672
+ mkdirSync15(this.profileDir, { recursive: true });
16291
16673
  }
16292
- writeFileSync11(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
16674
+ writeFileSync12(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
16293
16675
  }
16294
16676
  load() {
16295
16677
  const path = join25(this.profileDir, "profile.json");
16296
- if (!existsSync31(path))
16678
+ if (!existsSync32(path))
16297
16679
  return null;
16298
16680
  try {
16299
- const data = JSON.parse(readFileSync18(path, "utf-8"));
16681
+ const data = JSON.parse(readFileSync20(path, "utf-8"));
16300
16682
  this.info = {
16301
16683
  platform: data.platform,
16302
16684
  os: data.os,
@@ -16331,12 +16713,12 @@ class UserProfile {
16331
16713
  var init_profile = () => {};
16332
16714
 
16333
16715
  // src/modules/skills/loader.ts
16334
- import { readdirSync as readdirSync12, readFileSync as readFileSync19, existsSync as existsSync32, statSync as statSync6 } from "fs";
16716
+ import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync33, statSync as statSync6 } from "fs";
16335
16717
  import { join as join26 } from "path";
16336
16718
 
16337
16719
  class SkillsLoader {
16338
16720
  loadFromDir(dirPath) {
16339
- if (!existsSync32(dirPath))
16721
+ if (!existsSync33(dirPath))
16340
16722
  return [];
16341
16723
  const skills = [];
16342
16724
  this.scanDir(dirPath, skills);
@@ -16353,7 +16735,7 @@ class SkillsLoader {
16353
16735
  }
16354
16736
  if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
16355
16737
  continue;
16356
- const content = readFileSync19(fullPath, "utf-8");
16738
+ const content = readFileSync21(fullPath, "utf-8");
16357
16739
  const parsed = this.parseSkillFile(content, fullPath);
16358
16740
  if (parsed)
16359
16741
  skills.push(parsed);
@@ -16587,7 +16969,7 @@ var init_browser2 = __esm(() => {
16587
16969
 
16588
16970
  // src/modules/lsp/client.ts
16589
16971
  import { spawn as spawn5, execSync as execSync2 } from "child_process";
16590
- import { resolve as resolve16 } from "path";
16972
+ import { resolve as resolve19 } from "path";
16591
16973
 
16592
16974
  class LspClient {
16593
16975
  process = null;
@@ -16603,7 +16985,7 @@ class LspClient {
16603
16985
  const timeout = config.timeout ?? DEFAULT_TIMEOUT;
16604
16986
  try {
16605
16987
  await this.startServer(config, baseDir);
16606
- const rootUri = this.pathToUri(resolve16(baseDir));
16988
+ const rootUri = this.pathToUri(resolve19(baseDir));
16607
16989
  const initResult = await this.sendRequest("initialize", {
16608
16990
  processId: process.pid,
16609
16991
  rootUri,
@@ -16612,11 +16994,11 @@ class LspClient {
16612
16994
  }, timeout);
16613
16995
  this.initialized = true;
16614
16996
  this.sendNotification("initialized", {});
16615
- const uri = this.pathToUri(resolve16(filePath));
16997
+ const uri = this.pathToUri(resolve19(filePath));
16616
16998
  const fs2 = await import("fs");
16617
16999
  const content = fs2.readFileSync(filePath, "utf-8");
16618
- const diagPromise = new Promise((resolve17) => {
16619
- this.diagnosticsResolve = resolve17;
17000
+ const diagPromise = new Promise((resolve20) => {
17001
+ this.diagnosticsResolve = resolve20;
16620
17002
  this.diagnostics = [];
16621
17003
  this.diagnosticsTimer = setTimeout(() => {
16622
17004
  if (this.diagnosticsResolve) {
@@ -16648,7 +17030,7 @@ class LspClient {
16648
17030
  throw new Error(`${config.command} not found in PATH`);
16649
17031
  }
16650
17032
  }
16651
- return new Promise((resolve17, reject) => {
17033
+ return new Promise((resolve20, reject) => {
16652
17034
  const args = config.args ?? [];
16653
17035
  const proc = spawn5(config.command, args, {
16654
17036
  stdio: ["pipe", "pipe", "pipe"],
@@ -16661,7 +17043,7 @@ class LspClient {
16661
17043
  });
16662
17044
  proc.stderr.on("data", () => {});
16663
17045
  proc.once("spawn", () => {
16664
- resolve17();
17046
+ resolve20();
16665
17047
  });
16666
17048
  this.process = proc;
16667
17049
  setTimeout(() => {
@@ -16738,9 +17120,9 @@ class LspClient {
16738
17120
  }
16739
17121
  }
16740
17122
  sendRequest(method, params, timeout) {
16741
- return new Promise((resolve17, reject) => {
17123
+ return new Promise((resolve20, reject) => {
16742
17124
  const id = ++this.requestId;
16743
- this.pending.set(id, { resolve: resolve17, reject });
17125
+ this.pending.set(id, { resolve: resolve20, reject });
16744
17126
  const message = JSON.stringify({ jsonrpc: "2.0", id, method, params });
16745
17127
  this.write(message);
16746
17128
  setTimeout(() => {
@@ -16818,8 +17200,8 @@ var DEFAULT_TIMEOUT = 15000;
16818
17200
  var init_client2 = () => {};
16819
17201
 
16820
17202
  // src/modules/lsp/module.ts
16821
- import { existsSync as existsSync33 } from "fs";
16822
- import { resolve as resolve17 } from "path";
17203
+ import { existsSync as existsSync34 } from "fs";
17204
+ import { resolve as resolve20 } from "path";
16823
17205
 
16824
17206
  class LspModule {
16825
17207
  name = "lsp";
@@ -16843,8 +17225,8 @@ class LspModule {
16843
17225
  const filePath = String(call.arguments.path ?? "");
16844
17226
  if (!filePath)
16845
17227
  return;
16846
- const fullPath = resolve17(_ctx.baseDir, filePath);
16847
- if (!existsSync33(fullPath))
17228
+ const fullPath = resolve20(_ctx.baseDir, filePath);
17229
+ if (!existsSync34(fullPath))
16848
17230
  return;
16849
17231
  const serverConfig = getServerForFile(fullPath, self.config);
16850
17232
  if (!serverConfig)
@@ -16902,8 +17284,8 @@ var init_lsp = __esm(() => {
16902
17284
  });
16903
17285
 
16904
17286
  // 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";
17287
+ import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync35, watch } from "fs";
17288
+ import { join as join27, relative as relative2, extname as extname5 } from "path";
16907
17289
 
16908
17290
  class Indexer {
16909
17291
  baseDir;
@@ -16930,7 +17312,7 @@ class Indexer {
16930
17312
  let totalSize = 0;
16931
17313
  let count = 0;
16932
17314
  const walkDir = (dir) => {
16933
- if (!existsSync34(dir))
17315
+ if (!existsSync35(dir))
16934
17316
  return;
16935
17317
  let entries;
16936
17318
  try {
@@ -16942,7 +17324,7 @@ class Indexer {
16942
17324
  if (count >= this.MAX_FILES)
16943
17325
  return;
16944
17326
  const fullPath = join27(dir, entry);
16945
- const relPath = relative(this.baseDir, fullPath);
17327
+ const relPath = relative2(this.baseDir, fullPath);
16946
17328
  const stat = statSync7(fullPath);
16947
17329
  if (stat.isDirectory()) {
16948
17330
  if (!IGNORE_DIRS.has(entry)) {
@@ -16952,7 +17334,7 @@ class Indexer {
16952
17334
  const ext = extname5(entry).toLowerCase();
16953
17335
  const language = LANGUAGES[ext];
16954
17336
  if (language) {
16955
- const content = readFileSync20(fullPath, "utf-8");
17337
+ const content = readFileSync22(fullPath, "utf-8");
16956
17338
  const exports = this.extractExports(content, language);
16957
17339
  files.push({ path: relPath, language, exports, size: stat.size });
16958
17340
  totalSize += stat.size;
@@ -17004,7 +17386,7 @@ var init_walker = __esm(() => {
17004
17386
  });
17005
17387
 
17006
17388
  // src/modules/indexer/cache.ts
17007
- import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, existsSync as existsSync35, mkdirSync as mkdirSync15, rmSync as rmSync3 } from "fs";
17389
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync13, existsSync as existsSync36, mkdirSync as mkdirSync16, rmSync as rmSync3 } from "fs";
17008
17390
  import { join as join28 } from "path";
17009
17391
 
17010
17392
  class IndexCache {
@@ -17016,10 +17398,10 @@ class IndexCache {
17016
17398
  load() {
17017
17399
  if (this.cache)
17018
17400
  return this.cache;
17019
- if (!existsSync35(this.cachePath))
17401
+ if (!existsSync36(this.cachePath))
17020
17402
  return null;
17021
17403
  try {
17022
- this.cache = JSON.parse(readFileSync21(this.cachePath, "utf-8"));
17404
+ this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
17023
17405
  return this.cache;
17024
17406
  } catch {
17025
17407
  return null;
@@ -17028,13 +17410,13 @@ class IndexCache {
17028
17410
  save(result) {
17029
17411
  this.cache = result;
17030
17412
  const dir = join28(this.cachePath, "..");
17031
- if (!existsSync35(dir))
17032
- mkdirSync15(dir, { recursive: true });
17033
- writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
17413
+ if (!existsSync36(dir))
17414
+ mkdirSync16(dir, { recursive: true });
17415
+ writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
17034
17416
  }
17035
17417
  invalidate() {
17036
17418
  this.cache = null;
17037
- if (existsSync35(this.cachePath)) {
17419
+ if (existsSync36(this.cachePath)) {
17038
17420
  try {
17039
17421
  rmSync3(this.cachePath);
17040
17422
  } catch {}
@@ -17434,7 +17816,7 @@ class MemoryModule {
17434
17816
  }
17435
17817
  }
17436
17818
  var init_module8 = __esm(() => {
17437
- init_store();
17819
+ init_store2();
17438
17820
  init_remember();
17439
17821
  init_recall();
17440
17822
  });
@@ -17446,8 +17828,8 @@ __export(exports_bootstrap, {
17446
17828
  bootstrap: () => bootstrap
17447
17829
  });
17448
17830
  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";
17831
+ import { join as join30, resolve as resolve21 } from "path";
17832
+ import { existsSync as existsSync37, readFileSync as readFileSync24, writeFileSync as writeFileSync14 } from "fs";
17451
17833
  function buildSystemInfo(config, baseDir, profileCompressed) {
17452
17834
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
17453
17835
  const isWin = profileCompressed.toLowerCase().includes("win32");
@@ -17516,7 +17898,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17516
17898
  retry: config.retry,
17517
17899
  rateLimits: config.security?.rateLimits
17518
17900
  });
17519
- const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
17901
+ const baseDir = projectDir ? resolve21(projectDir) : process.cwd();
17520
17902
  const projectMapCacheDir = join30(baseDir, ".mma");
17521
17903
  const indexerModule = new IndexerModule({
17522
17904
  baseDir,
@@ -17545,8 +17927,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17545
17927
  estimatedTokens: Math.ceil(systemInfoContent.length / 4)
17546
17928
  };
17547
17929
  const agentsMdGlobal = join30(dir, "AGENTS.md");
17548
- if (!existsSync36(agentsMdGlobal)) {
17549
- writeFileSync13(agentsMdGlobal, "", "utf-8");
17930
+ if (!existsSync37(agentsMdGlobal)) {
17931
+ writeFileSync14(agentsMdGlobal, "", "utf-8");
17550
17932
  }
17551
17933
  const sessionDir = join30(dir, "sessions");
17552
17934
  const sessionStore = new SessionStore(sessionDir);
@@ -17689,8 +18071,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
17689
18071
  join30(dir, "AGENTS.md")
17690
18072
  ];
17691
18073
  for (const p of agentsMdCandidates) {
17692
- if (existsSync36(p)) {
17693
- const content = readFileSync22(p, "utf-8").trim();
18074
+ if (existsSync37(p)) {
18075
+ const content = readFileSync24(p, "utf-8").trim();
17694
18076
  if (content) {
17695
18077
  agentsMdBlocks.push({
17696
18078
  content,
@@ -18317,10 +18699,10 @@ function menuList(items) {
18317
18699
  console.log(l);
18318
18700
  }
18319
18701
  function ask(rl, question, defaultValue) {
18320
- return new Promise((resolve19) => {
18702
+ return new Promise((resolve22) => {
18321
18703
  const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
18322
18704
  rl.question(prompt, (answer) => {
18323
- resolve19(answer.trim() || defaultValue || "");
18705
+ resolve22(answer.trim() || defaultValue || "");
18324
18706
  });
18325
18707
  });
18326
18708
  }
@@ -18539,21 +18921,21 @@ __export(exports_manifest, {
18539
18921
  getCertMark: () => getCertMark,
18540
18922
  MANIFEST_PATH: () => MANIFEST_PATH
18541
18923
  });
18542
- import { existsSync as existsSync37, readFileSync as readFileSync23, mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "fs";
18924
+ import { existsSync as existsSync38, readFileSync as readFileSync25, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
18543
18925
  import { homedir as homedir13 } from "os";
18544
18926
  import { join as join32 } from "path";
18545
18927
  function readManifest(path = MANIFEST_PATH) {
18546
18928
  try {
18547
- if (existsSync37(path)) {
18548
- const raw = JSON.parse(readFileSync23(path, "utf-8"));
18929
+ if (existsSync38(path)) {
18930
+ const raw = JSON.parse(readFileSync25(path, "utf-8"));
18549
18931
  return { version: 1, certifications: raw.certifications ?? [] };
18550
18932
  }
18551
18933
  } catch {}
18552
18934
  return { version: 1, certifications: [] };
18553
18935
  }
18554
18936
  function saveManifest(m, path = MANIFEST_PATH) {
18555
- mkdirSync16(join32(homedir13(), ".mma"), { recursive: true });
18556
- writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
18937
+ mkdirSync17(join32(homedir13(), ".mma"), { recursive: true });
18938
+ writeFileSync15(path, JSON.stringify(m, null, 2), "utf-8");
18557
18939
  }
18558
18940
  function upsertCertification(entry, path = MANIFEST_PATH) {
18559
18941
  const m = readManifest(path);
@@ -25710,7 +26092,7 @@ var init_scenarios = __esm(() => {
25710
26092
  });
25711
26093
 
25712
26094
  // src/modules/certification/loader.ts
25713
- import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync24 } from "fs";
26095
+ import { existsSync as existsSync39, readdirSync as readdirSync14, readFileSync as readFileSync26 } from "fs";
25714
26096
  import { join as join33 } from "path";
25715
26097
  function validateScenario(s) {
25716
26098
  const errors2 = [];
@@ -25760,12 +26142,12 @@ function loadScenarios(userDir) {
25760
26142
  else
25761
26143
  scenarios.push(s);
25762
26144
  }
25763
- if (userDir && existsSync38(userDir)) {
26145
+ if (userDir && existsSync39(userDir)) {
25764
26146
  for (const file of readdirSync14(userDir)) {
25765
26147
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
25766
26148
  continue;
25767
26149
  try {
25768
- const raw = readFileSync24(join33(userDir, file), "utf-8");
26150
+ const raw = readFileSync26(join33(userDir, file), "utf-8");
25769
26151
  const data = $parse(raw);
25770
26152
  const parsed = normalizeScenario(data, file);
25771
26153
  const errs = validateScenario(parsed);
@@ -25818,7 +26200,7 @@ var init_loader3 = __esm(() => {
25818
26200
  });
25819
26201
 
25820
26202
  // src/modules/certification/fact-checker.ts
25821
- import { existsSync as existsSync39, readFileSync as readFileSync25, statSync as statSync8 } from "fs";
26203
+ import { existsSync as existsSync40, readFileSync as readFileSync27, statSync as statSync8 } from "fs";
25822
26204
  import { join as join34 } from "path";
25823
26205
  function checkSandbox(sandboxDir, checks, exitCode, output) {
25824
26206
  const failures = [];
@@ -25838,14 +26220,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
25838
26220
  case "fileExists":
25839
26221
  return isFile(join34(sandboxDir, check.path));
25840
26222
  case "fileNotExists":
25841
- return !existsSync39(join34(sandboxDir, check.path));
26223
+ return !existsSync40(join34(sandboxDir, check.path));
25842
26224
  case "dirExists":
25843
26225
  return isDir(join34(sandboxDir, check.path));
25844
26226
  case "fileContent": {
25845
26227
  const abs = join34(sandboxDir, check.path);
25846
26228
  if (!isFile(abs))
25847
26229
  return false;
25848
- const content = readFileSync25(abs, "utf-8");
26230
+ const content = readFileSync27(abs, "utf-8");
25849
26231
  if (check.contains !== undefined)
25850
26232
  return content.includes(check.contains);
25851
26233
  if (check.equals !== undefined)
@@ -25856,7 +26238,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
25856
26238
  const abs = join34(sandboxDir, check.path);
25857
26239
  if (!isFile(abs))
25858
26240
  return false;
25859
- return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
26241
+ return new RegExp(check.pattern).test(readFileSync27(abs, "utf-8"));
25860
26242
  }
25861
26243
  default:
25862
26244
  return false;
@@ -25864,14 +26246,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
25864
26246
  }
25865
26247
  function isFile(p) {
25866
26248
  try {
25867
- return existsSync39(p) && statSync8(p).isFile();
26249
+ return existsSync40(p) && statSync8(p).isFile();
25868
26250
  } catch {
25869
26251
  return false;
25870
26252
  }
25871
26253
  }
25872
26254
  function isDir(p) {
25873
26255
  try {
25874
- return existsSync39(p) && statSync8(p).isDirectory();
26256
+ return existsSync40(p) && statSync8(p).isDirectory();
25875
26257
  } catch {
25876
26258
  return false;
25877
26259
  }
@@ -25902,9 +26284,9 @@ var init_fact_checker = () => {};
25902
26284
 
25903
26285
  // src/modules/certification/runner.ts
25904
26286
  import { spawn as spawn6 } from "child_process";
25905
- import { existsSync as existsSync40, mkdirSync as mkdirSync17, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
26287
+ import { existsSync as existsSync41, mkdirSync as mkdirSync18, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
25906
26288
  import { platform as platform5 } from "os";
25907
- import { join as join35, resolve as resolve19, dirname as dirname8 } from "path";
26289
+ import { join as join35, resolve as resolve22, dirname as dirname8 } from "path";
25908
26290
  async function runScenario(scenario, opts) {
25909
26291
  if (scenario.mode === "skip") {
25910
26292
  return {
@@ -25982,30 +26364,30 @@ ${res.stderr}`;
25982
26364
  }
25983
26365
  function prepareSandbox(sandbox, scenario, mmaRoot) {
25984
26366
  rmSync4(sandbox, { recursive: true, force: true });
25985
- mkdirSync17(sandbox, { recursive: true });
26367
+ mkdirSync18(sandbox, { recursive: true });
25986
26368
  for (const f of scenario.fixtures ?? []) {
25987
26369
  const src = join35(mmaRoot, f.source);
25988
- if (!existsSync40(src)) {
26370
+ if (!existsSync41(src)) {
25989
26371
  throw new Error(`fixture missing: ${f.source}`);
25990
26372
  }
25991
26373
  const dest = join35(sandbox, f.dest);
25992
- mkdirSync17(dirname8(dest), { recursive: true });
26374
+ mkdirSync18(dirname8(dest), { recursive: true });
25993
26375
  cpSync2(src, dest);
25994
26376
  }
25995
26377
  }
25996
26378
  function resolveMmaEntry(mmaRoot) {
25997
26379
  const dev = join35(mmaRoot, "src", "cli", "main.ts");
25998
- if (existsSync40(dev))
26380
+ if (existsSync41(dev))
25999
26381
  return dev;
26000
26382
  return join35(mmaRoot, "dist", "main.js");
26001
26383
  }
26002
26384
  function findMmaRoot(fromDir) {
26003
26385
  const candidates = [
26004
- resolve19(fromDir, "..", "..", ".."),
26005
- resolve19(fromDir, "..")
26386
+ resolve22(fromDir, "..", "..", ".."),
26387
+ resolve22(fromDir, "..")
26006
26388
  ];
26007
26389
  for (const c of candidates) {
26008
- if (existsSync40(join35(c, "package.json")))
26390
+ if (existsSync41(join35(c, "package.json")))
26009
26391
  return c;
26010
26392
  }
26011
26393
  return process.cwd();
@@ -26075,13 +26457,13 @@ import { rmSync as rmSync5 } from "fs";
26075
26457
  import { homedir as homedir14 } from "os";
26076
26458
  import { join as join36, dirname as dirname9 } from "path";
26077
26459
  import { fileURLToPath } from "url";
26078
- import { existsSync as existsSync41, readFileSync as readFileSync26 } from "fs";
26460
+ import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
26079
26461
  function readVersion() {
26080
26462
  const candidates = [join36(MMA_ROOT, "package.json")];
26081
26463
  for (const p of candidates) {
26082
- if (existsSync41(p)) {
26464
+ if (existsSync42(p)) {
26083
26465
  try {
26084
- const raw = JSON.parse(readFileSync26(p, "utf-8"));
26466
+ const raw = JSON.parse(readFileSync28(p, "utf-8"));
26085
26467
  if (raw.version)
26086
26468
  return raw.version;
26087
26469
  } catch {}
@@ -26242,7 +26624,7 @@ __export(exports_repl_commands, {
26242
26624
  });
26243
26625
  import { join as join38, dirname as dirname11 } from "path";
26244
26626
  import { homedir as homedir16 } from "os";
26245
- import { existsSync as existsSync43, readFileSync as readFileSync28 } from "fs";
26627
+ import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
26246
26628
  import { fileURLToPath as fileURLToPath3 } from "url";
26247
26629
  function readVersion3() {
26248
26630
  const here = dirname11(fileURLToPath3(import.meta.url));
@@ -26251,9 +26633,9 @@ function readVersion3() {
26251
26633
  join38(here, "..", "package.json")
26252
26634
  ];
26253
26635
  for (const p of candidates) {
26254
- if (existsSync43(p)) {
26636
+ if (existsSync44(p)) {
26255
26637
  try {
26256
- const raw = JSON.parse(readFileSync28(p, "utf8"));
26638
+ const raw = JSON.parse(readFileSync30(p, "utf8"));
26257
26639
  if (raw.version)
26258
26640
  return raw.version;
26259
26641
  } catch {}
@@ -26317,8 +26699,8 @@ function registerMmaCommands(ctx) {
26317
26699
  }
26318
26700
  try {
26319
26701
  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");
26702
+ const { existsSync: existsSync45 } = await import("fs");
26703
+ const { resolve: resolve23 } = await import("path");
26322
26704
  let dataUrl;
26323
26705
  let label;
26324
26706
  if (source.toLowerCase() === "clipboard") {
@@ -26336,8 +26718,8 @@ function registerMmaCommands(ctx) {
26336
26718
  dataUrl = result.dataUrl;
26337
26719
  label = source;
26338
26720
  } else {
26339
- const absPath = resolve20(process.cwd(), source);
26340
- if (!existsSync44(absPath)) {
26721
+ const absPath = resolve23(process.cwd(), source);
26722
+ if (!existsSync45(absPath)) {
26341
26723
  console.log(pc2.red(t("image.not_found", { path: source })));
26342
26724
  return;
26343
26725
  }
@@ -26875,7 +27257,7 @@ init_setup();
26875
27257
  init_i18n();
26876
27258
  import { join as join37, dirname as dirname10 } from "path";
26877
27259
  import { homedir as homedir15 } from "os";
26878
- import { existsSync as existsSync42, readFileSync as readFileSync27 } from "fs";
27260
+ import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
26879
27261
 
26880
27262
  // src/cli/security-commands.ts
26881
27263
  init_bootstrap();
@@ -27503,9 +27885,9 @@ function readVersion2() {
27503
27885
  join37(here, "..", "package.json")
27504
27886
  ];
27505
27887
  for (const p of candidates) {
27506
- if (existsSync42(p)) {
27888
+ if (existsSync43(p)) {
27507
27889
  try {
27508
- const raw = JSON.parse(readFileSync27(p, "utf8"));
27890
+ const raw = JSON.parse(readFileSync29(p, "utf8"));
27509
27891
  if (raw.version)
27510
27892
  return raw.version;
27511
27893
  } catch {}
@@ -27732,7 +28114,7 @@ init_bootstrap();
27732
28114
  // src/cli/repl.ts
27733
28115
  init_colors();
27734
28116
  import * as readline2 from "readline";
27735
- import { existsSync as existsSync44, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
28117
+ import { existsSync as existsSync45, readFileSync as readFileSync31, writeFileSync as writeFileSync16 } from "fs";
27736
28118
  import { join as join39, dirname as dirname12 } from "path";
27737
28119
  import { homedir as homedir17 } from "os";
27738
28120
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -28251,9 +28633,9 @@ function readVersion4() {
28251
28633
  join39(here, "..", "package.json")
28252
28634
  ];
28253
28635
  for (const p of candidates) {
28254
- if (existsSync44(p)) {
28636
+ if (existsSync45(p)) {
28255
28637
  try {
28256
- const raw = JSON.parse(readFileSync29(p, "utf8"));
28638
+ const raw = JSON.parse(readFileSync31(p, "utf8"));
28257
28639
  if (raw.version)
28258
28640
  return raw.version;
28259
28641
  } catch {}
@@ -28331,9 +28713,9 @@ class Repl {
28331
28713
  this.setupListeners();
28332
28714
  }
28333
28715
  loadHistory() {
28334
- if (existsSync44(this.historyPath)) {
28716
+ if (existsSync45(this.historyPath)) {
28335
28717
  try {
28336
- const raw = readFileSync29(this.historyPath, "utf-8");
28718
+ const raw = readFileSync31(this.historyPath, "utf-8");
28337
28719
  this.history = raw.split(`
28338
28720
  `).filter(Boolean).slice(-this.maxHistory);
28339
28721
  } catch {
@@ -28343,7 +28725,7 @@ class Repl {
28343
28725
  }
28344
28726
  saveHistory() {
28345
28727
  const allHistory = this.history.slice(-this.maxHistory);
28346
- writeFileSync15(this.historyPath, allHistory.join(`
28728
+ writeFileSync16(this.historyPath, allHistory.join(`
28347
28729
  `), "utf-8");
28348
28730
  }
28349
28731
  setupCompleter() {
@@ -28668,7 +29050,7 @@ ${t("image.clipboard_empty")}`));
28668
29050
  join39(this.baseDir, ".mma", "AGENTS.md"),
28669
29051
  join39(this.configDir, "AGENTS.md")
28670
29052
  ];
28671
- const foundAgents = agentsMdCandidates.filter((p) => existsSync44(p));
29053
+ const foundAgents = agentsMdCandidates.filter((p) => existsSync45(p));
28672
29054
  if (foundAgents.length > 0) {
28673
29055
  for (const p of foundAgents) {
28674
29056
  row(t("repl.agents_label"), pc2.dim(p));
@@ -28705,7 +29087,7 @@ init_setup();
28705
29087
  init_config2();
28706
29088
  init_i18n();
28707
29089
  init_colors();
28708
- import { existsSync as existsSync45 } from "fs";
29090
+ import { existsSync as existsSync46 } from "fs";
28709
29091
  import { join as join40 } from "path";
28710
29092
  import { homedir as homedir18 } from "os";
28711
29093
  async function main() {
@@ -28774,7 +29156,7 @@ async function main() {
28774
29156
  agent.shutdown();
28775
29157
  } else {
28776
29158
  const configPath = join40(homedir18(), ".mma", "config.json");
28777
- if (!existsSync45(configPath)) {
29159
+ if (!existsSync46(configPath)) {
28778
29160
  console.log(pc2.yellow(`
28779
29161
  ` + t("cli.first_run") + `
28780
29162
  `));