micro-models-agent 0.28.4 → 0.28.6

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 +289 -255
  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
  });
@@ -2378,7 +2381,7 @@ var init_en = __esm(() => {
2378
2381
  "tool.question.answered": "User has answered your questions: {formatted}. You can now continue with the user's answers in mind.",
2379
2382
  "tool.name_or_task": 'Provide either "name" or "task" parameter',
2380
2383
  "tool.invalid_params": "Invalid parameters",
2381
- "tool.skill_budget": "[Skill loaded. {remaining} tokens remaining in skills budget]",
2384
+ "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
2385
  "tool.skill_available_hint": "Available skills",
2383
2386
  "tool.no_results": 'No results found for "{query}"',
2384
2387
  "tool.search_results": `Search results for "{query}":
@@ -2923,7 +2926,7 @@ var init_ru = __esm(() => {
2923
2926
  "tool.question.answered": "Пользователь ответил на ваши вопросы: {formatted}. Теперь продолжайте с учётом ответов.",
2924
2927
  "tool.name_or_task": 'Укажите параметр "name" или "task"',
2925
2928
  "tool.invalid_params": "Неверные параметры",
2926
- "tool.skill_budget": "[Скилл загружен. Осталось {remaining} токенов в бюджете скиллов]",
2929
+ "tool.skill_budget": 'Скилл "{name}" загружен ({tokens} токенов, осталось {remaining} в бюджете скиллов). Контент скилла теперь в системном промпте — перезагрузка после компрессии не нужна.',
2927
2930
  "tool.skill_available_hint": "Доступные скиллы",
2928
2931
  "tool.no_results": 'Нет результатов по "{query}"',
2929
2932
  "tool.search_results": `Результаты поиска "{query}":
@@ -8977,28 +8980,6 @@ var init_stuck_detector = __esm(() => {
8977
8980
  init_i18n();
8978
8981
  });
8979
8982
 
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
8983
  // src/modules/execution/moe-executor.ts
9003
8984
  function isTransientError(error) {
9004
8985
  return TRANSIENT_ERROR_PATTERNS.some((p) => error.includes(p));
@@ -9126,7 +9107,6 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
9126
9107
  continue;
9127
9108
  }
9128
9109
  const hints = stuckDetector.getActionableHints();
9129
- const suggestedSkill = suggestSkill(lastError);
9130
9110
  let errorDetail = result.output;
9131
9111
  if (hints.length > 0) {
9132
9112
  errorDetail += `
@@ -9134,10 +9114,10 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
9134
9114
  ${t("exec.hints", { hints: hints.map((h) => `- ${h}`).join(`
9135
9115
  `) })}`;
9136
9116
  }
9137
- if (suggestedSkill) {
9117
+ if (lastError) {
9138
9118
  errorDetail += `
9139
9119
 
9140
- Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9120
+ If relevant skills are available, consider loading one with load_skill for expert guidance.`;
9141
9121
  }
9142
9122
  return {
9143
9123
  subtaskId: subtask.id,
@@ -9157,7 +9137,6 @@ Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9157
9137
  continue;
9158
9138
  }
9159
9139
  const hints = stuckDetector.getActionableHints();
9160
- const suggestedSkill = suggestSkill(lastError);
9161
9140
  let errorDetail = e.message;
9162
9141
  if (hints.length > 0) {
9163
9142
  errorDetail += `
@@ -9165,10 +9144,10 @@ Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9165
9144
  ${t("exec.hints", { hints: hints.map((h) => `- ${h}`).join(`
9166
9145
  `) })}`;
9167
9146
  }
9168
- if (suggestedSkill) {
9147
+ if (lastError) {
9169
9148
  errorDetail += `
9170
9149
 
9171
- Consider loading the "${suggestedSkill}" skill for expert guidance.`;
9150
+ If relevant skills are available, consider loading one with load_skill for expert guidance.`;
9172
9151
  }
9173
9152
  return {
9174
9153
  subtaskId: subtask.id,
@@ -9207,7 +9186,12 @@ class MoEExecutor {
9207
9186
  const warnings = [];
9208
9187
  const waves = topologicalSort(plan.subtasks);
9209
9188
  if (waves.length === 0) {
9210
- return { success: false, results: [], errors: ["Failed to topologically sort subtasks (possible cycle)"], warnings: [] };
9189
+ return {
9190
+ success: false,
9191
+ results: [],
9192
+ errors: ["Failed to topologically sort subtasks (possible cycle)"],
9193
+ warnings: []
9194
+ };
9211
9195
  }
9212
9196
  const sortedCount = waves.flat().length;
9213
9197
  if (sortedCount < plan.subtasks.length) {
@@ -9215,7 +9199,9 @@ class MoEExecutor {
9215
9199
  return {
9216
9200
  success: false,
9217
9201
  results: [],
9218
- errors: [`Missing subtasks after topological sort: ${missing.join(", ")} (dangling or invalid depends_on)`],
9202
+ errors: [
9203
+ `Missing subtasks after topological sort: ${missing.join(", ")} (dangling or invalid depends_on)`
9204
+ ],
9219
9205
  warnings: []
9220
9206
  };
9221
9207
  }
@@ -9251,7 +9237,6 @@ class MoEExecutor {
9251
9237
  var TRANSIENT_ERROR_PATTERNS;
9252
9238
  var init_moe_executor = __esm(() => {
9253
9239
  init_stuck_detector();
9254
- init_error_skill_map();
9255
9240
  init_i18n();
9256
9241
  TRANSIENT_ERROR_PATTERNS = [
9257
9242
  "timeout",
@@ -10131,11 +10116,16 @@ ${taskReminder}</system-summary>`
10131
10116
  }
10132
10117
  if (hallucinationResult.status === "warn") {
10133
10118
  logger.warn(`Hallucination warning: ${hallucinationResult.reason}`);
10134
- const warnPrefix = t("hall.uncertainty_prefix");
10135
- if (onChunk) {
10136
- onChunk(warnPrefix);
10119
+ const warnLine = `${t("hall.uncertainty_prefix").trim()} ${hallucinationResult.reason ?? ""}`;
10120
+ if (onMeta) {
10121
+ onMeta(`
10122
+ ${pc2.yellow(warnLine)}
10123
+ `);
10124
+ } else if (onChunk) {
10125
+ onChunk(`
10126
+ ${warnLine}
10127
+ `);
10137
10128
  }
10138
- lastText = warnPrefix + lastText;
10139
10129
  }
10140
10130
  if (hallucinationResult.status === "retry") {
10141
10131
  if (this.deps.exitOnComplete) {
@@ -10673,8 +10663,8 @@ var init_confidence = __esm(() => {
10673
10663
  });
10674
10664
 
10675
10665
  // src/modules/hallucination/factual.ts
10676
- import { existsSync as existsSync20 } from "fs";
10677
- import { resolve as resolve11, isAbsolute } from "path";
10666
+ import { existsSync as existsSync20, readdirSync as readdirSync4 } from "fs";
10667
+ import { resolve as resolve11, isAbsolute, join as join12 } from "path";
10678
10668
  function looksLikeFilePath(s) {
10679
10669
  const lower = s.toLowerCase();
10680
10670
  if (TECH_NAMES.has(lower))
@@ -10687,6 +10677,12 @@ function looksLikeFilePath(s) {
10687
10677
 
10688
10678
  class FactualCheck {
10689
10679
  baseDir;
10680
+ nameCache = null;
10681
+ nameCacheTime = 0;
10682
+ lastRescan = 0;
10683
+ static NAME_CACHE_TTL_MS = 5000;
10684
+ static RESCAN_COOLDOWN_MS = 2000;
10685
+ static MAX_INDEXED_FILES = 20000;
10690
10686
  constructor(baseDir) {
10691
10687
  this.baseDir = baseDir;
10692
10688
  }
@@ -10696,8 +10692,7 @@ class FactualCheck {
10696
10692
  return { status: "pass" };
10697
10693
  const nonExistent = [];
10698
10694
  for (const fp of filePaths) {
10699
- const abs = isAbsolute(fp) ? fp : resolve11(this.baseDir, fp);
10700
- if (!existsSync20(abs)) {
10695
+ if (!this.pathExists(fp)) {
10701
10696
  nonExistent.push(fp);
10702
10697
  }
10703
10698
  }
@@ -10711,15 +10706,89 @@ class FactualCheck {
10711
10706
  }
10712
10707
  return { status: "pass" };
10713
10708
  }
10709
+ pathExists(fp) {
10710
+ if (isAbsolute(fp))
10711
+ return existsSync20(fp);
10712
+ if (!fp.includes("/") && !fp.includes("\\")) {
10713
+ return this.bareNameExists(fp);
10714
+ }
10715
+ return existsSync20(resolve11(this.baseDir, fp));
10716
+ }
10717
+ bareNameExists(name) {
10718
+ if (existsSync20(resolve11(this.baseDir, name)))
10719
+ return true;
10720
+ if (this.indexHas(name))
10721
+ return true;
10722
+ const now = Date.now();
10723
+ if (now - this.lastRescan < FactualCheck.RESCAN_COOLDOWN_MS)
10724
+ return false;
10725
+ this.lastRescan = now;
10726
+ this.nameCache = null;
10727
+ this.nameCacheTime = 0;
10728
+ return this.indexHas(name);
10729
+ }
10730
+ indexHas(name) {
10731
+ return (this.getNameIndex().get(name)?.length ?? 0) > 0;
10732
+ }
10733
+ getNameIndex() {
10734
+ const now = Date.now();
10735
+ if (this.nameCache && now - this.nameCacheTime < FactualCheck.NAME_CACHE_TTL_MS) {
10736
+ return this.nameCache;
10737
+ }
10738
+ const index = new Map;
10739
+ const scanned = this.scanDir(this.baseDir, index, 0);
10740
+ if (scanned > 0 || index.size > 0) {
10741
+ this.nameCache = index;
10742
+ this.nameCacheTime = now;
10743
+ }
10744
+ return index;
10745
+ }
10746
+ scanDir(dir, index, count) {
10747
+ if (count >= FactualCheck.MAX_INDEXED_FILES)
10748
+ return count;
10749
+ let entries;
10750
+ try {
10751
+ entries = readdirSync4(dir, { withFileTypes: true });
10752
+ } catch {
10753
+ return count;
10754
+ }
10755
+ for (const entry of entries) {
10756
+ if (count >= FactualCheck.MAX_INDEXED_FILES)
10757
+ break;
10758
+ const full = join12(dir, entry.name);
10759
+ if (entry.isDirectory()) {
10760
+ if (!IGNORED_DIRS.has(entry.name)) {
10761
+ count = this.scanDir(full, index, count);
10762
+ }
10763
+ } else if (entry.isFile()) {
10764
+ const list = index.get(entry.name);
10765
+ if (list)
10766
+ list.push(full);
10767
+ else
10768
+ index.set(entry.name, [full]);
10769
+ count++;
10770
+ }
10771
+ }
10772
+ return count;
10773
+ }
10714
10774
  extractFilePaths(text) {
10715
10775
  const pattern = /\b(?:[a-zA-Z]:[\\/])?[\w./\\-]+\.[a-z]{2,6}\b/gi;
10716
10776
  const matches = text.match(pattern) || [];
10717
10777
  return [...new Set(matches)].filter(looksLikeFilePath);
10718
10778
  }
10719
10779
  }
10720
- var NON_FILE_EXTENSIONS, TECH_NAMES;
10780
+ var IGNORED_DIRS, NON_FILE_EXTENSIONS, TECH_NAMES;
10721
10781
  var init_factual = __esm(() => {
10722
10782
  init_i18n();
10783
+ IGNORED_DIRS = new Set([
10784
+ "node_modules",
10785
+ ".git",
10786
+ "dist",
10787
+ "build",
10788
+ "coverage",
10789
+ ".mma",
10790
+ "_testing"
10791
+ ]);
10723
10792
  NON_FILE_EXTENSIONS = new Set([
10724
10793
  "com",
10725
10794
  "org",
@@ -11457,31 +11526,23 @@ function createLoadSkillTool(skillsModule) {
11457
11526
  return {
11458
11527
  name: "load_skill",
11459
11528
  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.",
11529
+ 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
11530
  parameters: {
11462
11531
  type: "object",
11463
11532
  properties: {
11464
- name: { type: "string", description: "Skill name to load directly" },
11465
- task: {
11533
+ name: {
11466
11534
  type: "string",
11467
- description: "Task description to find matching skill"
11535
+ description: "Exact skill name to load (see [Available Skills] for names)"
11468
11536
  }
11469
- }
11537
+ },
11538
+ required: ["name"]
11470
11539
  },
11471
11540
  handler: async (_ctx, args) => {
11472
11541
  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 {
11542
+ if (!name) {
11483
11543
  return { success: false, output: t("tool.invalid_params") };
11484
11544
  }
11545
+ const result = skillsModule.loadByName(name);
11485
11546
  if (!result.success) {
11486
11547
  const available = skillsModule.getAvailable();
11487
11548
  const hint = available.length > 0 ? `
@@ -11489,16 +11550,15 @@ function createLoadSkillTool(skillsModule) {
11489
11550
  ${t("tool.skill_available_hint")}: ${available.map((s) => s.name).join(", ")}` : "";
11490
11551
  return { success: false, output: result.message + hint };
11491
11552
  }
11492
- const skill = result.skill;
11493
11553
  const budget = skillsModule.getBudget();
11554
+ const tokens = result.skill ? Math.ceil(result.skill.content.length / 4) : 0;
11494
11555
  return {
11495
11556
  success: true,
11496
- output: `${result.message}
11497
-
11498
- --- Skill Content ---
11499
- ${skill.content}
11500
-
11501
- ${t("tool.skill_budget", { remaining: budget.remaining })}`
11557
+ output: t("tool.skill_budget", {
11558
+ name,
11559
+ tokens,
11560
+ remaining: budget.remaining
11561
+ })
11502
11562
  };
11503
11563
  }
11504
11564
  };
@@ -12272,7 +12332,7 @@ ${JSON.stringify(result, null, 2)}`
12272
12332
 
12273
12333
  // src/tools/search-history.ts
12274
12334
  import * as fs from "fs";
12275
- import { join as join12 } from "path";
12335
+ import { join as join13 } from "path";
12276
12336
  import { homedir as homedir5 } from "os";
12277
12337
  function searchFile(filePath, query, maxResults, results) {
12278
12338
  if (!fs.existsSync(filePath))
@@ -12316,7 +12376,7 @@ var init_search_history = __esm(() => {
12316
12376
  const query = String(args.query || "").toLowerCase();
12317
12377
  const maxResults = Number(args.maxResults) || 5;
12318
12378
  const sessionId = args.sessionId ? String(args.sessionId) : null;
12319
- const sessionDir = join12(homedir5(), ".mma", "sessions");
12379
+ const sessionDir = join13(homedir5(), ".mma", "sessions");
12320
12380
  const results = [];
12321
12381
  try {
12322
12382
  if (!fs.existsSync(sessionDir)) {
@@ -12331,7 +12391,7 @@ var init_search_history = __esm(() => {
12331
12391
  continue;
12332
12392
  if (sessionId && entry.name !== sessionId)
12333
12393
  continue;
12334
- const historyFile = join12(sessionDir, entry.name, "history.jsonl");
12394
+ const historyFile = join13(sessionDir, entry.name, "history.jsonl");
12335
12395
  searchFile(historyFile, query, maxResults, results);
12336
12396
  if (results.length >= maxResults)
12337
12397
  break;
@@ -12359,7 +12419,7 @@ var init_search_history = __esm(() => {
12359
12419
 
12360
12420
  // src/tools/remember.ts
12361
12421
  import { homedir as homedir6 } from "os";
12362
- import { join as join13 } from "path";
12422
+ import { join as join14 } from "path";
12363
12423
  var CATEGORIES, rememberTool;
12364
12424
  var init_remember = __esm(() => {
12365
12425
  init_i18n();
@@ -12397,7 +12457,7 @@ var init_remember = __esm(() => {
12397
12457
  if (!CATEGORIES.includes(category)) {
12398
12458
  return { success: false, output: t("tool.invalid_params") };
12399
12459
  }
12400
- const memoryDir = join13(homedir6(), ".mma", "memory");
12460
+ const memoryDir = join14(homedir6(), ".mma", "memory");
12401
12461
  const store = new MemoryStore(memoryDir);
12402
12462
  try {
12403
12463
  if (category === "preferences") {
@@ -12430,7 +12490,7 @@ var init_remember = __esm(() => {
12430
12490
 
12431
12491
  // src/tools/recall.ts
12432
12492
  import { homedir as homedir7 } from "os";
12433
- import { join as join14 } from "path";
12493
+ import { join as join15 } from "path";
12434
12494
  function formatAll(store) {
12435
12495
  const parts = [];
12436
12496
  const prefs = store.getPreferences();
@@ -12513,7 +12573,7 @@ var init_recall = __esm(() => {
12513
12573
  handler: async (_ctx, args) => {
12514
12574
  const query = args.query ? String(args.query) : "";
12515
12575
  const category = args.category ? String(args.category) : "";
12516
- const memoryDir = join14(homedir7(), ".mma", "memory");
12576
+ const memoryDir = join15(homedir7(), ".mma", "memory");
12517
12577
  const store = new MemoryStore(memoryDir);
12518
12578
  try {
12519
12579
  if (!query && !category) {
@@ -12709,15 +12769,15 @@ function buildIndexInjectionScript() {
12709
12769
 
12710
12770
  // src/modules/browser/cookie-store.ts
12711
12771
  import { readFile, writeFile, mkdir } from "fs/promises";
12712
- import { join as join15 } from "path";
12772
+ import { join as join16 } from "path";
12713
12773
 
12714
12774
  class CookieStore {
12715
12775
  filePath;
12716
12776
  constructor(cookieDir) {
12717
- this.filePath = join15(cookieDir, "cookies.json");
12777
+ this.filePath = join16(cookieDir, "cookies.json");
12718
12778
  }
12719
12779
  async save(cookies) {
12720
- await mkdir(join15(this.filePath, ".."), { recursive: true });
12780
+ await mkdir(join16(this.filePath, ".."), { recursive: true });
12721
12781
  await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
12722
12782
  }
12723
12783
  async load() {
@@ -13037,10 +13097,10 @@ var init_types = __esm(() => {
13037
13097
  });
13038
13098
 
13039
13099
  // src/tools/browser.ts
13040
- import { join as join16 } from "path";
13100
+ import { join as join17 } from "path";
13041
13101
  function getSession(ctx) {
13042
13102
  if (!session) {
13043
- const cookieDir = join16(ctx.baseDir, ".mma", "browser");
13103
+ const cookieDir = join17(ctx.baseDir, ".mma", "browser");
13044
13104
  session = new BrowserSession({
13045
13105
  ...DEFAULT_BROWSER_CONFIG,
13046
13106
  headless: ctx.config.browser?.headless ?? true,
@@ -13170,8 +13230,8 @@ async function readClipboardFallback() {
13170
13230
  const { platform: platform3 } = await import("os");
13171
13231
  const { execSync } = await import("child_process");
13172
13232
  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`);
13233
+ const { join: join18 } = await import("path");
13234
+ const tmpPath = join18(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
13175
13235
  try {
13176
13236
  if (platform3() === "linux") {
13177
13237
  execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
@@ -13448,16 +13508,16 @@ class ModuleRegistry {
13448
13508
  }
13449
13509
 
13450
13510
  // 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";
13511
+ import { readdirSync as readdirSync6, existsSync as existsSync23, statSync as statSync4 } from "fs";
13512
+ import { join as join18 } from "path";
13453
13513
 
13454
13514
  class PluginLoader {
13455
13515
  loadFromDir(dirPath, pluginManager, logger) {
13456
13516
  if (!existsSync23(dirPath))
13457
13517
  return;
13458
- const entries = readdirSync5(dirPath);
13518
+ const entries = readdirSync6(dirPath);
13459
13519
  for (const entry of entries) {
13460
- const fullPath = join17(dirPath, entry);
13520
+ const fullPath = join18(dirPath, entry);
13461
13521
  if (!statSync4(fullPath).isFile())
13462
13522
  continue;
13463
13523
  if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
@@ -13482,7 +13542,7 @@ var init_loader = __esm(() => {
13482
13542
  // src/modules/plugins/builtin/lint-on-write.ts
13483
13543
  import { spawn as spawn4, execSync } from "child_process";
13484
13544
  import { existsSync as existsSync24, readFileSync as readFileSync13 } from "fs";
13485
- import { resolve as resolve13, extname as extname4, join as join18 } from "path";
13545
+ import { resolve as resolve13, extname as extname4, join as join19 } from "path";
13486
13546
  import { platform as platform3 } from "os";
13487
13547
  function getWinDecoder() {
13488
13548
  if (_winDecoder === undefined) {
@@ -13567,7 +13627,7 @@ class LintOnWritePlugin {
13567
13627
  }
13568
13628
  async runProjectLint(ctx, result) {
13569
13629
  try {
13570
- const packageJsonPath = join18(ctx.baseDir, "package.json");
13630
+ const packageJsonPath = join19(ctx.baseDir, "package.json");
13571
13631
  if (!existsSync24(packageJsonPath)) {
13572
13632
  return;
13573
13633
  }
@@ -13587,7 +13647,7 @@ class LintOnWritePlugin {
13587
13647
  }
13588
13648
  }
13589
13649
  async runProjectTypeCheck(ctx, result) {
13590
- const tsconfigPath = join18(ctx.baseDir, "tsconfig.json");
13650
+ const tsconfigPath = join19(ctx.baseDir, "tsconfig.json");
13591
13651
  if (!existsSync24(tsconfigPath)) {
13592
13652
  return;
13593
13653
  }
@@ -13862,16 +13922,16 @@ var init_auditor = __esm(() => {
13862
13922
 
13863
13923
  // src/modules/execution/plan-persister.ts
13864
13924
  import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11, existsSync as existsSync26 } from "fs";
13865
- import { join as join19 } from "path";
13925
+ import { join as join20 } from "path";
13866
13926
 
13867
13927
  class PlanPersister {
13868
13928
  filePath;
13869
13929
  constructor(baseDir) {
13870
- const mmaDir = join19(baseDir, ".mma");
13930
+ const mmaDir = join20(baseDir, ".mma");
13871
13931
  if (!existsSync26(mmaDir)) {
13872
13932
  mkdirSync11(mmaDir, { recursive: true });
13873
13933
  }
13874
- this.filePath = join19(mmaDir, "plan.json");
13934
+ this.filePath = join20(mmaDir, "plan.json");
13875
13935
  }
13876
13936
  save(plan) {
13877
13937
  const file = {
@@ -14296,9 +14356,8 @@ Sub-tasks: ${note}`
14296
14356
  const recovery = this.stuckDetector.getRecoveryMessage();
14297
14357
  if (recovery && ctx.contextManager) {
14298
14358
  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.` : "";
14359
+ const skillHint = lastError ? `
14360
+ If you have relevant skills available, consider loading one with load_skill for expert guidance.` : "";
14302
14361
  const actionableHints = this.stuckDetector.getActionableHints();
14303
14362
  const actionableHintStr = actionableHints.length > 0 ? `
14304
14363
  ${t("exec.hints", { hints: actionableHints.map((h) => `- ${h}`).join(`
@@ -14542,12 +14601,11 @@ var init_module = __esm(() => {
14542
14601
  init_auditor();
14543
14602
  init_plan_persister();
14544
14603
  init_plan_coverage();
14545
- init_error_skill_map();
14546
14604
  });
14547
14605
 
14548
14606
  // 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";
14607
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, existsSync as existsSync28, readdirSync as readdirSync7, unlinkSync as unlinkSync3 } from "fs";
14608
+ import { join as join21 } from "path";
14551
14609
  import { homedir as homedir8 } from "os";
14552
14610
 
14553
14611
  class SessionFileEncryptor {
@@ -14556,7 +14614,7 @@ class SessionFileEncryptor {
14556
14614
  constructor(config) {
14557
14615
  this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
14558
14616
  this.encryptor = new ConfigEncryptor({
14559
- keyPath: config?.keyPath || join20(homedir8(), ".mma", ".session-encryption-key")
14617
+ keyPath: config?.keyPath || join21(homedir8(), ".mma", ".session-encryption-key")
14560
14618
  });
14561
14619
  }
14562
14620
  isEnabled() {
@@ -14626,9 +14684,9 @@ class SessionFileEncryptor {
14626
14684
  encryptSessionDirectory(sessionDir) {
14627
14685
  if (!this.config.enabled)
14628
14686
  return;
14629
- const files = readdirSync6(sessionDir);
14687
+ const files = readdirSync7(sessionDir);
14630
14688
  for (const file of files) {
14631
- const filePath = join20(sessionDir, file);
14689
+ const filePath = join21(sessionDir, file);
14632
14690
  if (existsSync28(filePath) && !file.endsWith(".enc")) {
14633
14691
  try {
14634
14692
  const content = readFileSync16(filePath, "utf8");
@@ -14642,10 +14700,10 @@ class SessionFileEncryptor {
14642
14700
  decryptSessionDirectory(sessionDir) {
14643
14701
  if (!this.config.enabled)
14644
14702
  return;
14645
- const files = readdirSync6(sessionDir);
14703
+ const files = readdirSync7(sessionDir);
14646
14704
  for (const file of files) {
14647
14705
  if (file.endsWith(".enc")) {
14648
- const encFilePath = join20(sessionDir, file);
14706
+ const encFilePath = join21(sessionDir, file);
14649
14707
  const decFilePath = encFilePath.slice(0, -4);
14650
14708
  try {
14651
14709
  const content = readFileSync16(encFilePath, "utf8");
@@ -14672,13 +14730,13 @@ var init_session_encryption = __esm(() => {
14672
14730
  import {
14673
14731
  existsSync as existsSync29,
14674
14732
  mkdirSync as mkdirSync12,
14675
- readdirSync as readdirSync7,
14733
+ readdirSync as readdirSync8,
14676
14734
  readFileSync as readFileSync17,
14677
14735
  rmSync,
14678
14736
  writeFileSync as writeFileSync10,
14679
14737
  appendFileSync as appendFileSync5
14680
14738
  } from "fs";
14681
- import { join as join21 } from "path";
14739
+ import { join as join22 } from "path";
14682
14740
  import { gzipSync } from "zlib";
14683
14741
 
14684
14742
  class SessionStore {
@@ -14692,7 +14750,7 @@ class SessionStore {
14692
14750
  }
14693
14751
  }
14694
14752
  getSessionDir(id) {
14695
- return join21(this.baseDir, id);
14753
+ return join22(this.baseDir, id);
14696
14754
  }
14697
14755
  updateEncryption(config) {
14698
14756
  if (config?.enabled) {
@@ -14708,16 +14766,16 @@ class SessionStore {
14708
14766
  mkdirSync12(this.baseDir, { recursive: true });
14709
14767
  }
14710
14768
  sessionDir(id) {
14711
- return join21(this.baseDir, id);
14769
+ return join22(this.baseDir, id);
14712
14770
  }
14713
14771
  metaPath(id) {
14714
- return join21(this.sessionDir(id), "meta.json");
14772
+ return join22(this.sessionDir(id), "meta.json");
14715
14773
  }
14716
14774
  historyPath(id) {
14717
- return join21(this.sessionDir(id), "history.jsonl");
14775
+ return join22(this.sessionDir(id), "history.jsonl");
14718
14776
  }
14719
14777
  sessionLogPath(id) {
14720
- return join21(this.sessionDir(id), "session.jsonl");
14778
+ return join22(this.sessionDir(id), "session.jsonl");
14721
14779
  }
14722
14780
  sessionExists(id) {
14723
14781
  return existsSync29(this.metaPath(id));
@@ -14841,7 +14899,7 @@ class SessionStore {
14841
14899
  listSessions() {
14842
14900
  if (!existsSync29(this.baseDir))
14843
14901
  return [];
14844
- const entries = readdirSync7(this.baseDir, { withFileTypes: true });
14902
+ const entries = readdirSync8(this.baseDir, { withFileTypes: true });
14845
14903
  const sessions = [];
14846
14904
  for (const entry of entries) {
14847
14905
  if (entry.isDirectory()) {
@@ -14871,7 +14929,7 @@ class SessionStore {
14871
14929
  if (existsSync29(historyPath)) {
14872
14930
  const content = readFileSync17(historyPath, "utf-8");
14873
14931
  const compressed = gzipSync(content);
14874
- const gzPath = join21(this.baseDir, `${session2.id}.jsonl.gz`);
14932
+ const gzPath = join22(this.baseDir, `${session2.id}.jsonl.gz`);
14875
14933
  writeFileSync10(gzPath, compressed);
14876
14934
  rmSync(historyPath);
14877
14935
  }
@@ -15082,7 +15140,7 @@ class ProfileCompressor {
15082
15140
 
15083
15141
  // src/modules/user-profile/profile.ts
15084
15142
  import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
15085
- import { join as join22 } from "path";
15143
+ import { join as join23 } from "path";
15086
15144
  import { homedir as homedir9, hostname, platform as platform4, type } from "os";
15087
15145
  import { env } from "process";
15088
15146
 
@@ -15109,10 +15167,10 @@ class UserProfile {
15109
15167
  if (!existsSync30(this.profileDir)) {
15110
15168
  mkdirSync13(this.profileDir, { recursive: true });
15111
15169
  }
15112
- writeFileSync11(join22(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
15170
+ writeFileSync11(join23(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
15113
15171
  }
15114
15172
  load() {
15115
- const path = join22(this.profileDir, "profile.json");
15173
+ const path = join23(this.profileDir, "profile.json");
15116
15174
  if (!existsSync30(path))
15117
15175
  return null;
15118
15176
  try {
@@ -15151,8 +15209,8 @@ class UserProfile {
15151
15209
  var init_profile = () => {};
15152
15210
 
15153
15211
  // 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";
15212
+ import { readdirSync as readdirSync9, readFileSync as readFileSync19, existsSync as existsSync31, statSync as statSync5 } from "fs";
15213
+ import { join as join24 } from "path";
15156
15214
 
15157
15215
  class SkillsLoader {
15158
15216
  loadFromDir(dirPath) {
@@ -15163,9 +15221,9 @@ class SkillsLoader {
15163
15221
  return skills;
15164
15222
  }
15165
15223
  scanDir(dirPath, skills) {
15166
- const entries = readdirSync8(dirPath);
15224
+ const entries = readdirSync9(dirPath);
15167
15225
  for (const entry of entries) {
15168
- const fullPath = join23(dirPath, entry);
15226
+ const fullPath = join24(dirPath, entry);
15169
15227
  const stat = statSync5(fullPath);
15170
15228
  if (stat.isDirectory()) {
15171
15229
  this.scanDir(fullPath, skills);
@@ -15223,42 +15281,15 @@ class SkillsLoader {
15223
15281
  }
15224
15282
  var init_loader2 = () => {};
15225
15283
 
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
15284
  // src/modules/skills/module.ts
15252
15285
  class SkillsModule {
15253
15286
  name = "skills";
15254
15287
  availableSkills;
15255
15288
  loadedSkills = new Map;
15256
- matcher;
15257
15289
  budget;
15258
15290
  currentTokens = 0;
15259
- constructor(availableSkills, matcher, budget) {
15291
+ constructor(availableSkills, budget) {
15260
15292
  this.availableSkills = availableSkills;
15261
- this.matcher = matcher;
15262
15293
  this.budget = budget;
15263
15294
  }
15264
15295
  loadByName(name) {
@@ -15267,24 +15298,10 @@ class SkillsModule {
15267
15298
  }
15268
15299
  const skill = this.availableSkills.find((s) => s.name === name);
15269
15300
  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
15301
  return { success: false, message: t("skill.not_found", { name }) };
15275
15302
  }
15276
15303
  return this.tryLoad(skill);
15277
15304
  }
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
15305
  unload(name) {
15289
15306
  const skill = this.loadedSkills.get(name);
15290
15307
  if (!skill)
@@ -15303,7 +15320,8 @@ class SkillsModule {
15303
15320
  return this.availableSkills.find((s) => s.name === name);
15304
15321
  }
15305
15322
  search(query) {
15306
- return this.matcher.match(query, this.availableSkills, 10);
15323
+ const q = query.toLowerCase();
15324
+ return this.availableSkills.filter((s) => s.name.toLowerCase().includes(q) || s.description.toLowerCase().includes(q));
15307
15325
  }
15308
15326
  getBudget() {
15309
15327
  return {
@@ -15322,16 +15340,17 @@ class SkillsModule {
15322
15340
  lines.push("[Available Skills]");
15323
15341
  lines.push(t("skill.prompt_hint"));
15324
15342
  for (const skill of this.availableSkills) {
15325
- const desc = skill.description.slice(0, 60);
15343
+ const desc = skill.description.slice(0, 80);
15326
15344
  lines.push(`- ${skill.name}: ${desc}`);
15327
15345
  }
15328
- lines.push(t("skill.prompt_fallback"));
15329
15346
  }
15330
15347
  if (this.loadedSkills.size > 0) {
15348
+ lines.push("");
15331
15349
  lines.push("[Loaded Skills]");
15332
15350
  for (const skill of this.loadedSkills.values()) {
15333
- const desc = skill.description.slice(0, 80);
15334
- lines.push(`- ${skill.name}: ${desc}`);
15351
+ lines.push(`--- ${skill.name} (${this.estimateTokens(skill.content)} tokens) ---`);
15352
+ lines.push(skill.content);
15353
+ lines.push("");
15335
15354
  }
15336
15355
  }
15337
15356
  if (lines.length === 0)
@@ -15341,7 +15360,7 @@ class SkillsModule {
15341
15360
  const tokens = this.estimateTokens(content);
15342
15361
  return {
15343
15362
  content,
15344
- priority: "normal",
15363
+ priority: "high",
15345
15364
  essential: false,
15346
15365
  estimatedTokens: tokens
15347
15366
  };
@@ -15761,8 +15780,8 @@ var init_lsp = __esm(() => {
15761
15780
  });
15762
15781
 
15763
15782
  // 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";
15783
+ import { readdirSync as readdirSync10, readFileSync as readFileSync20, statSync as statSync6, existsSync as existsSync33, watch } from "fs";
15784
+ import { join as join25, relative, extname as extname5 } from "path";
15766
15785
 
15767
15786
  class Indexer {
15768
15787
  baseDir;
@@ -15793,14 +15812,14 @@ class Indexer {
15793
15812
  return;
15794
15813
  let entries;
15795
15814
  try {
15796
- entries = readdirSync9(dir);
15815
+ entries = readdirSync10(dir);
15797
15816
  } catch {
15798
15817
  return;
15799
15818
  }
15800
15819
  for (const entry of entries) {
15801
15820
  if (count >= this.MAX_FILES)
15802
15821
  return;
15803
- const fullPath = join24(dir, entry);
15822
+ const fullPath = join25(dir, entry);
15804
15823
  const relPath = relative(this.baseDir, fullPath);
15805
15824
  const stat = statSync6(fullPath);
15806
15825
  if (stat.isDirectory()) {
@@ -15864,13 +15883,13 @@ var init_walker = __esm(() => {
15864
15883
 
15865
15884
  // src/modules/indexer/cache.ts
15866
15885
  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";
15886
+ import { join as join26 } from "path";
15868
15887
 
15869
15888
  class IndexCache {
15870
15889
  cachePath;
15871
15890
  cache = null;
15872
15891
  constructor(cacheDir) {
15873
- this.cachePath = join25(cacheDir, "index-cache.json");
15892
+ this.cachePath = join26(cacheDir, "index-cache.json");
15874
15893
  }
15875
15894
  load() {
15876
15895
  if (this.cache)
@@ -15886,7 +15905,7 @@ class IndexCache {
15886
15905
  }
15887
15906
  save(result) {
15888
15907
  this.cache = result;
15889
- const dir = join25(this.cachePath, "..");
15908
+ const dir = join26(this.cachePath, "..");
15890
15909
  if (!existsSync34(dir))
15891
15910
  mkdirSync14(dir, { recursive: true });
15892
15911
  writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
@@ -16251,13 +16270,13 @@ var init_mcp = __esm(() => {
16251
16270
 
16252
16271
  // src/modules/memory/module.ts
16253
16272
  import { homedir as homedir10 } from "os";
16254
- import { join as join26 } from "path";
16273
+ import { join as join27 } from "path";
16255
16274
 
16256
16275
  class MemoryModule {
16257
16276
  name = "memory";
16258
16277
  store;
16259
16278
  constructor(memoryDir) {
16260
- const dir = memoryDir || join26(homedir10(), ".mma", "memory");
16279
+ const dir = memoryDir || join27(homedir10(), ".mma", "memory");
16261
16280
  this.store = new MemoryStore(dir);
16262
16281
  }
16263
16282
  getSystemPromptBlock() {
@@ -16304,7 +16323,7 @@ __export(exports_bootstrap, {
16304
16323
  bootstrap: () => bootstrap
16305
16324
  });
16306
16325
  import { homedir as homedir11 } from "os";
16307
- import { join as join27, resolve as resolve18 } from "path";
16326
+ import { join as join28, resolve as resolve18 } from "path";
16308
16327
  import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
16309
16328
  function buildSystemInfo(config, baseDir, profileCompressed) {
16310
16329
  const now = new Date().toISOString().replace("T", " ").slice(0, 19);
@@ -16339,8 +16358,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
16339
16358
  `);
16340
16359
  }
16341
16360
  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");
16361
+ const dir = configDir || join28(homedir11(), ".mma");
16362
+ const projectConfigPath = projectDir ? join28(projectDir, ".mmrc") : join28(process.cwd(), ".mmrc");
16344
16363
  const config = loadConfig({ configDir: dir, projectConfigPath });
16345
16364
  setLocale(config.locale);
16346
16365
  try {
@@ -16350,7 +16369,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16350
16369
  }
16351
16370
  } catch {}
16352
16371
  const logger = new Logger(config.logLevel);
16353
- logger.setLogDir(join27(dir, "logs"));
16372
+ logger.setLogDir(join28(dir, "logs"));
16354
16373
  logger.debug("MMA bootstrap", {
16355
16374
  version: config.version,
16356
16375
  model: config.model
@@ -16372,7 +16391,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16372
16391
  logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
16373
16392
  }
16374
16393
  }
16375
- const profile = new UserProfile(join27(dir));
16394
+ const profile = new UserProfile(join28(dir));
16376
16395
  profile.load() || profile.collect();
16377
16396
  profile.save();
16378
16397
  const llmProvider = new OpenAICompatProvider({
@@ -16384,7 +16403,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16384
16403
  rateLimits: config.security?.rateLimits
16385
16404
  });
16386
16405
  const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
16387
- const projectMapCacheDir = join27(baseDir, ".mma");
16406
+ const projectMapCacheDir = join28(baseDir, ".mma");
16388
16407
  const indexerModule = new IndexerModule({
16389
16408
  baseDir,
16390
16409
  cacheDir: projectMapCacheDir
@@ -16395,13 +16414,12 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16395
16414
  logger.warn(`Project indexing failed: ${err.message}`);
16396
16415
  }
16397
16416
  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");
16417
+ const builtinDir = join28(import.meta.dirname, "skills", "builtin");
16418
+ const globalDir = join28(homedir11(), ".agents", "skills");
16419
+ const projectSkillsDir = join28(baseDir, ".mma", "skills");
16401
16420
  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);
16421
+ const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
16422
+ const skillsModule = new SkillsModule(availableSkills, skillsBudget);
16405
16423
  const toolRegistry = new ToolRegistry;
16406
16424
  registerAllTools(toolRegistry, skillsModule);
16407
16425
  const pluginManager = new PluginManager;
@@ -16411,11 +16429,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16411
16429
  essential: true,
16412
16430
  estimatedTokens: 250
16413
16431
  };
16414
- const agentsMdGlobal = join27(dir, "AGENTS.md");
16432
+ const agentsMdGlobal = join28(dir, "AGENTS.md");
16415
16433
  if (!existsSync35(agentsMdGlobal)) {
16416
16434
  writeFileSync13(agentsMdGlobal, "", "utf-8");
16417
16435
  }
16418
- const sessionDir = join27(dir, "sessions");
16436
+ const sessionDir = join28(dir, "sessions");
16419
16437
  const sessionStore = new SessionStore(sessionDir);
16420
16438
  sessionStore.init();
16421
16439
  const sessionManager = new SessionManager(sessionStore, {
@@ -16478,12 +16496,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16478
16496
  moduleRegistry.register(execModule);
16479
16497
  const sessionModule = new SessionModule(sessionManager);
16480
16498
  moduleRegistry.register(sessionModule);
16481
- moduleRegistry.register(skillsModule);
16482
16499
  moduleRegistry.register(indexerModule);
16483
16500
  const mcpModule = new MCPModule(config);
16484
16501
  await mcpModule.initialize();
16485
16502
  moduleRegistry.register(mcpModule);
16486
- const memoryModule = new MemoryModule(join27(dir, "memory"));
16503
+ const memoryModule = new MemoryModule(join28(dir, "memory"));
16487
16504
  moduleRegistry.register(memoryModule);
16488
16505
  if (config.browser.enabled) {
16489
16506
  const browserModule = new BrowserModule;
@@ -16533,8 +16550,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16533
16550
  pluginManager.register(plugin);
16534
16551
  pluginManager.register(plugin2);
16535
16552
  const pluginLoader = new PluginLoader;
16536
- const globalPluginsDir = join27(homedir11(), ".mma", "plugins");
16537
- const projectPluginsDir = join27(baseDir, ".mma", "plugins");
16553
+ const globalPluginsDir = join28(homedir11(), ".mma", "plugins");
16554
+ const projectPluginsDir = join28(baseDir, ".mma", "plugins");
16538
16555
  pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
16539
16556
  pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
16540
16557
  contextManager.onCompact = (summary) => {
@@ -16552,9 +16569,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16552
16569
  const skipAgentsMd = noAgentsMd === true;
16553
16570
  if (!skipAgentsMd) {
16554
16571
  const agentsMdCandidates = [
16555
- join27(baseDir, "AGENTS.md"),
16556
- join27(baseDir, ".mma", "AGENTS.md"),
16557
- join27(dir, "AGENTS.md")
16572
+ join28(baseDir, "AGENTS.md"),
16573
+ join28(baseDir, ".mma", "AGENTS.md"),
16574
+ join28(dir, "AGENTS.md")
16558
16575
  ];
16559
16576
  for (const p of agentsMdCandidates) {
16560
16577
  if (existsSync35(p)) {
@@ -16586,8 +16603,14 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
16586
16603
  baseDir,
16587
16604
  promptBlocks,
16588
16605
  getDynamicPromptBlocks: () => {
16606
+ const blocks = [];
16589
16607
  const planBlock = execModule.getSystemPromptBlock();
16590
- return planBlock ? [planBlock] : [];
16608
+ if (planBlock)
16609
+ blocks.push(planBlock);
16610
+ const skillsBlock = skillsModule.getSystemPromptBlock();
16611
+ if (skillsBlock)
16612
+ blocks.push(skillsBlock);
16613
+ return blocks;
16591
16614
  },
16592
16615
  finalAudit: () => execModule.runFinalAudit(),
16593
16616
  sessionManager,
@@ -17333,7 +17356,7 @@ __export(exports_manifest, {
17333
17356
  });
17334
17357
  import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "fs";
17335
17358
  import { homedir as homedir13 } from "os";
17336
- import { join as join29 } from "path";
17359
+ import { join as join30 } from "path";
17337
17360
  function readManifest(path = MANIFEST_PATH) {
17338
17361
  try {
17339
17362
  if (existsSync36(path)) {
@@ -17344,7 +17367,7 @@ function readManifest(path = MANIFEST_PATH) {
17344
17367
  return { version: 1, certifications: [] };
17345
17368
  }
17346
17369
  function saveManifest(m, path = MANIFEST_PATH) {
17347
- mkdirSync15(join29(homedir13(), ".mma"), { recursive: true });
17370
+ mkdirSync15(join30(homedir13(), ".mma"), { recursive: true });
17348
17371
  writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
17349
17372
  }
17350
17373
  function upsertCertification(entry, path = MANIFEST_PATH) {
@@ -17379,7 +17402,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
17379
17402
  }
17380
17403
  var MANIFEST_PATH;
17381
17404
  var init_manifest = __esm(() => {
17382
- MANIFEST_PATH = join29(homedir13(), ".mma", "certifications.json");
17405
+ MANIFEST_PATH = join30(homedir13(), ".mma", "certifications.json");
17383
17406
  });
17384
17407
 
17385
17408
  // node_modules/yaml/dist/nodes/identity.js
@@ -24502,8 +24525,8 @@ var init_scenarios = __esm(() => {
24502
24525
  });
24503
24526
 
24504
24527
  // 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";
24528
+ import { existsSync as existsSync37, readdirSync as readdirSync11, readFileSync as readFileSync24 } from "fs";
24529
+ import { join as join31 } from "path";
24507
24530
  function validateScenario(s) {
24508
24531
  const errors2 = [];
24509
24532
  const isSkip = s.mode === "skip";
@@ -24553,11 +24576,11 @@ function loadScenarios(userDir) {
24553
24576
  scenarios.push(s);
24554
24577
  }
24555
24578
  if (userDir && existsSync37(userDir)) {
24556
- for (const file of readdirSync10(userDir)) {
24579
+ for (const file of readdirSync11(userDir)) {
24557
24580
  if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
24558
24581
  continue;
24559
24582
  try {
24560
- const raw = readFileSync24(join30(userDir, file), "utf-8");
24583
+ const raw = readFileSync24(join31(userDir, file), "utf-8");
24561
24584
  const data = $parse(raw);
24562
24585
  const parsed = normalizeScenario(data, file);
24563
24586
  const errs = validateScenario(parsed);
@@ -24611,7 +24634,7 @@ var init_loader3 = __esm(() => {
24611
24634
 
24612
24635
  // src/modules/certification/fact-checker.ts
24613
24636
  import { existsSync as existsSync38, readFileSync as readFileSync25, statSync as statSync7 } from "fs";
24614
- import { join as join31 } from "path";
24637
+ import { join as join32 } from "path";
24615
24638
  function checkSandbox(sandboxDir, checks, exitCode, output) {
24616
24639
  const failures = [];
24617
24640
  for (const check of checks) {
@@ -24628,13 +24651,13 @@ function runCheck(sandboxDir, check, exitCode, output) {
24628
24651
  case "outputContains":
24629
24652
  return output.includes(check.text);
24630
24653
  case "fileExists":
24631
- return isFile(join31(sandboxDir, check.path));
24654
+ return isFile(join32(sandboxDir, check.path));
24632
24655
  case "fileNotExists":
24633
- return !existsSync38(join31(sandboxDir, check.path));
24656
+ return !existsSync38(join32(sandboxDir, check.path));
24634
24657
  case "dirExists":
24635
- return isDir(join31(sandboxDir, check.path));
24658
+ return isDir(join32(sandboxDir, check.path));
24636
24659
  case "fileContent": {
24637
- const abs = join31(sandboxDir, check.path);
24660
+ const abs = join32(sandboxDir, check.path);
24638
24661
  if (!isFile(abs))
24639
24662
  return false;
24640
24663
  const content = readFileSync25(abs, "utf-8");
@@ -24645,7 +24668,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
24645
24668
  return false;
24646
24669
  }
24647
24670
  case "fileRegex": {
24648
- const abs = join31(sandboxDir, check.path);
24671
+ const abs = join32(sandboxDir, check.path);
24649
24672
  if (!isFile(abs))
24650
24673
  return false;
24651
24674
  return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
@@ -24696,7 +24719,7 @@ var init_fact_checker = () => {};
24696
24719
  import { spawn as spawn6 } from "child_process";
24697
24720
  import { existsSync as existsSync39, mkdirSync as mkdirSync16, rmSync as rmSync3, cpSync as cpSync2 } from "fs";
24698
24721
  import { platform as platform5 } from "os";
24699
- import { join as join32, resolve as resolve19, dirname as dirname9 } from "path";
24722
+ import { join as join33, resolve as resolve19, dirname as dirname9 } from "path";
24700
24723
  async function runScenario(scenario, opts) {
24701
24724
  if (scenario.mode === "skip") {
24702
24725
  return {
@@ -24715,7 +24738,7 @@ async function runScenario(scenario, opts) {
24715
24738
  let passed = 0;
24716
24739
  let firstError;
24717
24740
  for (let i = 1;i <= reps; i++) {
24718
- const sandbox = join32(opts.sandboxBase, `run-${scenario.id}-${i}`);
24741
+ const sandbox = join33(opts.sandboxBase, `run-${scenario.id}-${i}`);
24719
24742
  let failures = [];
24720
24743
  let exitCode = -1;
24721
24744
  let output = "";
@@ -24776,20 +24799,20 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
24776
24799
  rmSync3(sandbox, { recursive: true, force: true });
24777
24800
  mkdirSync16(sandbox, { recursive: true });
24778
24801
  for (const f of scenario.fixtures ?? []) {
24779
- const src = join32(mmaRoot, f.source);
24802
+ const src = join33(mmaRoot, f.source);
24780
24803
  if (!existsSync39(src)) {
24781
24804
  throw new Error(`fixture missing: ${f.source}`);
24782
24805
  }
24783
- const dest = join32(sandbox, f.dest);
24806
+ const dest = join33(sandbox, f.dest);
24784
24807
  mkdirSync16(dirname9(dest), { recursive: true });
24785
24808
  cpSync2(src, dest);
24786
24809
  }
24787
24810
  }
24788
24811
  function resolveMmaEntry(mmaRoot) {
24789
- const dev = join32(mmaRoot, "src", "cli", "main.ts");
24812
+ const dev = join33(mmaRoot, "src", "cli", "main.ts");
24790
24813
  if (existsSync39(dev))
24791
24814
  return dev;
24792
- return join32(mmaRoot, "dist", "main.js");
24815
+ return join33(mmaRoot, "dist", "main.js");
24793
24816
  }
24794
24817
  function findMmaRoot(fromDir) {
24795
24818
  const candidates = [
@@ -24797,7 +24820,7 @@ function findMmaRoot(fromDir) {
24797
24820
  resolve19(fromDir, "..")
24798
24821
  ];
24799
24822
  for (const c of candidates) {
24800
- if (existsSync39(join32(c, "package.json")))
24823
+ if (existsSync39(join33(c, "package.json")))
24801
24824
  return c;
24802
24825
  }
24803
24826
  return process.cwd();
@@ -24865,12 +24888,12 @@ __export(exports_cli, {
24865
24888
  });
24866
24889
  import { rmSync as rmSync4 } from "fs";
24867
24890
  import { homedir as homedir14 } from "os";
24868
- import { join as join33, dirname as dirname10 } from "path";
24891
+ import { join as join34, dirname as dirname10 } from "path";
24869
24892
  import { fileURLToPath } from "url";
24870
24893
  import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
24871
24894
  function readVersion() {
24872
24895
  const candidates = [
24873
- join33(MMA_ROOT, "package.json")
24896
+ join34(MMA_ROOT, "package.json")
24874
24897
  ];
24875
24898
  for (const p of candidates) {
24876
24899
  if (existsSync40(p)) {
@@ -24909,7 +24932,7 @@ async function certify(opts) {
24909
24932
  return;
24910
24933
  }
24911
24934
  console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
24912
- const sandboxBase = join33(process.cwd(), ".mma", "certification");
24935
+ const sandboxBase = join34(process.cwd(), ".mma", "certification");
24913
24936
  const results = [];
24914
24937
  const total = selected.length;
24915
24938
  let idx = 0;
@@ -25017,7 +25040,7 @@ var init_cli = __esm(() => {
25017
25040
  init_manifest();
25018
25041
  HERE = dirname10(fileURLToPath(import.meta.url));
25019
25042
  MMA_ROOT = findMmaRoot(HERE);
25020
- USER_SCENARIO_DIR = join33(homedir14(), ".mma", "certification", "scenarios");
25043
+ USER_SCENARIO_DIR = join34(homedir14(), ".mma", "certification", "scenarios");
25021
25044
  });
25022
25045
 
25023
25046
  // src/cli/repl-commands.ts
@@ -25026,15 +25049,15 @@ __export(exports_repl_commands, {
25026
25049
  registerAllCommands: () => registerAllCommands,
25027
25050
  COMMAND_GROUPS: () => COMMAND_GROUPS
25028
25051
  });
25029
- import { join as join35, dirname as dirname12 } from "path";
25052
+ import { join as join36, dirname as dirname12 } from "path";
25030
25053
  import { homedir as homedir16 } from "os";
25031
25054
  import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
25032
25055
  import { fileURLToPath as fileURLToPath3 } from "url";
25033
25056
  function readVersion3() {
25034
25057
  const here = dirname12(fileURLToPath3(import.meta.url));
25035
25058
  const candidates = [
25036
- join35(here, "..", "..", "package.json"),
25037
- join35(here, "..", "package.json")
25059
+ join36(here, "..", "..", "package.json"),
25060
+ join36(here, "..", "package.json")
25038
25061
  ];
25039
25062
  for (const p of candidates) {
25040
25063
  if (existsSync42(p)) {
@@ -25200,7 +25223,7 @@ function registerMmaCommands(ctx) {
25200
25223
  console.log(pc2.yellow(t("repl.wizard_running")));
25201
25224
  await ctx.withExclusiveInput(async () => {
25202
25225
  const answers = await runSetup(ctx.rl);
25203
- const configPath = join35(homedir16(), ".mma", "config.json");
25226
+ const configPath = join36(homedir16(), ".mma", "config.json");
25204
25227
  ctx.config.provider.type = answers.provider;
25205
25228
  ctx.config.provider.baseUrl = answers.apiBase;
25206
25229
  ctx.config.provider.apiKey = answers.apiKey;
@@ -25254,7 +25277,7 @@ Excluded blocks: ${info.excluded.length}`));
25254
25277
  return;
25255
25278
  }
25256
25279
  ctx.config.provider.type = name;
25257
- const configPath = join35(homedir16(), ".mma", "config.json");
25280
+ const configPath = join36(homedir16(), ".mma", "config.json");
25258
25281
  saveConfig(ctx.config, configPath);
25259
25282
  await ctx.agent.reconfigure(ctx.config);
25260
25283
  console.log(pc2.green(t("repl.provider_set", { name })));
@@ -25310,7 +25333,7 @@ Excluded blocks: ${info.excluded.length}`));
25310
25333
  return;
25311
25334
  }
25312
25335
  ctx.config.model = name;
25313
- const configPath = join35(homedir16(), ".mma", "config.json");
25336
+ const configPath = join36(homedir16(), ".mma", "config.json");
25314
25337
  saveConfig(ctx.config, configPath);
25315
25338
  await ctx.agent.reconfigure(ctx.config);
25316
25339
  console.log(pc2.green(t("repl.model_set", { name })));
@@ -25335,7 +25358,7 @@ Excluded blocks: ${info.excluded.length}`));
25335
25358
  return;
25336
25359
  }
25337
25360
  ctx.config.contextWindow = size;
25338
- const configPath = join35(homedir16(), ".mma", "config.json");
25361
+ const configPath = join36(homedir16(), ".mma", "config.json");
25339
25362
  saveConfig(ctx.config, configPath);
25340
25363
  await ctx.agent.reconfigure(ctx.config);
25341
25364
  console.log(pc2.green(t("cli.context_set", { size })));
@@ -25354,10 +25377,10 @@ Excluded blocks: ${info.excluded.length}`));
25354
25377
  ctx.agent.shutdown();
25355
25378
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
25356
25379
  const { homedir: homedir17 } = await import("os");
25357
- const { join: join36 } = await import("path");
25380
+ const { join: join37 } = await import("path");
25358
25381
  const configDir = ctx.configDir;
25359
25382
  const baseDir = ctx.baseDir;
25360
- const projectConfigPath = join36(baseDir, ".mmrc");
25383
+ const projectConfigPath = join37(baseDir, ".mmrc");
25361
25384
  const freshConfig = loadConfig2({ configDir, projectConfigPath });
25362
25385
  Object.assign(ctx.config, freshConfig);
25363
25386
  const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
@@ -25657,14 +25680,14 @@ init_bootstrap();
25657
25680
  init_config2();
25658
25681
  init_setup();
25659
25682
  init_i18n();
25660
- import { join as join34, dirname as dirname11 } from "path";
25683
+ import { join as join35, dirname as dirname11 } from "path";
25661
25684
  import { homedir as homedir15 } from "os";
25662
25685
  import { existsSync as existsSync41, readFileSync as readFileSync27 } from "fs";
25663
25686
 
25664
25687
  // src/cli/security-commands.ts
25665
25688
  init_bootstrap();
25666
25689
  init_config2();
25667
- import { join as join28 } from "path";
25690
+ import { join as join29 } from "path";
25668
25691
  import { homedir as homedir12 } from "os";
25669
25692
 
25670
25693
  // src/modules/security/security-policies.ts
@@ -26194,7 +26217,7 @@ function createSecurityCommand(program2) {
26194
26217
  }
26195
26218
  });
26196
26219
  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");
26220
+ const configPath = join29(homedir12(), ".mma", "config.json");
26198
26221
  const { config: appConfig } = await bootstrap();
26199
26222
  const validPresets = ["strict", "balanced", "permissive"];
26200
26223
  if (!validPresets.includes(preset)) {
@@ -26209,7 +26232,7 @@ function createSecurityCommand(program2) {
26209
26232
  console.log(t("cli.security.policy_description", { description: policy.description }));
26210
26233
  });
26211
26234
  securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
26212
- const configPath = join28(homedir12(), ".mma", "config.json");
26235
+ const configPath = join29(homedir12(), ".mma", "config.json");
26213
26236
  const { config: appConfig } = await bootstrap();
26214
26237
  appConfig.security = appConfig.security || {};
26215
26238
  appConfig.security.sessionEncryption = {
@@ -26221,7 +26244,7 @@ function createSecurityCommand(program2) {
26221
26244
  console.log(t("cli.security.encryption_enabled"));
26222
26245
  });
26223
26246
  securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
26224
- const configPath = join28(homedir12(), ".mma", "config.json");
26247
+ const configPath = join29(homedir12(), ".mma", "config.json");
26225
26248
  const { config: appConfig } = await bootstrap();
26226
26249
  appConfig.security = appConfig.security || {};
26227
26250
  appConfig.security.sessionEncryption = {
@@ -26233,7 +26256,7 @@ function createSecurityCommand(program2) {
26233
26256
  console.log(t("cli.security.encryption_disabled"));
26234
26257
  });
26235
26258
  securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
26236
- const configPath = join28(homedir12(), ".mma", "config.json");
26259
+ const configPath = join29(homedir12(), ".mma", "config.json");
26237
26260
  const { config: appConfig } = await bootstrap();
26238
26261
  appConfig.security = appConfig.security || {};
26239
26262
  appConfig.security.auditNotifier = {
@@ -26247,7 +26270,7 @@ function createSecurityCommand(program2) {
26247
26270
  console.log(t("cli.security.audit_enabled"));
26248
26271
  });
26249
26272
  securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
26250
- const configPath = join28(homedir12(), ".mma", "config.json");
26273
+ const configPath = join29(homedir12(), ".mma", "config.json");
26251
26274
  const { config: appConfig } = await bootstrap();
26252
26275
  appConfig.security = appConfig.security || {};
26253
26276
  appConfig.security.auditNotifier = {
@@ -26283,8 +26306,8 @@ import { fileURLToPath as fileURLToPath2 } from "url";
26283
26306
  function readVersion2() {
26284
26307
  const here = dirname11(fileURLToPath2(import.meta.url));
26285
26308
  const candidates = [
26286
- join34(here, "..", "..", "package.json"),
26287
- join34(here, "..", "package.json")
26309
+ join35(here, "..", "..", "package.json"),
26310
+ join35(here, "..", "package.json")
26288
26311
  ];
26289
26312
  for (const p of candidates) {
26290
26313
  if (existsSync41(p)) {
@@ -26300,7 +26323,7 @@ function createProgram() {
26300
26323
  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
26324
  program2.command("init").description(t("cli.init")).action(async () => {
26302
26325
  const answers = await runSetup();
26303
- const configPath = join34(homedir15(), ".mma", "config.json");
26326
+ const configPath = join35(homedir15(), ".mma", "config.json");
26304
26327
  const { config } = await bootstrap();
26305
26328
  config.provider.type = answers.provider;
26306
26329
  config.provider.baseUrl = answers.apiBase;
@@ -26345,7 +26368,7 @@ function createProgram() {
26345
26368
  });
26346
26369
  const configCmd = program2.command("config").description(t("cli.manage_config"));
26347
26370
  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");
26371
+ const configPath = join35(homedir15(), ".mma", "config.json");
26349
26372
  const { config } = await bootstrap();
26350
26373
  const keys = key.split(".");
26351
26374
  let obj = config;
@@ -26408,7 +26431,7 @@ function createProgram() {
26408
26431
  console.log(t("cli.model_hint"));
26409
26432
  });
26410
26433
  model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
26411
- const configPath = join34(homedir15(), ".mma", "config.json");
26434
+ const configPath = join35(homedir15(), ".mma", "config.json");
26412
26435
  const { config } = await bootstrap();
26413
26436
  config.model = name;
26414
26437
  saveConfig(config, configPath);
@@ -26444,7 +26467,7 @@ function createProgram() {
26444
26467
  await uncertify2(name, config);
26445
26468
  });
26446
26469
  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");
26470
+ const configPath = join35(homedir15(), ".mma", "config.json");
26448
26471
  const { config } = await bootstrap();
26449
26472
  const contextWindow = parseInt(size, 10);
26450
26473
  if (isNaN(contextWindow) || contextWindow < 1024) {
@@ -26462,7 +26485,7 @@ function createProgram() {
26462
26485
  console.log(t("cli.base_url"), config.provider.baseUrl);
26463
26486
  });
26464
26487
  provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
26465
- const configPath = join34(homedir15(), ".mma", "config.json");
26488
+ const configPath = join35(homedir15(), ".mma", "config.json");
26466
26489
  const { config } = await bootstrap();
26467
26490
  config.provider.type = name;
26468
26491
  saveConfig(config, configPath);
@@ -26515,7 +26538,7 @@ init_bootstrap();
26515
26538
  init_colors();
26516
26539
  import * as readline2 from "readline";
26517
26540
  import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
26518
- import { join as join36, dirname as dirname13 } from "path";
26541
+ import { join as join37, dirname as dirname13 } from "path";
26519
26542
  import { homedir as homedir17 } from "os";
26520
26543
  import { fileURLToPath as fileURLToPath4 } from "url";
26521
26544
 
@@ -27029,8 +27052,8 @@ init_repl_commands();
27029
27052
  function readVersion4() {
27030
27053
  const here = dirname13(fileURLToPath4(import.meta.url));
27031
27054
  const candidates = [
27032
- join36(here, "..", "..", "package.json"),
27033
- join36(here, "..", "package.json")
27055
+ join37(here, "..", "..", "package.json"),
27056
+ join37(here, "..", "package.json")
27034
27057
  ];
27035
27058
  for (const p of candidates) {
27036
27059
  if (existsSync43(p)) {
@@ -27085,10 +27108,10 @@ class Repl {
27085
27108
  this.sessionManager = sessionManager;
27086
27109
  this.skillsModule = skillsModule;
27087
27110
  this.pluginManager = pluginManager;
27088
- this.configDir = configDir || join36(homedir17(), ".mma");
27111
+ this.configDir = configDir || join37(homedir17(), ".mma");
27089
27112
  this.baseDir = baseDir || process.cwd();
27090
27113
  this.noAgentsMd = noAgentsMd === true;
27091
- this.historyPath = join36(homedir17(), ".mma", "repl-history");
27114
+ this.historyPath = join37(homedir17(), ".mma", "repl-history");
27092
27115
  this.loadHistory();
27093
27116
  this.rl = readline2.createInterface({
27094
27117
  input: process.stdin,
@@ -27380,8 +27403,13 @@ ${t("image.clipboard_empty")}`));
27380
27403
  console.log();
27381
27404
  }
27382
27405
  }
27406
+ lastCompactionShown = 0;
27383
27407
  showContextBar(result) {
27384
- if (result.contextUsed !== undefined && result.contextLimit !== undefined && result.contextLimit > 0) {
27408
+ if (result.contextUsed === undefined || result.contextLimit === undefined || result.contextLimit <= 0) {
27409
+ return;
27410
+ }
27411
+ const ui = this.config.ui;
27412
+ if (ui?.showContextStats) {
27385
27413
  console.log();
27386
27414
  const ctxLine = formatContextBar(result.contextUsed, result.contextLimit, result.compactionCount, result.contextQuality);
27387
27415
  console.log(ctxLine);
@@ -27389,6 +27417,12 @@ ${t("image.clipboard_empty")}`));
27389
27417
  const apiLine = pc2.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
27390
27418
  console.log(apiLine);
27391
27419
  }
27420
+ } else if (ui?.showCompaction && result.compactionCount !== undefined) {
27421
+ if (result.compactionCount > this.lastCompactionShown) {
27422
+ this.lastCompactionShown = result.compactionCount;
27423
+ console.log(pc2.dim(`
27424
+ ⟳ Context compacted (${result.compactionCount})`));
27425
+ }
27392
27426
  }
27393
27427
  }
27394
27428
  start() {
@@ -27429,9 +27463,9 @@ ${t("image.clipboard_empty")}`));
27429
27463
  row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
27430
27464
  } else {
27431
27465
  const agentsMdCandidates = [
27432
- join36(this.baseDir, "AGENTS.md"),
27433
- join36(this.baseDir, ".mma", "AGENTS.md"),
27434
- join36(this.configDir, "AGENTS.md")
27466
+ join37(this.baseDir, "AGENTS.md"),
27467
+ join37(this.baseDir, ".mma", "AGENTS.md"),
27468
+ join37(this.configDir, "AGENTS.md")
27435
27469
  ];
27436
27470
  const foundAgents = agentsMdCandidates.filter((p) => existsSync43(p));
27437
27471
  if (foundAgents.length > 0) {
@@ -27444,7 +27478,7 @@ ${t("image.clipboard_empty")}`));
27444
27478
  }
27445
27479
  const meta = this.sessionManager?.getActiveMeta();
27446
27480
  if (meta) {
27447
- const sessionPath = join36(this.configDir, "sessions", meta.id);
27481
+ const sessionPath = join37(this.configDir, "sessions", meta.id);
27448
27482
  row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
27449
27483
  }
27450
27484
  const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
@@ -27471,7 +27505,7 @@ init_config2();
27471
27505
  init_i18n();
27472
27506
  init_colors();
27473
27507
  import { existsSync as existsSync44 } from "fs";
27474
- import { join as join37 } from "path";
27508
+ import { join as join38 } from "path";
27475
27509
  import { homedir as homedir18 } from "os";
27476
27510
  async function main() {
27477
27511
  const program2 = createProgram();
@@ -27538,15 +27572,15 @@ async function main() {
27538
27572
  }
27539
27573
  agent.shutdown();
27540
27574
  } else {
27541
- const configPath = join37(homedir18(), ".mma", "config.json");
27575
+ const configPath = join38(homedir18(), ".mma", "config.json");
27542
27576
  if (!existsSync44(configPath)) {
27543
27577
  console.log(pc2.yellow(`
27544
27578
  ` + t("cli.first_run") + `
27545
27579
  `));
27546
27580
  const answers = await runSetup();
27547
27581
  const config2 = loadConfig({
27548
- configDir: join37(homedir18(), ".mma"),
27549
- projectConfigPath: projectDir ? join37(projectDir, ".mmrc") : join37(process.cwd(), ".mmrc")
27582
+ configDir: join38(homedir18(), ".mma"),
27583
+ projectConfigPath: projectDir ? join38(projectDir, ".mmrc") : join38(process.cwd(), ".mmrc")
27550
27584
  });
27551
27585
  config2.provider.type = answers.provider;
27552
27586
  config2.provider.baseUrl = answers.apiBase;