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