micro-models-agent 0.28.5 → 0.28.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.js +354 -281
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2253,6 +2253,9 @@ var init_defaults = __esm(() => {
2253
2253
  isolatePlugins: true,
2254
2254
  isolateTempFiles: true
2255
2255
  },
2256
+ skills: {
2257
+ budget: 0.15
2258
+ },
2256
2259
  lsp: DEFAULT_LSP_CONFIG
2257
2260
  };
2258
2261
  });
@@ -2348,6 +2351,8 @@ var init_en = __esm(() => {
2348
2351
  "tool.friendly.web_search": "Web search",
2349
2352
  "tool.friendly.web_fetch": "Fetching page",
2350
2353
  "tool.friendly.web_browse": "Browsing page",
2354
+ "tool.web_fetch_result": "Fetched page: {url} — {chars} chars, {lines} lines{truncated}",
2355
+ "tool.web_browse_result": "Browsed page: {url} — {chars} chars, {lines} lines{truncated}",
2351
2356
  "tool.friendly.browser": "Browser",
2352
2357
  "tool.friendly.subagent": "Sub-agent task",
2353
2358
  "tool.friendly.question": "Question to user",
@@ -2378,7 +2383,7 @@ var init_en = __esm(() => {
2378
2383
  "tool.question.answered": "User has answered your questions: {formatted}. You can now continue with the user's answers in mind.",
2379
2384
  "tool.name_or_task": 'Provide either "name" or "task" parameter',
2380
2385
  "tool.invalid_params": "Invalid parameters",
2381
- "tool.skill_budget": "[Skill loaded. {remaining} tokens remaining in skills budget]",
2386
+ "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.',
2382
2387
  "tool.skill_available_hint": "Available skills",
2383
2388
  "tool.no_results": 'No results found for "{query}"',
2384
2389
  "tool.search_results": `Search results for "{query}":
@@ -2893,6 +2898,8 @@ var init_ru = __esm(() => {
2893
2898
  "tool.friendly.web_search": "Поиск в интернете",
2894
2899
  "tool.friendly.web_fetch": "Загрузка страницы",
2895
2900
  "tool.friendly.web_browse": "Просмотр страницы",
2901
+ "tool.web_fetch_result": "Загружена страница: {url} — {chars} симв., {lines} строк{truncated}",
2902
+ "tool.web_browse_result": "Просмотрена страница: {url} — {chars} симв., {lines} строк{truncated}",
2896
2903
  "tool.friendly.browser": "Браузер",
2897
2904
  "tool.friendly.subagent": "Задача подагенту",
2898
2905
  "tool.friendly.question": "Вопрос пользователю",
@@ -2923,7 +2930,7 @@ var init_ru = __esm(() => {
2923
2930
  "tool.question.answered": "Пользователь ответил на ваши вопросы: {formatted}. Теперь продолжайте с учётом ответов.",
2924
2931
  "tool.name_or_task": 'Укажите параметр "name" или "task"',
2925
2932
  "tool.invalid_params": "Неверные параметры",
2926
- "tool.skill_budget": "[Скилл загружен. Осталось {remaining} токенов в бюджете скиллов]",
2933
+ "tool.skill_budget": 'Скилл "{name}" загружен ({tokens} токенов, осталось {remaining} в бюджете скиллов). Контент скилла теперь в системном промпте — перезагрузка после компрессии не нужна.',
2927
2934
  "tool.skill_available_hint": "Доступные скиллы",
2928
2935
  "tool.no_results": 'Нет результатов по "{query}"',
2929
2936
  "tool.search_results": `Результаты поиска "{query}":
@@ -8977,28 +8984,6 @@ var init_stuck_detector = __esm(() => {
8977
8984
  init_i18n();
8978
8985
  });
8979
8986
 
8980
- // src/modules/skills/error-skill-map.ts
8981
- function suggestSkill(errorOutput) {
8982
- for (const { pattern, skill } of ERROR_SKILL_MAP) {
8983
- if (pattern.test(errorOutput))
8984
- return skill;
8985
- }
8986
- return null;
8987
- }
8988
- var ERROR_SKILL_MAP;
8989
- var init_error_skill_map = __esm(() => {
8990
- ERROR_SKILL_MAP = [
8991
- { pattern: /TS\d{4}:/i, skill: "typescript-expert" },
8992
- { pattern: /Cannot find name|No overload matches/i, skill: "typescript-type-expert" },
8993
- { pattern: /ts-node|tsx.*error/i, skill: "typescript-expert" },
8994
- { pattern: /Module not found|Cannot resolve module/i, skill: "typescript-expert" },
8995
- { pattern: /ECONNREFUSED|ETIMEDOUT|fetch failed/i, skill: "devops-expert" },
8996
- { pattern: /permission denied|EACCES/i, skill: "linux-server-expert" },
8997
- { pattern: /docker|container/i, skill: "docker-expert" },
8998
- { pattern: /jest|vitest|test.*fail/i, skill: "vitest-testing-expert" }
8999
- ];
9000
- });
9001
-
9002
8987
  // src/modules/execution/moe-executor.ts
9003
8988
  function isTransientError(error) {
9004
8989
  return TRANSIENT_ERROR_PATTERNS.some((p) => error.includes(p));
@@ -9126,7 +9111,6 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
9126
9111
  continue;
9127
9112
  }
9128
9113
  const hints = stuckDetector.getActionableHints();
9129
- const suggestedSkill = suggestSkill(lastError);
9130
9114
  let errorDetail = result.output;
9131
9115
  if (hints.length > 0) {
9132
9116
  errorDetail += `
@@ -9134,10 +9118,10 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
9134
9118
  ${t("exec.hints", { hints: hints.map((h) => `- ${h}`).join(`
9135
9119
  `) })}`;
9136
9120
  }
9137
- if (suggestedSkill) {
9121
+ if (lastError) {
9138
9122
  errorDetail += `
9139
9123
 
9140
- Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9124
+ If relevant skills are available, consider loading one with load_skill for expert guidance.`;
9141
9125
  }
9142
9126
  return {
9143
9127
  subtaskId: subtask.id,
@@ -9157,7 +9141,6 @@ Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9157
9141
  continue;
9158
9142
  }
9159
9143
  const hints = stuckDetector.getActionableHints();
9160
- const suggestedSkill = suggestSkill(lastError);
9161
9144
  let errorDetail = e.message;
9162
9145
  if (hints.length > 0) {
9163
9146
  errorDetail += `
@@ -9165,10 +9148,10 @@ Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9165
9148
  ${t("exec.hints", { hints: hints.map((h) => `- ${h}`).join(`
9166
9149
  `) })}`;
9167
9150
  }
9168
- if (suggestedSkill) {
9151
+ if (lastError) {
9169
9152
  errorDetail += `
9170
9153
 
9171
- Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9154
+ If relevant skills are available, consider loading one with load_skill for expert guidance.`;
9172
9155
  }
9173
9156
  return {
9174
9157
  subtaskId: subtask.id,
@@ -9207,7 +9190,12 @@ class MoEExecutor {
9207
9190
  const warnings = [];
9208
9191
  const waves = topologicalSort(plan.subtasks);
9209
9192
  if (waves.length === 0) {
9210
- return { success: false, results: [], errors: ["Failed to topologically sort subtasks (possible cycle)"], warnings: [] };
9193
+ return {
9194
+ success: false,
9195
+ results: [],
9196
+ errors: ["Failed to topologically sort subtasks (possible cycle)"],
9197
+ warnings: []
9198
+ };
9211
9199
  }
9212
9200
  const sortedCount = waves.flat().length;
9213
9201
  if (sortedCount < plan.subtasks.length) {
@@ -9215,7 +9203,9 @@ class MoEExecutor {
9215
9203
  return {
9216
9204
  success: false,
9217
9205
  results: [],
9218
- errors: [`Missing subtasks after topological sort: ${missing.join(", ")} (dangling or invalid depends_on)`],
9206
+ errors: [
9207
+ `Missing subtasks after topological sort: ${missing.join(", ")} (dangling or invalid depends_on)`
9208
+ ],
9219
9209
  warnings: []
9220
9210
  };
9221
9211
  }
@@ -9251,7 +9241,6 @@ class MoEExecutor {
9251
9241
  var TRANSIENT_ERROR_PATTERNS;
9252
9242
  var init_moe_executor = __esm(() => {
9253
9243
  init_stuck_detector();
9254
- init_error_skill_map();
9255
9244
  init_i18n();
9256
9245
  TRANSIENT_ERROR_PATTERNS = [
9257
9246
  "timeout",
@@ -10131,11 +10120,16 @@ ${taskReminder}</system-summary>`
10131
10120
  }
10132
10121
  if (hallucinationResult.status === "warn") {
10133
10122
  logger.warn(`Hallucination warning: ${hallucinationResult.reason}`);
10134
- const warnPrefix = t("hall.uncertainty_prefix");
10135
- if (onChunk) {
10136
- onChunk(warnPrefix);
10123
+ const warnLine = `${t("hall.uncertainty_prefix").trim()} ${hallucinationResult.reason ?? ""}`;
10124
+ if (onMeta) {
10125
+ onMeta(`
10126
+ ${pc2.yellow(warnLine)}
10127
+ `);
10128
+ } else if (onChunk) {
10129
+ onChunk(`
10130
+ ${warnLine}
10131
+ `);
10137
10132
  }
10138
- lastText = warnPrefix + lastText;
10139
10133
  }
10140
10134
  if (hallucinationResult.status === "retry") {
10141
10135
  if (this.deps.exitOnComplete) {
@@ -10673,8 +10667,8 @@ var init_confidence = __esm(() => {
10673
10667
  });
10674
10668
 
10675
10669
  // src/modules/hallucination/factual.ts
10676
- import { existsSync as existsSync20 } from "fs";
10677
- import { resolve as resolve11, isAbsolute } from "path";
10670
+ import { existsSync as existsSync20, readdirSync as readdirSync4 } from "fs";
10671
+ import { resolve as resolve11, isAbsolute, join as join12 } from "path";
10678
10672
  function looksLikeFilePath(s) {
10679
10673
  const lower = s.toLowerCase();
10680
10674
  if (TECH_NAMES.has(lower))
@@ -10687,6 +10681,12 @@ function looksLikeFilePath(s) {
10687
10681
 
10688
10682
  class FactualCheck {
10689
10683
  baseDir;
10684
+ nameCache = null;
10685
+ nameCacheTime = 0;
10686
+ lastRescan = 0;
10687
+ static NAME_CACHE_TTL_MS = 5000;
10688
+ static RESCAN_COOLDOWN_MS = 2000;
10689
+ static MAX_INDEXED_FILES = 20000;
10690
10690
  constructor(baseDir) {
10691
10691
  this.baseDir = baseDir;
10692
10692
  }
@@ -10696,8 +10696,7 @@ class FactualCheck {
10696
10696
  return { status: "pass" };
10697
10697
  const nonExistent = [];
10698
10698
  for (const fp of filePaths) {
10699
- const abs = isAbsolute(fp) ? fp : resolve11(this.baseDir, fp);
10700
- if (!existsSync20(abs)) {
10699
+ if (!this.pathExists(fp)) {
10701
10700
  nonExistent.push(fp);
10702
10701
  }
10703
10702
  }
@@ -10711,15 +10710,89 @@ class FactualCheck {
10711
10710
  }
10712
10711
  return { status: "pass" };
10713
10712
  }
10713
+ pathExists(fp) {
10714
+ if (isAbsolute(fp))
10715
+ return existsSync20(fp);
10716
+ if (!fp.includes("/") && !fp.includes("\\")) {
10717
+ return this.bareNameExists(fp);
10718
+ }
10719
+ return existsSync20(resolve11(this.baseDir, fp));
10720
+ }
10721
+ bareNameExists(name) {
10722
+ if (existsSync20(resolve11(this.baseDir, name)))
10723
+ return true;
10724
+ if (this.indexHas(name))
10725
+ return true;
10726
+ const now = Date.now();
10727
+ if (now - this.lastRescan < FactualCheck.RESCAN_COOLDOWN_MS)
10728
+ return false;
10729
+ this.lastRescan = now;
10730
+ this.nameCache = null;
10731
+ this.nameCacheTime = 0;
10732
+ return this.indexHas(name);
10733
+ }
10734
+ indexHas(name) {
10735
+ return (this.getNameIndex().get(name)?.length ?? 0) > 0;
10736
+ }
10737
+ getNameIndex() {
10738
+ const now = Date.now();
10739
+ if (this.nameCache && now - this.nameCacheTime < FactualCheck.NAME_CACHE_TTL_MS) {
10740
+ return this.nameCache;
10741
+ }
10742
+ const index = new Map;
10743
+ const scanned = this.scanDir(this.baseDir, index, 0);
10744
+ if (scanned > 0 || index.size > 0) {
10745
+ this.nameCache = index;
10746
+ this.nameCacheTime = now;
10747
+ }
10748
+ return index;
10749
+ }
10750
+ scanDir(dir, index, count) {
10751
+ if (count >= FactualCheck.MAX_INDEXED_FILES)
10752
+ return count;
10753
+ let entries;
10754
+ try {
10755
+ entries = readdirSync4(dir, { withFileTypes: true });
10756
+ } catch {
10757
+ return count;
10758
+ }
10759
+ for (const entry of entries) {
10760
+ if (count >= FactualCheck.MAX_INDEXED_FILES)
10761
+ break;
10762
+ const full = join12(dir, entry.name);
10763
+ if (entry.isDirectory()) {
10764
+ if (!IGNORED_DIRS.has(entry.name)) {
10765
+ count = this.scanDir(full, index, count);
10766
+ }
10767
+ } else if (entry.isFile()) {
10768
+ const list = index.get(entry.name);
10769
+ if (list)
10770
+ list.push(full);
10771
+ else
10772
+ index.set(entry.name, [full]);
10773
+ count++;
10774
+ }
10775
+ }
10776
+ return count;
10777
+ }
10714
10778
  extractFilePaths(text) {
10715
10779
  const pattern = /\b(?:[a-zA-Z]:[\\/])?[\w./\\-]+\.[a-z]{2,6}\b/gi;
10716
10780
  const matches = text.match(pattern) || [];
10717
10781
  return [...new Set(matches)].filter(looksLikeFilePath);
10718
10782
  }
10719
10783
  }
10720
- var NON_FILE_EXTENSIONS, TECH_NAMES;
10784
+ var IGNORED_DIRS, NON_FILE_EXTENSIONS, TECH_NAMES;
10721
10785
  var init_factual = __esm(() => {
10722
10786
  init_i18n();
10787
+ IGNORED_DIRS = new Set([
10788
+ "node_modules",
10789
+ ".git",
10790
+ "dist",
10791
+ "build",
10792
+ "coverage",
10793
+ ".mma",
10794
+ "_testing"
10795
+ ]);
10723
10796
  NON_FILE_EXTENSIONS = new Set([
10724
10797
  "com",
10725
10798
  "org",
@@ -11365,36 +11438,56 @@ var init_web_fetch = __esm(() => {
11365
11438
  };
11366
11439
  }
11367
11440
  try {
11368
- const response = await fetch(url, { signal: AbortSignal.timeout(securityConfig?.requestTimeout || 15000) });
11441
+ const response = await fetch(url, {
11442
+ signal: AbortSignal.timeout(securityConfig?.requestTimeout || 15000)
11443
+ });
11369
11444
  if (!response.ok) {
11370
- return { success: false, output: t("error.http", { status: response.status, statusText: response.statusText }) };
11445
+ return {
11446
+ success: false,
11447
+ output: t("error.http", {
11448
+ status: response.status,
11449
+ statusText: response.statusText
11450
+ })
11451
+ };
11371
11452
  }
11372
11453
  const contentType = response.headers.get("content-type") || "";
11373
11454
  const text = await response.text();
11374
11455
  const cleaned = contentType.includes("html") ? stripHtml(text) : text;
11375
11456
  logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
11376
- if (cleaned.length > (securityConfig?.maxResponseSize || MAX_CHARS)) {
11377
- let content = cleaned.slice(0, securityConfig?.maxResponseSize || MAX_CHARS) + t("file.truncated");
11378
- const lines2 = content.split(`
11379
- `);
11380
- if (lines2.length > MAX_PREVIEW_LINES) {
11381
- content = lines2.slice(0, MAX_PREVIEW_LINES).join(`
11382
- `) + `
11383
- ... (${lines2.length - MAX_PREVIEW_LINES} more lines)`;
11384
- }
11385
- return { success: true, output: content };
11457
+ const fullChars = cleaned.length;
11458
+ const fullLines = cleaned.split(`
11459
+ `).length;
11460
+ const maxChars = securityConfig?.maxResponseSize || MAX_CHARS;
11461
+ let content;
11462
+ if (cleaned.length > maxChars) {
11463
+ content = cleaned.slice(0, maxChars) + t("file.truncated");
11464
+ } else {
11465
+ content = cleaned;
11386
11466
  }
11387
- const lines = cleaned.split(`
11467
+ const contentLines = content.split(`
11388
11468
  `);
11389
- if (lines.length > MAX_PREVIEW_LINES) {
11390
- return { success: true, output: lines.slice(0, MAX_PREVIEW_LINES).join(`
11469
+ if (contentLines.length > MAX_PREVIEW_LINES) {
11470
+ content = contentLines.slice(0, MAX_PREVIEW_LINES).join(`
11391
11471
  `) + `
11392
- ... (${lines.length - MAX_PREVIEW_LINES} more lines)` };
11472
+ ... (${contentLines.length - MAX_PREVIEW_LINES} more lines)`;
11393
11473
  }
11394
- return { success: true, output: cleaned || t("file.empty_page") };
11474
+ const truncated = cleaned.length > maxChars || fullLines > MAX_PREVIEW_LINES ? t("file.truncated").trim() : "";
11475
+ return {
11476
+ success: true,
11477
+ output: content || t("file.empty_page"),
11478
+ display: t("tool.web_fetch_result", {
11479
+ url: sanitizeUrl(url),
11480
+ chars: String(fullChars),
11481
+ lines: String(fullLines),
11482
+ truncated
11483
+ })
11484
+ };
11395
11485
  } catch (e) {
11396
11486
  logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Error: ${e.message}`);
11397
- return { success: false, output: t("error.fetch_failed", { message: e.message }) };
11487
+ return {
11488
+ success: false,
11489
+ output: t("error.fetch_failed", { message: e.message })
11490
+ };
11398
11491
  }
11399
11492
  }
11400
11493
  };
@@ -11430,23 +11523,49 @@ var init_web_browse = __esm(() => {
11430
11523
  };
11431
11524
  }
11432
11525
  try {
11433
- const response = await fetch(url, { signal: AbortSignal.timeout(securityConfig?.requestTimeout || 15000) });
11526
+ const response = await fetch(url, {
11527
+ signal: AbortSignal.timeout(securityConfig?.requestTimeout || 15000)
11528
+ });
11434
11529
  const text = await response.text();
11435
11530
  const stripped = text.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<[^>]+>/g, "").replace(/&[^;]+;/g, " ").replace(/\s+/g, " ").trim();
11436
11531
  logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
11437
- const maxLen = securityConfig?.maxResponseSize || MAX_CHARS2;
11438
- let content = stripped.length > maxLen ? stripped.slice(0, maxLen) + t("file.truncated") : stripped;
11439
- const lines = content.split(`
11532
+ const fullChars = stripped.length;
11533
+ const fullLines = stripped.split(`
11534
+ `).length;
11535
+ const maxChars = securityConfig?.maxResponseSize || MAX_CHARS2;
11536
+ let content;
11537
+ if (stripped.length > maxChars) {
11538
+ content = stripped.slice(0, maxChars) + t("file.truncated");
11539
+ } else {
11540
+ content = stripped;
11541
+ }
11542
+ const contentLines = content.split(`
11440
11543
  `);
11441
- if (lines.length > MAX_PREVIEW_LINES) {
11442
- content = lines.slice(0, MAX_PREVIEW_LINES).join(`
11544
+ if (contentLines.length > MAX_PREVIEW_LINES) {
11545
+ content = contentLines.slice(0, MAX_PREVIEW_LINES).join(`
11443
11546
  `) + `
11444
- ... (${lines.length - MAX_PREVIEW_LINES} more lines)`;
11547
+ ... (${contentLines.length - MAX_PREVIEW_LINES} more lines)`;
11445
11548
  }
11446
- return { success: true, output: content || t("file.empty_page") };
11549
+ const truncated = stripped.length > maxChars || fullLines > MAX_PREVIEW_LINES ? t("file.truncated").trim() : "";
11550
+ return {
11551
+ success: true,
11552
+ output: content || t("file.empty_page"),
11553
+ display: t("tool.web_browse_result", {
11554
+ url: sanitizeUrl(url),
11555
+ chars: String(fullChars),
11556
+ lines: String(fullLines),
11557
+ truncated
11558
+ })
11559
+ };
11447
11560
  } catch (err) {
11448
11561
  logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Error: ${err.message}`);
11449
- return { success: false, output: t("error.fetch_url_failed", { url: sanitizeUrl(url), message: err.message }) };
11562
+ return {
11563
+ success: false,
11564
+ output: t("error.fetch_url_failed", {
11565
+ url: sanitizeUrl(url),
11566
+ message: err.message
11567
+ })
11568
+ };
11450
11569
  }
11451
11570
  }
11452
11571
  };
@@ -11457,31 +11576,23 @@ function createLoadSkillTool(skillsModule) {
11457
11576
  return {
11458
11577
  name: "load_skill",
11459
11578
  tags: ["core"],
11460
- description: "Load a skill by name or task description. Skills provide specialized instructions and workflows. Only use when the task clearly requires domain-specific knowledge. If loading fails because the skill is too large, continue the task without it.",
11579
+ description: "Load a skill by name. Skills provide specialized instructions and workflows. When loaded, the skill content is injected into the system prompt (not conversation history) so it persists through context compaction. Only use when the task clearly requires domain-specific knowledge.",
11461
11580
  parameters: {
11462
11581
  type: "object",
11463
11582
  properties: {
11464
- name: { type: "string", description: "Skill name to load directly" },
11465
- task: {
11583
+ name: {
11466
11584
  type: "string",
11467
- description: "Task description to find matching skill"
11585
+ description: "Exact skill name to load (see [Available Skills] for names)"
11468
11586
  }
11469
- }
11587
+ },
11588
+ required: ["name"]
11470
11589
  },
11471
11590
  handler: async (_ctx, args) => {
11472
11591
  const name = args.name ? String(args.name) : undefined;
11473
- const task = args.task ? String(args.task) : undefined;
11474
- if (!name && !task) {
11475
- return { success: false, output: t("tool.name_or_task") };
11476
- }
11477
- let result;
11478
- if (name) {
11479
- result = skillsModule.loadByName(name);
11480
- } else if (task) {
11481
- result = skillsModule.loadByMatch(task);
11482
- } else {
11592
+ if (!name) {
11483
11593
  return { success: false, output: t("tool.invalid_params") };
11484
11594
  }
11595
+ const result = skillsModule.loadByName(name);
11485
11596
  if (!result.success) {
11486
11597
  const available = skillsModule.getAvailable();
11487
11598
  const hint = available.length > 0 ? `
@@ -11489,16 +11600,15 @@ function createLoadSkillTool(skillsModule) {
11489
11600
  ${t("tool.skill_available_hint")}: ${available.map((s) => s.name).join(", ")}` : "";
11490
11601
  return { success: false, output: result.message + hint };
11491
11602
  }
11492
- const skill = result.skill;
11493
11603
  const budget = skillsModule.getBudget();
11604
+ const tokens = result.skill ? Math.ceil(result.skill.content.length / 4) : 0;
11494
11605
  return {
11495
11606
  success: true,
11496
- output: `${result.message}
11497
-
11498
- --- Skill Content ---
11499
- ${skill.content}
11500
-
11501
- ${t("tool.skill_budget", { remaining: budget.remaining })}`
11607
+ output: t("tool.skill_budget", {
11608
+ name,
11609
+ tokens,
11610
+ remaining: budget.remaining
11611
+ })
11502
11612
  };
11503
11613
  }
11504
11614
  };
@@ -12272,7 +12382,7 @@ ${JSON.stringify(result, null, 2)}`
12272
12382
 
12273
12383
  // src/tools/search-history.ts
12274
12384
  import * as fs from "fs";
12275
- import { join as join12 } from "path";
12385
+ import { join as join13 } from "path";
12276
12386
  import { homedir as homedir5 } from "os";
12277
12387
  function searchFile(filePath, query, maxResults, results) {
12278
12388
  if (!fs.existsSync(filePath))
@@ -12316,7 +12426,7 @@ var init_search_history = __esm(() => {
12316
12426
  const query = String(args.query || "").toLowerCase();
12317
12427
  const maxResults = Number(args.maxResults) || 5;
12318
12428
  const sessionId = args.sessionId ? String(args.sessionId) : null;
12319
- const sessionDir = join12(homedir5(), ".mma", "sessions");
12429
+ const sessionDir = join13(homedir5(), ".mma", "sessions");
12320
12430
  const results = [];
12321
12431
  try {
12322
12432
  if (!fs.existsSync(sessionDir)) {
@@ -12331,7 +12441,7 @@ var init_search_history = __esm(() => {
12331
12441
  continue;
12332
12442
  if (sessionId && entry.name !== sessionId)
12333
12443
  continue;
12334
- const historyFile = join12(sessionDir, entry.name, "history.jsonl");
12444
+ const historyFile = join13(sessionDir, entry.name, "history.jsonl");
12335
12445
  searchFile(historyFile, query, maxResults, results);
12336
12446
  if (results.length >= maxResults)
12337
12447
  break;
@@ -12359,7 +12469,7 @@ var init_search_history = __esm(() => {
12359
12469
 
12360
12470
  // src/tools/remember.ts
12361
12471
  import { homedir as homedir6 } from "os";
12362
- import { join as join13 } from "path";
12472
+ import { join as join14 } from "path";
12363
12473
  var CATEGORIES, rememberTool;
12364
12474
  var init_remember = __esm(() => {
12365
12475
  init_i18n();
@@ -12397,7 +12507,7 @@ var init_remember = __esm(() => {
12397
12507
  if (!CATEGORIES.includes(category)) {
12398
12508
  return { success: false, output: t("tool.invalid_params") };
12399
12509
  }
12400
- const memoryDir = join13(homedir6(), ".mma", "memory");
12510
+ const memoryDir = join14(homedir6(), ".mma", "memory");
12401
12511
  const store = new MemoryStore(memoryDir);
12402
12512
  try {
12403
12513
  if (category === "preferences") {
@@ -12430,7 +12540,7 @@ var init_remember = __esm(() => {
12430
12540
 
12431
12541
  // src/tools/recall.ts
12432
12542
  import { homedir as homedir7 } from "os";
12433
- import { join as join14 } from "path";
12543
+ import { join as join15 } from "path";
12434
12544
  function formatAll(store) {
12435
12545
  const parts = [];
12436
12546
  const prefs = store.getPreferences();
@@ -12513,7 +12623,7 @@ var init_recall = __esm(() => {
12513
12623
  handler: async (_ctx, args) => {
12514
12624
  const query = args.query ? String(args.query) : "";
12515
12625
  const category = args.category ? String(args.category) : "";
12516
- const memoryDir = join14(homedir7(), ".mma", "memory");
12626
+ const memoryDir = join15(homedir7(), ".mma", "memory");
12517
12627
  const store = new MemoryStore(memoryDir);
12518
12628
  try {
12519
12629
  if (!query && !category) {
@@ -12709,15 +12819,15 @@ function buildIndexInjectionScript() {
12709
12819
 
12710
12820
  // src/modules/browser/cookie-store.ts
12711
12821
  import { readFile, writeFile, mkdir } from "fs/promises";
12712
- import { join as join15 } from "path";
12822
+ import { join as join16 } from "path";
12713
12823
 
12714
12824
  class CookieStore {
12715
12825
  filePath;
12716
12826
  constructor(cookieDir) {
12717
- this.filePath = join15(cookieDir, "cookies.json");
12827
+ this.filePath = join16(cookieDir, "cookies.json");
12718
12828
  }
12719
12829
  async save(cookies) {
12720
- await mkdir(join15(this.filePath, ".."), { recursive: true });
12830
+ await mkdir(join16(this.filePath, ".."), { recursive: true });
12721
12831
  await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
12722
12832
  }
12723
12833
  async load() {
@@ -13037,10 +13147,10 @@ var init_types = __esm(() => {
13037
13147
  });
13038
13148
 
13039
13149
  // src/tools/browser.ts
13040
- import { join as join16 } from "path";
13150
+ import { join as join17 } from "path";
13041
13151
  function getSession(ctx) {
13042
13152
  if (!session) {
13043
- const cookieDir = join16(ctx.baseDir, ".mma", "browser");
13153
+ const cookieDir = join17(ctx.baseDir, ".mma", "browser");
13044
13154
  session = new BrowserSession({
13045
13155
  ...DEFAULT_BROWSER_CONFIG,
13046
13156
  headless: ctx.config.browser?.headless ?? true,
@@ -13170,8 +13280,8 @@ async function readClipboardFallback() {
13170
13280
  const { platform: platform3 } = await import("os");
13171
13281
  const { execSync } = await import("child_process");
13172
13282
  const { readFileSync: readFileSync13, unlinkSync: unlinkSync3 } = await import("fs");
13173
- const { join: join17 } = await import("path");
13174
- const tmpPath = join17(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13283
+ const { join: join18 } = await import("path");
13284
+ const tmpPath = join18(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13175
13285
  try {
13176
13286
  if (platform3() === "linux") {
13177
13287
  execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
@@ -13448,16 +13558,16 @@ class ModuleRegistry {
13448
13558
  }
13449
13559
 
13450
13560
  // src/modules/plugins/loader.ts
13451
- import { readdirSync as readdirSync5, existsSync as existsSync23, statSync as statSync4 } from "fs";
13452
- import { join as join17 } from "path";
13561
+ import { readdirSync as readdirSync6, existsSync as existsSync23, statSync as statSync4 } from "fs";
13562
+ import { join as join18 } from "path";
13453
13563
 
13454
13564
  class PluginLoader {
13455
13565
  loadFromDir(dirPath, pluginManager, logger) {
13456
13566
  if (!existsSync23(dirPath))
13457
13567
  return;
13458
- const entries = readdirSync5(dirPath);
13568
+ const entries = readdirSync6(dirPath);
13459
13569
  for (const entry of entries) {
13460
- const fullPath = join17(dirPath, entry);
13570
+ const fullPath = join18(dirPath, entry);
13461
13571
  if (!statSync4(fullPath).isFile())
13462
13572
  continue;
13463
13573
  if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
@@ -13482,7 +13592,7 @@ var init_loader = __esm(() => {
13482
13592
  // src/modules/plugins/builtin/lint-on-write.ts
13483
13593
  import { spawn as spawn4, execSync } from "child_process";
13484
13594
  import { existsSync as existsSync24, readFileSync as readFileSync13 } from "fs";
13485
- import { resolve as resolve13, extname as extname4, join as join18 } from "path";
13595
+ import { resolve as resolve13, extname as extname4, join as join19 } from "path";
13486
13596
  import { platform as platform3 } from "os";
13487
13597
  function getWinDecoder() {
13488
13598
  if (_winDecoder === undefined) {
@@ -13567,7 +13677,7 @@ class LintOnWritePlugin {
13567
13677
  }
13568
13678
  async runProjectLint(ctx, result) {
13569
13679
  try {
13570
- const packageJsonPath = join18(ctx.baseDir, "package.json");
13680
+ const packageJsonPath = join19(ctx.baseDir, "package.json");
13571
13681
  if (!existsSync24(packageJsonPath)) {
13572
13682
  return;
13573
13683
  }
@@ -13587,7 +13697,7 @@ class LintOnWritePlugin {
13587
13697
  }
13588
13698
  }
13589
13699
  async runProjectTypeCheck(ctx, result) {
13590
- const tsconfigPath = join18(ctx.baseDir, "tsconfig.json");
13700
+ const tsconfigPath = join19(ctx.baseDir, "tsconfig.json");
13591
13701
  if (!existsSync24(tsconfigPath)) {
13592
13702
  return;
13593
13703
  }
@@ -13862,16 +13972,16 @@ var init_auditor = __esm(() => {
13862
13972
 
13863
13973
  // src/modules/execution/plan-persister.ts
13864
13974
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11, existsSync as existsSync26 } from "fs";
13865
- import { join as join19 } from "path";
13975
+ import { join as join20 } from "path";
13866
13976
 
13867
13977
  class PlanPersister {
13868
13978
  filePath;
13869
13979
  constructor(baseDir) {
13870
- const mmaDir = join19(baseDir, ".mma");
13980
+ const mmaDir = join20(baseDir, ".mma");
13871
13981
  if (!existsSync26(mmaDir)) {
13872
13982
  mkdirSync11(mmaDir, { recursive: true });
13873
13983
  }
13874
- this.filePath = join19(mmaDir, "plan.json");
13984
+ this.filePath = join20(mmaDir, "plan.json");
13875
13985
  }
13876
13986
  save(plan) {
13877
13987
  const file = {
@@ -14296,9 +14406,8 @@ Sub-tasks: ${note}`
14296
14406
  const recovery = this.stuckDetector.getRecoveryMessage();
14297
14407
  if (recovery && ctx.contextManager) {
14298
14408
  const lastError = this.stuckDetector.getLastErrorOutput();
14299
- const suggestedSkill = suggestSkill(lastError);
14300
- const skillHint = suggestedSkill ? `
14301
- Consider loading the "${suggestedSkill}" skill for expert guidance on this error.` : "";
14409
+ const skillHint = lastError ? `
14410
+ If you have relevant skills available, consider loading one with load_skill for expert guidance.` : "";
14302
14411
  const actionableHints = this.stuckDetector.getActionableHints();
14303
14412
  const actionableHintStr = actionableHints.length > 0 ? `
14304
14413
  ${t("exec.hints", { hints: actionableHints.map((h) => `- ${h}`).join(`
@@ -14542,12 +14651,11 @@ var init_module = __esm(() => {
14542
14651
  init_auditor();
14543
14652
  init_plan_persister();
14544
14653
  init_plan_coverage();
14545
- init_error_skill_map();
14546
14654
  });
14547
14655
 
14548
14656
  // src/modules/security/session-encryption.ts
14549
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, existsSync as existsSync28, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
14550
- import { join as join20 } from "path";
14657
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, existsSync as existsSync28, readdirSync as readdirSync7, unlinkSync as unlinkSync3 } from "fs";
14658
+ import { join as join21 } from "path";
14551
14659
  import { homedir as homedir8 } from "os";
14552
14660
 
14553
14661
  class SessionFileEncryptor {
@@ -14556,7 +14664,7 @@ class SessionFileEncryptor {
14556
14664
  constructor(config) {
14557
14665
  this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
14558
14666
  this.encryptor = new ConfigEncryptor({
14559
- keyPath: config?.keyPath || join20(homedir8(), ".mma", ".session-encryption-key")
14667
+ keyPath: config?.keyPath || join21(homedir8(), ".mma", ".session-encryption-key")
14560
14668
  });
14561
14669
  }
14562
14670
  isEnabled() {
@@ -14626,9 +14734,9 @@ class SessionFileEncryptor {
14626
14734
  encryptSessionDirectory(sessionDir) {
14627
14735
  if (!this.config.enabled)
14628
14736
  return;
14629
- const files = readdirSync6(sessionDir);
14737
+ const files = readdirSync7(sessionDir);
14630
14738
  for (const file of files) {
14631
- const filePath = join20(sessionDir, file);
14739
+ const filePath = join21(sessionDir, file);
14632
14740
  if (existsSync28(filePath) && !file.endsWith(".enc")) {
14633
14741
  try {
14634
14742
  const content = readFileSync16(filePath, "utf8");
@@ -14642,10 +14750,10 @@ class SessionFileEncryptor {
14642
14750
  decryptSessionDirectory(sessionDir) {
14643
14751
  if (!this.config.enabled)
14644
14752
  return;
14645
- const files = readdirSync6(sessionDir);
14753
+ const files = readdirSync7(sessionDir);
14646
14754
  for (const file of files) {
14647
14755
  if (file.endsWith(".enc")) {
14648
- const encFilePath = join20(sessionDir, file);
14756
+ const encFilePath = join21(sessionDir, file);
14649
14757
  const decFilePath = encFilePath.slice(0, -4);
14650
14758
  try {
14651
14759
  const content = readFileSync16(encFilePath, "utf8");
@@ -14672,13 +14780,13 @@ var init_session_encryption = __esm(() => {
14672
14780
  import {
14673
14781
  existsSync as existsSync29,
14674
14782
  mkdirSync as mkdirSync12,
14675
- readdirSync as readdirSync7,
14783
+ readdirSync as readdirSync8,
14676
14784
  readFileSync as readFileSync17,
14677
14785
  rmSync,
14678
14786
  writeFileSync as writeFileSync10,
14679
14787
  appendFileSync as appendFileSync5
14680
14788
  } from "fs";
14681
- import { join as join21 } from "path";
14789
+ import { join as join22 } from "path";
14682
14790
  import { gzipSync } from "zlib";
14683
14791
 
14684
14792
  class SessionStore {
@@ -14692,7 +14800,7 @@ class SessionStore {
14692
14800
  }
14693
14801
  }
14694
14802
  getSessionDir(id) {
14695
- return join21(this.baseDir, id);
14803
+ return join22(this.baseDir, id);
14696
14804
  }
14697
14805
  updateEncryption(config) {
14698
14806
  if (config?.enabled) {
@@ -14708,16 +14816,16 @@ class SessionStore {
14708
14816
  mkdirSync12(this.baseDir, { recursive: true });
14709
14817
  }
14710
14818
  sessionDir(id) {
14711
- return join21(this.baseDir, id);
14819
+ return join22(this.baseDir, id);
14712
14820
  }
14713
14821
  metaPath(id) {
14714
- return join21(this.sessionDir(id), "meta.json");
14822
+ return join22(this.sessionDir(id), "meta.json");
14715
14823
  }
14716
14824
  historyPath(id) {
14717
- return join21(this.sessionDir(id), "history.jsonl");
14825
+ return join22(this.sessionDir(id), "history.jsonl");
14718
14826
  }
14719
14827
  sessionLogPath(id) {
14720
- return join21(this.sessionDir(id), "session.jsonl");
14828
+ return join22(this.sessionDir(id), "session.jsonl");
14721
14829
  }
14722
14830
  sessionExists(id) {
14723
14831
  return existsSync29(this.metaPath(id));
@@ -14841,7 +14949,7 @@ class SessionStore {
14841
14949
  listSessions() {
14842
14950
  if (!existsSync29(this.baseDir))
14843
14951
  return [];
14844
- const entries = readdirSync7(this.baseDir, { withFileTypes: true });
14952
+ const entries = readdirSync8(this.baseDir, { withFileTypes: true });
14845
14953
  const sessions = [];
14846
14954
  for (const entry of entries) {
14847
14955
  if (entry.isDirectory()) {
@@ -14871,7 +14979,7 @@ class SessionStore {
14871
14979
  if (existsSync29(historyPath)) {
14872
14980
  const content = readFileSync17(historyPath, "utf-8");
14873
14981
  const compressed = gzipSync(content);
14874
- const gzPath = join21(this.baseDir, `${session2.id}.jsonl.gz`);
14982
+ const gzPath = join22(this.baseDir, `${session2.id}.jsonl.gz`);
14875
14983
  writeFileSync10(gzPath, compressed);
14876
14984
  rmSync(historyPath);
14877
14985
  }
@@ -15082,7 +15190,7 @@ class ProfileCompressor {
15082
15190
 
15083
15191
  // src/modules/user-profile/profile.ts
15084
15192
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
15085
- import { join as join22 } from "path";
15193
+ import { join as join23 } from "path";
15086
15194
  import { homedir as homedir9, hostname, platform as platform4, type } from "os";
15087
15195
  import { env } from "process";
15088
15196
 
@@ -15109,10 +15217,10 @@ class UserProfile {
15109
15217
  if (!existsSync30(this.profileDir)) {
15110
15218
  mkdirSync13(this.profileDir, { recursive: true });
15111
15219
  }
15112
- writeFileSync11(join22(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
15220
+ writeFileSync11(join23(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
15113
15221
  }
15114
15222
  load() {
15115
- const path = join22(this.profileDir, "profile.json");
15223
+ const path = join23(this.profileDir, "profile.json");
15116
15224
  if (!existsSync30(path))
15117
15225
  return null;
15118
15226
  try {
@@ -15151,8 +15259,8 @@ class UserProfile {
15151
15259
  var init_profile = () => {};
15152
15260
 
15153
15261
  // src/modules/skills/loader.ts
15154
- import { readdirSync as readdirSync8, readFileSync as readFileSync19, existsSync as existsSync31, statSync as statSync5 } from "fs";
15155
- import { join as join23 } from "path";
15262
+ import { readdirSync as readdirSync9, readFileSync as readFileSync19, existsSync as existsSync31, statSync as statSync5 } from "fs";
15263
+ import { join as join24 } from "path";
15156
15264
 
15157
15265
  class SkillsLoader {
15158
15266
  loadFromDir(dirPath) {
@@ -15163,9 +15271,9 @@ class SkillsLoader {
15163
15271
  return skills;
15164
15272
  }
15165
15273
  scanDir(dirPath, skills) {
15166
- const entries = readdirSync8(dirPath);
15274
+ const entries = readdirSync9(dirPath);
15167
15275
  for (const entry of entries) {
15168
- const fullPath = join23(dirPath, entry);
15276
+ const fullPath = join24(dirPath, entry);
15169
15277
  const stat = statSync5(fullPath);
15170
15278
  if (stat.isDirectory()) {
15171
15279
  this.scanDir(fullPath, skills);
@@ -15223,42 +15331,15 @@ class SkillsLoader {
15223
15331
  }
15224
15332
  var init_loader2 = () => {};
15225
15333
 
15226
- // src/modules/skills/matcher.ts
15227
- class SkillsMatcher {
15228
- match(taskDescription, skills, maxResults = 3) {
15229
- const taskWords = taskDescription.toLowerCase().split(/\W+/).filter((w) => w.length >= MIN_WORD_LENGTH);
15230
- const scored = skills.map((skill) => {
15231
- const allKeywords = [
15232
- skill.name.toLowerCase(),
15233
- skill.description.toLowerCase(),
15234
- ...skill.keywords.map((k) => k.toLowerCase())
15235
- ];
15236
- let score = 0;
15237
- for (const word of taskWords) {
15238
- for (const kw of allKeywords) {
15239
- if (kw === word || kw.length >= MIN_WORD_LENGTH && kw.includes(word)) {
15240
- score++;
15241
- }
15242
- }
15243
- }
15244
- return { skill, score };
15245
- });
15246
- return scored.filter((s) => s.score > 0).sort((a, b) => b.score - a.score).slice(0, maxResults).map((s) => s.skill);
15247
- }
15248
- }
15249
- var MIN_WORD_LENGTH = 4;
15250
-
15251
15334
  // src/modules/skills/module.ts
15252
15335
  class SkillsModule {
15253
15336
  name = "skills";
15254
15337
  availableSkills;
15255
15338
  loadedSkills = new Map;
15256
- matcher;
15257
15339
  budget;
15258
15340
  currentTokens = 0;
15259
- constructor(availableSkills, matcher, budget) {
15341
+ constructor(availableSkills, budget) {
15260
15342
  this.availableSkills = availableSkills;
15261
- this.matcher = matcher;
15262
15343
  this.budget = budget;
15263
15344
  }
15264
15345
  loadByName(name) {
@@ -15267,24 +15348,10 @@ class SkillsModule {
15267
15348
  }
15268
15349
  const skill = this.availableSkills.find((s) => s.name === name);
15269
15350
  if (!skill) {
15270
- const fuzzyMatches = this.matcher.match(name, this.availableSkills, 1);
15271
- if (fuzzyMatches.length > 0) {
15272
- return this.tryLoad(fuzzyMatches[0]);
15273
- }
15274
15351
  return { success: false, message: t("skill.not_found", { name }) };
15275
15352
  }
15276
15353
  return this.tryLoad(skill);
15277
15354
  }
15278
- loadByMatch(taskDescription) {
15279
- const matches = this.matcher.match(taskDescription, this.availableSkills, 1);
15280
- if (matches.length === 0) {
15281
- return {
15282
- success: false,
15283
- message: t("skill.no_match", { task: taskDescription })
15284
- };
15285
- }
15286
- return this.tryLoad(matches[0]);
15287
- }
15288
15355
  unload(name) {
15289
15356
  const skill = this.loadedSkills.get(name);
15290
15357
  if (!skill)
@@ -15303,7 +15370,8 @@ class SkillsModule {
15303
15370
  return this.availableSkills.find((s) => s.name === name);
15304
15371
  }
15305
15372
  search(query) {
15306
- return this.matcher.match(query, this.availableSkills, 10);
15373
+ const q = query.toLowerCase();
15374
+ return this.availableSkills.filter((s) => s.name.toLowerCase().includes(q) || s.description.toLowerCase().includes(q));
15307
15375
  }
15308
15376
  getBudget() {
15309
15377
  return {
@@ -15322,16 +15390,17 @@ class SkillsModule {
15322
15390
  lines.push("[Available Skills]");
15323
15391
  lines.push(t("skill.prompt_hint"));
15324
15392
  for (const skill of this.availableSkills) {
15325
- const desc = skill.description.slice(0, 60);
15393
+ const desc = skill.description.slice(0, 80);
15326
15394
  lines.push(`- ${skill.name}: ${desc}`);
15327
15395
  }
15328
- lines.push(t("skill.prompt_fallback"));
15329
15396
  }
15330
15397
  if (this.loadedSkills.size > 0) {
15398
+ lines.push("");
15331
15399
  lines.push("[Loaded Skills]");
15332
15400
  for (const skill of this.loadedSkills.values()) {
15333
- const desc = skill.description.slice(0, 80);
15334
- lines.push(`- ${skill.name}: ${desc}`);
15401
+ lines.push(`--- ${skill.name} (${this.estimateTokens(skill.content)} tokens) ---`);
15402
+ lines.push(skill.content);
15403
+ lines.push("");
15335
15404
  }
15336
15405
  }
15337
15406
  if (lines.length === 0)
@@ -15341,7 +15410,7 @@ class SkillsModule {
15341
15410
  const tokens = this.estimateTokens(content);
15342
15411
  return {
15343
15412
  content,
15344
- priority: "normal",
15413
+ priority: "high",
15345
15414
  essential: false,
15346
15415
  estimatedTokens: tokens
15347
15416
  };
@@ -15761,8 +15830,8 @@ var init_lsp = __esm(() => {
15761
15830
  });
15762
15831
 
15763
15832
  // src/modules/indexer/walker.ts
15764
- import { readdirSync as readdirSync9, readFileSync as readFileSync20, statSync as statSync6, existsSync as existsSync33, watch } from "fs";
15765
- import { join as join24, relative, extname as extname5 } from "path";
15833
+ import { readdirSync as readdirSync10, readFileSync as readFileSync20, statSync as statSync6, existsSync as existsSync33, watch } from "fs";
15834
+ import { join as join25, relative, extname as extname5 } from "path";
15766
15835
 
15767
15836
  class Indexer {
15768
15837
  baseDir;
@@ -15793,14 +15862,14 @@ class Indexer {
15793
15862
  return;
15794
15863
  let entries;
15795
15864
  try {
15796
- entries = readdirSync9(dir);
15865
+ entries = readdirSync10(dir);
15797
15866
  } catch {
15798
15867
  return;
15799
15868
  }
15800
15869
  for (const entry of entries) {
15801
15870
  if (count >= this.MAX_FILES)
15802
15871
  return;
15803
- const fullPath = join24(dir, entry);
15872
+ const fullPath = join25(dir, entry);
15804
15873
  const relPath = relative(this.baseDir, fullPath);
15805
15874
  const stat = statSync6(fullPath);
15806
15875
  if (stat.isDirectory()) {
@@ -15864,13 +15933,13 @@ var init_walker = __esm(() => {
15864
15933
 
15865
15934
  // src/modules/indexer/cache.ts
15866
15935
  import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, existsSync as existsSync34, mkdirSync as mkdirSync14, rmSync as rmSync2 } from "fs";
15867
- import { join as join25 } from "path";
15936
+ import { join as join26 } from "path";
15868
15937
 
15869
15938
  class IndexCache {
15870
15939
  cachePath;
15871
15940
  cache = null;
15872
15941
  constructor(cacheDir) {
15873
- this.cachePath = join25(cacheDir, "index-cache.json");
15942
+ this.cachePath = join26(cacheDir, "index-cache.json");
15874
15943
  }
15875
15944
  load() {
15876
15945
  if (this.cache)
@@ -15886,7 +15955,7 @@ class IndexCache {
15886
15955
  }
15887
15956
  save(result) {
15888
15957
  this.cache = result;
15889
- const dir = join25(this.cachePath, "..");
15958
+ const dir = join26(this.cachePath, "..");
15890
15959
  if (!existsSync34(dir))
15891
15960
  mkdirSync14(dir, { recursive: true });
15892
15961
  writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
@@ -16251,13 +16320,13 @@ var init_mcp = __esm(() => {
16251
16320
 
16252
16321
  // src/modules/memory/module.ts
16253
16322
  import { homedir as homedir10 } from "os";
16254
- import { join as join26 } from "path";
16323
+ import { join as join27 } from "path";
16255
16324
 
16256
16325
  class MemoryModule {
16257
16326
  name = "memory";
16258
16327
  store;
16259
16328
  constructor(memoryDir) {
16260
- const dir = memoryDir || join26(homedir10(), ".mma", "memory");
16329
+ const dir = memoryDir || join27(homedir10(), ".mma", "memory");
16261
16330
  this.store = new MemoryStore(dir);
16262
16331
  }
16263
16332
  getSystemPromptBlock() {
@@ -16304,7 +16373,7 @@ __export(exports_bootstrap, {
16304
16373
  bootstrap: () => bootstrap
16305
16374
  });
16306
16375
  import { homedir as homedir11 } from "os";
16307
- import { join as join27, resolve as resolve18 } from "path";
16376
+ import { join as join28, resolve as resolve18 } from "path";
16308
16377
  import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
16309
16378
  function buildSystemInfo(config, baseDir, profileCompressed) {
16310
16379
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
@@ -16339,8 +16408,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
16339
16408
  `);
16340
16409
  }
16341
16410
  async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16342
- const dir = configDir || join27(homedir11(), ".mma");
16343
- const projectConfigPath = projectDir ? join27(projectDir, ".mmrc") : join27(process.cwd(), ".mmrc");
16411
+ const dir = configDir || join28(homedir11(), ".mma");
16412
+ const projectConfigPath = projectDir ? join28(projectDir, ".mmrc") : join28(process.cwd(), ".mmrc");
16344
16413
  const config = loadConfig({ configDir: dir, projectConfigPath });
16345
16414
  setLocale(config.locale);
16346
16415
  try {
@@ -16350,7 +16419,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16350
16419
  }
16351
16420
  } catch {}
16352
16421
  const logger = new Logger(config.logLevel);
16353
- logger.setLogDir(join27(dir, "logs"));
16422
+ logger.setLogDir(join28(dir, "logs"));
16354
16423
  logger.debug("MMA bootstrap", {
16355
16424
  version: config.version,
16356
16425
  model: config.model
@@ -16372,7 +16441,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16372
16441
  logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
16373
16442
  }
16374
16443
  }
16375
- const profile = new UserProfile(join27(dir));
16444
+ const profile = new UserProfile(join28(dir));
16376
16445
  profile.load() || profile.collect();
16377
16446
  profile.save();
16378
16447
  const llmProvider = new OpenAICompatProvider({
@@ -16384,7 +16453,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16384
16453
  rateLimits: config.security?.rateLimits
16385
16454
  });
16386
16455
  const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
16387
- const projectMapCacheDir = join27(baseDir, ".mma");
16456
+ const projectMapCacheDir = join28(baseDir, ".mma");
16388
16457
  const indexerModule = new IndexerModule({
16389
16458
  baseDir,
16390
16459
  cacheDir: projectMapCacheDir
@@ -16395,13 +16464,12 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16395
16464
  logger.warn(`Project indexing failed: ${err.message}`);
16396
16465
  }
16397
16466
  const skillsLoader = new SkillsLoader;
16398
- const builtinDir = join27(import.meta.dirname, "skills", "builtin");
16399
- const globalDir = join27(homedir11(), ".agents", "skills");
16400
- const projectSkillsDir = join27(baseDir, ".mma", "skills");
16467
+ const builtinDir = join28(import.meta.dirname, "skills", "builtin");
16468
+ const globalDir = join28(homedir11(), ".agents", "skills");
16469
+ const projectSkillsDir = join28(baseDir, ".mma", "skills");
16401
16470
  const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
16402
- const skillsMatcher = new SkillsMatcher;
16403
- const skillsBudget = Math.floor(config.contextWindow * 0.1);
16404
- const skillsModule = new SkillsModule(availableSkills, skillsMatcher, skillsBudget);
16471
+ const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
16472
+ const skillsModule = new SkillsModule(availableSkills, skillsBudget);
16405
16473
  const toolRegistry = new ToolRegistry;
16406
16474
  registerAllTools(toolRegistry, skillsModule);
16407
16475
  const pluginManager = new PluginManager;
@@ -16411,11 +16479,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16411
16479
  essential: true,
16412
16480
  estimatedTokens: 250
16413
16481
  };
16414
- const agentsMdGlobal = join27(dir, "AGENTS.md");
16482
+ const agentsMdGlobal = join28(dir, "AGENTS.md");
16415
16483
  if (!existsSync35(agentsMdGlobal)) {
16416
16484
  writeFileSync13(agentsMdGlobal, "", "utf-8");
16417
16485
  }
16418
- const sessionDir = join27(dir, "sessions");
16486
+ const sessionDir = join28(dir, "sessions");
16419
16487
  const sessionStore = new SessionStore(sessionDir);
16420
16488
  sessionStore.init();
16421
16489
  const sessionManager = new SessionManager(sessionStore, {
@@ -16478,12 +16546,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16478
16546
  moduleRegistry.register(execModule);
16479
16547
  const sessionModule = new SessionModule(sessionManager);
16480
16548
  moduleRegistry.register(sessionModule);
16481
- moduleRegistry.register(skillsModule);
16482
16549
  moduleRegistry.register(indexerModule);
16483
16550
  const mcpModule = new MCPModule(config);
16484
16551
  await mcpModule.initialize();
16485
16552
  moduleRegistry.register(mcpModule);
16486
- const memoryModule = new MemoryModule(join27(dir, "memory"));
16553
+ const memoryModule = new MemoryModule(join28(dir, "memory"));
16487
16554
  moduleRegistry.register(memoryModule);
16488
16555
  if (config.browser.enabled) {
16489
16556
  const browserModule = new BrowserModule;
@@ -16533,8 +16600,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16533
16600
  pluginManager.register(plugin);
16534
16601
  pluginManager.register(plugin2);
16535
16602
  const pluginLoader = new PluginLoader;
16536
- const globalPluginsDir = join27(homedir11(), ".mma", "plugins");
16537
- const projectPluginsDir = join27(baseDir, ".mma", "plugins");
16603
+ const globalPluginsDir = join28(homedir11(), ".mma", "plugins");
16604
+ const projectPluginsDir = join28(baseDir, ".mma", "plugins");
16538
16605
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
16539
16606
  pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
16540
16607
  contextManager.onCompact = (summary) => {
@@ -16552,9 +16619,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16552
16619
  const skipAgentsMd = noAgentsMd === true;
16553
16620
  if (!skipAgentsMd) {
16554
16621
  const agentsMdCandidates = [
16555
- join27(baseDir, "AGENTS.md"),
16556
- join27(baseDir, ".mma", "AGENTS.md"),
16557
- join27(dir, "AGENTS.md")
16622
+ join28(baseDir, "AGENTS.md"),
16623
+ join28(baseDir, ".mma", "AGENTS.md"),
16624
+ join28(dir, "AGENTS.md")
16558
16625
  ];
16559
16626
  for (const p of agentsMdCandidates) {
16560
16627
  if (existsSync35(p)) {
@@ -16586,8 +16653,14 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16586
16653
  baseDir,
16587
16654
  promptBlocks,
16588
16655
  getDynamicPromptBlocks: () => {
16656
+ const blocks = [];
16589
16657
  const planBlock = execModule.getSystemPromptBlock();
16590
- return planBlock ? [planBlock] : [];
16658
+ if (planBlock)
16659
+ blocks.push(planBlock);
16660
+ const skillsBlock = skillsModule.getSystemPromptBlock();
16661
+ if (skillsBlock)
16662
+ blocks.push(skillsBlock);
16663
+ return blocks;
16591
16664
  },
16592
16665
  finalAudit: () => execModule.runFinalAudit(),
16593
16666
  sessionManager,
@@ -17333,7 +17406,7 @@ __export(exports_manifest, {
17333
17406
  });
17334
17407
  import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "fs";
17335
17408
  import { homedir as homedir13 } from "os";
17336
- import { join as join29 } from "path";
17409
+ import { join as join30 } from "path";
17337
17410
  function readManifest(path = MANIFEST_PATH) {
17338
17411
  try {
17339
17412
  if (existsSync36(path)) {
@@ -17344,7 +17417,7 @@ function readManifest(path = MANIFEST_PATH) {
17344
17417
  return { version: 1, certifications: [] };
17345
17418
  }
17346
17419
  function saveManifest(m, path = MANIFEST_PATH) {
17347
- mkdirSync15(join29(homedir13(), ".mma"), { recursive: true });
17420
+ mkdirSync15(join30(homedir13(), ".mma"), { recursive: true });
17348
17421
  writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
17349
17422
  }
17350
17423
  function upsertCertification(entry, path = MANIFEST_PATH) {
@@ -17379,7 +17452,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
17379
17452
  }
17380
17453
  var MANIFEST_PATH;
17381
17454
  var init_manifest = __esm(() => {
17382
- MANIFEST_PATH = join29(homedir13(), ".mma", "certifications.json");
17455
+ MANIFEST_PATH = join30(homedir13(), ".mma", "certifications.json");
17383
17456
  });
17384
17457
 
17385
17458
  // node_modules/yaml/dist/nodes/identity.js
@@ -24502,8 +24575,8 @@ var init_scenarios = __esm(() => {
24502
24575
  });
24503
24576
 
24504
24577
  // src/modules/certification/loader.ts
24505
- import { existsSync as existsSync37, readdirSync as readdirSync10, readFileSync as readFileSync24 } from "fs";
24506
- import { join as join30 } from "path";
24578
+ import { existsSync as existsSync37, readdirSync as readdirSync11, readFileSync as readFileSync24 } from "fs";
24579
+ import { join as join31 } from "path";
24507
24580
  function validateScenario(s) {
24508
24581
  const errors2 = [];
24509
24582
  const isSkip = s.mode === "skip";
@@ -24553,11 +24626,11 @@ function loadScenarios(userDir) {
24553
24626
  scenarios.push(s);
24554
24627
  }
24555
24628
  if (userDir && existsSync37(userDir)) {
24556
- for (const file of readdirSync10(userDir)) {
24629
+ for (const file of readdirSync11(userDir)) {
24557
24630
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
24558
24631
  continue;
24559
24632
  try {
24560
- const raw = readFileSync24(join30(userDir, file), "utf-8");
24633
+ const raw = readFileSync24(join31(userDir, file), "utf-8");
24561
24634
  const data = $parse(raw);
24562
24635
  const parsed = normalizeScenario(data, file);
24563
24636
  const errs = validateScenario(parsed);
@@ -24611,7 +24684,7 @@ var init_loader3 = __esm(() => {
24611
24684
 
24612
24685
  // src/modules/certification/fact-checker.ts
24613
24686
  import { existsSync as existsSync38, readFileSync as readFileSync25, statSync as statSync7 } from "fs";
24614
- import { join as join31 } from "path";
24687
+ import { join as join32 } from "path";
24615
24688
  function checkSandbox(sandboxDir, checks, exitCode, output) {
24616
24689
  const failures = [];
24617
24690
  for (const check of checks) {
@@ -24628,13 +24701,13 @@ function runCheck(sandboxDir, check, exitCode, output) {
24628
24701
  case "outputContains":
24629
24702
  return output.includes(check.text);
24630
24703
  case "fileExists":
24631
- return isFile(join31(sandboxDir, check.path));
24704
+ return isFile(join32(sandboxDir, check.path));
24632
24705
  case "fileNotExists":
24633
- return !existsSync38(join31(sandboxDir, check.path));
24706
+ return !existsSync38(join32(sandboxDir, check.path));
24634
24707
  case "dirExists":
24635
- return isDir(join31(sandboxDir, check.path));
24708
+ return isDir(join32(sandboxDir, check.path));
24636
24709
  case "fileContent": {
24637
- const abs = join31(sandboxDir, check.path);
24710
+ const abs = join32(sandboxDir, check.path);
24638
24711
  if (!isFile(abs))
24639
24712
  return false;
24640
24713
  const content = readFileSync25(abs, "utf-8");
@@ -24645,7 +24718,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
24645
24718
  return false;
24646
24719
  }
24647
24720
  case "fileRegex": {
24648
- const abs = join31(sandboxDir, check.path);
24721
+ const abs = join32(sandboxDir, check.path);
24649
24722
  if (!isFile(abs))
24650
24723
  return false;
24651
24724
  return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
@@ -24696,7 +24769,7 @@ var init_fact_checker = () => {};
24696
24769
  import { spawn as spawn6 } from "child_process";
24697
24770
  import { existsSync as existsSync39, mkdirSync as mkdirSync16, rmSync as rmSync3, cpSync as cpSync2 } from "fs";
24698
24771
  import { platform as platform5 } from "os";
24699
- import { join as join32, resolve as resolve19, dirname as dirname9 } from "path";
24772
+ import { join as join33, resolve as resolve19, dirname as dirname9 } from "path";
24700
24773
  async function runScenario(scenario, opts) {
24701
24774
  if (scenario.mode === "skip") {
24702
24775
  return {
@@ -24715,7 +24788,7 @@ async function runScenario(scenario, opts) {
24715
24788
  let passed = 0;
24716
24789
  let firstError;
24717
24790
  for (let i = 1;i <= reps; i++) {
24718
- const sandbox = join32(opts.sandboxBase, `run-${scenario.id}-${i}`);
24791
+ const sandbox = join33(opts.sandboxBase, `run-${scenario.id}-${i}`);
24719
24792
  let failures = [];
24720
24793
  let exitCode = -1;
24721
24794
  let output = "";
@@ -24776,20 +24849,20 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
24776
24849
  rmSync3(sandbox, { recursive: true, force: true });
24777
24850
  mkdirSync16(sandbox, { recursive: true });
24778
24851
  for (const f of scenario.fixtures ?? []) {
24779
- const src = join32(mmaRoot, f.source);
24852
+ const src = join33(mmaRoot, f.source);
24780
24853
  if (!existsSync39(src)) {
24781
24854
  throw new Error(`fixture missing: ${f.source}`);
24782
24855
  }
24783
- const dest = join32(sandbox, f.dest);
24856
+ const dest = join33(sandbox, f.dest);
24784
24857
  mkdirSync16(dirname9(dest), { recursive: true });
24785
24858
  cpSync2(src, dest);
24786
24859
  }
24787
24860
  }
24788
24861
  function resolveMmaEntry(mmaRoot) {
24789
- const dev = join32(mmaRoot, "src", "cli", "main.ts");
24862
+ const dev = join33(mmaRoot, "src", "cli", "main.ts");
24790
24863
  if (existsSync39(dev))
24791
24864
  return dev;
24792
- return join32(mmaRoot, "dist", "main.js");
24865
+ return join33(mmaRoot, "dist", "main.js");
24793
24866
  }
24794
24867
  function findMmaRoot(fromDir) {
24795
24868
  const candidates = [
@@ -24797,7 +24870,7 @@ function findMmaRoot(fromDir) {
24797
24870
  resolve19(fromDir, "..")
24798
24871
  ];
24799
24872
  for (const c of candidates) {
24800
- if (existsSync39(join32(c, "package.json")))
24873
+ if (existsSync39(join33(c, "package.json")))
24801
24874
  return c;
24802
24875
  }
24803
24876
  return process.cwd();
@@ -24865,12 +24938,12 @@ __export(exports_cli, {
24865
24938
  });
24866
24939
  import { rmSync as rmSync4 } from "fs";
24867
24940
  import { homedir as homedir14 } from "os";
24868
- import { join as join33, dirname as dirname10 } from "path";
24941
+ import { join as join34, dirname as dirname10 } from "path";
24869
24942
  import { fileURLToPath } from "url";
24870
24943
  import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
24871
24944
  function readVersion() {
24872
24945
  const candidates = [
24873
- join33(MMA_ROOT, "package.json")
24946
+ join34(MMA_ROOT, "package.json")
24874
24947
  ];
24875
24948
  for (const p of candidates) {
24876
24949
  if (existsSync40(p)) {
@@ -24909,7 +24982,7 @@ async function certify(opts) {
24909
24982
  return;
24910
24983
  }
24911
24984
  console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
24912
- const sandboxBase = join33(process.cwd(), ".mma", "certification");
24985
+ const sandboxBase = join34(process.cwd(), ".mma", "certification");
24913
24986
  const results = [];
24914
24987
  const total = selected.length;
24915
24988
  let idx = 0;
@@ -25017,7 +25090,7 @@ var init_cli = __esm(() => {
25017
25090
  init_manifest();
25018
25091
  HERE = dirname10(fileURLToPath(import.meta.url));
25019
25092
  MMA_ROOT = findMmaRoot(HERE);
25020
- USER_SCENARIO_DIR = join33(homedir14(), ".mma", "certification", "scenarios");
25093
+ USER_SCENARIO_DIR = join34(homedir14(), ".mma", "certification", "scenarios");
25021
25094
  });
25022
25095
 
25023
25096
  // src/cli/repl-commands.ts
@@ -25026,15 +25099,15 @@ __export(exports_repl_commands, {
25026
25099
  registerAllCommands: () => registerAllCommands,
25027
25100
  COMMAND_GROUPS: () => COMMAND_GROUPS
25028
25101
  });
25029
- import { join as join35, dirname as dirname12 } from "path";
25102
+ import { join as join36, dirname as dirname12 } from "path";
25030
25103
  import { homedir as homedir16 } from "os";
25031
25104
  import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
25032
25105
  import { fileURLToPath as fileURLToPath3 } from "url";
25033
25106
  function readVersion3() {
25034
25107
  const here = dirname12(fileURLToPath3(import.meta.url));
25035
25108
  const candidates = [
25036
- join35(here, "..", "..", "package.json"),
25037
- join35(here, "..", "package.json")
25109
+ join36(here, "..", "..", "package.json"),
25110
+ join36(here, "..", "package.json")
25038
25111
  ];
25039
25112
  for (const p of candidates) {
25040
25113
  if (existsSync42(p)) {
@@ -25200,7 +25273,7 @@ function registerMmaCommands(ctx) {
25200
25273
  console.log(pc2.yellow(t("repl.wizard_running")));
25201
25274
  await ctx.withExclusiveInput(async () => {
25202
25275
  const answers = await runSetup(ctx.rl);
25203
- const configPath = join35(homedir16(), ".mma", "config.json");
25276
+ const configPath = join36(homedir16(), ".mma", "config.json");
25204
25277
  ctx.config.provider.type = answers.provider;
25205
25278
  ctx.config.provider.baseUrl = answers.apiBase;
25206
25279
  ctx.config.provider.apiKey = answers.apiKey;
@@ -25254,7 +25327,7 @@ Excluded blocks: ${info.excluded.length}`));
25254
25327
  return;
25255
25328
  }
25256
25329
  ctx.config.provider.type = name;
25257
- const configPath = join35(homedir16(), ".mma", "config.json");
25330
+ const configPath = join36(homedir16(), ".mma", "config.json");
25258
25331
  saveConfig(ctx.config, configPath);
25259
25332
  await ctx.agent.reconfigure(ctx.config);
25260
25333
  console.log(pc2.green(t("repl.provider_set", { name })));
@@ -25310,7 +25383,7 @@ Excluded blocks: ${info.excluded.length}`));
25310
25383
  return;
25311
25384
  }
25312
25385
  ctx.config.model = name;
25313
- const configPath = join35(homedir16(), ".mma", "config.json");
25386
+ const configPath = join36(homedir16(), ".mma", "config.json");
25314
25387
  saveConfig(ctx.config, configPath);
25315
25388
  await ctx.agent.reconfigure(ctx.config);
25316
25389
  console.log(pc2.green(t("repl.model_set", { name })));
@@ -25335,7 +25408,7 @@ Excluded blocks: ${info.excluded.length}`));
25335
25408
  return;
25336
25409
  }
25337
25410
  ctx.config.contextWindow = size;
25338
- const configPath = join35(homedir16(), ".mma", "config.json");
25411
+ const configPath = join36(homedir16(), ".mma", "config.json");
25339
25412
  saveConfig(ctx.config, configPath);
25340
25413
  await ctx.agent.reconfigure(ctx.config);
25341
25414
  console.log(pc2.green(t("cli.context_set", { size })));
@@ -25354,10 +25427,10 @@ Excluded blocks: ${info.excluded.length}`));
25354
25427
  ctx.agent.shutdown();
25355
25428
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
25356
25429
  const { homedir: homedir17 } = await import("os");
25357
- const { join: join36 } = await import("path");
25430
+ const { join: join37 } = await import("path");
25358
25431
  const configDir = ctx.configDir;
25359
25432
  const baseDir = ctx.baseDir;
25360
- const projectConfigPath = join36(baseDir, ".mmrc");
25433
+ const projectConfigPath = join37(baseDir, ".mmrc");
25361
25434
  const freshConfig = loadConfig2({ configDir, projectConfigPath });
25362
25435
  Object.assign(ctx.config, freshConfig);
25363
25436
  const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
@@ -25657,14 +25730,14 @@ init_bootstrap();
25657
25730
  init_config2();
25658
25731
  init_setup();
25659
25732
  init_i18n();
25660
- import { join as join34, dirname as dirname11 } from "path";
25733
+ import { join as join35, dirname as dirname11 } from "path";
25661
25734
  import { homedir as homedir15 } from "os";
25662
25735
  import { existsSync as existsSync41, readFileSync as readFileSync27 } from "fs";
25663
25736
 
25664
25737
  // src/cli/security-commands.ts
25665
25738
  init_bootstrap();
25666
25739
  init_config2();
25667
- import { join as join28 } from "path";
25740
+ import { join as join29 } from "path";
25668
25741
  import { homedir as homedir12 } from "os";
25669
25742
 
25670
25743
  // src/modules/security/security-policies.ts
@@ -26194,7 +26267,7 @@ function createSecurityCommand(program2) {
26194
26267
  }
26195
26268
  });
26196
26269
  securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
26197
- const configPath = join28(homedir12(), ".mma", "config.json");
26270
+ const configPath = join29(homedir12(), ".mma", "config.json");
26198
26271
  const { config: appConfig } = await bootstrap();
26199
26272
  const validPresets = ["strict", "balanced", "permissive"];
26200
26273
  if (!validPresets.includes(preset)) {
@@ -26209,7 +26282,7 @@ function createSecurityCommand(program2) {
26209
26282
  console.log(t("cli.security.policy_description", { description: policy.description }));
26210
26283
  });
26211
26284
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
26212
- const configPath = join28(homedir12(), ".mma", "config.json");
26285
+ const configPath = join29(homedir12(), ".mma", "config.json");
26213
26286
  const { config: appConfig } = await bootstrap();
26214
26287
  appConfig.security = appConfig.security || {};
26215
26288
  appConfig.security.sessionEncryption = {
@@ -26221,7 +26294,7 @@ function createSecurityCommand(program2) {
26221
26294
  console.log(t("cli.security.encryption_enabled"));
26222
26295
  });
26223
26296
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
26224
- const configPath = join28(homedir12(), ".mma", "config.json");
26297
+ const configPath = join29(homedir12(), ".mma", "config.json");
26225
26298
  const { config: appConfig } = await bootstrap();
26226
26299
  appConfig.security = appConfig.security || {};
26227
26300
  appConfig.security.sessionEncryption = {
@@ -26233,7 +26306,7 @@ function createSecurityCommand(program2) {
26233
26306
  console.log(t("cli.security.encryption_disabled"));
26234
26307
  });
26235
26308
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
26236
- const configPath = join28(homedir12(), ".mma", "config.json");
26309
+ const configPath = join29(homedir12(), ".mma", "config.json");
26237
26310
  const { config: appConfig } = await bootstrap();
26238
26311
  appConfig.security = appConfig.security || {};
26239
26312
  appConfig.security.auditNotifier = {
@@ -26247,7 +26320,7 @@ function createSecurityCommand(program2) {
26247
26320
  console.log(t("cli.security.audit_enabled"));
26248
26321
  });
26249
26322
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
26250
- const configPath = join28(homedir12(), ".mma", "config.json");
26323
+ const configPath = join29(homedir12(), ".mma", "config.json");
26251
26324
  const { config: appConfig } = await bootstrap();
26252
26325
  appConfig.security = appConfig.security || {};
26253
26326
  appConfig.security.auditNotifier = {
@@ -26283,8 +26356,8 @@ import { fileURLToPath as fileURLToPath2 } from "url";
26283
26356
  function readVersion2() {
26284
26357
  const here = dirname11(fileURLToPath2(import.meta.url));
26285
26358
  const candidates = [
26286
- join34(here, "..", "..", "package.json"),
26287
- join34(here, "..", "package.json")
26359
+ join35(here, "..", "..", "package.json"),
26360
+ join35(here, "..", "package.json")
26288
26361
  ];
26289
26362
  for (const p of candidates) {
26290
26363
  if (existsSync41(p)) {
@@ -26300,7 +26373,7 @@ function createProgram() {
26300
26373
  const program2 = new Command().name("mma").description(t("cli.description")).version(version).option("--no-agents-md", t("cli.no_agents_md")).option("-d, --dir <path>", t("cli.dir")).option("-e, --exit-on-complete", t("cli.exit_on_complete")).option("-j, --json", t("cli.json"));
26301
26374
  program2.command("init").description(t("cli.init")).action(async () => {
26302
26375
  const answers = await runSetup();
26303
- const configPath = join34(homedir15(), ".mma", "config.json");
26376
+ const configPath = join35(homedir15(), ".mma", "config.json");
26304
26377
  const { config } = await bootstrap();
26305
26378
  config.provider.type = answers.provider;
26306
26379
  config.provider.baseUrl = answers.apiBase;
@@ -26345,7 +26418,7 @@ function createProgram() {
26345
26418
  });
26346
26419
  const configCmd = program2.command("config").description(t("cli.manage_config"));
26347
26420
  configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
26348
- const configPath = join34(homedir15(), ".mma", "config.json");
26421
+ const configPath = join35(homedir15(), ".mma", "config.json");
26349
26422
  const { config } = await bootstrap();
26350
26423
  const keys = key.split(".");
26351
26424
  let obj = config;
@@ -26408,7 +26481,7 @@ function createProgram() {
26408
26481
  console.log(t("cli.model_hint"));
26409
26482
  });
26410
26483
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
26411
- const configPath = join34(homedir15(), ".mma", "config.json");
26484
+ const configPath = join35(homedir15(), ".mma", "config.json");
26412
26485
  const { config } = await bootstrap();
26413
26486
  config.model = name;
26414
26487
  saveConfig(config, configPath);
@@ -26444,7 +26517,7 @@ function createProgram() {
26444
26517
  await uncertify2(name, config);
26445
26518
  });
26446
26519
  program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
26447
- const configPath = join34(homedir15(), ".mma", "config.json");
26520
+ const configPath = join35(homedir15(), ".mma", "config.json");
26448
26521
  const { config } = await bootstrap();
26449
26522
  const contextWindow = parseInt(size, 10);
26450
26523
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -26462,7 +26535,7 @@ function createProgram() {
26462
26535
  console.log(t("cli.base_url"), config.provider.baseUrl);
26463
26536
  });
26464
26537
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
26465
- const configPath = join34(homedir15(), ".mma", "config.json");
26538
+ const configPath = join35(homedir15(), ".mma", "config.json");
26466
26539
  const { config } = await bootstrap();
26467
26540
  config.provider.type = name;
26468
26541
  saveConfig(config, configPath);
@@ -26515,7 +26588,7 @@ init_bootstrap();
26515
26588
  init_colors();
26516
26589
  import * as readline2 from "readline";
26517
26590
  import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
26518
- import { join as join36, dirname as dirname13 } from "path";
26591
+ import { join as join37, dirname as dirname13 } from "path";
26519
26592
  import { homedir as homedir17 } from "os";
26520
26593
  import { fileURLToPath as fileURLToPath4 } from "url";
26521
26594
 
@@ -27029,8 +27102,8 @@ init_repl_commands();
27029
27102
  function readVersion4() {
27030
27103
  const here = dirname13(fileURLToPath4(import.meta.url));
27031
27104
  const candidates = [
27032
- join36(here, "..", "..", "package.json"),
27033
- join36(here, "..", "package.json")
27105
+ join37(here, "..", "..", "package.json"),
27106
+ join37(here, "..", "package.json")
27034
27107
  ];
27035
27108
  for (const p of candidates) {
27036
27109
  if (existsSync43(p)) {
@@ -27085,10 +27158,10 @@ class Repl {
27085
27158
  this.sessionManager = sessionManager;
27086
27159
  this.skillsModule = skillsModule;
27087
27160
  this.pluginManager = pluginManager;
27088
- this.configDir = configDir || join36(homedir17(), ".mma");
27161
+ this.configDir = configDir || join37(homedir17(), ".mma");
27089
27162
  this.baseDir = baseDir || process.cwd();
27090
27163
  this.noAgentsMd = noAgentsMd === true;
27091
- this.historyPath = join36(homedir17(), ".mma", "repl-history");
27164
+ this.historyPath = join37(homedir17(), ".mma", "repl-history");
27092
27165
  this.loadHistory();
27093
27166
  this.rl = readline2.createInterface({
27094
27167
  input: process.stdin,
@@ -27440,9 +27513,9 @@ ${t("image.clipboard_empty")}`));
27440
27513
  row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
27441
27514
  } else {
27442
27515
  const agentsMdCandidates = [
27443
- join36(this.baseDir, "AGENTS.md"),
27444
- join36(this.baseDir, ".mma", "AGENTS.md"),
27445
- join36(this.configDir, "AGENTS.md")
27516
+ join37(this.baseDir, "AGENTS.md"),
27517
+ join37(this.baseDir, ".mma", "AGENTS.md"),
27518
+ join37(this.configDir, "AGENTS.md")
27446
27519
  ];
27447
27520
  const foundAgents = agentsMdCandidates.filter((p) => existsSync43(p));
27448
27521
  if (foundAgents.length > 0) {
@@ -27455,7 +27528,7 @@ ${t("image.clipboard_empty")}`));
27455
27528
  }
27456
27529
  const meta = this.sessionManager?.getActiveMeta();
27457
27530
  if (meta) {
27458
- const sessionPath = join36(this.configDir, "sessions", meta.id);
27531
+ const sessionPath = join37(this.configDir, "sessions", meta.id);
27459
27532
  row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
27460
27533
  }
27461
27534
  const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
@@ -27482,7 +27555,7 @@ init_config2();
27482
27555
  init_i18n();
27483
27556
  init_colors();
27484
27557
  import { existsSync as existsSync44 } from "fs";
27485
- import { join as join37 } from "path";
27558
+ import { join as join38 } from "path";
27486
27559
  import { homedir as homedir18 } from "os";
27487
27560
  async function main() {
27488
27561
  const program2 = createProgram();
@@ -27549,15 +27622,15 @@ async function main() {
27549
27622
  }
27550
27623
  agent.shutdown();
27551
27624
  } else {
27552
- const configPath = join37(homedir18(), ".mma", "config.json");
27625
+ const configPath = join38(homedir18(), ".mma", "config.json");
27553
27626
  if (!existsSync44(configPath)) {
27554
27627
  console.log(pc2.yellow(`
27555
27628
  ` + t("cli.first_run") + `
27556
27629
  `));
27557
27630
  const answers = await runSetup();
27558
27631
  const config2 = loadConfig({
27559
- configDir: join37(homedir18(), ".mma"),
27560
- projectConfigPath: projectDir ? join37(projectDir, ".mmrc") : join37(process.cwd(), ".mmrc")
27632
+ configDir: join38(homedir18(), ".mma"),
27633
+ projectConfigPath: projectDir ? join38(projectDir, ".mmrc") : join38(process.cwd(), ".mmrc")
27561
27634
  });
27562
27635
  config2.provider.type = answers.provider;
27563
27636
  config2.provider.baseUrl = answers.apiBase;