micro-models-agent 0.33.5 → 0.35.0
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 +471 -161
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2372,9 +2372,12 @@ var init_en = __esm(() => {
|
|
|
2372
2372
|
"tool.friendly.web_search": "Web search",
|
|
2373
2373
|
"tool.friendly.web_fetch": "Fetching page",
|
|
2374
2374
|
"tool.friendly.web_browse": "Browsing page",
|
|
2375
|
+
"tool.friendly.download_file": "Downloading file",
|
|
2375
2376
|
"tool.web_fetch_result": "Fetched page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2376
2377
|
"tool.web_browse_result": "Browsed page: {url} — {chars} chars, {lines} lines{truncated}",
|
|
2377
2378
|
"tool.web_search_result": 'Search results for "{query}" — {count} results',
|
|
2379
|
+
"tool.downloaded": "Downloaded {url} → {path} ({size} bytes, {type})",
|
|
2380
|
+
"tool.download_too_large": "Download blocked: file exceeds the {max} bytes limit",
|
|
2378
2381
|
"tool.friendly.browser": "Browser",
|
|
2379
2382
|
"tool.friendly.subagent": "Sub-agent task",
|
|
2380
2383
|
"tool.friendly.question": "Question to user",
|
|
@@ -2825,6 +2828,9 @@ Use this knowledge to answer the user's question.`,
|
|
|
2825
2828
|
"indexer.find_results": `Found {count} matching files:
|
|
2826
2829
|
{results}`,
|
|
2827
2830
|
"indexer.no_matches": 'No matching files for "{query}"',
|
|
2831
|
+
"indexer.stack_deps": "deps",
|
|
2832
|
+
"indexer.stack_dev": "dev",
|
|
2833
|
+
"indexer.stack_scripts": "scripts",
|
|
2828
2834
|
"tool.friendly.project_map": "Project map",
|
|
2829
2835
|
"config.decryption_warning": "Warning: Failed to decrypt config: {error}",
|
|
2830
2836
|
"config.encryption_warning": "Warning: Failed to encrypt config: {error}",
|
|
@@ -2954,9 +2960,12 @@ var init_ru = __esm(() => {
|
|
|
2954
2960
|
"tool.friendly.web_search": "Поиск в интернете",
|
|
2955
2961
|
"tool.friendly.web_fetch": "Загрузка страницы",
|
|
2956
2962
|
"tool.friendly.web_browse": "Просмотр страницы",
|
|
2963
|
+
"tool.friendly.download_file": "Скачивание файла",
|
|
2957
2964
|
"tool.web_fetch_result": "Загружена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
2958
2965
|
"tool.web_browse_result": "Просмотрена страница: {url} — {chars} симв., {lines} строк{truncated}",
|
|
2959
2966
|
"tool.web_search_result": 'Результаты поиска "{query}" — {count} результатов',
|
|
2967
|
+
"tool.downloaded": "Скачано {url} → {path} ({size} байт, {type})",
|
|
2968
|
+
"tool.download_too_large": "Скачивание заблокировано: файл превышает лимит {max} байт",
|
|
2960
2969
|
"tool.friendly.browser": "Браузер",
|
|
2961
2970
|
"tool.friendly.subagent": "Задача подагенту",
|
|
2962
2971
|
"tool.friendly.question": "Вопрос пользователю",
|
|
@@ -3407,6 +3416,9 @@ var init_ru = __esm(() => {
|
|
|
3407
3416
|
"indexer.find_results": `Найдено {count} совпадающих файлов:
|
|
3408
3417
|
{results}`,
|
|
3409
3418
|
"indexer.no_matches": 'Нет совпадающих файлов для "{query}"',
|
|
3419
|
+
"indexer.stack_deps": "зависимости",
|
|
3420
|
+
"indexer.stack_dev": "dev",
|
|
3421
|
+
"indexer.stack_scripts": "скрипты",
|
|
3410
3422
|
"tool.friendly.project_map": "Карта проекта",
|
|
3411
3423
|
"config.decryption_warning": "Предупреждение: не удалось расшифровать конфигурацию: {error}",
|
|
3412
3424
|
"config.encryption_warning": "Предупреждение: не удалось зашифровать конфигурацию: {error}",
|
|
@@ -12819,6 +12831,120 @@ var init_web_browse = __esm(() => {
|
|
|
12819
12831
|
};
|
|
12820
12832
|
});
|
|
12821
12833
|
|
|
12834
|
+
// src/tools/download-file.ts
|
|
12835
|
+
import { writeFileSync as writeFileSync9, mkdirSync as mkdirSync13 } from "fs";
|
|
12836
|
+
import { dirname as dirname6 } from "path";
|
|
12837
|
+
var MAX_DOWNLOAD_BYTES, downloadFileTool;
|
|
12838
|
+
var init_download_file = __esm(() => {
|
|
12839
|
+
init_i18n();
|
|
12840
|
+
init_network_validator();
|
|
12841
|
+
init_path_validator();
|
|
12842
|
+
init_audit_log();
|
|
12843
|
+
init_session_isolation();
|
|
12844
|
+
init_security();
|
|
12845
|
+
init_path_utils();
|
|
12846
|
+
MAX_DOWNLOAD_BYTES = 100 * 1024 * 1024;
|
|
12847
|
+
downloadFileTool = {
|
|
12848
|
+
name: "download_file",
|
|
12849
|
+
description: "Download a file (image, archive, binary, font, etc.) from a URL and save it to disk. Returns only the path, size and content type — read the saved file with read_file/attach_image afterwards. Use this for binary files; web_fetch/web_browse return text only and cannot save bytes.",
|
|
12850
|
+
tags: ["file", "research"],
|
|
12851
|
+
parameters: {
|
|
12852
|
+
type: "object",
|
|
12853
|
+
properties: {
|
|
12854
|
+
url: { type: "string", description: "URL to download" },
|
|
12855
|
+
path: {
|
|
12856
|
+
type: "string",
|
|
12857
|
+
description: "Destination path (relative to the working directory)"
|
|
12858
|
+
},
|
|
12859
|
+
max_bytes: {
|
|
12860
|
+
type: "number",
|
|
12861
|
+
description: "Optional size cap in bytes (default 100 MB)"
|
|
12862
|
+
}
|
|
12863
|
+
},
|
|
12864
|
+
required: ["url", "path"]
|
|
12865
|
+
},
|
|
12866
|
+
handler: async (ctx, args) => {
|
|
12867
|
+
const url = String(args.url || "").trim();
|
|
12868
|
+
const path = String(args.path || "").trim();
|
|
12869
|
+
if (!url || !path) {
|
|
12870
|
+
return { success: false, output: t("tool.invalid_params") };
|
|
12871
|
+
}
|
|
12872
|
+
const securityConfig = ctx.sessionContext ? getSessionSecurityConfig(ctx.config, ctx.sessionContext).network : ctx.config.security?.network || DEFAULT_SECURITY_CONFIG.network;
|
|
12873
|
+
const validation = isUrlAllowed(url, securityConfig);
|
|
12874
|
+
if (!validation.allowed) {
|
|
12875
|
+
logSecurityBlock(ctx.sessionId, "network_request", validation.reason || "URL blocked by security policy", sanitizeUrl(url));
|
|
12876
|
+
return {
|
|
12877
|
+
success: false,
|
|
12878
|
+
output: `[SECURITY BLOCKED] URL is not allowed: ${validation.reason}`
|
|
12879
|
+
};
|
|
12880
|
+
}
|
|
12881
|
+
const resolved = safeResolvePath(ctx.baseDir, path);
|
|
12882
|
+
const scopeCheck = isPathWritable(ctx.baseDir, resolved, ctx.scope, ctx.config.security?.paths);
|
|
12883
|
+
if (!scopeCheck.allowed) {
|
|
12884
|
+
logSecurityBlock(ctx.sessionId, "file_write", scopeCheck.reason || "Path not allowed", path);
|
|
12885
|
+
return {
|
|
12886
|
+
success: false,
|
|
12887
|
+
output: t("file.path_not_allowed", {
|
|
12888
|
+
path: `${path} — ${scopeCheck.reason}`
|
|
12889
|
+
})
|
|
12890
|
+
};
|
|
12891
|
+
}
|
|
12892
|
+
const maxBytes = Number(args.max_bytes) > 0 ? Number(args.max_bytes) : MAX_DOWNLOAD_BYTES;
|
|
12893
|
+
try {
|
|
12894
|
+
const response = await fetch(url, {
|
|
12895
|
+
signal: AbortSignal.timeout(securityConfig?.requestTimeout || 15000)
|
|
12896
|
+
});
|
|
12897
|
+
if (!response.ok) {
|
|
12898
|
+
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Status: ${response.status}`);
|
|
12899
|
+
return {
|
|
12900
|
+
success: false,
|
|
12901
|
+
output: t("error.http", {
|
|
12902
|
+
status: response.status,
|
|
12903
|
+
statusText: response.statusText
|
|
12904
|
+
})
|
|
12905
|
+
};
|
|
12906
|
+
}
|
|
12907
|
+
const contentLength = Number(response.headers.get("content-length") || "0");
|
|
12908
|
+
if (contentLength > maxBytes) {
|
|
12909
|
+
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Too large: ${contentLength}`);
|
|
12910
|
+
return {
|
|
12911
|
+
success: false,
|
|
12912
|
+
output: t("tool.download_too_large", { max: String(maxBytes) })
|
|
12913
|
+
};
|
|
12914
|
+
}
|
|
12915
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
12916
|
+
if (buffer.byteLength > maxBytes) {
|
|
12917
|
+
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Too large: ${buffer.byteLength}`);
|
|
12918
|
+
return {
|
|
12919
|
+
success: false,
|
|
12920
|
+
output: t("tool.download_too_large", { max: String(maxBytes) })
|
|
12921
|
+
};
|
|
12922
|
+
}
|
|
12923
|
+
mkdirSync13(dirname6(resolved), { recursive: true });
|
|
12924
|
+
writeFileSync9(resolved, buffer);
|
|
12925
|
+
const contentType = response.headers.get("content-type")?.split(";")[0]?.trim() || "unknown";
|
|
12926
|
+
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
|
|
12927
|
+
logFileWrite(ctx.sessionId, resolved, true, `Downloaded ${buffer.byteLength} bytes`);
|
|
12928
|
+
return {
|
|
12929
|
+
success: true,
|
|
12930
|
+
output: t("tool.downloaded", {
|
|
12931
|
+
url: sanitizeUrl(url),
|
|
12932
|
+
path: resolved,
|
|
12933
|
+
size: String(buffer.byteLength),
|
|
12934
|
+
type: contentType
|
|
12935
|
+
})
|
|
12936
|
+
};
|
|
12937
|
+
} catch (e) {
|
|
12938
|
+
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), false, `Error: ${e.message}`);
|
|
12939
|
+
return {
|
|
12940
|
+
success: false,
|
|
12941
|
+
output: t("error.fetch_failed", { message: e.message })
|
|
12942
|
+
};
|
|
12943
|
+
}
|
|
12944
|
+
}
|
|
12945
|
+
};
|
|
12946
|
+
});
|
|
12947
|
+
|
|
12822
12948
|
// src/tools/load-skill.ts
|
|
12823
12949
|
function createLoadSkillTool(skillsModule) {
|
|
12824
12950
|
return {
|
|
@@ -13909,10 +14035,10 @@ __export(exports_bridge_client, {
|
|
|
13909
14035
|
});
|
|
13910
14036
|
import { spawn as spawn4 } from "child_process";
|
|
13911
14037
|
import { createInterface } from "readline";
|
|
13912
|
-
import { dirname as
|
|
14038
|
+
import { dirname as dirname7, join as join17 } from "path";
|
|
13913
14039
|
import { fileURLToPath } from "url";
|
|
13914
14040
|
function bridgeScriptPath() {
|
|
13915
|
-
return join17(
|
|
14041
|
+
return join17(dirname7(fileURLToPath(import.meta.url)), "bridge-server.mjs");
|
|
13916
14042
|
}
|
|
13917
14043
|
|
|
13918
14044
|
class BridgeDriver {
|
|
@@ -15139,6 +15265,7 @@ function registerAllTools(registry2, skillsModule) {
|
|
|
15139
15265
|
webSearchTool,
|
|
15140
15266
|
webFetchTool,
|
|
15141
15267
|
webBrowseTool,
|
|
15268
|
+
downloadFileTool,
|
|
15142
15269
|
pipelineRunTool,
|
|
15143
15270
|
mcpCallTool,
|
|
15144
15271
|
searchHistoryTool,
|
|
@@ -15172,6 +15299,7 @@ var init_tools = __esm(() => {
|
|
|
15172
15299
|
init_web_search();
|
|
15173
15300
|
init_web_fetch();
|
|
15174
15301
|
init_web_browse();
|
|
15302
|
+
init_download_file();
|
|
15175
15303
|
init_load_skill();
|
|
15176
15304
|
init_pipeline_run();
|
|
15177
15305
|
init_mcp_call();
|
|
@@ -15194,9 +15322,11 @@ class ModuleRegistry {
|
|
|
15194
15322
|
listModules() {
|
|
15195
15323
|
return Array.from(this.modules.keys()).sort();
|
|
15196
15324
|
}
|
|
15197
|
-
collectPromptBlocks() {
|
|
15325
|
+
collectPromptBlocks(exclude = []) {
|
|
15198
15326
|
const blocks = [];
|
|
15199
|
-
for (const mod of this.modules
|
|
15327
|
+
for (const [name, mod] of this.modules) {
|
|
15328
|
+
if (exclude.includes(name))
|
|
15329
|
+
continue;
|
|
15200
15330
|
if (mod.getSystemPromptBlock) {
|
|
15201
15331
|
const block = mod.getSystemPromptBlock();
|
|
15202
15332
|
if (block)
|
|
@@ -15833,7 +15963,7 @@ var init_auditor = __esm(() => {
|
|
|
15833
15963
|
});
|
|
15834
15964
|
|
|
15835
15965
|
// src/modules/execution/plan-store.ts
|
|
15836
|
-
import { readFileSync as readFileSync16, writeFileSync as
|
|
15966
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as existsSync28, readdirSync as readdirSync9, rmSync } from "fs";
|
|
15837
15967
|
import { join as join23 } from "path";
|
|
15838
15968
|
function readPlanFile(path, fallbackBaseDir) {
|
|
15839
15969
|
try {
|
|
@@ -15856,7 +15986,7 @@ function readPlanFile(path, fallbackBaseDir) {
|
|
|
15856
15986
|
}
|
|
15857
15987
|
}
|
|
15858
15988
|
function writePlanFile(path, plan) {
|
|
15859
|
-
|
|
15989
|
+
writeFileSync10(path, JSON.stringify(plan, null, 2), "utf-8");
|
|
15860
15990
|
}
|
|
15861
15991
|
function listDir(dir, baseDir) {
|
|
15862
15992
|
if (!existsSync28(dir))
|
|
@@ -15885,7 +16015,7 @@ class PlanStore {
|
|
|
15885
16015
|
constructor(baseDir) {
|
|
15886
16016
|
const mmaDir = join23(baseDir, ".mma");
|
|
15887
16017
|
if (!existsSync28(mmaDir))
|
|
15888
|
-
|
|
16018
|
+
mkdirSync14(mmaDir, { recursive: true });
|
|
15889
16019
|
this.baseDir = baseDir;
|
|
15890
16020
|
this.plansDir = join23(mmaDir, "plans");
|
|
15891
16021
|
this.draftsDir = join23(this.plansDir, "drafts");
|
|
@@ -15893,7 +16023,7 @@ class PlanStore {
|
|
|
15893
16023
|
this.legacyPath = join23(mmaDir, LEGACY_FILE);
|
|
15894
16024
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
15895
16025
|
if (!existsSync28(dir))
|
|
15896
|
-
|
|
16026
|
+
mkdirSync14(dir, { recursive: true });
|
|
15897
16027
|
}
|
|
15898
16028
|
}
|
|
15899
16029
|
activePath() {
|
|
@@ -16868,7 +16998,7 @@ var init_module = __esm(() => {
|
|
|
16868
16998
|
// src/modules/security/session-encryption.ts
|
|
16869
16999
|
import {
|
|
16870
17000
|
readFileSync as readFileSync18,
|
|
16871
|
-
writeFileSync as
|
|
17001
|
+
writeFileSync as writeFileSync11,
|
|
16872
17002
|
existsSync as existsSync30,
|
|
16873
17003
|
readdirSync as readdirSync10,
|
|
16874
17004
|
unlinkSync as unlinkSync4
|
|
@@ -16932,7 +17062,7 @@ class SessionFileEncryptor {
|
|
|
16932
17062
|
}
|
|
16933
17063
|
writeSessionFile(filePath, content) {
|
|
16934
17064
|
const encrypted = this.encryptFileContent(content);
|
|
16935
|
-
|
|
17065
|
+
writeFileSync11(filePath, encrypted, "utf8");
|
|
16936
17066
|
}
|
|
16937
17067
|
readSessionJSON(filePath) {
|
|
16938
17068
|
const content = readFileSync18(filePath, "utf8");
|
|
@@ -16940,7 +17070,7 @@ class SessionFileEncryptor {
|
|
|
16940
17070
|
}
|
|
16941
17071
|
writeSessionJSON(filePath, obj) {
|
|
16942
17072
|
const content = this.encryptJSON(obj);
|
|
16943
|
-
|
|
17073
|
+
writeFileSync11(filePath, content, "utf8");
|
|
16944
17074
|
}
|
|
16945
17075
|
readSessionJSONL(filePath) {
|
|
16946
17076
|
const content = readFileSync18(filePath, "utf8");
|
|
@@ -16957,7 +17087,7 @@ class SessionFileEncryptor {
|
|
|
16957
17087
|
}
|
|
16958
17088
|
appendToSessionJSONL(filePath, obj) {
|
|
16959
17089
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
16960
|
-
|
|
17090
|
+
writeFileSync11(filePath, encryptedLine + `
|
|
16961
17091
|
`, {
|
|
16962
17092
|
flag: "a",
|
|
16963
17093
|
encoding: "utf8"
|
|
@@ -16973,7 +17103,7 @@ class SessionFileEncryptor {
|
|
|
16973
17103
|
try {
|
|
16974
17104
|
const content = readFileSync18(filePath, "utf8");
|
|
16975
17105
|
const encrypted = this.encryptFileContent(content);
|
|
16976
|
-
|
|
17106
|
+
writeFileSync11(filePath + ".enc", encrypted, "utf8");
|
|
16977
17107
|
unlinkSync4(filePath);
|
|
16978
17108
|
} catch {}
|
|
16979
17109
|
}
|
|
@@ -16990,7 +17120,7 @@ class SessionFileEncryptor {
|
|
|
16990
17120
|
try {
|
|
16991
17121
|
const content = readFileSync18(encFilePath, "utf8");
|
|
16992
17122
|
const decrypted = this.decryptFileContent(content);
|
|
16993
|
-
|
|
17123
|
+
writeFileSync11(decFilePath, decrypted, "utf8");
|
|
16994
17124
|
unlinkSync4(encFilePath);
|
|
16995
17125
|
} catch {}
|
|
16996
17126
|
}
|
|
@@ -17011,11 +17141,11 @@ var init_session_encryption = __esm(() => {
|
|
|
17011
17141
|
// src/modules/session/store.ts
|
|
17012
17142
|
import {
|
|
17013
17143
|
existsSync as existsSync31,
|
|
17014
|
-
mkdirSync as
|
|
17144
|
+
mkdirSync as mkdirSync15,
|
|
17015
17145
|
readdirSync as readdirSync11,
|
|
17016
17146
|
readFileSync as readFileSync19,
|
|
17017
17147
|
rmSync as rmSync2,
|
|
17018
|
-
writeFileSync as
|
|
17148
|
+
writeFileSync as writeFileSync12,
|
|
17019
17149
|
appendFileSync as appendFileSync6
|
|
17020
17150
|
} from "fs";
|
|
17021
17151
|
import { join as join25 } from "path";
|
|
@@ -17045,7 +17175,7 @@ class SessionStore {
|
|
|
17045
17175
|
return this.encryptor?.isEnabled() ?? false;
|
|
17046
17176
|
}
|
|
17047
17177
|
init() {
|
|
17048
|
-
|
|
17178
|
+
mkdirSync15(this.baseDir, { recursive: true });
|
|
17049
17179
|
}
|
|
17050
17180
|
sessionDir(id) {
|
|
17051
17181
|
return join25(this.baseDir, id);
|
|
@@ -17065,12 +17195,12 @@ class SessionStore {
|
|
|
17065
17195
|
saveMeta(id, meta) {
|
|
17066
17196
|
this._metaCache.set(id, meta);
|
|
17067
17197
|
const dir = this.sessionDir(id);
|
|
17068
|
-
|
|
17198
|
+
mkdirSync15(dir, { recursive: true });
|
|
17069
17199
|
const content = JSON.stringify(meta, null, 2);
|
|
17070
17200
|
if (this.encryptor) {
|
|
17071
|
-
|
|
17201
|
+
writeFileSync12(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
|
|
17072
17202
|
} else {
|
|
17073
|
-
|
|
17203
|
+
writeFileSync12(this.metaPath(id), content, "utf-8");
|
|
17074
17204
|
}
|
|
17075
17205
|
}
|
|
17076
17206
|
loadMeta(id) {
|
|
@@ -17092,7 +17222,7 @@ class SessionStore {
|
|
|
17092
17222
|
}
|
|
17093
17223
|
appendMessage(id, msg) {
|
|
17094
17224
|
const dir = this.sessionDir(id);
|
|
17095
|
-
|
|
17225
|
+
mkdirSync15(dir, { recursive: true });
|
|
17096
17226
|
const line = JSON.stringify(msg);
|
|
17097
17227
|
if (this.encryptor?.isEnabled()) {
|
|
17098
17228
|
appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -17139,7 +17269,7 @@ class SessionStore {
|
|
|
17139
17269
|
}
|
|
17140
17270
|
appendSessionLog(id, entry) {
|
|
17141
17271
|
const dir = this.sessionDir(id);
|
|
17142
|
-
|
|
17272
|
+
mkdirSync15(dir, { recursive: true });
|
|
17143
17273
|
const line = JSON.stringify(entry);
|
|
17144
17274
|
if (this.encryptor?.isEnabled()) {
|
|
17145
17275
|
appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -17212,7 +17342,7 @@ class SessionStore {
|
|
|
17212
17342
|
const content = readFileSync19(historyPath, "utf-8");
|
|
17213
17343
|
const compressed = gzipSync(content);
|
|
17214
17344
|
const gzPath = join25(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
17215
|
-
|
|
17345
|
+
writeFileSync12(gzPath, compressed);
|
|
17216
17346
|
rmSync2(historyPath);
|
|
17217
17347
|
}
|
|
17218
17348
|
}
|
|
@@ -17421,7 +17551,7 @@ class ProfileCompressor {
|
|
|
17421
17551
|
}
|
|
17422
17552
|
|
|
17423
17553
|
// src/modules/user-profile/profile.ts
|
|
17424
|
-
import { readFileSync as readFileSync20, writeFileSync as
|
|
17554
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as existsSync32, mkdirSync as mkdirSync16 } from "fs";
|
|
17425
17555
|
import { join as join26 } from "path";
|
|
17426
17556
|
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
17427
17557
|
import { env } from "process";
|
|
@@ -17447,9 +17577,9 @@ class UserProfile {
|
|
|
17447
17577
|
}
|
|
17448
17578
|
save() {
|
|
17449
17579
|
if (!existsSync32(this.profileDir)) {
|
|
17450
|
-
|
|
17580
|
+
mkdirSync16(this.profileDir, { recursive: true });
|
|
17451
17581
|
}
|
|
17452
|
-
|
|
17582
|
+
writeFileSync13(join26(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
17453
17583
|
}
|
|
17454
17584
|
load() {
|
|
17455
17585
|
const path = join26(this.profileDir, "profile.json");
|
|
@@ -18202,7 +18332,7 @@ var init_walker = __esm(() => {
|
|
|
18202
18332
|
});
|
|
18203
18333
|
|
|
18204
18334
|
// src/modules/indexer/cache.ts
|
|
18205
|
-
import { readFileSync as readFileSync23, writeFileSync as
|
|
18335
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as existsSync37, mkdirSync as mkdirSync17, rmSync as rmSync3 } from "fs";
|
|
18206
18336
|
import { join as join30 } from "path";
|
|
18207
18337
|
|
|
18208
18338
|
class IndexCache {
|
|
@@ -18227,8 +18357,8 @@ class IndexCache {
|
|
|
18227
18357
|
this.cache = result;
|
|
18228
18358
|
const dir = join30(this.cachePath, "..");
|
|
18229
18359
|
if (!existsSync37(dir))
|
|
18230
|
-
|
|
18231
|
-
|
|
18360
|
+
mkdirSync17(dir, { recursive: true });
|
|
18361
|
+
writeFileSync14(this.cachePath, JSON.stringify(result), "utf-8");
|
|
18232
18362
|
}
|
|
18233
18363
|
invalidate() {
|
|
18234
18364
|
this.cache = null;
|
|
@@ -18241,8 +18371,176 @@ class IndexCache {
|
|
|
18241
18371
|
}
|
|
18242
18372
|
var init_cache = () => {};
|
|
18243
18373
|
|
|
18374
|
+
// src/modules/indexer/project-profile.ts
|
|
18375
|
+
import { readFileSync as readFileSync24, existsSync as existsSync38 } from "fs";
|
|
18376
|
+
import { join as join31 } from "path";
|
|
18377
|
+
function detectManifest(baseDir) {
|
|
18378
|
+
for (const manifest of MANIFEST_ORDER) {
|
|
18379
|
+
if (existsSync38(join31(baseDir, manifest)))
|
|
18380
|
+
return manifest;
|
|
18381
|
+
}
|
|
18382
|
+
return null;
|
|
18383
|
+
}
|
|
18384
|
+
function cleanDependency(entry) {
|
|
18385
|
+
let name = entry.trim();
|
|
18386
|
+
const eq = name.indexOf("=");
|
|
18387
|
+
if (eq > 0)
|
|
18388
|
+
name = name.slice(0, eq);
|
|
18389
|
+
const ineq = name.search(/[<>=!~^]/);
|
|
18390
|
+
if (ineq > 0)
|
|
18391
|
+
name = name.slice(0, ineq);
|
|
18392
|
+
return name.replace(/["',]/g, "").trim();
|
|
18393
|
+
}
|
|
18394
|
+
function readPackageJson(baseDir) {
|
|
18395
|
+
try {
|
|
18396
|
+
const raw = JSON.parse(readFileSync24(join31(baseDir, "package.json"), "utf-8"));
|
|
18397
|
+
if (!raw || typeof raw !== "object")
|
|
18398
|
+
return null;
|
|
18399
|
+
const profile = {
|
|
18400
|
+
runtime: "node",
|
|
18401
|
+
deps: Object.keys(raw.dependencies || {}),
|
|
18402
|
+
devDeps: Object.keys(raw.devDependencies || {}),
|
|
18403
|
+
scripts: {}
|
|
18404
|
+
};
|
|
18405
|
+
if (typeof raw.name === "string" && raw.name)
|
|
18406
|
+
profile.name = raw.name;
|
|
18407
|
+
if (raw.scripts && typeof raw.scripts === "object") {
|
|
18408
|
+
for (const [key, val] of Object.entries(raw.scripts)) {
|
|
18409
|
+
if (typeof val === "string" && val)
|
|
18410
|
+
profile.scripts[key] = val;
|
|
18411
|
+
}
|
|
18412
|
+
}
|
|
18413
|
+
return profile;
|
|
18414
|
+
} catch {
|
|
18415
|
+
return null;
|
|
18416
|
+
}
|
|
18417
|
+
}
|
|
18418
|
+
function readPyproject(baseDir) {
|
|
18419
|
+
try {
|
|
18420
|
+
const content = readFileSync24(join31(baseDir, "pyproject.toml"), "utf-8");
|
|
18421
|
+
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
18422
|
+
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
18423
|
+
if (nameMatch)
|
|
18424
|
+
profile.name = nameMatch[1];
|
|
18425
|
+
const depsBlock = content.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
|
|
18426
|
+
if (depsBlock) {
|
|
18427
|
+
profile.deps = [...depsBlock[1].matchAll(/"([^"]+)"/g)].map((m) => cleanDependency(m[1])).filter(Boolean);
|
|
18428
|
+
}
|
|
18429
|
+
return profile;
|
|
18430
|
+
} catch {
|
|
18431
|
+
return null;
|
|
18432
|
+
}
|
|
18433
|
+
}
|
|
18434
|
+
function readCargo(baseDir) {
|
|
18435
|
+
try {
|
|
18436
|
+
const content = readFileSync24(join31(baseDir, "Cargo.toml"), "utf-8");
|
|
18437
|
+
const profile = { runtime: "rust", deps: [], devDeps: [], scripts: {} };
|
|
18438
|
+
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
18439
|
+
if (nameMatch)
|
|
18440
|
+
profile.name = nameMatch[1];
|
|
18441
|
+
let inDeps = false;
|
|
18442
|
+
for (const line of content.split(`
|
|
18443
|
+
`)) {
|
|
18444
|
+
const trimmed = line.trim();
|
|
18445
|
+
if (/^\[.*\]$/.test(trimmed)) {
|
|
18446
|
+
inDeps = trimmed === "[dependencies]";
|
|
18447
|
+
continue;
|
|
18448
|
+
}
|
|
18449
|
+
if (inDeps && /^[A-Za-z0-9_-]+\s*=/.test(trimmed)) {
|
|
18450
|
+
profile.deps.push(trimmed.split("=")[0].trim());
|
|
18451
|
+
}
|
|
18452
|
+
}
|
|
18453
|
+
return profile;
|
|
18454
|
+
} catch {
|
|
18455
|
+
return null;
|
|
18456
|
+
}
|
|
18457
|
+
}
|
|
18458
|
+
function readGoMod(baseDir) {
|
|
18459
|
+
try {
|
|
18460
|
+
const content = readFileSync24(join31(baseDir, "go.mod"), "utf-8");
|
|
18461
|
+
const profile = { runtime: "go", deps: [], devDeps: [], scripts: {} };
|
|
18462
|
+
const moduleMatch = content.match(/^module\s+(\S+)/m);
|
|
18463
|
+
if (moduleMatch)
|
|
18464
|
+
profile.name = moduleMatch[1];
|
|
18465
|
+
for (const line of content.split(`
|
|
18466
|
+
`)) {
|
|
18467
|
+
const m = line.match(/^\s*(\S+)\s+v[\d.]+/);
|
|
18468
|
+
if (m && !line.startsWith("//"))
|
|
18469
|
+
profile.deps.push(m[1]);
|
|
18470
|
+
}
|
|
18471
|
+
return profile;
|
|
18472
|
+
} catch {
|
|
18473
|
+
return null;
|
|
18474
|
+
}
|
|
18475
|
+
}
|
|
18476
|
+
function readRequirements(baseDir) {
|
|
18477
|
+
try {
|
|
18478
|
+
const content = readFileSync24(join31(baseDir, "requirements.txt"), "utf-8");
|
|
18479
|
+
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
18480
|
+
for (const line of content.split(`
|
|
18481
|
+
`)) {
|
|
18482
|
+
const trimmed = line.trim();
|
|
18483
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("-"))
|
|
18484
|
+
continue;
|
|
18485
|
+
profile.deps.push(cleanDependency(trimmed));
|
|
18486
|
+
}
|
|
18487
|
+
return profile;
|
|
18488
|
+
} catch {
|
|
18489
|
+
return null;
|
|
18490
|
+
}
|
|
18491
|
+
}
|
|
18492
|
+
function readProjectProfile(baseDir) {
|
|
18493
|
+
const manifest = detectManifest(baseDir);
|
|
18494
|
+
if (!manifest)
|
|
18495
|
+
return null;
|
|
18496
|
+
switch (manifest) {
|
|
18497
|
+
case "package.json":
|
|
18498
|
+
return readPackageJson(baseDir);
|
|
18499
|
+
case "pyproject.toml":
|
|
18500
|
+
return readPyproject(baseDir);
|
|
18501
|
+
case "Cargo.toml":
|
|
18502
|
+
return readCargo(baseDir);
|
|
18503
|
+
case "go.mod":
|
|
18504
|
+
return readGoMod(baseDir);
|
|
18505
|
+
case "requirements.txt":
|
|
18506
|
+
return readRequirements(baseDir);
|
|
18507
|
+
default:
|
|
18508
|
+
return null;
|
|
18509
|
+
}
|
|
18510
|
+
}
|
|
18511
|
+
function formatProjectProfile(profile) {
|
|
18512
|
+
const parts = [];
|
|
18513
|
+
if (profile.deps.length > 0) {
|
|
18514
|
+
parts.push(`${t("indexer.stack_deps")}: ${profile.deps.slice(0, MAX_DEPS).join(", ")}`);
|
|
18515
|
+
}
|
|
18516
|
+
if (profile.devDeps.length > 0) {
|
|
18517
|
+
parts.push(`${t("indexer.stack_dev")}: ${profile.devDeps.slice(0, MAX_DEV_DEPS).join(", ")}`);
|
|
18518
|
+
}
|
|
18519
|
+
const scripts = Object.entries(profile.scripts).slice(0, MAX_SCRIPTS);
|
|
18520
|
+
if (scripts.length > 0) {
|
|
18521
|
+
parts.push(`${t("indexer.stack_scripts")}: ${scripts.map(([k, v]) => `${k}=${v}`).join(", ")}`);
|
|
18522
|
+
}
|
|
18523
|
+
const name = profile.name ? ` ${profile.name}` : "";
|
|
18524
|
+
return `[Stack: ${profile.runtime}${name} — ${parts.join(" | ")}]`;
|
|
18525
|
+
}
|
|
18526
|
+
function buildProjectProfileLine(baseDir) {
|
|
18527
|
+
const profile = readProjectProfile(baseDir);
|
|
18528
|
+
return profile ? formatProjectProfile(profile) : null;
|
|
18529
|
+
}
|
|
18530
|
+
var MANIFEST_ORDER, MAX_DEPS = 5, MAX_DEV_DEPS = 3, MAX_SCRIPTS = 3;
|
|
18531
|
+
var init_project_profile = __esm(() => {
|
|
18532
|
+
init_i18n();
|
|
18533
|
+
MANIFEST_ORDER = [
|
|
18534
|
+
"package.json",
|
|
18535
|
+
"pyproject.toml",
|
|
18536
|
+
"Cargo.toml",
|
|
18537
|
+
"go.mod",
|
|
18538
|
+
"requirements.txt"
|
|
18539
|
+
];
|
|
18540
|
+
});
|
|
18541
|
+
|
|
18244
18542
|
// src/modules/indexer/module.ts
|
|
18245
|
-
import { dirname as
|
|
18543
|
+
import { dirname as dirname9 } from "path";
|
|
18246
18544
|
|
|
18247
18545
|
class IndexerModule {
|
|
18248
18546
|
name = "indexer";
|
|
@@ -18336,6 +18634,7 @@ class IndexerModule {
|
|
|
18336
18634
|
}
|
|
18337
18635
|
formatMap(result) {
|
|
18338
18636
|
const summary = this.indexer.summarize(result);
|
|
18637
|
+
const stackLine = buildProjectProfileLine(this.baseDir);
|
|
18339
18638
|
const dirCounts = this.getDirectoryCounts(result);
|
|
18340
18639
|
const topDirs = Object.entries(dirCounts).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([dir, count]) => `${dir} (${count})`).join(", ") || "-";
|
|
18341
18640
|
const fileLines = result.files.slice(0, 100).map((f) => {
|
|
@@ -18348,6 +18647,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
18348
18647
|
return [
|
|
18349
18648
|
`${t("indexer.map_header")} (${this.baseDir})`,
|
|
18350
18649
|
summary,
|
|
18650
|
+
...stackLine ? [stackLine] : [],
|
|
18351
18651
|
`${t("indexer.top_directories")}: ${topDirs}`,
|
|
18352
18652
|
`${t("indexer.files")}:` + (fileLines.length > 0 ? "" : " " + t("indexer.empty")),
|
|
18353
18653
|
...fileLines,
|
|
@@ -18359,7 +18659,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
18359
18659
|
const counts = {};
|
|
18360
18660
|
for (const f of result.files) {
|
|
18361
18661
|
const normalized = f.path.replace(/\\/g, "/");
|
|
18362
|
-
const dir =
|
|
18662
|
+
const dir = dirname9(normalized);
|
|
18363
18663
|
const key = dir === "." ? "(root)" : dir;
|
|
18364
18664
|
counts[key] = (counts[key] || 0) + 1;
|
|
18365
18665
|
}
|
|
@@ -18392,7 +18692,10 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
18392
18692
|
if (action === "refresh") {
|
|
18393
18693
|
const result = await this.refresh();
|
|
18394
18694
|
const summary2 = result ? this.indexer.summarize(result) : t("indexer.empty");
|
|
18395
|
-
|
|
18695
|
+
const stackLine2 = result ? buildProjectProfileLine(this.baseDir) : null;
|
|
18696
|
+
const output2 = summary2 && stackLine2 ? `${summary2}
|
|
18697
|
+
${stackLine2}` : summary2;
|
|
18698
|
+
return this.makeResult(t("indexer.refreshed", { summary: output2 }));
|
|
18396
18699
|
}
|
|
18397
18700
|
if (action === "find") {
|
|
18398
18701
|
const query = String(args.query || "").toLowerCase();
|
|
@@ -18417,7 +18720,10 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
18417
18720
|
return this.makeResult(t("indexer.not_indexed"));
|
|
18418
18721
|
}
|
|
18419
18722
|
const summary = this.indexer.summarize(this.index);
|
|
18420
|
-
|
|
18723
|
+
const stackLine = buildProjectProfileLine(this.baseDir);
|
|
18724
|
+
const output = summary && stackLine ? `${summary}
|
|
18725
|
+
${stackLine}` : summary;
|
|
18726
|
+
return this.makeResult(t("indexer.summary", { summary: output }));
|
|
18421
18727
|
}
|
|
18422
18728
|
};
|
|
18423
18729
|
}
|
|
@@ -18428,6 +18734,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
18428
18734
|
var init_module6 = __esm(() => {
|
|
18429
18735
|
init_walker();
|
|
18430
18736
|
init_cache();
|
|
18737
|
+
init_project_profile();
|
|
18431
18738
|
init_i18n();
|
|
18432
18739
|
});
|
|
18433
18740
|
|
|
@@ -18590,13 +18897,13 @@ var init_mcp = __esm(() => {
|
|
|
18590
18897
|
|
|
18591
18898
|
// src/modules/memory/module.ts
|
|
18592
18899
|
import { homedir as homedir10 } from "os";
|
|
18593
|
-
import { join as
|
|
18900
|
+
import { join as join32 } from "path";
|
|
18594
18901
|
|
|
18595
18902
|
class MemoryModule {
|
|
18596
18903
|
name = "memory";
|
|
18597
18904
|
store;
|
|
18598
18905
|
constructor(memoryDir) {
|
|
18599
|
-
const dir = memoryDir ||
|
|
18906
|
+
const dir = memoryDir || join32(homedir10(), ".mma", "memory");
|
|
18600
18907
|
this.store = new MemoryStore(dir);
|
|
18601
18908
|
}
|
|
18602
18909
|
getSystemPromptBlock() {
|
|
@@ -18644,8 +18951,8 @@ __export(exports_bootstrap, {
|
|
|
18644
18951
|
bootstrap: () => bootstrap
|
|
18645
18952
|
});
|
|
18646
18953
|
import { homedir as homedir11 } from "os";
|
|
18647
|
-
import { join as
|
|
18648
|
-
import { existsSync as
|
|
18954
|
+
import { join as join33, resolve as resolve21 } from "path";
|
|
18955
|
+
import { existsSync as existsSync39, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
|
|
18649
18956
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
18650
18957
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
18651
18958
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -18670,8 +18977,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
18670
18977
|
`);
|
|
18671
18978
|
}
|
|
18672
18979
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
18673
|
-
const dir = configDir ||
|
|
18674
|
-
const projectConfigPath = projectDir ?
|
|
18980
|
+
const dir = configDir || join33(homedir11(), ".mma");
|
|
18981
|
+
const projectConfigPath = projectDir ? join33(projectDir, ".mmrc") : join33(process.cwd(), ".mmrc");
|
|
18675
18982
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
18676
18983
|
setLocale(config.locale);
|
|
18677
18984
|
try {
|
|
@@ -18681,7 +18988,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18681
18988
|
}
|
|
18682
18989
|
} catch {}
|
|
18683
18990
|
const logger = new Logger(config.logLevel);
|
|
18684
|
-
logger.setLogDir(
|
|
18991
|
+
logger.setLogDir(join33(dir, "logs"));
|
|
18685
18992
|
logger.debug("MMA bootstrap", {
|
|
18686
18993
|
version: config.version,
|
|
18687
18994
|
model: config.model
|
|
@@ -18703,7 +19010,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18703
19010
|
logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
18704
19011
|
}
|
|
18705
19012
|
}
|
|
18706
|
-
const profile = new UserProfile(
|
|
19013
|
+
const profile = new UserProfile(join33(dir));
|
|
18707
19014
|
profile.load() || profile.collect();
|
|
18708
19015
|
profile.save();
|
|
18709
19016
|
const llmProvider = new OpenAICompatProvider({
|
|
@@ -18715,7 +19022,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18715
19022
|
rateLimits: config.security?.rateLimits
|
|
18716
19023
|
});
|
|
18717
19024
|
const baseDir = projectDir ? resolve21(projectDir) : process.cwd();
|
|
18718
|
-
const projectMapCacheDir =
|
|
19025
|
+
const projectMapCacheDir = join33(baseDir, ".mma");
|
|
18719
19026
|
const indexerModule = new IndexerModule({
|
|
18720
19027
|
baseDir,
|
|
18721
19028
|
cacheDir: projectMapCacheDir
|
|
@@ -18726,9 +19033,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18726
19033
|
logger.warn(`Project indexing failed: ${err.message}`);
|
|
18727
19034
|
}
|
|
18728
19035
|
const skillsLoader = new SkillsLoader;
|
|
18729
|
-
const builtinDir =
|
|
18730
|
-
const globalDir =
|
|
18731
|
-
const projectSkillsDir =
|
|
19036
|
+
const builtinDir = join33(import.meta.dirname, "skills", "builtin");
|
|
19037
|
+
const globalDir = join33(homedir11(), ".agents", "skills");
|
|
19038
|
+
const projectSkillsDir = join33(baseDir, ".mma", "skills");
|
|
18732
19039
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
18733
19040
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
18734
19041
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
@@ -18742,11 +19049,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18742
19049
|
essential: true,
|
|
18743
19050
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
18744
19051
|
};
|
|
18745
|
-
const agentsMdGlobal =
|
|
18746
|
-
if (!
|
|
18747
|
-
|
|
19052
|
+
const agentsMdGlobal = join33(dir, "AGENTS.md");
|
|
19053
|
+
if (!existsSync39(agentsMdGlobal)) {
|
|
19054
|
+
writeFileSync15(agentsMdGlobal, "", "utf-8");
|
|
18748
19055
|
}
|
|
18749
|
-
const sessionDir =
|
|
19056
|
+
const sessionDir = join33(dir, "sessions");
|
|
18750
19057
|
const sessionStore = new SessionStore(sessionDir);
|
|
18751
19058
|
sessionStore.init();
|
|
18752
19059
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -18813,7 +19120,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18813
19120
|
const mcpModule = new MCPModule(config);
|
|
18814
19121
|
await mcpModule.initialize();
|
|
18815
19122
|
moduleRegistry.register(mcpModule);
|
|
18816
|
-
const memoryModule = new MemoryModule(
|
|
19123
|
+
const memoryModule = new MemoryModule(join33(dir, "memory"));
|
|
18817
19124
|
moduleRegistry.register(memoryModule);
|
|
18818
19125
|
if (config.browser.enabled) {
|
|
18819
19126
|
const browserModule = new BrowserModule;
|
|
@@ -18863,8 +19170,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18863
19170
|
pluginManager.register(plugin);
|
|
18864
19171
|
pluginManager.register(plugin2);
|
|
18865
19172
|
const pluginLoader = new PluginLoader;
|
|
18866
|
-
const globalPluginsDir =
|
|
18867
|
-
const projectPluginsDir =
|
|
19173
|
+
const globalPluginsDir = join33(homedir11(), ".mma", "plugins");
|
|
19174
|
+
const projectPluginsDir = join33(baseDir, ".mma", "plugins");
|
|
18868
19175
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
|
|
18869
19176
|
pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
|
|
18870
19177
|
contextManager.onCompact = (summary) => {
|
|
@@ -18882,13 +19189,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18882
19189
|
const skipAgentsMd = noAgentsMd === true;
|
|
18883
19190
|
if (!skipAgentsMd) {
|
|
18884
19191
|
const agentsMdCandidates = [
|
|
18885
|
-
|
|
18886
|
-
|
|
18887
|
-
|
|
19192
|
+
join33(baseDir, "AGENTS.md"),
|
|
19193
|
+
join33(baseDir, ".mma", "AGENTS.md"),
|
|
19194
|
+
join33(dir, "AGENTS.md")
|
|
18888
19195
|
];
|
|
18889
19196
|
for (const p of agentsMdCandidates) {
|
|
18890
|
-
if (
|
|
18891
|
-
const content =
|
|
19197
|
+
if (existsSync39(p)) {
|
|
19198
|
+
const content = readFileSync25(p, "utf-8").trim();
|
|
18892
19199
|
if (content) {
|
|
18893
19200
|
agentsMdBlocks.push({
|
|
18894
19201
|
content,
|
|
@@ -18902,7 +19209,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18902
19209
|
}
|
|
18903
19210
|
const promptBlocks = [
|
|
18904
19211
|
systemInfoPrompt,
|
|
18905
|
-
...moduleRegistry.collectPromptBlocks(),
|
|
19212
|
+
...moduleRegistry.collectPromptBlocks(["indexer"]),
|
|
18906
19213
|
...agentsMdBlocks
|
|
18907
19214
|
];
|
|
18908
19215
|
const agentDeps = {
|
|
@@ -18923,6 +19230,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
18923
19230
|
const skillsBlock = skillsModule.getSystemPromptBlock();
|
|
18924
19231
|
if (skillsBlock)
|
|
18925
19232
|
blocks.push(skillsBlock);
|
|
19233
|
+
const mapBlock = indexerModule.getSystemPromptBlock();
|
|
19234
|
+
if (mapBlock)
|
|
19235
|
+
blocks.push(mapBlock);
|
|
18926
19236
|
return blocks;
|
|
18927
19237
|
},
|
|
18928
19238
|
finalAudit: () => execModule.runFinalAudit(),
|
|
@@ -19737,21 +20047,21 @@ __export(exports_manifest, {
|
|
|
19737
20047
|
getCertMark: () => getCertMark,
|
|
19738
20048
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
19739
20049
|
});
|
|
19740
|
-
import { existsSync as
|
|
20050
|
+
import { existsSync as existsSync40, readFileSync as readFileSync26, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
19741
20051
|
import { homedir as homedir13 } from "os";
|
|
19742
|
-
import { join as
|
|
20052
|
+
import { join as join35 } from "path";
|
|
19743
20053
|
function readManifest(path = MANIFEST_PATH) {
|
|
19744
20054
|
try {
|
|
19745
|
-
if (
|
|
19746
|
-
const raw = JSON.parse(
|
|
20055
|
+
if (existsSync40(path)) {
|
|
20056
|
+
const raw = JSON.parse(readFileSync26(path, "utf-8"));
|
|
19747
20057
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
19748
20058
|
}
|
|
19749
20059
|
} catch {}
|
|
19750
20060
|
return { version: 1, certifications: [] };
|
|
19751
20061
|
}
|
|
19752
20062
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
19753
|
-
|
|
19754
|
-
|
|
20063
|
+
mkdirSync18(join35(homedir13(), ".mma"), { recursive: true });
|
|
20064
|
+
writeFileSync16(path, JSON.stringify(m, null, 2), "utf-8");
|
|
19755
20065
|
}
|
|
19756
20066
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
19757
20067
|
const m = readManifest(path);
|
|
@@ -19785,7 +20095,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
|
|
|
19785
20095
|
}
|
|
19786
20096
|
var MANIFEST_PATH;
|
|
19787
20097
|
var init_manifest = __esm(() => {
|
|
19788
|
-
MANIFEST_PATH =
|
|
20098
|
+
MANIFEST_PATH = join35(homedir13(), ".mma", "certifications.json");
|
|
19789
20099
|
});
|
|
19790
20100
|
|
|
19791
20101
|
// node_modules/yaml/dist/nodes/identity.js
|
|
@@ -26908,8 +27218,8 @@ var init_scenarios = __esm(() => {
|
|
|
26908
27218
|
});
|
|
26909
27219
|
|
|
26910
27220
|
// src/modules/certification/loader.ts
|
|
26911
|
-
import { existsSync as
|
|
26912
|
-
import { join as
|
|
27221
|
+
import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync27 } from "fs";
|
|
27222
|
+
import { join as join36 } from "path";
|
|
26913
27223
|
function validateScenario(s) {
|
|
26914
27224
|
const errors2 = [];
|
|
26915
27225
|
const isSkip = s.mode === "skip";
|
|
@@ -26958,12 +27268,12 @@ function loadScenarios(userDir) {
|
|
|
26958
27268
|
else
|
|
26959
27269
|
scenarios.push(s);
|
|
26960
27270
|
}
|
|
26961
|
-
if (userDir &&
|
|
27271
|
+
if (userDir && existsSync41(userDir)) {
|
|
26962
27272
|
for (const file of readdirSync14(userDir)) {
|
|
26963
27273
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
26964
27274
|
continue;
|
|
26965
27275
|
try {
|
|
26966
|
-
const raw =
|
|
27276
|
+
const raw = readFileSync27(join36(userDir, file), "utf-8");
|
|
26967
27277
|
const data = $parse(raw);
|
|
26968
27278
|
const parsed = normalizeScenario(data, file);
|
|
26969
27279
|
const errs = validateScenario(parsed);
|
|
@@ -27016,8 +27326,8 @@ var init_loader3 = __esm(() => {
|
|
|
27016
27326
|
});
|
|
27017
27327
|
|
|
27018
27328
|
// src/modules/certification/fact-checker.ts
|
|
27019
|
-
import { existsSync as
|
|
27020
|
-
import { join as
|
|
27329
|
+
import { existsSync as existsSync42, readFileSync as readFileSync28, statSync as statSync8 } from "fs";
|
|
27330
|
+
import { join as join37 } from "path";
|
|
27021
27331
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
27022
27332
|
const failures = [];
|
|
27023
27333
|
for (const check of checks) {
|
|
@@ -27034,16 +27344,16 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27034
27344
|
case "outputContains":
|
|
27035
27345
|
return output.includes(check.text);
|
|
27036
27346
|
case "fileExists":
|
|
27037
|
-
return isFile(
|
|
27347
|
+
return isFile(join37(sandboxDir, check.path));
|
|
27038
27348
|
case "fileNotExists":
|
|
27039
|
-
return !
|
|
27349
|
+
return !existsSync42(join37(sandboxDir, check.path));
|
|
27040
27350
|
case "dirExists":
|
|
27041
|
-
return isDir(
|
|
27351
|
+
return isDir(join37(sandboxDir, check.path));
|
|
27042
27352
|
case "fileContent": {
|
|
27043
|
-
const abs =
|
|
27353
|
+
const abs = join37(sandboxDir, check.path);
|
|
27044
27354
|
if (!isFile(abs))
|
|
27045
27355
|
return false;
|
|
27046
|
-
const content =
|
|
27356
|
+
const content = readFileSync28(abs, "utf-8");
|
|
27047
27357
|
if (check.contains !== undefined)
|
|
27048
27358
|
return content.includes(check.contains);
|
|
27049
27359
|
if (check.equals !== undefined)
|
|
@@ -27051,10 +27361,10 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27051
27361
|
return false;
|
|
27052
27362
|
}
|
|
27053
27363
|
case "fileRegex": {
|
|
27054
|
-
const abs =
|
|
27364
|
+
const abs = join37(sandboxDir, check.path);
|
|
27055
27365
|
if (!isFile(abs))
|
|
27056
27366
|
return false;
|
|
27057
|
-
return new RegExp(check.pattern).test(
|
|
27367
|
+
return new RegExp(check.pattern).test(readFileSync28(abs, "utf-8"));
|
|
27058
27368
|
}
|
|
27059
27369
|
default:
|
|
27060
27370
|
return false;
|
|
@@ -27062,14 +27372,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27062
27372
|
}
|
|
27063
27373
|
function isFile(p) {
|
|
27064
27374
|
try {
|
|
27065
|
-
return
|
|
27375
|
+
return existsSync42(p) && statSync8(p).isFile();
|
|
27066
27376
|
} catch {
|
|
27067
27377
|
return false;
|
|
27068
27378
|
}
|
|
27069
27379
|
}
|
|
27070
27380
|
function isDir(p) {
|
|
27071
27381
|
try {
|
|
27072
|
-
return
|
|
27382
|
+
return existsSync42(p) && statSync8(p).isDirectory();
|
|
27073
27383
|
} catch {
|
|
27074
27384
|
return false;
|
|
27075
27385
|
}
|
|
@@ -27100,9 +27410,9 @@ var init_fact_checker = () => {};
|
|
|
27100
27410
|
|
|
27101
27411
|
// src/modules/certification/runner.ts
|
|
27102
27412
|
import { spawn as spawn7 } from "child_process";
|
|
27103
|
-
import { existsSync as
|
|
27413
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
27104
27414
|
import { platform as platform6 } from "os";
|
|
27105
|
-
import { join as
|
|
27415
|
+
import { join as join38, resolve as resolve22, dirname as dirname10 } from "path";
|
|
27106
27416
|
async function runScenario(scenario, opts) {
|
|
27107
27417
|
if (scenario.mode === "skip") {
|
|
27108
27418
|
return {
|
|
@@ -27121,7 +27431,7 @@ async function runScenario(scenario, opts) {
|
|
|
27121
27431
|
let passed = 0;
|
|
27122
27432
|
let firstError;
|
|
27123
27433
|
for (let i = 1;i <= reps; i++) {
|
|
27124
|
-
const sandbox =
|
|
27434
|
+
const sandbox = join38(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
27125
27435
|
let failures = [];
|
|
27126
27436
|
let exitCode = -1;
|
|
27127
27437
|
let output = "";
|
|
@@ -27180,22 +27490,22 @@ ${res.stderr}`;
|
|
|
27180
27490
|
}
|
|
27181
27491
|
function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
27182
27492
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
27183
|
-
|
|
27493
|
+
mkdirSync19(sandbox, { recursive: true });
|
|
27184
27494
|
for (const f of scenario.fixtures ?? []) {
|
|
27185
|
-
const src =
|
|
27186
|
-
if (!
|
|
27495
|
+
const src = join38(mmaRoot, f.source);
|
|
27496
|
+
if (!existsSync43(src)) {
|
|
27187
27497
|
throw new Error(`fixture missing: ${f.source}`);
|
|
27188
27498
|
}
|
|
27189
|
-
const dest =
|
|
27190
|
-
|
|
27499
|
+
const dest = join38(sandbox, f.dest);
|
|
27500
|
+
mkdirSync19(dirname10(dest), { recursive: true });
|
|
27191
27501
|
cpSync2(src, dest);
|
|
27192
27502
|
}
|
|
27193
27503
|
}
|
|
27194
27504
|
function resolveMmaEntry(mmaRoot) {
|
|
27195
|
-
const dev =
|
|
27196
|
-
if (
|
|
27505
|
+
const dev = join38(mmaRoot, "src", "cli", "main.ts");
|
|
27506
|
+
if (existsSync43(dev))
|
|
27197
27507
|
return dev;
|
|
27198
|
-
return
|
|
27508
|
+
return join38(mmaRoot, "dist", "main.js");
|
|
27199
27509
|
}
|
|
27200
27510
|
function findMmaRoot(fromDir) {
|
|
27201
27511
|
const candidates = [
|
|
@@ -27203,7 +27513,7 @@ function findMmaRoot(fromDir) {
|
|
|
27203
27513
|
resolve22(fromDir, "..")
|
|
27204
27514
|
];
|
|
27205
27515
|
for (const c of candidates) {
|
|
27206
|
-
if (
|
|
27516
|
+
if (existsSync43(join38(c, "package.json")))
|
|
27207
27517
|
return c;
|
|
27208
27518
|
}
|
|
27209
27519
|
return process.cwd();
|
|
@@ -27271,15 +27581,15 @@ __export(exports_cli, {
|
|
|
27271
27581
|
});
|
|
27272
27582
|
import { rmSync as rmSync5 } from "fs";
|
|
27273
27583
|
import { homedir as homedir14 } from "os";
|
|
27274
|
-
import { join as
|
|
27584
|
+
import { join as join39, dirname as dirname11 } from "path";
|
|
27275
27585
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
27276
|
-
import { existsSync as
|
|
27586
|
+
import { existsSync as existsSync44, readFileSync as readFileSync29 } from "fs";
|
|
27277
27587
|
function readVersion() {
|
|
27278
|
-
const candidates = [
|
|
27588
|
+
const candidates = [join39(MMA_ROOT, "package.json")];
|
|
27279
27589
|
for (const p of candidates) {
|
|
27280
|
-
if (
|
|
27590
|
+
if (existsSync44(p)) {
|
|
27281
27591
|
try {
|
|
27282
|
-
const raw = JSON.parse(
|
|
27592
|
+
const raw = JSON.parse(readFileSync29(p, "utf-8"));
|
|
27283
27593
|
if (raw.version)
|
|
27284
27594
|
return raw.version;
|
|
27285
27595
|
} catch {}
|
|
@@ -27315,7 +27625,7 @@ async function certify(opts) {
|
|
|
27315
27625
|
return;
|
|
27316
27626
|
}
|
|
27317
27627
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
27318
|
-
const sandboxBase =
|
|
27628
|
+
const sandboxBase = join39(process.cwd(), ".mma", "certification");
|
|
27319
27629
|
const results = [];
|
|
27320
27630
|
const total = selected.length;
|
|
27321
27631
|
let idx = 0;
|
|
@@ -27427,9 +27737,9 @@ var init_cli = __esm(() => {
|
|
|
27427
27737
|
init_loader3();
|
|
27428
27738
|
init_runner2();
|
|
27429
27739
|
init_manifest();
|
|
27430
|
-
HERE =
|
|
27740
|
+
HERE = dirname11(fileURLToPath2(import.meta.url));
|
|
27431
27741
|
MMA_ROOT = findMmaRoot(HERE);
|
|
27432
|
-
USER_SCENARIO_DIR =
|
|
27742
|
+
USER_SCENARIO_DIR = join39(homedir14(), ".mma", "certification", "scenarios");
|
|
27433
27743
|
});
|
|
27434
27744
|
|
|
27435
27745
|
// src/cli/repl-commands.ts
|
|
@@ -27438,20 +27748,20 @@ __export(exports_repl_commands, {
|
|
|
27438
27748
|
registerAllCommands: () => registerAllCommands,
|
|
27439
27749
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
27440
27750
|
});
|
|
27441
|
-
import { join as
|
|
27751
|
+
import { join as join41, dirname as dirname13 } from "path";
|
|
27442
27752
|
import { homedir as homedir16 } from "os";
|
|
27443
|
-
import { existsSync as
|
|
27753
|
+
import { existsSync as existsSync46, readFileSync as readFileSync31 } from "fs";
|
|
27444
27754
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
27445
27755
|
function readVersion3() {
|
|
27446
|
-
const here =
|
|
27756
|
+
const here = dirname13(fileURLToPath4(import.meta.url));
|
|
27447
27757
|
const candidates = [
|
|
27448
|
-
|
|
27449
|
-
|
|
27758
|
+
join41(here, "..", "..", "package.json"),
|
|
27759
|
+
join41(here, "..", "package.json")
|
|
27450
27760
|
];
|
|
27451
27761
|
for (const p of candidates) {
|
|
27452
|
-
if (
|
|
27762
|
+
if (existsSync46(p)) {
|
|
27453
27763
|
try {
|
|
27454
|
-
const raw = JSON.parse(
|
|
27764
|
+
const raw = JSON.parse(readFileSync31(p, "utf8"));
|
|
27455
27765
|
if (raw.version)
|
|
27456
27766
|
return raw.version;
|
|
27457
27767
|
} catch {}
|
|
@@ -27515,7 +27825,7 @@ function registerMmaCommands(ctx) {
|
|
|
27515
27825
|
}
|
|
27516
27826
|
try {
|
|
27517
27827
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
27518
|
-
const { existsSync:
|
|
27828
|
+
const { existsSync: existsSync47 } = await import("fs");
|
|
27519
27829
|
const { resolve: resolve23 } = await import("path");
|
|
27520
27830
|
let dataUrl;
|
|
27521
27831
|
let label;
|
|
@@ -27535,7 +27845,7 @@ function registerMmaCommands(ctx) {
|
|
|
27535
27845
|
label = source;
|
|
27536
27846
|
} else {
|
|
27537
27847
|
const absPath = resolve23(process.cwd(), source);
|
|
27538
|
-
if (!
|
|
27848
|
+
if (!existsSync47(absPath)) {
|
|
27539
27849
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
27540
27850
|
return;
|
|
27541
27851
|
}
|
|
@@ -27614,7 +27924,7 @@ function registerMmaCommands(ctx) {
|
|
|
27614
27924
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
27615
27925
|
await ctx.withExclusiveInput(async () => {
|
|
27616
27926
|
const answers = await runSetup(ctx.rl);
|
|
27617
|
-
const configPath =
|
|
27927
|
+
const configPath = join41(homedir16(), ".mma", "config.json");
|
|
27618
27928
|
ctx.config.provider.type = answers.provider;
|
|
27619
27929
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
27620
27930
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -27668,7 +27978,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
27668
27978
|
return;
|
|
27669
27979
|
}
|
|
27670
27980
|
ctx.config.provider.type = name;
|
|
27671
|
-
const configPath =
|
|
27981
|
+
const configPath = join41(homedir16(), ".mma", "config.json");
|
|
27672
27982
|
saveConfig(ctx.config, configPath);
|
|
27673
27983
|
await ctx.agent.reconfigure(ctx.config);
|
|
27674
27984
|
console.log(pc2.green(t("repl.provider_set", { name })));
|
|
@@ -27724,7 +28034,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
27724
28034
|
return;
|
|
27725
28035
|
}
|
|
27726
28036
|
ctx.config.model = name;
|
|
27727
|
-
const configPath =
|
|
28037
|
+
const configPath = join41(homedir16(), ".mma", "config.json");
|
|
27728
28038
|
saveConfig(ctx.config, configPath);
|
|
27729
28039
|
await ctx.agent.reconfigure(ctx.config);
|
|
27730
28040
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
@@ -27749,7 +28059,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
27749
28059
|
return;
|
|
27750
28060
|
}
|
|
27751
28061
|
ctx.config.contextWindow = size;
|
|
27752
|
-
const configPath =
|
|
28062
|
+
const configPath = join41(homedir16(), ".mma", "config.json");
|
|
27753
28063
|
saveConfig(ctx.config, configPath);
|
|
27754
28064
|
await ctx.agent.reconfigure(ctx.config);
|
|
27755
28065
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
@@ -27768,10 +28078,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
27768
28078
|
ctx.agent.shutdown();
|
|
27769
28079
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
27770
28080
|
const { homedir: homedir17 } = await import("os");
|
|
27771
|
-
const { join:
|
|
28081
|
+
const { join: join42 } = await import("path");
|
|
27772
28082
|
const configDir = ctx.configDir;
|
|
27773
28083
|
const baseDir = ctx.baseDir;
|
|
27774
|
-
const projectConfigPath =
|
|
28084
|
+
const projectConfigPath = join42(baseDir, ".mmrc");
|
|
27775
28085
|
const freshConfig = loadConfig2({ configDir, projectConfigPath });
|
|
27776
28086
|
Object.assign(ctx.config, freshConfig);
|
|
27777
28087
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -28071,14 +28381,14 @@ init_bootstrap();
|
|
|
28071
28381
|
init_config2();
|
|
28072
28382
|
init_setup();
|
|
28073
28383
|
init_i18n();
|
|
28074
|
-
import { join as
|
|
28384
|
+
import { join as join40, dirname as dirname12 } from "path";
|
|
28075
28385
|
import { homedir as homedir15 } from "os";
|
|
28076
|
-
import { existsSync as
|
|
28386
|
+
import { existsSync as existsSync45, readFileSync as readFileSync30 } from "fs";
|
|
28077
28387
|
|
|
28078
28388
|
// src/cli/security-commands.ts
|
|
28079
28389
|
init_bootstrap();
|
|
28080
28390
|
init_config2();
|
|
28081
|
-
import { join as
|
|
28391
|
+
import { join as join34 } from "path";
|
|
28082
28392
|
import { homedir as homedir12 } from "os";
|
|
28083
28393
|
|
|
28084
28394
|
// src/modules/security/security-policies.ts
|
|
@@ -28608,7 +28918,7 @@ function createSecurityCommand(program2) {
|
|
|
28608
28918
|
}
|
|
28609
28919
|
});
|
|
28610
28920
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
28611
|
-
const configPath =
|
|
28921
|
+
const configPath = join34(homedir12(), ".mma", "config.json");
|
|
28612
28922
|
const { config: appConfig } = await bootstrap();
|
|
28613
28923
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
28614
28924
|
if (!validPresets.includes(preset)) {
|
|
@@ -28623,7 +28933,7 @@ function createSecurityCommand(program2) {
|
|
|
28623
28933
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
28624
28934
|
});
|
|
28625
28935
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
28626
|
-
const configPath =
|
|
28936
|
+
const configPath = join34(homedir12(), ".mma", "config.json");
|
|
28627
28937
|
const { config: appConfig } = await bootstrap();
|
|
28628
28938
|
appConfig.security = appConfig.security || {};
|
|
28629
28939
|
appConfig.security.sessionEncryption = {
|
|
@@ -28635,7 +28945,7 @@ function createSecurityCommand(program2) {
|
|
|
28635
28945
|
console.log(t("cli.security.encryption_enabled"));
|
|
28636
28946
|
});
|
|
28637
28947
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
28638
|
-
const configPath =
|
|
28948
|
+
const configPath = join34(homedir12(), ".mma", "config.json");
|
|
28639
28949
|
const { config: appConfig } = await bootstrap();
|
|
28640
28950
|
appConfig.security = appConfig.security || {};
|
|
28641
28951
|
appConfig.security.sessionEncryption = {
|
|
@@ -28647,7 +28957,7 @@ function createSecurityCommand(program2) {
|
|
|
28647
28957
|
console.log(t("cli.security.encryption_disabled"));
|
|
28648
28958
|
});
|
|
28649
28959
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
28650
|
-
const configPath =
|
|
28960
|
+
const configPath = join34(homedir12(), ".mma", "config.json");
|
|
28651
28961
|
const { config: appConfig } = await bootstrap();
|
|
28652
28962
|
appConfig.security = appConfig.security || {};
|
|
28653
28963
|
appConfig.security.auditNotifier = {
|
|
@@ -28661,7 +28971,7 @@ function createSecurityCommand(program2) {
|
|
|
28661
28971
|
console.log(t("cli.security.audit_enabled"));
|
|
28662
28972
|
});
|
|
28663
28973
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
28664
|
-
const configPath =
|
|
28974
|
+
const configPath = join34(homedir12(), ".mma", "config.json");
|
|
28665
28975
|
const { config: appConfig } = await bootstrap();
|
|
28666
28976
|
appConfig.security = appConfig.security || {};
|
|
28667
28977
|
appConfig.security.auditNotifier = {
|
|
@@ -28695,15 +29005,15 @@ function createSecurityCommand(program2) {
|
|
|
28695
29005
|
// src/cli/commands.ts
|
|
28696
29006
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
28697
29007
|
function readVersion2() {
|
|
28698
|
-
const here =
|
|
29008
|
+
const here = dirname12(fileURLToPath3(import.meta.url));
|
|
28699
29009
|
const candidates = [
|
|
28700
|
-
|
|
28701
|
-
|
|
29010
|
+
join40(here, "..", "..", "package.json"),
|
|
29011
|
+
join40(here, "..", "package.json")
|
|
28702
29012
|
];
|
|
28703
29013
|
for (const p of candidates) {
|
|
28704
|
-
if (
|
|
29014
|
+
if (existsSync45(p)) {
|
|
28705
29015
|
try {
|
|
28706
|
-
const raw = JSON.parse(
|
|
29016
|
+
const raw = JSON.parse(readFileSync30(p, "utf8"));
|
|
28707
29017
|
if (raw.version)
|
|
28708
29018
|
return raw.version;
|
|
28709
29019
|
} catch {}
|
|
@@ -28716,7 +29026,7 @@ function createProgram() {
|
|
|
28716
29026
|
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"));
|
|
28717
29027
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
28718
29028
|
const answers = await runSetup();
|
|
28719
|
-
const configPath =
|
|
29029
|
+
const configPath = join40(homedir15(), ".mma", "config.json");
|
|
28720
29030
|
const { config } = await bootstrap();
|
|
28721
29031
|
config.provider.type = answers.provider;
|
|
28722
29032
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -28761,7 +29071,7 @@ function createProgram() {
|
|
|
28761
29071
|
});
|
|
28762
29072
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
28763
29073
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
28764
|
-
const configPath =
|
|
29074
|
+
const configPath = join40(homedir15(), ".mma", "config.json");
|
|
28765
29075
|
const { config } = await bootstrap();
|
|
28766
29076
|
const keys = key.split(".");
|
|
28767
29077
|
let obj = config;
|
|
@@ -28824,7 +29134,7 @@ function createProgram() {
|
|
|
28824
29134
|
console.log(t("cli.model_hint"));
|
|
28825
29135
|
});
|
|
28826
29136
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
28827
|
-
const configPath =
|
|
29137
|
+
const configPath = join40(homedir15(), ".mma", "config.json");
|
|
28828
29138
|
const { config } = await bootstrap();
|
|
28829
29139
|
config.model = name;
|
|
28830
29140
|
saveConfig(config, configPath);
|
|
@@ -28860,7 +29170,7 @@ function createProgram() {
|
|
|
28860
29170
|
await uncertify2(name, config);
|
|
28861
29171
|
});
|
|
28862
29172
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
28863
|
-
const configPath =
|
|
29173
|
+
const configPath = join40(homedir15(), ".mma", "config.json");
|
|
28864
29174
|
const { config } = await bootstrap();
|
|
28865
29175
|
const contextWindow = parseInt(size, 10);
|
|
28866
29176
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -28878,7 +29188,7 @@ function createProgram() {
|
|
|
28878
29188
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
28879
29189
|
});
|
|
28880
29190
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
28881
|
-
const configPath =
|
|
29191
|
+
const configPath = join40(homedir15(), ".mma", "config.json");
|
|
28882
29192
|
const { config } = await bootstrap();
|
|
28883
29193
|
config.provider.type = name;
|
|
28884
29194
|
saveConfig(config, configPath);
|
|
@@ -29648,8 +29958,8 @@ class LineEditor {
|
|
|
29648
29958
|
}
|
|
29649
29959
|
|
|
29650
29960
|
// src/cli/repl.ts
|
|
29651
|
-
import { existsSync as
|
|
29652
|
-
import { join as
|
|
29961
|
+
import { existsSync as existsSync47, readFileSync as readFileSync32, writeFileSync as writeFileSync17 } from "fs";
|
|
29962
|
+
import { join as join42, dirname as dirname14 } from "path";
|
|
29653
29963
|
import { homedir as homedir17 } from "os";
|
|
29654
29964
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
29655
29965
|
|
|
@@ -30153,15 +30463,15 @@ init_box();
|
|
|
30153
30463
|
init_i18n();
|
|
30154
30464
|
init_repl_commands();
|
|
30155
30465
|
function readVersion4() {
|
|
30156
|
-
const here =
|
|
30466
|
+
const here = dirname14(fileURLToPath5(import.meta.url));
|
|
30157
30467
|
const candidates = [
|
|
30158
|
-
|
|
30159
|
-
|
|
30468
|
+
join42(here, "..", "..", "package.json"),
|
|
30469
|
+
join42(here, "..", "package.json")
|
|
30160
30470
|
];
|
|
30161
30471
|
for (const p of candidates) {
|
|
30162
|
-
if (
|
|
30472
|
+
if (existsSync47(p)) {
|
|
30163
30473
|
try {
|
|
30164
|
-
const raw = JSON.parse(
|
|
30474
|
+
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
30165
30475
|
if (raw.version)
|
|
30166
30476
|
return raw.version;
|
|
30167
30477
|
} catch {}
|
|
@@ -30217,10 +30527,10 @@ class Repl {
|
|
|
30217
30527
|
this.skillsModule = skillsModule;
|
|
30218
30528
|
this.pluginManager = pluginManager;
|
|
30219
30529
|
this.logger = logger;
|
|
30220
|
-
this.configDir = configDir ||
|
|
30530
|
+
this.configDir = configDir || join42(homedir17(), ".mma");
|
|
30221
30531
|
this.baseDir = baseDir || process.cwd();
|
|
30222
30532
|
this.noAgentsMd = noAgentsMd === true;
|
|
30223
|
-
this.historyPath =
|
|
30533
|
+
this.historyPath = join42(homedir17(), ".mma", "repl-history");
|
|
30224
30534
|
this.loadHistory();
|
|
30225
30535
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
30226
30536
|
input: process.stdin,
|
|
@@ -30253,9 +30563,9 @@ class Repl {
|
|
|
30253
30563
|
this.setupListeners();
|
|
30254
30564
|
}
|
|
30255
30565
|
loadHistory() {
|
|
30256
|
-
if (
|
|
30566
|
+
if (existsSync47(this.historyPath)) {
|
|
30257
30567
|
try {
|
|
30258
|
-
const raw =
|
|
30568
|
+
const raw = readFileSync32(this.historyPath, "utf-8");
|
|
30259
30569
|
this.history = raw.split(`
|
|
30260
30570
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
30261
30571
|
} catch {
|
|
@@ -30265,7 +30575,7 @@ class Repl {
|
|
|
30265
30575
|
}
|
|
30266
30576
|
saveHistory() {
|
|
30267
30577
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
30268
|
-
|
|
30578
|
+
writeFileSync17(this.historyPath, allHistory.join(`
|
|
30269
30579
|
`), "utf-8");
|
|
30270
30580
|
}
|
|
30271
30581
|
setupCompleter() {
|
|
@@ -30612,11 +30922,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
30612
30922
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
30613
30923
|
} else {
|
|
30614
30924
|
const agentsMdCandidates = [
|
|
30615
|
-
|
|
30616
|
-
|
|
30617
|
-
|
|
30925
|
+
join42(this.baseDir, "AGENTS.md"),
|
|
30926
|
+
join42(this.baseDir, ".mma", "AGENTS.md"),
|
|
30927
|
+
join42(this.configDir, "AGENTS.md")
|
|
30618
30928
|
];
|
|
30619
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
30929
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync47(p));
|
|
30620
30930
|
if (foundAgents.length > 0) {
|
|
30621
30931
|
for (const p of foundAgents) {
|
|
30622
30932
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -30627,7 +30937,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
30627
30937
|
}
|
|
30628
30938
|
const meta = this.sessionManager?.getActiveMeta();
|
|
30629
30939
|
if (meta) {
|
|
30630
|
-
const sessionPath =
|
|
30940
|
+
const sessionPath = join42(this.configDir, "sessions", meta.id);
|
|
30631
30941
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
30632
30942
|
}
|
|
30633
30943
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
@@ -30668,8 +30978,8 @@ init_setup();
|
|
|
30668
30978
|
init_config2();
|
|
30669
30979
|
init_i18n();
|
|
30670
30980
|
init_colors();
|
|
30671
|
-
import { existsSync as
|
|
30672
|
-
import { join as
|
|
30981
|
+
import { existsSync as existsSync48, readFileSync as readFileSync33 } from "fs";
|
|
30982
|
+
import { join as join43, dirname as dirname15 } from "path";
|
|
30673
30983
|
import { homedir as homedir18 } from "os";
|
|
30674
30984
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
30675
30985
|
|
|
@@ -30831,15 +31141,15 @@ class UpdaterModule {
|
|
|
30831
31141
|
}
|
|
30832
31142
|
// src/cli/main.ts
|
|
30833
31143
|
function readVersion5() {
|
|
30834
|
-
const here =
|
|
31144
|
+
const here = dirname15(fileURLToPath6(import.meta.url));
|
|
30835
31145
|
const candidates = [
|
|
30836
|
-
|
|
30837
|
-
|
|
31146
|
+
join43(here, "..", "..", "package.json"),
|
|
31147
|
+
join43(here, "..", "package.json")
|
|
30838
31148
|
];
|
|
30839
31149
|
for (const p of candidates) {
|
|
30840
|
-
if (
|
|
31150
|
+
if (existsSync48(p)) {
|
|
30841
31151
|
try {
|
|
30842
|
-
const raw = JSON.parse(
|
|
31152
|
+
const raw = JSON.parse(readFileSync33(p, "utf8"));
|
|
30843
31153
|
if (raw.version)
|
|
30844
31154
|
return raw.version;
|
|
30845
31155
|
} catch {}
|
|
@@ -30910,15 +31220,15 @@ async function main() {
|
|
|
30910
31220
|
agent.shutdown();
|
|
30911
31221
|
process.exit(exitCode);
|
|
30912
31222
|
} else {
|
|
30913
|
-
const configPath =
|
|
30914
|
-
if (!
|
|
31223
|
+
const configPath = join43(homedir18(), ".mma", "config.json");
|
|
31224
|
+
if (!existsSync48(configPath)) {
|
|
30915
31225
|
console.log(pc2.yellow(`
|
|
30916
31226
|
` + t("cli.first_run") + `
|
|
30917
31227
|
`));
|
|
30918
31228
|
const answers = await runSetup();
|
|
30919
31229
|
const config2 = loadConfig({
|
|
30920
|
-
configDir:
|
|
30921
|
-
projectConfigPath: projectDir ?
|
|
31230
|
+
configDir: join43(homedir18(), ".mma"),
|
|
31231
|
+
projectConfigPath: projectDir ? join43(projectDir, ".mmrc") : join43(process.cwd(), ".mmrc")
|
|
30922
31232
|
});
|
|
30923
31233
|
config2.provider.type = answers.provider;
|
|
30924
31234
|
config2.provider.baseUrl = answers.apiBase;
|