micro-models-agent 0.28.5 → 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.
- package/dist/main.js +277 -254
- 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":
|
|
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":
|
|
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 (
|
|
9117
|
+
if (lastError) {
|
|
9138
9118
|
errorDetail += `
|
|
9139
9119
|
|
|
9140
|
-
|
|
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 (
|
|
9147
|
+
if (lastError) {
|
|
9169
9148
|
errorDetail += `
|
|
9170
9149
|
|
|
9171
|
-
|
|
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 {
|
|
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: [
|
|
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
|
|
10135
|
-
if (
|
|
10136
|
-
|
|
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
|
-
|
|
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
|
|
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: {
|
|
11465
|
-
task: {
|
|
11533
|
+
name: {
|
|
11466
11534
|
type: "string",
|
|
11467
|
-
description: "
|
|
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
|
-
|
|
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:
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
12772
|
+
import { join as join16 } from "path";
|
|
12713
12773
|
|
|
12714
12774
|
class CookieStore {
|
|
12715
12775
|
filePath;
|
|
12716
12776
|
constructor(cookieDir) {
|
|
12717
|
-
this.filePath =
|
|
12777
|
+
this.filePath = join16(cookieDir, "cookies.json");
|
|
12718
12778
|
}
|
|
12719
12779
|
async save(cookies) {
|
|
12720
|
-
await mkdir(
|
|
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
|
|
13100
|
+
import { join as join17 } from "path";
|
|
13041
13101
|
function getSession(ctx) {
|
|
13042
13102
|
if (!session) {
|
|
13043
|
-
const cookieDir =
|
|
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:
|
|
13174
|
-
const tmpPath =
|
|
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
|
|
13452
|
-
import { join as
|
|
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 =
|
|
13518
|
+
const entries = readdirSync6(dirPath);
|
|
13459
13519
|
for (const entry of entries) {
|
|
13460
|
-
const fullPath =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
13925
|
+
import { join as join20 } from "path";
|
|
13866
13926
|
|
|
13867
13927
|
class PlanPersister {
|
|
13868
13928
|
filePath;
|
|
13869
13929
|
constructor(baseDir) {
|
|
13870
|
-
const mmaDir =
|
|
13930
|
+
const mmaDir = join20(baseDir, ".mma");
|
|
13871
13931
|
if (!existsSync26(mmaDir)) {
|
|
13872
13932
|
mkdirSync11(mmaDir, { recursive: true });
|
|
13873
13933
|
}
|
|
13874
|
-
this.filePath =
|
|
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
|
|
14300
|
-
|
|
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
|
|
14550
|
-
import { join as
|
|
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 ||
|
|
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 =
|
|
14687
|
+
const files = readdirSync7(sessionDir);
|
|
14630
14688
|
for (const file of files) {
|
|
14631
|
-
const filePath =
|
|
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 =
|
|
14703
|
+
const files = readdirSync7(sessionDir);
|
|
14646
14704
|
for (const file of files) {
|
|
14647
14705
|
if (file.endsWith(".enc")) {
|
|
14648
|
-
const encFilePath =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
14769
|
+
return join22(this.baseDir, id);
|
|
14712
14770
|
}
|
|
14713
14771
|
metaPath(id) {
|
|
14714
|
-
return
|
|
14772
|
+
return join22(this.sessionDir(id), "meta.json");
|
|
14715
14773
|
}
|
|
14716
14774
|
historyPath(id) {
|
|
14717
|
-
return
|
|
14775
|
+
return join22(this.sessionDir(id), "history.jsonl");
|
|
14718
14776
|
}
|
|
14719
14777
|
sessionLogPath(id) {
|
|
14720
|
-
return
|
|
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 =
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
15155
|
-
import { join as
|
|
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 =
|
|
15224
|
+
const entries = readdirSync9(dirPath);
|
|
15167
15225
|
for (const entry of entries) {
|
|
15168
|
-
const fullPath =
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
15334
|
-
lines.push(
|
|
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: "
|
|
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
|
|
15765
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 ||
|
|
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
|
|
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 ||
|
|
16343
|
-
const projectConfigPath = projectDir ?
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
16399
|
-
const globalDir =
|
|
16400
|
-
const projectSkillsDir =
|
|
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
|
|
16403
|
-
const
|
|
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 =
|
|
16432
|
+
const agentsMdGlobal = join28(dir, "AGENTS.md");
|
|
16415
16433
|
if (!existsSync35(agentsMdGlobal)) {
|
|
16416
16434
|
writeFileSync13(agentsMdGlobal, "", "utf-8");
|
|
16417
16435
|
}
|
|
16418
|
-
const sessionDir =
|
|
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(
|
|
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 =
|
|
16537
|
-
const projectPluginsDir =
|
|
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
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
24506
|
-
import { join as
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
24654
|
+
return isFile(join32(sandboxDir, check.path));
|
|
24632
24655
|
case "fileNotExists":
|
|
24633
|
-
return !existsSync38(
|
|
24656
|
+
return !existsSync38(join32(sandboxDir, check.path));
|
|
24634
24657
|
case "dirExists":
|
|
24635
|
-
return isDir(
|
|
24658
|
+
return isDir(join32(sandboxDir, check.path));
|
|
24636
24659
|
case "fileContent": {
|
|
24637
|
-
const abs =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
24812
|
+
const dev = join33(mmaRoot, "src", "cli", "main.ts");
|
|
24790
24813
|
if (existsSync39(dev))
|
|
24791
24814
|
return dev;
|
|
24792
|
-
return
|
|
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(
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
25037
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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:
|
|
25380
|
+
const { join: join37 } = await import("path");
|
|
25358
25381
|
const configDir = ctx.configDir;
|
|
25359
25382
|
const baseDir = ctx.baseDir;
|
|
25360
|
-
const projectConfigPath =
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
26287
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
27033
|
-
|
|
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 ||
|
|
27111
|
+
this.configDir = configDir || join37(homedir17(), ".mma");
|
|
27089
27112
|
this.baseDir = baseDir || process.cwd();
|
|
27090
27113
|
this.noAgentsMd = noAgentsMd === true;
|
|
27091
|
-
this.historyPath =
|
|
27114
|
+
this.historyPath = join37(homedir17(), ".mma", "repl-history");
|
|
27092
27115
|
this.loadHistory();
|
|
27093
27116
|
this.rl = readline2.createInterface({
|
|
27094
27117
|
input: process.stdin,
|
|
@@ -27440,9 +27463,9 @@ ${t("image.clipboard_empty")}`));
|
|
|
27440
27463
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
27441
27464
|
} else {
|
|
27442
27465
|
const agentsMdCandidates = [
|
|
27443
|
-
|
|
27444
|
-
|
|
27445
|
-
|
|
27466
|
+
join37(this.baseDir, "AGENTS.md"),
|
|
27467
|
+
join37(this.baseDir, ".mma", "AGENTS.md"),
|
|
27468
|
+
join37(this.configDir, "AGENTS.md")
|
|
27446
27469
|
];
|
|
27447
27470
|
const foundAgents = agentsMdCandidates.filter((p) => existsSync43(p));
|
|
27448
27471
|
if (foundAgents.length > 0) {
|
|
@@ -27455,7 +27478,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
27455
27478
|
}
|
|
27456
27479
|
const meta = this.sessionManager?.getActiveMeta();
|
|
27457
27480
|
if (meta) {
|
|
27458
|
-
const sessionPath =
|
|
27481
|
+
const sessionPath = join37(this.configDir, "sessions", meta.id);
|
|
27459
27482
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
27460
27483
|
}
|
|
27461
27484
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
@@ -27482,7 +27505,7 @@ init_config2();
|
|
|
27482
27505
|
init_i18n();
|
|
27483
27506
|
init_colors();
|
|
27484
27507
|
import { existsSync as existsSync44 } from "fs";
|
|
27485
|
-
import { join as
|
|
27508
|
+
import { join as join38 } from "path";
|
|
27486
27509
|
import { homedir as homedir18 } from "os";
|
|
27487
27510
|
async function main() {
|
|
27488
27511
|
const program2 = createProgram();
|
|
@@ -27549,15 +27572,15 @@ async function main() {
|
|
|
27549
27572
|
}
|
|
27550
27573
|
agent.shutdown();
|
|
27551
27574
|
} else {
|
|
27552
|
-
const configPath =
|
|
27575
|
+
const configPath = join38(homedir18(), ".mma", "config.json");
|
|
27553
27576
|
if (!existsSync44(configPath)) {
|
|
27554
27577
|
console.log(pc2.yellow(`
|
|
27555
27578
|
` + t("cli.first_run") + `
|
|
27556
27579
|
`));
|
|
27557
27580
|
const answers = await runSetup();
|
|
27558
27581
|
const config2 = loadConfig({
|
|
27559
|
-
configDir:
|
|
27560
|
-
projectConfigPath: projectDir ?
|
|
27582
|
+
configDir: join38(homedir18(), ".mma"),
|
|
27583
|
+
projectConfigPath: projectDir ? join38(projectDir, ".mmrc") : join38(process.cwd(), ".mmrc")
|
|
27561
27584
|
});
|
|
27562
27585
|
config2.provider.type = answers.provider;
|
|
27563
27586
|
config2.provider.baseUrl = answers.apiBase;
|