micro-models-agent 0.35.1 → 0.35.4
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/bin/mma.mjs +41 -8
- package/dist/main.js +595 -435
- package/package.json +3 -3
package/dist/main.js
CHANGED
|
@@ -2096,47 +2096,55 @@ var init_config = __esm(() => {
|
|
|
2096
2096
|
command: "npx",
|
|
2097
2097
|
args: ["typescript-language-server", "--stdio"],
|
|
2098
2098
|
timeout: 20000,
|
|
2099
|
-
autoInstall: true
|
|
2099
|
+
autoInstall: true,
|
|
2100
|
+
workspaceMarkers: ["package.json", "tsconfig.json"]
|
|
2100
2101
|
},
|
|
2101
2102
|
javascript: {
|
|
2102
2103
|
command: "npx",
|
|
2103
2104
|
args: ["typescript-language-server", "--stdio"],
|
|
2104
2105
|
timeout: 15000,
|
|
2105
|
-
autoInstall: true
|
|
2106
|
+
autoInstall: true,
|
|
2107
|
+
workspaceMarkers: ["package.json", "tsconfig.json"]
|
|
2106
2108
|
},
|
|
2107
2109
|
python: {
|
|
2108
2110
|
command: "npx",
|
|
2109
2111
|
args: ["pyright", "--stdio"],
|
|
2110
2112
|
timeout: 15000,
|
|
2111
|
-
autoInstall: true
|
|
2113
|
+
autoInstall: true,
|
|
2114
|
+
workspaceMarkers: ["pyproject.toml", "setup.py", "requirements.txt"]
|
|
2112
2115
|
},
|
|
2113
2116
|
rust: {
|
|
2114
2117
|
command: "rust-analyzer",
|
|
2115
2118
|
timeout: 15000,
|
|
2116
|
-
autoInstall: false
|
|
2119
|
+
autoInstall: false,
|
|
2120
|
+
workspaceMarkers: ["Cargo.toml"]
|
|
2117
2121
|
},
|
|
2118
2122
|
go: {
|
|
2119
2123
|
command: "gopls",
|
|
2120
2124
|
timeout: 15000,
|
|
2121
|
-
autoInstall: false
|
|
2125
|
+
autoInstall: false,
|
|
2126
|
+
workspaceMarkers: ["go.mod"]
|
|
2122
2127
|
},
|
|
2123
2128
|
json: {
|
|
2124
2129
|
command: "npx",
|
|
2125
2130
|
args: ["vscode-json-languageserver", "--stdio"],
|
|
2126
2131
|
timeout: 1e4,
|
|
2127
|
-
autoInstall: true
|
|
2132
|
+
autoInstall: true,
|
|
2133
|
+
workspaceMarkers: ["package.json"]
|
|
2128
2134
|
},
|
|
2129
2135
|
html: {
|
|
2130
2136
|
command: "npx",
|
|
2131
2137
|
args: ["vscode-html-languageserver", "--stdio"],
|
|
2132
2138
|
timeout: 1e4,
|
|
2133
|
-
autoInstall: true
|
|
2139
|
+
autoInstall: true,
|
|
2140
|
+
workspaceMarkers: ["package.json"]
|
|
2134
2141
|
},
|
|
2135
2142
|
css: {
|
|
2136
2143
|
command: "npx",
|
|
2137
2144
|
args: ["vscode-css-languageserver", "--stdio"],
|
|
2138
2145
|
timeout: 1e4,
|
|
2139
|
-
autoInstall: true
|
|
2146
|
+
autoInstall: true,
|
|
2147
|
+
workspaceMarkers: ["package.json"]
|
|
2140
2148
|
}
|
|
2141
2149
|
}
|
|
2142
2150
|
};
|
|
@@ -2487,6 +2495,7 @@ Command: {command}`,
|
|
|
2487
2495
|
"verify.script_passed": "Script '{script}' passed",
|
|
2488
2496
|
"verify.script_failed": "Script '{script}' failed: {message}",
|
|
2489
2497
|
"verify.syntax_error": "Syntax error in: {path}",
|
|
2498
|
+
"lsp.unavailable": "static checks are unavailable (server not found). Verify via the project's own build/test instead.",
|
|
2490
2499
|
"cli.description": "Micro Models Agent — AI coding agent for small models",
|
|
2491
2500
|
"cli.init": "Run interactive setup wizard",
|
|
2492
2501
|
"cli.config_saved": "Configuration saved to ~/.mma/config.json",
|
|
@@ -2830,6 +2839,7 @@ Use this knowledge to answer the user's question.`,
|
|
|
2830
2839
|
"indexer.find_results": `Found {count} matching files:
|
|
2831
2840
|
{results}`,
|
|
2832
2841
|
"indexer.no_matches": 'No matching files for "{query}"',
|
|
2842
|
+
"indexer.duplicates": "Duplicate basenames (verify which file is the real source): {names}",
|
|
2833
2843
|
"indexer.stack_deps": "deps",
|
|
2834
2844
|
"indexer.stack_dev": "dev",
|
|
2835
2845
|
"indexer.stack_scripts": "scripts",
|
|
@@ -3077,6 +3087,7 @@ var init_ru = __esm(() => {
|
|
|
3077
3087
|
"verify.script_passed": "Скрипт '{script}' пройден",
|
|
3078
3088
|
"verify.script_failed": "Скрипт '{script}' не пройден: {message}",
|
|
3079
3089
|
"verify.syntax_error": "Синтаксическая ошибка в: {path}",
|
|
3090
|
+
"lsp.unavailable": "статические проверки недоступны (сервер не найден). Проверяйте через собственный build/test проекта.",
|
|
3080
3091
|
"cli.description": "Micro Models Agent — ИИ-агент для кодинга на малых моделях",
|
|
3081
3092
|
"cli.init": "Запустить мастер настройки",
|
|
3082
3093
|
"cli.config_saved": "Конфигурация сохранена в ~/.mma/config.json",
|
|
@@ -3420,6 +3431,7 @@ var init_ru = __esm(() => {
|
|
|
3420
3431
|
"indexer.find_results": `Найдено {count} совпадающих файлов:
|
|
3421
3432
|
{results}`,
|
|
3422
3433
|
"indexer.no_matches": 'Нет совпадающих файлов для "{query}"',
|
|
3434
|
+
"indexer.duplicates": "Дубликаты basename (проверьте, какой файл реально используется): {names}",
|
|
3423
3435
|
"indexer.stack_deps": "зависимости",
|
|
3424
3436
|
"indexer.stack_dev": "dev",
|
|
3425
3437
|
"indexer.stack_scripts": "скрипты",
|
|
@@ -5351,7 +5363,8 @@ class ToolRegistry {
|
|
|
5351
5363
|
return tools.map((t2) => ({
|
|
5352
5364
|
name: t2.name,
|
|
5353
5365
|
description: t2.description,
|
|
5354
|
-
parameters: t2.parameters
|
|
5366
|
+
parameters: t2.parameters,
|
|
5367
|
+
boundedOutput: t2.boundedOutput
|
|
5355
5368
|
}));
|
|
5356
5369
|
}
|
|
5357
5370
|
}
|
|
@@ -6056,6 +6069,7 @@ var init_read_file = __esm(() => {
|
|
|
6056
6069
|
name: "read_file",
|
|
6057
6070
|
description: `Read a file from the filesystem. Reads up to ${DEFAULT_LIMIT} lines at a time by default; use offset to page through large files.`,
|
|
6058
6071
|
tags: ["file", "code"],
|
|
6072
|
+
boundedOutput: true,
|
|
6059
6073
|
parameters: {
|
|
6060
6074
|
type: "object",
|
|
6061
6075
|
properties: {
|
|
@@ -6688,6 +6702,7 @@ var init_list_dir = __esm(() => {
|
|
|
6688
6702
|
name: "list_dir",
|
|
6689
6703
|
description: `List files and directories in a given path. Shows up to ${MAX_PREVIEW_LINES} entries by default.`,
|
|
6690
6704
|
tags: ["file"],
|
|
6705
|
+
boundedOutput: true,
|
|
6691
6706
|
parameters: {
|
|
6692
6707
|
type: "object",
|
|
6693
6708
|
properties: {
|
|
@@ -6932,6 +6947,7 @@ var init_file_info = __esm(() => {
|
|
|
6932
6947
|
name: "file_info",
|
|
6933
6948
|
description: "Get metadata about a file or directory (size, creation date, modification date).",
|
|
6934
6949
|
tags: ["file"],
|
|
6950
|
+
boundedOutput: true,
|
|
6935
6951
|
parameters: {
|
|
6936
6952
|
type: "object",
|
|
6937
6953
|
properties: {
|
|
@@ -7290,7 +7306,7 @@ class ProcessRegistry {
|
|
|
7290
7306
|
entry.status = "killed";
|
|
7291
7307
|
}
|
|
7292
7308
|
entry.spawnError = err.message;
|
|
7293
|
-
|
|
7309
|
+
pushLine(`[process error] ${err.message}`);
|
|
7294
7310
|
resolveExit();
|
|
7295
7311
|
});
|
|
7296
7312
|
child.on("close", (code) => {
|
|
@@ -7689,19 +7705,19 @@ ${output2}`;
|
|
|
7689
7705
|
output2 = `(exit code ${code})`;
|
|
7690
7706
|
}
|
|
7691
7707
|
if (platform2() === "win32") {
|
|
7692
|
-
const
|
|
7693
|
-
if (
|
|
7708
|
+
const originalFirstWord = originalCommand.trim().split(/\s+/)[0]?.split(/[\\/]/).pop();
|
|
7709
|
+
if (originalFirstWord && originalFirstWord in UNIX_TO_WIN_HINTS) {
|
|
7694
7710
|
if (code === 0) {
|
|
7695
|
-
FAILING_FIRST_WORDS.delete(
|
|
7711
|
+
FAILING_FIRST_WORDS.delete(originalFirstWord);
|
|
7696
7712
|
} else {
|
|
7697
|
-
const failures = (FAILING_FIRST_WORDS.get(
|
|
7698
|
-
FAILING_FIRST_WORDS.set(
|
|
7713
|
+
const failures = (FAILING_FIRST_WORDS.get(originalFirstWord) || 0) + 1;
|
|
7714
|
+
FAILING_FIRST_WORDS.set(originalFirstWord, failures);
|
|
7699
7715
|
if (failures >= HARD_BLOCK_THRESHOLD) {
|
|
7700
|
-
output2 = `STOP using "${
|
|
7716
|
+
output2 = `STOP using "${originalFirstWord}" — it does not work in this cmd.exe shell and has failed ${failures} times in a row. ${UNIX_TO_WIN_HINTS[originalFirstWord]}`;
|
|
7701
7717
|
} else {
|
|
7702
7718
|
output2 = `${output2}
|
|
7703
7719
|
|
|
7704
|
-
Hint: "${
|
|
7720
|
+
Hint: "${originalFirstWord}" may not work on Windows. ${UNIX_TO_WIN_HINTS[originalFirstWord]}`;
|
|
7705
7721
|
}
|
|
7706
7722
|
}
|
|
7707
7723
|
}
|
|
@@ -7801,6 +7817,7 @@ var init_process_log = __esm(() => {
|
|
|
7801
7817
|
name: "process_log",
|
|
7802
7818
|
description: `Show the buffered output of a background process started via bash. Shows the last ${DEFAULT_TAIL} lines by default. Use after starting a dev server to verify it came up without errors, and while it runs to check its state.`,
|
|
7803
7819
|
tags: ["shell"],
|
|
7820
|
+
boundedOutput: true,
|
|
7804
7821
|
parameters: {
|
|
7805
7822
|
type: "object",
|
|
7806
7823
|
properties: {
|
|
@@ -9941,9 +9958,31 @@ var init_moe_executor = __esm(() => {
|
|
|
9941
9958
|
];
|
|
9942
9959
|
});
|
|
9943
9960
|
|
|
9944
|
-
// src/modules/
|
|
9961
|
+
// src/modules/lsp/project-root.ts
|
|
9945
9962
|
import { existsSync as existsSync19 } from "fs";
|
|
9946
|
-
import {
|
|
9963
|
+
import { dirname as dirname6, join as join10 } from "path";
|
|
9964
|
+
function findProjectRoot(filePath, baseDir, markers) {
|
|
9965
|
+
if (!markers || markers.length === 0)
|
|
9966
|
+
return baseDir;
|
|
9967
|
+
let dir = dirname6(filePath);
|
|
9968
|
+
const root = baseDir.replace(/[\\/]+$/, "");
|
|
9969
|
+
while (true) {
|
|
9970
|
+
if (markers.some((m) => existsSync19(join10(dir, m)))) {
|
|
9971
|
+
return dir;
|
|
9972
|
+
}
|
|
9973
|
+
if (dir === root)
|
|
9974
|
+
return dir;
|
|
9975
|
+
const parent = dirname6(dir);
|
|
9976
|
+
if (parent === dir)
|
|
9977
|
+
return root;
|
|
9978
|
+
dir = parent;
|
|
9979
|
+
}
|
|
9980
|
+
}
|
|
9981
|
+
var init_project_root = () => {};
|
|
9982
|
+
|
|
9983
|
+
// src/modules/execution/verifier.ts
|
|
9984
|
+
import { existsSync as existsSync20 } from "fs";
|
|
9985
|
+
import { resolve as resolve11, extname as extname2, join as join11 } from "path";
|
|
9947
9986
|
import { spawn as spawn2 } from "child_process";
|
|
9948
9987
|
|
|
9949
9988
|
class StepVerifier {
|
|
@@ -9953,7 +9992,7 @@ class StepVerifier {
|
|
|
9953
9992
|
}
|
|
9954
9993
|
async checkFileExists(path) {
|
|
9955
9994
|
const resolved = resolve11(this.baseDir, path);
|
|
9956
|
-
const exists =
|
|
9995
|
+
const exists = existsSync20(resolved);
|
|
9957
9996
|
return {
|
|
9958
9997
|
passed: exists,
|
|
9959
9998
|
message: exists ? t("verify.file_exists", { path }) : t("verify.file_not_found", { path })
|
|
@@ -9969,7 +10008,7 @@ class StepVerifier {
|
|
|
9969
10008
|
}
|
|
9970
10009
|
async runTypeCheck() {
|
|
9971
10010
|
const tsconfigPath = resolve11(this.baseDir, "tsconfig.json");
|
|
9972
|
-
if (!
|
|
10011
|
+
if (!existsSync20(tsconfigPath)) {
|
|
9973
10012
|
return { passed: true, message: "No tsconfig.json found — skipping type check" };
|
|
9974
10013
|
}
|
|
9975
10014
|
try {
|
|
@@ -9980,9 +10019,26 @@ class StepVerifier {
|
|
|
9980
10019
|
return { passed: false, message: `TypeScript type check failed: ${stderr.slice(0, 500)}` };
|
|
9981
10020
|
}
|
|
9982
10021
|
}
|
|
10022
|
+
async runTypeCheckForFile(filePath) {
|
|
10023
|
+
const projectRoot = findProjectRoot(filePath, this.baseDir, [
|
|
10024
|
+
"tsconfig.json",
|
|
10025
|
+
"package.json"
|
|
10026
|
+
]);
|
|
10027
|
+
const tsconfigPath = join11(projectRoot, "tsconfig.json");
|
|
10028
|
+
if (!existsSync20(tsconfigPath)) {
|
|
10029
|
+
return { passed: true, message: "No tsconfig.json found — skipping type check" };
|
|
10030
|
+
}
|
|
10031
|
+
try {
|
|
10032
|
+
await this.runAsync("npx tsc --noEmit --skipLibCheck", projectRoot, 60000);
|
|
10033
|
+
return { passed: true, message: "TypeScript type check passed" };
|
|
10034
|
+
} catch (e) {
|
|
10035
|
+
const stderr = e.stderr?.toString() || e.stdout?.toString() || e.message;
|
|
10036
|
+
return { passed: false, message: `TypeScript type check failed: ${stderr.slice(0, 500)}` };
|
|
10037
|
+
}
|
|
10038
|
+
}
|
|
9983
10039
|
async runTests() {
|
|
9984
10040
|
const pkgPath = resolve11(this.baseDir, "package.json");
|
|
9985
|
-
if (!
|
|
10041
|
+
if (!existsSync20(pkgPath)) {
|
|
9986
10042
|
return { passed: true, message: "No package.json found — skipping tests" };
|
|
9987
10043
|
}
|
|
9988
10044
|
try {
|
|
@@ -10115,6 +10171,7 @@ class StepVerifier {
|
|
|
10115
10171
|
}
|
|
10116
10172
|
var init_verifier = __esm(() => {
|
|
10117
10173
|
init_i18n();
|
|
10174
|
+
init_project_root();
|
|
10118
10175
|
});
|
|
10119
10176
|
|
|
10120
10177
|
// src/core/agent-moe.ts
|
|
@@ -10231,132 +10288,7 @@ var init_agent_moe = __esm(() => {
|
|
|
10231
10288
|
init_verifier();
|
|
10232
10289
|
});
|
|
10233
10290
|
|
|
10234
|
-
// src/modules/memory/search.ts
|
|
10235
|
-
import { readFileSync as readFileSync10, existsSync as existsSync20 } from "fs";
|
|
10236
|
-
import { join as join10 } from "path";
|
|
10237
|
-
|
|
10238
|
-
class MemorySearch {
|
|
10239
|
-
memoryDir;
|
|
10240
|
-
constructor(memoryDir) {
|
|
10241
|
-
this.memoryDir = memoryDir;
|
|
10242
|
-
}
|
|
10243
|
-
query(query) {
|
|
10244
|
-
const results = [];
|
|
10245
|
-
const lowerQuery = query.toLowerCase();
|
|
10246
|
-
for (const name of MEMORY_FILES) {
|
|
10247
|
-
const path = join10(this.memoryDir, `${name}.md`);
|
|
10248
|
-
if (!existsSync20(path))
|
|
10249
|
-
continue;
|
|
10250
|
-
const content = readFileSync10(path, "utf-8");
|
|
10251
|
-
const lines = content.split(`
|
|
10252
|
-
`);
|
|
10253
|
-
for (const line of lines) {
|
|
10254
|
-
if (line.toLowerCase().includes(lowerQuery)) {
|
|
10255
|
-
results.push({ file: name, match: line.trim() });
|
|
10256
|
-
}
|
|
10257
|
-
}
|
|
10258
|
-
}
|
|
10259
|
-
const prefsPath = join10(this.memoryDir, "preferences.json");
|
|
10260
|
-
if (existsSync20(prefsPath)) {
|
|
10261
|
-
try {
|
|
10262
|
-
const prefs = JSON.parse(readFileSync10(prefsPath, "utf-8"));
|
|
10263
|
-
for (const [key, value] of Object.entries(prefs)) {
|
|
10264
|
-
const searchStr = `${key}=${value}`;
|
|
10265
|
-
if (searchStr.toLowerCase().includes(lowerQuery)) {
|
|
10266
|
-
results.push({ file: "preferences", match: `${key} = ${value}` });
|
|
10267
|
-
}
|
|
10268
|
-
}
|
|
10269
|
-
} catch {}
|
|
10270
|
-
}
|
|
10271
|
-
return results;
|
|
10272
|
-
}
|
|
10273
|
-
}
|
|
10274
|
-
var MEMORY_FILES;
|
|
10275
|
-
var init_search = __esm(() => {
|
|
10276
|
-
MEMORY_FILES = ["conventions", "decisions", "errors", "facts"];
|
|
10277
|
-
});
|
|
10278
|
-
|
|
10279
|
-
// src/modules/memory/store.ts
|
|
10280
|
-
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, appendFileSync as appendFileSync5, existsSync as existsSync21, mkdirSync as mkdirSync12 } from "fs";
|
|
10281
|
-
import { join as join11 } from "path";
|
|
10282
|
-
|
|
10283
|
-
class MemoryStore {
|
|
10284
|
-
memoryDir;
|
|
10285
|
-
constructor(memoryDir) {
|
|
10286
|
-
this.memoryDir = memoryDir;
|
|
10287
|
-
this.ensureDir();
|
|
10288
|
-
for (const name of MEMORY_FILES2) {
|
|
10289
|
-
const path = join11(this.memoryDir, `${name}.md`);
|
|
10290
|
-
if (!existsSync21(path)) {
|
|
10291
|
-
writeFileSync8(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
10292
|
-
|
|
10293
|
-
`, "utf-8");
|
|
10294
|
-
}
|
|
10295
|
-
}
|
|
10296
|
-
}
|
|
10297
|
-
ensureDir() {
|
|
10298
|
-
if (!existsSync21(this.memoryDir)) {
|
|
10299
|
-
mkdirSync12(this.memoryDir, { recursive: true });
|
|
10300
|
-
}
|
|
10301
|
-
}
|
|
10302
|
-
read(name) {
|
|
10303
|
-
const path = join11(this.memoryDir, `${name}.md`);
|
|
10304
|
-
if (!existsSync21(path))
|
|
10305
|
-
return "";
|
|
10306
|
-
return readFileSync11(path, "utf-8");
|
|
10307
|
-
}
|
|
10308
|
-
append(name, entry) {
|
|
10309
|
-
const path = join11(this.memoryDir, `${name}.md`);
|
|
10310
|
-
const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
10311
|
-
const formatted = `- **${timestamp}** — ${entry}
|
|
10312
|
-
`;
|
|
10313
|
-
appendFileSync5(path, formatted, "utf-8");
|
|
10314
|
-
}
|
|
10315
|
-
search(query) {
|
|
10316
|
-
const searchModule = new MemorySearch(this.memoryDir);
|
|
10317
|
-
return searchModule.query(query);
|
|
10318
|
-
}
|
|
10319
|
-
prefsPath() {
|
|
10320
|
-
return join11(this.memoryDir, "preferences.json");
|
|
10321
|
-
}
|
|
10322
|
-
getPreferences() {
|
|
10323
|
-
const path = this.prefsPath();
|
|
10324
|
-
if (!existsSync21(path))
|
|
10325
|
-
return {};
|
|
10326
|
-
try {
|
|
10327
|
-
return JSON.parse(readFileSync11(path, "utf-8"));
|
|
10328
|
-
} catch {
|
|
10329
|
-
return {};
|
|
10330
|
-
}
|
|
10331
|
-
}
|
|
10332
|
-
setPreference(key, value) {
|
|
10333
|
-
const prefs = this.getPreferences();
|
|
10334
|
-
prefs[key] = value;
|
|
10335
|
-
writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
10336
|
-
}
|
|
10337
|
-
deletePreference(key) {
|
|
10338
|
-
const prefs = this.getPreferences();
|
|
10339
|
-
if (!(key in prefs))
|
|
10340
|
-
return false;
|
|
10341
|
-
delete prefs[key];
|
|
10342
|
-
writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
10343
|
-
return true;
|
|
10344
|
-
}
|
|
10345
|
-
appendRule(category, pattern, cause, solution) {
|
|
10346
|
-
const entry = `**pattern:** ${pattern}
|
|
10347
|
-
**cause:** ${cause}
|
|
10348
|
-
**solution:** ${solution}`;
|
|
10349
|
-
this.append(category, entry);
|
|
10350
|
-
}
|
|
10351
|
-
}
|
|
10352
|
-
var MEMORY_FILES2;
|
|
10353
|
-
var init_store2 = __esm(() => {
|
|
10354
|
-
init_search();
|
|
10355
|
-
MEMORY_FILES2 = ["conventions", "decisions", "errors", "facts"];
|
|
10356
|
-
});
|
|
10357
|
-
|
|
10358
10291
|
// src/core/agent.ts
|
|
10359
|
-
import { join as join12 } from "path";
|
|
10360
10292
|
function isToolCallJson(text) {
|
|
10361
10293
|
const trimmed = text.trim();
|
|
10362
10294
|
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
@@ -10369,6 +10301,12 @@ function isToolCallJson(text) {
|
|
|
10369
10301
|
}
|
|
10370
10302
|
return false;
|
|
10371
10303
|
}
|
|
10304
|
+
function toolOutputCharLimit(remainingBudget, historyBudget, bounded) {
|
|
10305
|
+
if (bounded)
|
|
10306
|
+
return Number.MAX_SAFE_INTEGER;
|
|
10307
|
+
const maxCharsByRatio = Math.floor(historyBudget * TOOL_RESULT_MAX_TOKENS_RATIO * 2);
|
|
10308
|
+
return Math.min(remainingBudget, maxCharsByRatio, TOOL_RESULT_ABSOLUTE_MAX_CHARS);
|
|
10309
|
+
}
|
|
10372
10310
|
|
|
10373
10311
|
class Agent {
|
|
10374
10312
|
deps;
|
|
@@ -10432,11 +10370,9 @@ class Agent {
|
|
|
10432
10370
|
this.deps.contextManager.updateSystemPrompt?.(prompt);
|
|
10433
10371
|
}
|
|
10434
10372
|
}
|
|
10435
|
-
truncateToolOutput(output, budget, currentTokens) {
|
|
10436
|
-
const remainingBudget = budget.history - currentTokens;
|
|
10437
|
-
const
|
|
10438
|
-
const maxCharsByRatio = Math.floor(budget.history * TOOL_RESULT_MAX_TOKENS_RATIO * 2);
|
|
10439
|
-
const maxChars = Math.min(maxCharsByBudget, maxCharsByRatio, TOOL_RESULT_ABSOLUTE_MAX_CHARS);
|
|
10373
|
+
truncateToolOutput(output, budget, currentTokens, bounded) {
|
|
10374
|
+
const remainingBudget = Math.max(0, budget.history - currentTokens);
|
|
10375
|
+
const maxChars = toolOutputCharLimit(remainingBudget, budget.history, bounded);
|
|
10440
10376
|
if (output.length <= maxChars)
|
|
10441
10377
|
return output;
|
|
10442
10378
|
const truncated = output.slice(0, maxChars);
|
|
@@ -10546,6 +10482,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10546
10482
|
let repeatedToolCount = 0;
|
|
10547
10483
|
const MAX_REPEATED_TOOL_CALLS = 2;
|
|
10548
10484
|
const allToolsForBudget = toolExecutor.getToolDefinitions(this.deps.toolTags);
|
|
10485
|
+
const boundedToolNames = new Set(allToolsForBudget.filter((t2) => t2.boundedOutput).map((t2) => t2.name));
|
|
10549
10486
|
const toolTokenEstimate = allToolsForBudget.reduce((sum, t2) => sum + Math.ceil((t2.description.length + JSON.stringify(t2.parameters).length) / 4), 0);
|
|
10550
10487
|
contextManager.setToolTokens(toolTokenEstimate);
|
|
10551
10488
|
while (iteration < config.maxToolIterations && !this.shutdownRequested) {
|
|
@@ -10748,7 +10685,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10748
10685
|
}
|
|
10749
10686
|
const currentTokens2 = contextManager.getEstimatedTokens();
|
|
10750
10687
|
const budget3 = contextManager.getBudget();
|
|
10751
|
-
const truncatedOutput = this.truncateToolOutput(result.output, budget3, currentTokens2);
|
|
10688
|
+
const truncatedOutput = this.truncateToolOutput(result.output, budget3, currentTokens2, boundedToolNames.has(call.name));
|
|
10752
10689
|
contextManager.addMessage({
|
|
10753
10690
|
role: "tool",
|
|
10754
10691
|
content: truncatedOutput,
|
|
@@ -10782,14 +10719,10 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10782
10719
|
toolFailureCounts.set(key, prev);
|
|
10783
10720
|
if (prev.count >= MIN_REPEATED_TOOL_FAILURES && !memoryRuleRecorded.has(key)) {
|
|
10784
10721
|
memoryRuleRecorded.add(key);
|
|
10785
|
-
|
|
10786
|
-
|
|
10787
|
-
|
|
10788
|
-
|
|
10789
|
-
const memStore = new MemoryStore(memDir);
|
|
10790
|
-
memStore.appendRule("errors", `Tool ${key} failed ${prev.count}x (${prev.error})`, `Repeated ${key} failures suggest a systemic problem (config, environment, or a broken tool), not a one-off`, "Check the error message, verify the tool's dependencies are installed/configured, and consider a different tool");
|
|
10791
|
-
logger.warn(`Recorded repeated ${key} failures to memory (${prev.count}x)`);
|
|
10792
|
-
}
|
|
10722
|
+
const memStore = this.deps.memoryStore;
|
|
10723
|
+
if (memStore) {
|
|
10724
|
+
memStore.appendRule("errors", `Tool ${key} failed ${prev.count}x (${prev.error})`, `Repeated ${key} failures suggest a systemic problem (config, environment, or a broken tool), not a one-off`, "Check the error message, verify the tool's dependencies are installed/configured, and consider a different tool");
|
|
10725
|
+
logger.warn(`Recorded repeated ${key} failures to memory (${prev.count}x)`);
|
|
10793
10726
|
}
|
|
10794
10727
|
}
|
|
10795
10728
|
}
|
|
@@ -10811,13 +10744,9 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
10811
10744
|
content: `<system-summary>${recoveryMsg}
|
|
10812
10745
|
${taskReminder}</system-summary>`
|
|
10813
10746
|
});
|
|
10814
|
-
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
const memDir = join12(baseDir, ".mma", "memory");
|
|
10818
|
-
const memStore = new MemoryStore(memDir);
|
|
10819
|
-
memStore.appendRule("errors", `${consecutiveToolFailures} consecutive tool failures`, "Multiple tools failing suggests environment or configuration issue", "Check dependencies, verify file paths, try write_file directly instead of shell commands");
|
|
10820
|
-
}
|
|
10747
|
+
const memStore = this.deps.memoryStore;
|
|
10748
|
+
if (memStore) {
|
|
10749
|
+
memStore.appendRule("errors", `${consecutiveToolFailures} consecutive tool failures`, "Multiple tools failing suggests environment or configuration issue", "Check dependencies, verify file paths, try write_file directly instead of shell commands");
|
|
10821
10750
|
}
|
|
10822
10751
|
}
|
|
10823
10752
|
contextManager.addMessage({
|
|
@@ -11077,7 +11006,6 @@ var init_agent = __esm(() => {
|
|
|
11077
11006
|
init_processes();
|
|
11078
11007
|
init_session_logger();
|
|
11079
11008
|
init_agent_moe();
|
|
11080
|
-
init_store2();
|
|
11081
11009
|
init_verifier();
|
|
11082
11010
|
});
|
|
11083
11011
|
|
|
@@ -11705,8 +11633,8 @@ var init_js_identifiers = __esm(() => {
|
|
|
11705
11633
|
});
|
|
11706
11634
|
|
|
11707
11635
|
// src/modules/hallucination/factual.ts
|
|
11708
|
-
import { existsSync as
|
|
11709
|
-
import { resolve as resolve12, isAbsolute as isAbsolute2, join as
|
|
11636
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5 } from "fs";
|
|
11637
|
+
import { resolve as resolve12, isAbsolute as isAbsolute2, join as join12 } from "path";
|
|
11710
11638
|
|
|
11711
11639
|
class FactualCheck {
|
|
11712
11640
|
baseDir;
|
|
@@ -11741,14 +11669,14 @@ class FactualCheck {
|
|
|
11741
11669
|
}
|
|
11742
11670
|
pathExists(fp) {
|
|
11743
11671
|
if (isAbsolute2(fp))
|
|
11744
|
-
return
|
|
11672
|
+
return existsSync21(fp);
|
|
11745
11673
|
if (!fp.includes("/") && !fp.includes("\\")) {
|
|
11746
11674
|
return this.bareNameExists(fp);
|
|
11747
11675
|
}
|
|
11748
|
-
return
|
|
11676
|
+
return existsSync21(resolve12(this.baseDir, fp));
|
|
11749
11677
|
}
|
|
11750
11678
|
bareNameExists(name) {
|
|
11751
|
-
if (
|
|
11679
|
+
if (existsSync21(resolve12(this.baseDir, name)))
|
|
11752
11680
|
return true;
|
|
11753
11681
|
if (this.indexHas(name))
|
|
11754
11682
|
return true;
|
|
@@ -11788,7 +11716,7 @@ class FactualCheck {
|
|
|
11788
11716
|
for (const entry of entries) {
|
|
11789
11717
|
if (count >= FactualCheck.MAX_INDEXED_FILES)
|
|
11790
11718
|
break;
|
|
11791
|
-
const full =
|
|
11719
|
+
const full = join12(dir, entry.name);
|
|
11792
11720
|
if (entry.isDirectory()) {
|
|
11793
11721
|
if (!IGNORED_DIRS.has(entry.name)) {
|
|
11794
11722
|
count = this.scanDir(full, index, count);
|
|
@@ -12418,7 +12346,7 @@ ${joined}` }
|
|
|
12418
12346
|
var DEFAULT_CHUNK_SYSTEM_PROMPT = 'Answer the query using ONLY the provided text. Be concise. If the text does not contain the answer, say "NO_EVIDENCE".', DEFAULT_SYNTHESIS_SYSTEM_PROMPT = "You are given a query and per-chunk answers over a large text. Produce the final answer to the query, combining evidence from the chunks. If no chunk had evidence, say so.";
|
|
12419
12347
|
|
|
12420
12348
|
// src/tools/chunk-query.ts
|
|
12421
|
-
import { readFileSync as
|
|
12349
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
12422
12350
|
import { resolve as resolve14 } from "node:path";
|
|
12423
12351
|
var chunkQueryTool;
|
|
12424
12352
|
var init_chunk_query = __esm(() => {
|
|
@@ -12487,7 +12415,7 @@ var init_chunk_query = __esm(() => {
|
|
|
12487
12415
|
return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
|
|
12488
12416
|
}
|
|
12489
12417
|
try {
|
|
12490
|
-
content =
|
|
12418
|
+
content = readFileSync10(resolve14(ctx.baseDir, inputPath), "utf8");
|
|
12491
12419
|
} catch (e) {
|
|
12492
12420
|
return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
|
|
12493
12421
|
}
|
|
@@ -12836,8 +12764,8 @@ var init_web_browse = __esm(() => {
|
|
|
12836
12764
|
});
|
|
12837
12765
|
|
|
12838
12766
|
// src/tools/download-file.ts
|
|
12839
|
-
import { writeFileSync as
|
|
12840
|
-
import { dirname as
|
|
12767
|
+
import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync12 } from "fs";
|
|
12768
|
+
import { dirname as dirname8 } from "path";
|
|
12841
12769
|
var MAX_DOWNLOAD_BYTES, downloadFileTool;
|
|
12842
12770
|
var init_download_file = __esm(() => {
|
|
12843
12771
|
init_i18n();
|
|
@@ -12924,8 +12852,8 @@ var init_download_file = __esm(() => {
|
|
|
12924
12852
|
output: t("tool.download_too_large", { max: String(maxBytes) })
|
|
12925
12853
|
};
|
|
12926
12854
|
}
|
|
12927
|
-
|
|
12928
|
-
|
|
12855
|
+
mkdirSync12(dirname8(resolved), { recursive: true });
|
|
12856
|
+
writeFileSync8(resolved, buffer);
|
|
12929
12857
|
const contentType = response.headers.get("content-type")?.split(";")[0]?.trim() || "unknown";
|
|
12930
12858
|
logNetworkRequest(ctx.sessionId, sanitizeUrl(url), true, `Status: ${response.status}`);
|
|
12931
12859
|
logFileWrite(ctx.sessionId, resolved, true, `Downloaded ${buffer.byteLength} bytes`);
|
|
@@ -13760,7 +13688,7 @@ ${JSON.stringify(result, null, 2)}`
|
|
|
13760
13688
|
|
|
13761
13689
|
// src/tools/search-history.ts
|
|
13762
13690
|
import * as fs from "fs";
|
|
13763
|
-
import { join as
|
|
13691
|
+
import { join as join13 } from "path";
|
|
13764
13692
|
import { homedir as homedir5 } from "os";
|
|
13765
13693
|
function searchFile(filePath, query, maxResults, results) {
|
|
13766
13694
|
if (!fs.existsSync(filePath))
|
|
@@ -13804,7 +13732,7 @@ var init_search_history = __esm(() => {
|
|
|
13804
13732
|
const query = String(args.query || "").toLowerCase();
|
|
13805
13733
|
const maxResults = Number(args.maxResults) || 5;
|
|
13806
13734
|
const sessionId = args.sessionId ? String(args.sessionId) : null;
|
|
13807
|
-
const sessionDir =
|
|
13735
|
+
const sessionDir = join13(homedir5(), ".mma", "sessions");
|
|
13808
13736
|
const results = [];
|
|
13809
13737
|
try {
|
|
13810
13738
|
if (!fs.existsSync(sessionDir)) {
|
|
@@ -13819,7 +13747,7 @@ var init_search_history = __esm(() => {
|
|
|
13819
13747
|
continue;
|
|
13820
13748
|
if (sessionId && entry.name !== sessionId)
|
|
13821
13749
|
continue;
|
|
13822
|
-
const historyFile =
|
|
13750
|
+
const historyFile = join13(sessionDir, entry.name, "history.jsonl");
|
|
13823
13751
|
searchFile(historyFile, query, maxResults, results);
|
|
13824
13752
|
if (results.length >= maxResults)
|
|
13825
13753
|
break;
|
|
@@ -13845,9 +13773,133 @@ var init_search_history = __esm(() => {
|
|
|
13845
13773
|
};
|
|
13846
13774
|
});
|
|
13847
13775
|
|
|
13776
|
+
// src/modules/memory/search.ts
|
|
13777
|
+
import { readFileSync as readFileSync12, existsSync as existsSync23 } from "fs";
|
|
13778
|
+
import { join as join14 } from "path";
|
|
13779
|
+
|
|
13780
|
+
class MemorySearch {
|
|
13781
|
+
memoryDir;
|
|
13782
|
+
constructor(memoryDir) {
|
|
13783
|
+
this.memoryDir = memoryDir;
|
|
13784
|
+
}
|
|
13785
|
+
query(query) {
|
|
13786
|
+
const results = [];
|
|
13787
|
+
const lowerQuery = query.toLowerCase();
|
|
13788
|
+
for (const name of MEMORY_FILES) {
|
|
13789
|
+
const path = join14(this.memoryDir, `${name}.md`);
|
|
13790
|
+
if (!existsSync23(path))
|
|
13791
|
+
continue;
|
|
13792
|
+
const content = readFileSync12(path, "utf-8");
|
|
13793
|
+
const lines = content.split(`
|
|
13794
|
+
`);
|
|
13795
|
+
for (const line of lines) {
|
|
13796
|
+
if (line.toLowerCase().includes(lowerQuery)) {
|
|
13797
|
+
results.push({ file: name, match: line.trim() });
|
|
13798
|
+
}
|
|
13799
|
+
}
|
|
13800
|
+
}
|
|
13801
|
+
const prefsPath = join14(this.memoryDir, "preferences.json");
|
|
13802
|
+
if (existsSync23(prefsPath)) {
|
|
13803
|
+
try {
|
|
13804
|
+
const prefs = JSON.parse(readFileSync12(prefsPath, "utf-8"));
|
|
13805
|
+
for (const [key, value] of Object.entries(prefs)) {
|
|
13806
|
+
const searchStr = `${key}=${value}`;
|
|
13807
|
+
if (searchStr.toLowerCase().includes(lowerQuery)) {
|
|
13808
|
+
results.push({ file: "preferences", match: `${key} = ${value}` });
|
|
13809
|
+
}
|
|
13810
|
+
}
|
|
13811
|
+
} catch {}
|
|
13812
|
+
}
|
|
13813
|
+
return results;
|
|
13814
|
+
}
|
|
13815
|
+
}
|
|
13816
|
+
var MEMORY_FILES;
|
|
13817
|
+
var init_search = __esm(() => {
|
|
13818
|
+
MEMORY_FILES = ["conventions", "decisions", "errors", "facts"];
|
|
13819
|
+
});
|
|
13820
|
+
|
|
13821
|
+
// src/modules/memory/store.ts
|
|
13822
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, appendFileSync as appendFileSync5, existsSync as existsSync24, mkdirSync as mkdirSync13 } from "fs";
|
|
13823
|
+
import { join as join15 } from "path";
|
|
13824
|
+
|
|
13825
|
+
class MemoryStore {
|
|
13826
|
+
memoryDir;
|
|
13827
|
+
constructor(memoryDir) {
|
|
13828
|
+
this.memoryDir = memoryDir;
|
|
13829
|
+
this.ensureDir();
|
|
13830
|
+
for (const name of MEMORY_FILES2) {
|
|
13831
|
+
const path = join15(this.memoryDir, `${name}.md`);
|
|
13832
|
+
if (!existsSync24(path)) {
|
|
13833
|
+
writeFileSync9(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
13834
|
+
|
|
13835
|
+
`, "utf-8");
|
|
13836
|
+
}
|
|
13837
|
+
}
|
|
13838
|
+
}
|
|
13839
|
+
ensureDir() {
|
|
13840
|
+
if (!existsSync24(this.memoryDir)) {
|
|
13841
|
+
mkdirSync13(this.memoryDir, { recursive: true });
|
|
13842
|
+
}
|
|
13843
|
+
}
|
|
13844
|
+
read(name) {
|
|
13845
|
+
const path = join15(this.memoryDir, `${name}.md`);
|
|
13846
|
+
if (!existsSync24(path))
|
|
13847
|
+
return "";
|
|
13848
|
+
return readFileSync13(path, "utf-8");
|
|
13849
|
+
}
|
|
13850
|
+
append(name, entry) {
|
|
13851
|
+
const path = join15(this.memoryDir, `${name}.md`);
|
|
13852
|
+
const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
13853
|
+
const formatted = `- **${timestamp}** — ${entry}
|
|
13854
|
+
`;
|
|
13855
|
+
appendFileSync5(path, formatted, "utf-8");
|
|
13856
|
+
}
|
|
13857
|
+
search(query) {
|
|
13858
|
+
const searchModule = new MemorySearch(this.memoryDir);
|
|
13859
|
+
return searchModule.query(query);
|
|
13860
|
+
}
|
|
13861
|
+
prefsPath() {
|
|
13862
|
+
return join15(this.memoryDir, "preferences.json");
|
|
13863
|
+
}
|
|
13864
|
+
getPreferences() {
|
|
13865
|
+
const path = this.prefsPath();
|
|
13866
|
+
if (!existsSync24(path))
|
|
13867
|
+
return {};
|
|
13868
|
+
try {
|
|
13869
|
+
return JSON.parse(readFileSync13(path, "utf-8"));
|
|
13870
|
+
} catch {
|
|
13871
|
+
return {};
|
|
13872
|
+
}
|
|
13873
|
+
}
|
|
13874
|
+
setPreference(key, value) {
|
|
13875
|
+
const prefs = this.getPreferences();
|
|
13876
|
+
prefs[key] = value;
|
|
13877
|
+
writeFileSync9(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
13878
|
+
}
|
|
13879
|
+
deletePreference(key) {
|
|
13880
|
+
const prefs = this.getPreferences();
|
|
13881
|
+
if (!(key in prefs))
|
|
13882
|
+
return false;
|
|
13883
|
+
delete prefs[key];
|
|
13884
|
+
writeFileSync9(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
13885
|
+
return true;
|
|
13886
|
+
}
|
|
13887
|
+
appendRule(category, pattern, cause, solution) {
|
|
13888
|
+
const entry = `**pattern:** ${pattern}
|
|
13889
|
+
**cause:** ${cause}
|
|
13890
|
+
**solution:** ${solution}`;
|
|
13891
|
+
this.append(category, entry);
|
|
13892
|
+
}
|
|
13893
|
+
}
|
|
13894
|
+
var MEMORY_FILES2;
|
|
13895
|
+
var init_store2 = __esm(() => {
|
|
13896
|
+
init_search();
|
|
13897
|
+
MEMORY_FILES2 = ["conventions", "decisions", "errors", "facts"];
|
|
13898
|
+
});
|
|
13899
|
+
|
|
13848
13900
|
// src/tools/remember.ts
|
|
13849
13901
|
import { homedir as homedir6 } from "os";
|
|
13850
|
-
import { join as
|
|
13902
|
+
import { join as join16 } from "path";
|
|
13851
13903
|
var CATEGORIES, rememberTool;
|
|
13852
13904
|
var init_remember = __esm(() => {
|
|
13853
13905
|
init_i18n();
|
|
@@ -13885,7 +13937,7 @@ var init_remember = __esm(() => {
|
|
|
13885
13937
|
if (!CATEGORIES.includes(category)) {
|
|
13886
13938
|
return { success: false, output: t("tool.invalid_params") };
|
|
13887
13939
|
}
|
|
13888
|
-
const memoryDir =
|
|
13940
|
+
const memoryDir = join16(homedir6(), ".mma", "memory");
|
|
13889
13941
|
const store = new MemoryStore(memoryDir);
|
|
13890
13942
|
try {
|
|
13891
13943
|
if (category === "preferences") {
|
|
@@ -13918,7 +13970,7 @@ var init_remember = __esm(() => {
|
|
|
13918
13970
|
|
|
13919
13971
|
// src/tools/recall.ts
|
|
13920
13972
|
import { homedir as homedir7 } from "os";
|
|
13921
|
-
import { join as
|
|
13973
|
+
import { join as join17 } from "path";
|
|
13922
13974
|
function formatAll(store) {
|
|
13923
13975
|
const parts = [];
|
|
13924
13976
|
const prefs = store.getPreferences();
|
|
@@ -14001,7 +14053,7 @@ var init_recall = __esm(() => {
|
|
|
14001
14053
|
handler: async (_ctx, args) => {
|
|
14002
14054
|
const query = args.query ? String(args.query) : "";
|
|
14003
14055
|
const category = args.category ? String(args.category) : "";
|
|
14004
|
-
const memoryDir =
|
|
14056
|
+
const memoryDir = join17(homedir7(), ".mma", "memory");
|
|
14005
14057
|
const store = new MemoryStore(memoryDir);
|
|
14006
14058
|
try {
|
|
14007
14059
|
if (!query && !category) {
|
|
@@ -14039,10 +14091,10 @@ __export(exports_bridge_client, {
|
|
|
14039
14091
|
});
|
|
14040
14092
|
import { spawn as spawn4 } from "child_process";
|
|
14041
14093
|
import { createInterface } from "readline";
|
|
14042
|
-
import { dirname as
|
|
14094
|
+
import { dirname as dirname9, join as join18 } from "path";
|
|
14043
14095
|
import { fileURLToPath } from "url";
|
|
14044
14096
|
function bridgeScriptPath() {
|
|
14045
|
-
return
|
|
14097
|
+
return join18(dirname9(fileURLToPath(import.meta.url)), "bridge-server.mjs");
|
|
14046
14098
|
}
|
|
14047
14099
|
|
|
14048
14100
|
class BridgeDriver {
|
|
@@ -14578,15 +14630,15 @@ function buildTextExtractionScript() {
|
|
|
14578
14630
|
|
|
14579
14631
|
// src/modules/browser/cookie-store.ts
|
|
14580
14632
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
14581
|
-
import { join as
|
|
14633
|
+
import { join as join19 } from "path";
|
|
14582
14634
|
|
|
14583
14635
|
class CookieStore {
|
|
14584
14636
|
filePath;
|
|
14585
14637
|
constructor(cookieDir) {
|
|
14586
|
-
this.filePath =
|
|
14638
|
+
this.filePath = join19(cookieDir, "cookies.json");
|
|
14587
14639
|
}
|
|
14588
14640
|
async save(cookies) {
|
|
14589
|
-
await mkdir(
|
|
14641
|
+
await mkdir(join19(this.filePath, ".."), { recursive: true });
|
|
14590
14642
|
await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
|
|
14591
14643
|
}
|
|
14592
14644
|
async load() {
|
|
@@ -14941,10 +14993,10 @@ var init_session = __esm(() => {
|
|
|
14941
14993
|
});
|
|
14942
14994
|
|
|
14943
14995
|
// src/tools/browser.ts
|
|
14944
|
-
import { join as
|
|
14996
|
+
import { join as join20 } from "path";
|
|
14945
14997
|
function getSession(ctx) {
|
|
14946
14998
|
if (!session) {
|
|
14947
|
-
const cookieDir =
|
|
14999
|
+
const cookieDir = join20(ctx.baseDir, ".mma", "browser");
|
|
14948
15000
|
session = new BrowserSession({
|
|
14949
15001
|
...DEFAULT_BROWSER_CONFIG,
|
|
14950
15002
|
headless: ctx.config.browser?.headless ?? true,
|
|
@@ -15080,8 +15132,8 @@ async function readClipboardFallback() {
|
|
|
15080
15132
|
const { platform: platform3 } = await import("os");
|
|
15081
15133
|
const { execSync } = await import("child_process");
|
|
15082
15134
|
const { readFileSync: readFileSync15, unlinkSync: unlinkSync4 } = await import("fs");
|
|
15083
|
-
const { join:
|
|
15084
|
-
const tmpPath =
|
|
15135
|
+
const { join: join21 } = await import("path");
|
|
15136
|
+
const tmpPath = join21(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
15085
15137
|
try {
|
|
15086
15138
|
if (platform3() === "linux") {
|
|
15087
15139
|
execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
|
|
@@ -15159,7 +15211,7 @@ var init_image_utils = __esm(() => {
|
|
|
15159
15211
|
});
|
|
15160
15212
|
|
|
15161
15213
|
// src/tools/attach-image.ts
|
|
15162
|
-
import { existsSync as
|
|
15214
|
+
import { existsSync as existsSync25 } from "fs";
|
|
15163
15215
|
import { resolve as resolve15 } from "path";
|
|
15164
15216
|
var attachImageTool;
|
|
15165
15217
|
var init_attach_image = __esm(() => {
|
|
@@ -15202,7 +15254,7 @@ var init_attach_image = __esm(() => {
|
|
|
15202
15254
|
dataUrl = result.dataUrl;
|
|
15203
15255
|
} else {
|
|
15204
15256
|
const absPath = resolve15(ctx.baseDir, source);
|
|
15205
|
-
if (!
|
|
15257
|
+
if (!existsSync25(absPath)) {
|
|
15206
15258
|
return {
|
|
15207
15259
|
success: false,
|
|
15208
15260
|
output: t("image.not_found", { path: source })
|
|
@@ -15364,16 +15416,16 @@ class ModuleRegistry {
|
|
|
15364
15416
|
}
|
|
15365
15417
|
|
|
15366
15418
|
// src/modules/plugins/loader.ts
|
|
15367
|
-
import { readdirSync as readdirSync7, existsSync as
|
|
15368
|
-
import { join as
|
|
15419
|
+
import { readdirSync as readdirSync7, existsSync as existsSync26, statSync as statSync5 } from "fs";
|
|
15420
|
+
import { join as join21 } from "path";
|
|
15369
15421
|
|
|
15370
15422
|
class PluginLoader {
|
|
15371
15423
|
loadFromDir(dirPath, pluginManager, logger) {
|
|
15372
|
-
if (!
|
|
15424
|
+
if (!existsSync26(dirPath))
|
|
15373
15425
|
return;
|
|
15374
15426
|
const entries = readdirSync7(dirPath);
|
|
15375
15427
|
for (const entry of entries) {
|
|
15376
|
-
const fullPath =
|
|
15428
|
+
const fullPath = join21(dirPath, entry);
|
|
15377
15429
|
if (!statSync5(fullPath).isFile())
|
|
15378
15430
|
continue;
|
|
15379
15431
|
if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
|
|
@@ -15397,8 +15449,8 @@ var init_loader = __esm(() => {
|
|
|
15397
15449
|
|
|
15398
15450
|
// src/modules/plugins/builtin/lint-on-write.ts
|
|
15399
15451
|
import { spawn as spawn5, execSync } from "child_process";
|
|
15400
|
-
import { existsSync as
|
|
15401
|
-
import { resolve as resolve16, extname as extname4, join as
|
|
15452
|
+
import { existsSync as existsSync27, readFileSync as readFileSync15 } from "fs";
|
|
15453
|
+
import { resolve as resolve16, extname as extname4, join as join22 } from "path";
|
|
15402
15454
|
import { platform as platform3 } from "os";
|
|
15403
15455
|
function contentHash(content) {
|
|
15404
15456
|
let h = 5381;
|
|
@@ -15444,7 +15496,7 @@ class LintOnWritePlugin {
|
|
|
15444
15496
|
if (!path)
|
|
15445
15497
|
return;
|
|
15446
15498
|
const fullPath = resolve16(ctx.baseDir, path);
|
|
15447
|
-
if (!
|
|
15499
|
+
if (!existsSync27(fullPath))
|
|
15448
15500
|
return;
|
|
15449
15501
|
const ext = extname4(fullPath);
|
|
15450
15502
|
const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir);
|
|
@@ -15455,7 +15507,7 @@ class LintOnWritePlugin {
|
|
|
15455
15507
|
return;
|
|
15456
15508
|
}
|
|
15457
15509
|
await this.runProjectLint(ctx, result);
|
|
15458
|
-
await this.runProjectTypeCheck(ctx, result);
|
|
15510
|
+
await this.runProjectTypeCheck(fullPath, ctx.baseDir, result);
|
|
15459
15511
|
}
|
|
15460
15512
|
async checkSyntax(filePath, ext, baseDir) {
|
|
15461
15513
|
if (ext === ".ts" || ext === ".tsx") {
|
|
@@ -15500,8 +15552,8 @@ class LintOnWritePlugin {
|
|
|
15500
15552
|
}
|
|
15501
15553
|
async runProjectLint(ctx, result) {
|
|
15502
15554
|
try {
|
|
15503
|
-
const packageJsonPath =
|
|
15504
|
-
if (!
|
|
15555
|
+
const packageJsonPath = join22(ctx.baseDir, "package.json");
|
|
15556
|
+
if (!existsSync27(packageJsonPath)) {
|
|
15505
15557
|
return;
|
|
15506
15558
|
}
|
|
15507
15559
|
const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
|
|
@@ -15519,9 +15571,13 @@ class LintOnWritePlugin {
|
|
|
15519
15571
|
[Project lint failed]: ${err.message}`;
|
|
15520
15572
|
}
|
|
15521
15573
|
}
|
|
15522
|
-
async runProjectTypeCheck(
|
|
15523
|
-
const
|
|
15524
|
-
|
|
15574
|
+
async runProjectTypeCheck(filePath, baseDir, result) {
|
|
15575
|
+
const projectRoot = findProjectRoot(filePath, baseDir, [
|
|
15576
|
+
"tsconfig.json",
|
|
15577
|
+
"package.json"
|
|
15578
|
+
]);
|
|
15579
|
+
const tsconfigPath = join22(projectRoot, "tsconfig.json");
|
|
15580
|
+
if (!existsSync27(tsconfigPath)) {
|
|
15525
15581
|
return;
|
|
15526
15582
|
}
|
|
15527
15583
|
const now = Date.now();
|
|
@@ -15535,7 +15591,7 @@ class LintOnWritePlugin {
|
|
|
15535
15591
|
return;
|
|
15536
15592
|
}
|
|
15537
15593
|
this._checkTimestamp = now;
|
|
15538
|
-
this._checkPromise = this.runTscCheck(
|
|
15594
|
+
this._checkPromise = this.runTscCheck(projectRoot);
|
|
15539
15595
|
const error = await this._checkPromise;
|
|
15540
15596
|
if (error) {
|
|
15541
15597
|
result.output += `
|
|
@@ -15604,6 +15660,7 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
15604
15660
|
}
|
|
15605
15661
|
var TYPE_CHECK_DEBOUNCE_MS = 2000, syntaxCache, _winDecoder, plugin;
|
|
15606
15662
|
var init_lint_on_write = __esm(() => {
|
|
15663
|
+
init_project_root();
|
|
15607
15664
|
syntaxCache = new Map;
|
|
15608
15665
|
plugin = new LintOnWritePlugin;
|
|
15609
15666
|
});
|
|
@@ -15766,11 +15823,11 @@ class PlanTracker {
|
|
|
15766
15823
|
var init_tracker = () => {};
|
|
15767
15824
|
|
|
15768
15825
|
// src/modules/execution/auditor.ts
|
|
15769
|
-
import { existsSync as
|
|
15770
|
-
import { resolve as resolve17, join as
|
|
15826
|
+
import { existsSync as existsSync28, readdirSync as readdirSync8 } from "fs";
|
|
15827
|
+
import { resolve as resolve17, join as join23, basename as basename2 } from "path";
|
|
15771
15828
|
function findExistingFile(baseDir, filePath) {
|
|
15772
15829
|
const direct = resolve17(baseDir, filePath);
|
|
15773
|
-
if (
|
|
15830
|
+
if (existsSync28(direct))
|
|
15774
15831
|
return direct;
|
|
15775
15832
|
const name = basename2(filePath).toLowerCase();
|
|
15776
15833
|
const suffix = filePath.replace(/\\/g, "/").toLowerCase();
|
|
@@ -15787,7 +15844,7 @@ function findExistingFile(baseDir, filePath) {
|
|
|
15787
15844
|
for (const e of entries) {
|
|
15788
15845
|
if (found)
|
|
15789
15846
|
return;
|
|
15790
|
-
const full =
|
|
15847
|
+
const full = join23(dir, e.name);
|
|
15791
15848
|
if (e.isDirectory()) {
|
|
15792
15849
|
if (SKIP_DIRS.has(e.name))
|
|
15793
15850
|
continue;
|
|
@@ -15811,7 +15868,7 @@ function findTestFile(dir, depth = 0) {
|
|
|
15811
15868
|
return null;
|
|
15812
15869
|
}
|
|
15813
15870
|
for (const e of entries) {
|
|
15814
|
-
const full =
|
|
15871
|
+
const full = join23(dir, e.name);
|
|
15815
15872
|
if (e.isDirectory()) {
|
|
15816
15873
|
if (SKIP_DIRS.has(e.name))
|
|
15817
15874
|
continue;
|
|
@@ -15882,7 +15939,7 @@ class Auditor {
|
|
|
15882
15939
|
this.baseDir = baseDir;
|
|
15883
15940
|
}
|
|
15884
15941
|
async audit(plan) {
|
|
15885
|
-
const allStepText = plan.steps.map((s) => s.description.replace(/\([^)]*\)/g, " ")).join(" ");
|
|
15942
|
+
const allStepText = plan.steps.filter((s) => s.status === "done").map((s) => s.description.replace(/\([^)]*\)/g, " ")).join(" ");
|
|
15886
15943
|
const uniqueFiles = extractFileLikeTokens(stripUrls(allStepText));
|
|
15887
15944
|
const missingFiles = [];
|
|
15888
15945
|
const existingFiles = [];
|
|
@@ -15903,6 +15960,7 @@ class Auditor {
|
|
|
15903
15960
|
}
|
|
15904
15961
|
}
|
|
15905
15962
|
const doneSteps = plan.steps.filter((s) => s.status === "done").length;
|
|
15963
|
+
const terminalSteps = plan.steps.filter((s) => s.status === "done" || s.status === "skipped").length;
|
|
15906
15964
|
const totalSteps = plan.steps.length;
|
|
15907
15965
|
let massEditWarning = null;
|
|
15908
15966
|
if (uniqueFiles.length > MASS_EDIT_THRESHOLD) {
|
|
@@ -15912,7 +15970,7 @@ class Auditor {
|
|
|
15912
15970
|
}
|
|
15913
15971
|
const testsFailing = testRun !== null && testRun.failed > 0;
|
|
15914
15972
|
const passed = missingFiles.length === 0 && !testsFailing;
|
|
15915
|
-
const stepsPending =
|
|
15973
|
+
const stepsPending = terminalSteps < totalSteps;
|
|
15916
15974
|
let summary;
|
|
15917
15975
|
if (missingFiles.length > 0) {
|
|
15918
15976
|
summary = t("exec.audit_fail", {
|
|
@@ -15973,8 +16031,8 @@ var init_auditor = __esm(() => {
|
|
|
15973
16031
|
});
|
|
15974
16032
|
|
|
15975
16033
|
// src/modules/execution/plan-store.ts
|
|
15976
|
-
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as
|
|
15977
|
-
import { join as
|
|
16034
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync14, existsSync as existsSync29, readdirSync as readdirSync9, rmSync } from "fs";
|
|
16035
|
+
import { join as join24 } from "path";
|
|
15978
16036
|
function readPlanFile(path, fallbackBaseDir) {
|
|
15979
16037
|
try {
|
|
15980
16038
|
const raw = readFileSync16(path, "utf-8");
|
|
@@ -15999,10 +16057,10 @@ function writePlanFile(path, plan) {
|
|
|
15999
16057
|
writeFileSync10(path, JSON.stringify(plan, null, 2), "utf-8");
|
|
16000
16058
|
}
|
|
16001
16059
|
function listDir(dir, baseDir) {
|
|
16002
|
-
if (!
|
|
16060
|
+
if (!existsSync29(dir))
|
|
16003
16061
|
return [];
|
|
16004
16062
|
const files = readdirSync9(dir).filter((f) => f.endsWith(".json"));
|
|
16005
|
-
return files.map((f) => readPlanFile(
|
|
16063
|
+
return files.map((f) => readPlanFile(join24(dir, f), baseDir)).filter((p) => p !== null);
|
|
16006
16064
|
}
|
|
16007
16065
|
function toMeta(plan, status) {
|
|
16008
16066
|
return {
|
|
@@ -16023,33 +16081,33 @@ class PlanStore {
|
|
|
16023
16081
|
archiveDir;
|
|
16024
16082
|
legacyPath;
|
|
16025
16083
|
constructor(baseDir) {
|
|
16026
|
-
const mmaDir =
|
|
16027
|
-
if (!
|
|
16084
|
+
const mmaDir = join24(baseDir, ".mma");
|
|
16085
|
+
if (!existsSync29(mmaDir))
|
|
16028
16086
|
mkdirSync14(mmaDir, { recursive: true });
|
|
16029
16087
|
this.baseDir = baseDir;
|
|
16030
|
-
this.plansDir =
|
|
16031
|
-
this.draftsDir =
|
|
16032
|
-
this.archiveDir =
|
|
16033
|
-
this.legacyPath =
|
|
16088
|
+
this.plansDir = join24(mmaDir, "plans");
|
|
16089
|
+
this.draftsDir = join24(this.plansDir, "drafts");
|
|
16090
|
+
this.archiveDir = join24(this.plansDir, "archive");
|
|
16091
|
+
this.legacyPath = join24(mmaDir, LEGACY_FILE);
|
|
16034
16092
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
16035
|
-
if (!
|
|
16093
|
+
if (!existsSync29(dir))
|
|
16036
16094
|
mkdirSync14(dir, { recursive: true });
|
|
16037
16095
|
}
|
|
16038
16096
|
}
|
|
16039
16097
|
activePath() {
|
|
16040
|
-
return
|
|
16098
|
+
return join24(this.plansDir, "active.json");
|
|
16041
16099
|
}
|
|
16042
16100
|
saveActive(plan) {
|
|
16043
16101
|
writePlanFile(this.activePath(), plan);
|
|
16044
16102
|
}
|
|
16045
16103
|
loadActive() {
|
|
16046
16104
|
const activePath = this.activePath();
|
|
16047
|
-
if (
|
|
16105
|
+
if (existsSync29(activePath)) {
|
|
16048
16106
|
const plan = readPlanFile(activePath, this.baseDir);
|
|
16049
16107
|
if (plan)
|
|
16050
16108
|
return plan;
|
|
16051
16109
|
}
|
|
16052
|
-
if (
|
|
16110
|
+
if (existsSync29(this.legacyPath)) {
|
|
16053
16111
|
const legacy = readPlanFile(this.legacyPath, this.baseDir);
|
|
16054
16112
|
if (legacy) {
|
|
16055
16113
|
this.saveActive(legacy);
|
|
@@ -16063,26 +16121,26 @@ class PlanStore {
|
|
|
16063
16121
|
}
|
|
16064
16122
|
clearActive() {
|
|
16065
16123
|
const p = this.activePath();
|
|
16066
|
-
if (
|
|
16124
|
+
if (existsSync29(p))
|
|
16067
16125
|
rmSync(p, { force: true });
|
|
16068
16126
|
}
|
|
16069
16127
|
saveDraft(plan) {
|
|
16070
|
-
writePlanFile(
|
|
16128
|
+
writePlanFile(join24(this.draftsDir, `${plan.id}.json`), plan);
|
|
16071
16129
|
}
|
|
16072
16130
|
loadDraft(id) {
|
|
16073
|
-
const p =
|
|
16074
|
-
return
|
|
16131
|
+
const p = join24(this.draftsDir, `${id}.json`);
|
|
16132
|
+
return existsSync29(p) ? readPlanFile(p, this.baseDir) : null;
|
|
16075
16133
|
}
|
|
16076
16134
|
removeDraft(id) {
|
|
16077
|
-
const p =
|
|
16078
|
-
if (
|
|
16135
|
+
const p = join24(this.draftsDir, `${id}.json`);
|
|
16136
|
+
if (existsSync29(p))
|
|
16079
16137
|
rmSync(p, { force: true });
|
|
16080
16138
|
}
|
|
16081
16139
|
listDrafts() {
|
|
16082
16140
|
return listDir(this.draftsDir, this.baseDir);
|
|
16083
16141
|
}
|
|
16084
16142
|
archivePlan(plan) {
|
|
16085
|
-
writePlanFile(
|
|
16143
|
+
writePlanFile(join24(this.archiveDir, `${plan.id}.json`), plan);
|
|
16086
16144
|
this.removeDraft(plan.id);
|
|
16087
16145
|
const active = this.loadActive();
|
|
16088
16146
|
if (active && active.id === plan.id) {
|
|
@@ -16093,8 +16151,8 @@ class PlanStore {
|
|
|
16093
16151
|
return listDir(this.archiveDir, this.baseDir);
|
|
16094
16152
|
}
|
|
16095
16153
|
removeArchived(id) {
|
|
16096
|
-
const p =
|
|
16097
|
-
if (
|
|
16154
|
+
const p = join24(this.archiveDir, `${id}.json`);
|
|
16155
|
+
if (existsSync29(p))
|
|
16098
16156
|
rmSync(p, { force: true });
|
|
16099
16157
|
}
|
|
16100
16158
|
listAll() {
|
|
@@ -16188,7 +16246,7 @@ var init_plan_coverage = __esm(() => {
|
|
|
16188
16246
|
});
|
|
16189
16247
|
|
|
16190
16248
|
// src/modules/execution/module.ts
|
|
16191
|
-
import { existsSync as
|
|
16249
|
+
import { existsSync as existsSync30, readFileSync as readFileSync17 } from "fs";
|
|
16192
16250
|
import { resolve as resolve18 } from "path";
|
|
16193
16251
|
|
|
16194
16252
|
class ExecutionModule {
|
|
@@ -16936,7 +16994,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
16936
16994
|
"poetry.lock",
|
|
16937
16995
|
"requirements.txt"
|
|
16938
16996
|
];
|
|
16939
|
-
const hasLockFile = lockFiles.some((f) =>
|
|
16997
|
+
const hasLockFile = lockFiles.some((f) => existsSync30(resolve18(this.baseDir, f)));
|
|
16940
16998
|
if (!hasLockFile) {
|
|
16941
16999
|
if (contextManager) {
|
|
16942
17000
|
const hints = this.depsGateHints.get(step.id) || 0;
|
|
@@ -16956,7 +17014,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
16956
17014
|
}
|
|
16957
17015
|
if (stepPaths.length === 0)
|
|
16958
17016
|
return;
|
|
16959
|
-
const allExist = stepPaths.every((p) =>
|
|
17017
|
+
const allExist = stepPaths.every((p) => existsSync30(resolve18(this.baseDir, p)));
|
|
16960
17018
|
if (!allExist)
|
|
16961
17019
|
return;
|
|
16962
17020
|
const emptyFiles = [];
|
|
@@ -17028,11 +17086,11 @@ var init_module = __esm(() => {
|
|
|
17028
17086
|
import {
|
|
17029
17087
|
readFileSync as readFileSync18,
|
|
17030
17088
|
writeFileSync as writeFileSync11,
|
|
17031
|
-
existsSync as
|
|
17089
|
+
existsSync as existsSync31,
|
|
17032
17090
|
readdirSync as readdirSync10,
|
|
17033
17091
|
unlinkSync as unlinkSync4
|
|
17034
17092
|
} from "fs";
|
|
17035
|
-
import { join as
|
|
17093
|
+
import { join as join25 } from "path";
|
|
17036
17094
|
import { homedir as homedir8 } from "os";
|
|
17037
17095
|
|
|
17038
17096
|
class SessionFileEncryptor {
|
|
@@ -17041,7 +17099,7 @@ class SessionFileEncryptor {
|
|
|
17041
17099
|
constructor(config) {
|
|
17042
17100
|
this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
|
|
17043
17101
|
this.encryptor = new ConfigEncryptor({
|
|
17044
|
-
keyPath: config?.keyPath ||
|
|
17102
|
+
keyPath: config?.keyPath || join25(homedir8(), ".mma", ".session-encryption-key")
|
|
17045
17103
|
});
|
|
17046
17104
|
}
|
|
17047
17105
|
isEnabled() {
|
|
@@ -17127,8 +17185,8 @@ class SessionFileEncryptor {
|
|
|
17127
17185
|
return;
|
|
17128
17186
|
const files = readdirSync10(sessionDir);
|
|
17129
17187
|
for (const file of files) {
|
|
17130
|
-
const filePath =
|
|
17131
|
-
if (
|
|
17188
|
+
const filePath = join25(sessionDir, file);
|
|
17189
|
+
if (existsSync31(filePath) && !file.endsWith(".enc")) {
|
|
17132
17190
|
try {
|
|
17133
17191
|
const content = readFileSync18(filePath, "utf8");
|
|
17134
17192
|
const encrypted = this.encryptFileContent(content);
|
|
@@ -17144,7 +17202,7 @@ class SessionFileEncryptor {
|
|
|
17144
17202
|
const files = readdirSync10(sessionDir);
|
|
17145
17203
|
for (const file of files) {
|
|
17146
17204
|
if (file.endsWith(".enc")) {
|
|
17147
|
-
const encFilePath =
|
|
17205
|
+
const encFilePath = join25(sessionDir, file);
|
|
17148
17206
|
const decFilePath = encFilePath.slice(0, -4);
|
|
17149
17207
|
try {
|
|
17150
17208
|
const content = readFileSync18(encFilePath, "utf8");
|
|
@@ -17169,7 +17227,7 @@ var init_session_encryption = __esm(() => {
|
|
|
17169
17227
|
|
|
17170
17228
|
// src/modules/session/store.ts
|
|
17171
17229
|
import {
|
|
17172
|
-
existsSync as
|
|
17230
|
+
existsSync as existsSync32,
|
|
17173
17231
|
mkdirSync as mkdirSync15,
|
|
17174
17232
|
readdirSync as readdirSync11,
|
|
17175
17233
|
readFileSync as readFileSync19,
|
|
@@ -17177,7 +17235,7 @@ import {
|
|
|
17177
17235
|
writeFileSync as writeFileSync12,
|
|
17178
17236
|
appendFileSync as appendFileSync6
|
|
17179
17237
|
} from "fs";
|
|
17180
|
-
import { join as
|
|
17238
|
+
import { join as join26 } from "path";
|
|
17181
17239
|
import { gzipSync } from "zlib";
|
|
17182
17240
|
|
|
17183
17241
|
class SessionStore {
|
|
@@ -17191,7 +17249,7 @@ class SessionStore {
|
|
|
17191
17249
|
}
|
|
17192
17250
|
}
|
|
17193
17251
|
getSessionDir(id) {
|
|
17194
|
-
return
|
|
17252
|
+
return join26(this.baseDir, id);
|
|
17195
17253
|
}
|
|
17196
17254
|
updateEncryption(config) {
|
|
17197
17255
|
if (config?.enabled) {
|
|
@@ -17207,19 +17265,19 @@ class SessionStore {
|
|
|
17207
17265
|
mkdirSync15(this.baseDir, { recursive: true });
|
|
17208
17266
|
}
|
|
17209
17267
|
sessionDir(id) {
|
|
17210
|
-
return
|
|
17268
|
+
return join26(this.baseDir, id);
|
|
17211
17269
|
}
|
|
17212
17270
|
metaPath(id) {
|
|
17213
|
-
return
|
|
17271
|
+
return join26(this.sessionDir(id), "meta.json");
|
|
17214
17272
|
}
|
|
17215
17273
|
historyPath(id) {
|
|
17216
|
-
return
|
|
17274
|
+
return join26(this.sessionDir(id), "history.jsonl");
|
|
17217
17275
|
}
|
|
17218
17276
|
sessionLogPath(id) {
|
|
17219
|
-
return
|
|
17277
|
+
return join26(this.sessionDir(id), "session.jsonl");
|
|
17220
17278
|
}
|
|
17221
17279
|
sessionExists(id) {
|
|
17222
|
-
return
|
|
17280
|
+
return existsSync32(this.metaPath(id));
|
|
17223
17281
|
}
|
|
17224
17282
|
saveMeta(id, meta) {
|
|
17225
17283
|
this._metaCache.set(id, meta);
|
|
@@ -17237,7 +17295,7 @@ class SessionStore {
|
|
|
17237
17295
|
if (cached)
|
|
17238
17296
|
return cached;
|
|
17239
17297
|
const path = this.metaPath(id);
|
|
17240
|
-
if (!
|
|
17298
|
+
if (!existsSync32(path))
|
|
17241
17299
|
return null;
|
|
17242
17300
|
try {
|
|
17243
17301
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17269,7 +17327,7 @@ class SessionStore {
|
|
|
17269
17327
|
}
|
|
17270
17328
|
loadHistory(id) {
|
|
17271
17329
|
const path = this.historyPath(id);
|
|
17272
|
-
if (!
|
|
17330
|
+
if (!existsSync32(path))
|
|
17273
17331
|
return [];
|
|
17274
17332
|
try {
|
|
17275
17333
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17310,7 +17368,7 @@ class SessionStore {
|
|
|
17310
17368
|
}
|
|
17311
17369
|
loadSessionLog(id) {
|
|
17312
17370
|
const path = this.sessionLogPath(id);
|
|
17313
|
-
if (!
|
|
17371
|
+
if (!existsSync32(path))
|
|
17314
17372
|
return [];
|
|
17315
17373
|
try {
|
|
17316
17374
|
const raw = readFileSync19(path, "utf-8");
|
|
@@ -17338,7 +17396,7 @@ class SessionStore {
|
|
|
17338
17396
|
}
|
|
17339
17397
|
}
|
|
17340
17398
|
listSessions() {
|
|
17341
|
-
if (!
|
|
17399
|
+
if (!existsSync32(this.baseDir))
|
|
17342
17400
|
return [];
|
|
17343
17401
|
const entries = readdirSync11(this.baseDir, { withFileTypes: true });
|
|
17344
17402
|
const sessions = [];
|
|
@@ -17355,7 +17413,7 @@ class SessionStore {
|
|
|
17355
17413
|
deleteSession(id) {
|
|
17356
17414
|
this._metaCache.delete(id);
|
|
17357
17415
|
const dir = this.sessionDir(id);
|
|
17358
|
-
if (
|
|
17416
|
+
if (existsSync32(dir)) {
|
|
17359
17417
|
rmSync2(dir, { recursive: true, force: true });
|
|
17360
17418
|
}
|
|
17361
17419
|
}
|
|
@@ -17367,10 +17425,10 @@ class SessionStore {
|
|
|
17367
17425
|
const updatedAt = new Date(session2.updatedAt);
|
|
17368
17426
|
if (updatedAt < thirtyDaysAgo) {
|
|
17369
17427
|
const historyPath = this.historyPath(session2.id);
|
|
17370
|
-
if (
|
|
17428
|
+
if (existsSync32(historyPath)) {
|
|
17371
17429
|
const content = readFileSync19(historyPath, "utf-8");
|
|
17372
17430
|
const compressed = gzipSync(content);
|
|
17373
|
-
const gzPath =
|
|
17431
|
+
const gzPath = join26(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
17374
17432
|
writeFileSync12(gzPath, compressed);
|
|
17375
17433
|
rmSync2(historyPath);
|
|
17376
17434
|
}
|
|
@@ -17580,8 +17638,8 @@ class ProfileCompressor {
|
|
|
17580
17638
|
}
|
|
17581
17639
|
|
|
17582
17640
|
// src/modules/user-profile/profile.ts
|
|
17583
|
-
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as
|
|
17584
|
-
import { join as
|
|
17641
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as existsSync33, mkdirSync as mkdirSync16 } from "fs";
|
|
17642
|
+
import { join as join27 } from "path";
|
|
17585
17643
|
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
17586
17644
|
import { env } from "process";
|
|
17587
17645
|
|
|
@@ -17605,14 +17663,14 @@ class UserProfile {
|
|
|
17605
17663
|
return this.info;
|
|
17606
17664
|
}
|
|
17607
17665
|
save() {
|
|
17608
|
-
if (!
|
|
17666
|
+
if (!existsSync33(this.profileDir)) {
|
|
17609
17667
|
mkdirSync16(this.profileDir, { recursive: true });
|
|
17610
17668
|
}
|
|
17611
|
-
writeFileSync13(
|
|
17669
|
+
writeFileSync13(join27(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
17612
17670
|
}
|
|
17613
17671
|
load() {
|
|
17614
|
-
const path =
|
|
17615
|
-
if (!
|
|
17672
|
+
const path = join27(this.profileDir, "profile.json");
|
|
17673
|
+
if (!existsSync33(path))
|
|
17616
17674
|
return null;
|
|
17617
17675
|
try {
|
|
17618
17676
|
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
@@ -17650,12 +17708,12 @@ class UserProfile {
|
|
|
17650
17708
|
var init_profile = () => {};
|
|
17651
17709
|
|
|
17652
17710
|
// src/modules/skills/loader.ts
|
|
17653
|
-
import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as
|
|
17654
|
-
import { join as
|
|
17711
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync34, statSync as statSync6 } from "fs";
|
|
17712
|
+
import { join as join28 } from "path";
|
|
17655
17713
|
|
|
17656
17714
|
class SkillsLoader {
|
|
17657
17715
|
loadFromDir(dirPath) {
|
|
17658
|
-
if (!
|
|
17716
|
+
if (!existsSync34(dirPath))
|
|
17659
17717
|
return [];
|
|
17660
17718
|
const skills = [];
|
|
17661
17719
|
this.scanDir(dirPath, skills);
|
|
@@ -17664,7 +17722,7 @@ class SkillsLoader {
|
|
|
17664
17722
|
scanDir(dirPath, skills) {
|
|
17665
17723
|
const entries = readdirSync12(dirPath);
|
|
17666
17724
|
for (const entry of entries) {
|
|
17667
|
-
const fullPath =
|
|
17725
|
+
const fullPath = join28(dirPath, entry);
|
|
17668
17726
|
const stat = statSync6(fullPath);
|
|
17669
17727
|
if (stat.isDirectory()) {
|
|
17670
17728
|
this.scanDir(fullPath, skills);
|
|
@@ -17908,8 +17966,8 @@ var init_browser2 = __esm(() => {
|
|
|
17908
17966
|
});
|
|
17909
17967
|
|
|
17910
17968
|
// src/modules/lsp/command.ts
|
|
17911
|
-
import { delimiter, join as
|
|
17912
|
-
import { existsSync as
|
|
17969
|
+
import { delimiter, join as join29 } from "path";
|
|
17970
|
+
import { existsSync as existsSync35 } from "fs";
|
|
17913
17971
|
import { platform as platform5 } from "os";
|
|
17914
17972
|
function resolveSpawnCommand(command, platformName = platform5(), pathEnv = process.env.PATH ?? "") {
|
|
17915
17973
|
if (platformName !== "win32")
|
|
@@ -17920,8 +17978,8 @@ function resolveSpawnCommand(command, platformName = platform5(), pathEnv = proc
|
|
|
17920
17978
|
const dirs = pathEnv.split(delimiter).filter(Boolean);
|
|
17921
17979
|
for (const dir of dirs) {
|
|
17922
17980
|
for (const ext of WIN_EXTS) {
|
|
17923
|
-
const candidate =
|
|
17924
|
-
if (
|
|
17981
|
+
const candidate = join29(dir, `${command}${ext}`);
|
|
17982
|
+
if (existsSync35(candidate))
|
|
17925
17983
|
return `${command}${ext}`;
|
|
17926
17984
|
}
|
|
17927
17985
|
}
|
|
@@ -17960,11 +18018,11 @@ class LspClient {
|
|
|
17960
18018
|
diagnosticsResolve = null;
|
|
17961
18019
|
diagnosticsTimer = null;
|
|
17962
18020
|
initialized = false;
|
|
17963
|
-
async checkFile(filePath, baseDir, config) {
|
|
18021
|
+
async checkFile(filePath, baseDir, config, projectRoot = baseDir) {
|
|
17964
18022
|
const timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
17965
18023
|
try {
|
|
17966
|
-
await this.startServer(config,
|
|
17967
|
-
const rootUri = this.pathToUri(
|
|
18024
|
+
await this.startServer(config, projectRoot);
|
|
18025
|
+
const rootUri = this.pathToUri(projectRoot);
|
|
17968
18026
|
const initResult = await this.sendRequest("initialize", {
|
|
17969
18027
|
processId: process.pid,
|
|
17970
18028
|
rootUri,
|
|
@@ -18001,7 +18059,7 @@ class LspClient {
|
|
|
18001
18059
|
await this.shutdown();
|
|
18002
18060
|
}
|
|
18003
18061
|
}
|
|
18004
|
-
async startServer(config,
|
|
18062
|
+
async startServer(config, projectRoot) {
|
|
18005
18063
|
if (config.autoInstall === false) {
|
|
18006
18064
|
try {
|
|
18007
18065
|
execSync2(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
|
|
@@ -18017,7 +18075,7 @@ class LspClient {
|
|
|
18017
18075
|
const spawnOpts = {
|
|
18018
18076
|
stdio: ["pipe", "pipe", "pipe"],
|
|
18019
18077
|
env: { ...process.env, ...config.env },
|
|
18020
|
-
cwd:
|
|
18078
|
+
cwd: projectRoot
|
|
18021
18079
|
};
|
|
18022
18080
|
if (isWin) {
|
|
18023
18081
|
spawnCommand = buildWinCommandLine(spawnCommand, args);
|
|
@@ -18190,16 +18248,21 @@ var init_client2 = __esm(() => {
|
|
|
18190
18248
|
});
|
|
18191
18249
|
|
|
18192
18250
|
// src/modules/lsp/module.ts
|
|
18193
|
-
import { existsSync as
|
|
18251
|
+
import { existsSync as existsSync36 } from "fs";
|
|
18194
18252
|
import { resolve as resolve20 } from "path";
|
|
18195
18253
|
|
|
18196
18254
|
class LspModule {
|
|
18197
18255
|
name = "lsp";
|
|
18198
18256
|
config;
|
|
18199
18257
|
client = new LspClient;
|
|
18258
|
+
consecutiveFailures = 0;
|
|
18259
|
+
lspDisabled = false;
|
|
18200
18260
|
constructor(config) {
|
|
18201
18261
|
this.config = { ...DEFAULT_LSP_CONFIG, ...config };
|
|
18202
18262
|
}
|
|
18263
|
+
isLspDisabled() {
|
|
18264
|
+
return this.lspDisabled;
|
|
18265
|
+
}
|
|
18203
18266
|
getPlugin() {
|
|
18204
18267
|
const self = this;
|
|
18205
18268
|
return {
|
|
@@ -18208,6 +18271,8 @@ class LspModule {
|
|
|
18208
18271
|
onAfterTool: async (_ctx, call, result) => {
|
|
18209
18272
|
if (!self.config.enabled)
|
|
18210
18273
|
return;
|
|
18274
|
+
if (self.lspDisabled)
|
|
18275
|
+
return;
|
|
18211
18276
|
if (call.name !== "write_file" && call.name !== "edit_file")
|
|
18212
18277
|
return;
|
|
18213
18278
|
if (!result.success)
|
|
@@ -18216,13 +18281,15 @@ class LspModule {
|
|
|
18216
18281
|
if (!filePath)
|
|
18217
18282
|
return;
|
|
18218
18283
|
const fullPath = resolve20(_ctx.baseDir, filePath);
|
|
18219
|
-
if (!
|
|
18284
|
+
if (!existsSync36(fullPath))
|
|
18220
18285
|
return;
|
|
18221
18286
|
const serverConfig = getServerForFile(fullPath, self.config);
|
|
18222
18287
|
if (!serverConfig)
|
|
18223
18288
|
return;
|
|
18289
|
+
const projectRoot = findProjectRoot(fullPath, _ctx.baseDir, serverConfig.workspaceMarkers ?? []);
|
|
18224
18290
|
try {
|
|
18225
|
-
const diagnostics = await self.client.checkFile(fullPath, _ctx.baseDir, serverConfig);
|
|
18291
|
+
const diagnostics = await self.client.checkFile(fullPath, _ctx.baseDir, serverConfig, projectRoot);
|
|
18292
|
+
self.consecutiveFailures = 0;
|
|
18226
18293
|
const errors = diagnostics.filter((d) => d.severity === 1);
|
|
18227
18294
|
const warnings = diagnostics.filter((d) => d.severity === 2);
|
|
18228
18295
|
if (errors.length > 0) {
|
|
@@ -18241,12 +18308,20 @@ ${items}`;
|
|
|
18241
18308
|
}
|
|
18242
18309
|
} catch (e) {
|
|
18243
18310
|
const msg = e instanceof Error ? e.message : String(e);
|
|
18311
|
+
self.consecutiveFailures++;
|
|
18244
18312
|
try {
|
|
18245
18313
|
_ctx.logger?.warn(`LSP check failed for ${filePath}: ${msg}`);
|
|
18246
18314
|
} catch {}
|
|
18247
|
-
|
|
18315
|
+
if (self.consecutiveFailures >= MAX_CONSECUTIVE_LSP_FAILURES) {
|
|
18316
|
+
self.lspDisabled = true;
|
|
18317
|
+
result.output += `
|
|
18318
|
+
|
|
18319
|
+
[LSP disabled: ${t("lsp.unavailable")}]`;
|
|
18320
|
+
} else {
|
|
18321
|
+
result.output += `
|
|
18248
18322
|
|
|
18249
18323
|
[LSP check failed]: ${msg}`;
|
|
18324
|
+
}
|
|
18250
18325
|
}
|
|
18251
18326
|
}
|
|
18252
18327
|
};
|
|
@@ -18262,10 +18337,12 @@ function formatDiagnostics(diagnostics, filePath) {
|
|
|
18262
18337
|
}).join(`
|
|
18263
18338
|
`);
|
|
18264
18339
|
}
|
|
18265
|
-
var severityLabels;
|
|
18340
|
+
var severityLabels, MAX_CONSECUTIVE_LSP_FAILURES = 3;
|
|
18266
18341
|
var init_module5 = __esm(() => {
|
|
18267
18342
|
init_client2();
|
|
18268
18343
|
init_config();
|
|
18344
|
+
init_project_root();
|
|
18345
|
+
init_i18n();
|
|
18269
18346
|
severityLabels = {
|
|
18270
18347
|
1: "error",
|
|
18271
18348
|
2: "warning",
|
|
@@ -18282,8 +18359,8 @@ var init_lsp = __esm(() => {
|
|
|
18282
18359
|
});
|
|
18283
18360
|
|
|
18284
18361
|
// src/modules/indexer/walker.ts
|
|
18285
|
-
import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as
|
|
18286
|
-
import { join as
|
|
18362
|
+
import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync37, watch } from "fs";
|
|
18363
|
+
import { join as join30, relative as relative2, extname as extname5 } from "path";
|
|
18287
18364
|
|
|
18288
18365
|
class Indexer {
|
|
18289
18366
|
baseDir;
|
|
@@ -18310,7 +18387,7 @@ class Indexer {
|
|
|
18310
18387
|
let totalSize = 0;
|
|
18311
18388
|
let count = 0;
|
|
18312
18389
|
const walkDir = (dir) => {
|
|
18313
|
-
if (!
|
|
18390
|
+
if (!existsSync37(dir))
|
|
18314
18391
|
return;
|
|
18315
18392
|
let entries;
|
|
18316
18393
|
try {
|
|
@@ -18321,7 +18398,7 @@ class Indexer {
|
|
|
18321
18398
|
for (const entry of entries) {
|
|
18322
18399
|
if (count >= this.MAX_FILES)
|
|
18323
18400
|
return;
|
|
18324
|
-
const fullPath =
|
|
18401
|
+
const fullPath = join30(dir, entry);
|
|
18325
18402
|
const relPath = relative2(this.baseDir, fullPath);
|
|
18326
18403
|
const stat = statSync7(fullPath);
|
|
18327
18404
|
if (stat.isDirectory()) {
|
|
@@ -18384,19 +18461,19 @@ var init_walker = __esm(() => {
|
|
|
18384
18461
|
});
|
|
18385
18462
|
|
|
18386
18463
|
// src/modules/indexer/cache.ts
|
|
18387
|
-
import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as
|
|
18388
|
-
import { join as
|
|
18464
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync14, existsSync as existsSync38, mkdirSync as mkdirSync17, rmSync as rmSync3 } from "fs";
|
|
18465
|
+
import { join as join31 } from "path";
|
|
18389
18466
|
|
|
18390
18467
|
class IndexCache {
|
|
18391
18468
|
cachePath;
|
|
18392
18469
|
cache = null;
|
|
18393
18470
|
constructor(cacheDir) {
|
|
18394
|
-
this.cachePath =
|
|
18471
|
+
this.cachePath = join31(cacheDir, "index-cache.json");
|
|
18395
18472
|
}
|
|
18396
18473
|
load() {
|
|
18397
18474
|
if (this.cache)
|
|
18398
18475
|
return this.cache;
|
|
18399
|
-
if (!
|
|
18476
|
+
if (!existsSync38(this.cachePath))
|
|
18400
18477
|
return null;
|
|
18401
18478
|
try {
|
|
18402
18479
|
this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
|
|
@@ -18407,14 +18484,14 @@ class IndexCache {
|
|
|
18407
18484
|
}
|
|
18408
18485
|
save(result) {
|
|
18409
18486
|
this.cache = result;
|
|
18410
|
-
const dir =
|
|
18411
|
-
if (!
|
|
18487
|
+
const dir = join31(this.cachePath, "..");
|
|
18488
|
+
if (!existsSync38(dir))
|
|
18412
18489
|
mkdirSync17(dir, { recursive: true });
|
|
18413
18490
|
writeFileSync14(this.cachePath, JSON.stringify(result), "utf-8");
|
|
18414
18491
|
}
|
|
18415
18492
|
invalidate() {
|
|
18416
18493
|
this.cache = null;
|
|
18417
|
-
if (
|
|
18494
|
+
if (existsSync38(this.cachePath)) {
|
|
18418
18495
|
try {
|
|
18419
18496
|
rmSync3(this.cachePath);
|
|
18420
18497
|
} catch {}
|
|
@@ -18424,11 +18501,11 @@ class IndexCache {
|
|
|
18424
18501
|
var init_cache = () => {};
|
|
18425
18502
|
|
|
18426
18503
|
// src/modules/indexer/project-profile.ts
|
|
18427
|
-
import { readFileSync as readFileSync24, existsSync as
|
|
18428
|
-
import { join as
|
|
18504
|
+
import { readFileSync as readFileSync24, existsSync as existsSync39 } from "fs";
|
|
18505
|
+
import { join as join32 } from "path";
|
|
18429
18506
|
function detectManifest(baseDir) {
|
|
18430
18507
|
for (const manifest of MANIFEST_ORDER) {
|
|
18431
|
-
if (
|
|
18508
|
+
if (existsSync39(join32(baseDir, manifest)))
|
|
18432
18509
|
return manifest;
|
|
18433
18510
|
}
|
|
18434
18511
|
return null;
|
|
@@ -18445,7 +18522,7 @@ function cleanDependency(entry) {
|
|
|
18445
18522
|
}
|
|
18446
18523
|
function readPackageJson(baseDir) {
|
|
18447
18524
|
try {
|
|
18448
|
-
const raw = JSON.parse(readFileSync24(
|
|
18525
|
+
const raw = JSON.parse(readFileSync24(join32(baseDir, "package.json"), "utf-8"));
|
|
18449
18526
|
if (!raw || typeof raw !== "object")
|
|
18450
18527
|
return null;
|
|
18451
18528
|
const profile = {
|
|
@@ -18469,7 +18546,7 @@ function readPackageJson(baseDir) {
|
|
|
18469
18546
|
}
|
|
18470
18547
|
function readPyproject(baseDir) {
|
|
18471
18548
|
try {
|
|
18472
|
-
const content = readFileSync24(
|
|
18549
|
+
const content = readFileSync24(join32(baseDir, "pyproject.toml"), "utf-8");
|
|
18473
18550
|
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
18474
18551
|
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
18475
18552
|
if (nameMatch)
|
|
@@ -18485,7 +18562,7 @@ function readPyproject(baseDir) {
|
|
|
18485
18562
|
}
|
|
18486
18563
|
function readCargo(baseDir) {
|
|
18487
18564
|
try {
|
|
18488
|
-
const content = readFileSync24(
|
|
18565
|
+
const content = readFileSync24(join32(baseDir, "Cargo.toml"), "utf-8");
|
|
18489
18566
|
const profile = { runtime: "rust", deps: [], devDeps: [], scripts: {} };
|
|
18490
18567
|
const nameMatch = content.match(/^\s*name\s*=\s*"([^"]+)"/m);
|
|
18491
18568
|
if (nameMatch)
|
|
@@ -18509,7 +18586,7 @@ function readCargo(baseDir) {
|
|
|
18509
18586
|
}
|
|
18510
18587
|
function readGoMod(baseDir) {
|
|
18511
18588
|
try {
|
|
18512
|
-
const content = readFileSync24(
|
|
18589
|
+
const content = readFileSync24(join32(baseDir, "go.mod"), "utf-8");
|
|
18513
18590
|
const profile = { runtime: "go", deps: [], devDeps: [], scripts: {} };
|
|
18514
18591
|
const moduleMatch = content.match(/^module\s+(\S+)/m);
|
|
18515
18592
|
if (moduleMatch)
|
|
@@ -18527,7 +18604,7 @@ function readGoMod(baseDir) {
|
|
|
18527
18604
|
}
|
|
18528
18605
|
function readRequirements(baseDir) {
|
|
18529
18606
|
try {
|
|
18530
|
-
const content = readFileSync24(
|
|
18607
|
+
const content = readFileSync24(join32(baseDir, "requirements.txt"), "utf-8");
|
|
18531
18608
|
const profile = { runtime: "python", deps: [], devDeps: [], scripts: {} };
|
|
18532
18609
|
for (const line of content.split(`
|
|
18533
18610
|
`)) {
|
|
@@ -18592,7 +18669,7 @@ var init_project_profile = __esm(() => {
|
|
|
18592
18669
|
});
|
|
18593
18670
|
|
|
18594
18671
|
// src/modules/indexer/module.ts
|
|
18595
|
-
import { dirname as
|
|
18672
|
+
import { dirname as dirname11 } from "path";
|
|
18596
18673
|
|
|
18597
18674
|
class IndexerModule {
|
|
18598
18675
|
name = "indexer";
|
|
@@ -18696,22 +18773,54 @@ class IndexerModule {
|
|
|
18696
18773
|
});
|
|
18697
18774
|
const more = result.files.length > 100 ? `
|
|
18698
18775
|
${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
18776
|
+
const duplicates = this.findDuplicateBasenames(result);
|
|
18699
18777
|
return [
|
|
18700
18778
|
`${t("indexer.map_header")} (${this.baseDir})`,
|
|
18701
18779
|
summary,
|
|
18702
18780
|
...stackLine ? [stackLine] : [],
|
|
18703
18781
|
`${t("indexer.top_directories")}: ${topDirs}`,
|
|
18782
|
+
...duplicates.length > 0 ? [t("indexer.duplicates", { names: duplicates.join(", ") })] : [],
|
|
18704
18783
|
`${t("indexer.files")}:` + (fileLines.length > 0 ? "" : " " + t("indexer.empty")),
|
|
18705
18784
|
...fileLines,
|
|
18706
18785
|
more
|
|
18707
18786
|
].join(`
|
|
18708
18787
|
`);
|
|
18709
18788
|
}
|
|
18789
|
+
findDuplicateBasenames(result) {
|
|
18790
|
+
const byDir = {};
|
|
18791
|
+
for (const f of result.files) {
|
|
18792
|
+
const path = f.path.replace(/\\/g, "/");
|
|
18793
|
+
const idx = path.lastIndexOf("/");
|
|
18794
|
+
const dir = idx >= 0 ? path.slice(0, idx) : "";
|
|
18795
|
+
const name = path.slice(idx + 1);
|
|
18796
|
+
const dot = name.lastIndexOf(".");
|
|
18797
|
+
if (dot <= 0)
|
|
18798
|
+
continue;
|
|
18799
|
+
const base = name.slice(0, dot);
|
|
18800
|
+
const ext = name.slice(dot + 1);
|
|
18801
|
+
if (!byDir[dir])
|
|
18802
|
+
byDir[dir] = new Map;
|
|
18803
|
+
const list = byDir[dir].get(base) ?? [];
|
|
18804
|
+
list.push(ext);
|
|
18805
|
+
byDir[dir].set(base, list);
|
|
18806
|
+
}
|
|
18807
|
+
const dups = [];
|
|
18808
|
+
for (const dir of Object.keys(byDir).sort()) {
|
|
18809
|
+
for (const [base, exts] of byDir[dir]) {
|
|
18810
|
+
if (exts.length < 2)
|
|
18811
|
+
continue;
|
|
18812
|
+
const uniqueExts = [...new Set(exts)].sort();
|
|
18813
|
+
const dirPrefix = dir ? `${dir}/` : "";
|
|
18814
|
+
dups.push(`${dirPrefix}${base}.{${uniqueExts.join(",")}}`);
|
|
18815
|
+
}
|
|
18816
|
+
}
|
|
18817
|
+
return dups;
|
|
18818
|
+
}
|
|
18710
18819
|
getDirectoryCounts(result) {
|
|
18711
18820
|
const counts = {};
|
|
18712
18821
|
for (const f of result.files) {
|
|
18713
18822
|
const normalized = f.path.replace(/\\/g, "/");
|
|
18714
|
-
const dir =
|
|
18823
|
+
const dir = dirname11(normalized);
|
|
18715
18824
|
const key = dir === "." ? "(root)" : dir;
|
|
18716
18825
|
counts[key] = (counts[key] || 0) + 1;
|
|
18717
18826
|
}
|
|
@@ -18949,27 +19058,65 @@ var init_mcp = __esm(() => {
|
|
|
18949
19058
|
|
|
18950
19059
|
// src/modules/memory/module.ts
|
|
18951
19060
|
import { homedir as homedir10 } from "os";
|
|
18952
|
-
import { join as
|
|
19061
|
+
import { join as join33 } from "path";
|
|
18953
19062
|
|
|
18954
19063
|
class MemoryModule {
|
|
18955
19064
|
name = "memory";
|
|
18956
19065
|
store;
|
|
18957
|
-
constructor(
|
|
18958
|
-
|
|
18959
|
-
|
|
19066
|
+
constructor(storeOrDir) {
|
|
19067
|
+
if (storeOrDir instanceof MemoryStore) {
|
|
19068
|
+
this.store = storeOrDir;
|
|
19069
|
+
} else {
|
|
19070
|
+
const dir = storeOrDir || join33(homedir10(), ".mma", "memory");
|
|
19071
|
+
this.store = new MemoryStore(dir);
|
|
19072
|
+
}
|
|
18960
19073
|
}
|
|
18961
19074
|
getSystemPromptBlock() {
|
|
19075
|
+
const parts = [];
|
|
18962
19076
|
const prefs = this.store.getPreferences();
|
|
18963
|
-
if (Object.keys(prefs).length
|
|
19077
|
+
if (Object.keys(prefs).length > 0) {
|
|
19078
|
+
const prefStr = Object.entries(prefs).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
19079
|
+
parts.push(`User preferences: ${prefStr}`);
|
|
19080
|
+
}
|
|
19081
|
+
const memoryTail = this.getMemoryTail();
|
|
19082
|
+
if (memoryTail)
|
|
19083
|
+
parts.push(memoryTail);
|
|
19084
|
+
if (parts.length === 0)
|
|
18964
19085
|
return null;
|
|
18965
|
-
const
|
|
19086
|
+
const content = parts.join(`
|
|
19087
|
+
|
|
19088
|
+
`);
|
|
18966
19089
|
return {
|
|
18967
|
-
content
|
|
19090
|
+
content,
|
|
18968
19091
|
priority: "normal",
|
|
18969
19092
|
essential: false,
|
|
18970
|
-
estimatedTokens: Math.ceil(
|
|
19093
|
+
estimatedTokens: Math.ceil(content.length / 4) + 10
|
|
18971
19094
|
};
|
|
18972
19095
|
}
|
|
19096
|
+
getMemoryTail() {
|
|
19097
|
+
const sections = [];
|
|
19098
|
+
const tailPerFile = 3;
|
|
19099
|
+
for (const name of MEMORY_MD_FILES) {
|
|
19100
|
+
const content = this.store.read(name).trim();
|
|
19101
|
+
if (!content)
|
|
19102
|
+
continue;
|
|
19103
|
+
const entries = content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.startsWith("- ")).slice(-tailPerFile);
|
|
19104
|
+
if (entries.length === 0)
|
|
19105
|
+
continue;
|
|
19106
|
+
sections.push(`[Memory ${name}]:
|
|
19107
|
+
${entries.join(`
|
|
19108
|
+
`)}`);
|
|
19109
|
+
}
|
|
19110
|
+
if (sections.length === 0)
|
|
19111
|
+
return null;
|
|
19112
|
+
let joined = sections.join(`
|
|
19113
|
+
|
|
19114
|
+
`);
|
|
19115
|
+
if (joined.length > 1200)
|
|
19116
|
+
joined = joined.slice(0, 1200) + `
|
|
19117
|
+
…`;
|
|
19118
|
+
return joined;
|
|
19119
|
+
}
|
|
18973
19120
|
getToolDefinitions() {
|
|
18974
19121
|
return [rememberTool, recallTool];
|
|
18975
19122
|
}
|
|
@@ -18978,11 +19125,18 @@ class MemoryModule {
|
|
|
18978
19125
|
name: "memory",
|
|
18979
19126
|
isBuiltin: true,
|
|
18980
19127
|
onBuildPrompt: () => {
|
|
19128
|
+
const parts = [];
|
|
18981
19129
|
const prefs = this.store.getPreferences();
|
|
18982
|
-
if (Object.keys(prefs).length
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
19130
|
+
if (Object.keys(prefs).length > 0) {
|
|
19131
|
+
const prefStr = Object.entries(prefs).map(([k, v]) => `${k}=${v}`).join(", ");
|
|
19132
|
+
parts.push(`User preferences: ${prefStr}`);
|
|
19133
|
+
}
|
|
19134
|
+
const memoryTail = this.getMemoryTail();
|
|
19135
|
+
if (memoryTail)
|
|
19136
|
+
parts.push(memoryTail);
|
|
19137
|
+
return parts.length > 0 ? parts.join(`
|
|
19138
|
+
|
|
19139
|
+
`) : null;
|
|
18986
19140
|
}
|
|
18987
19141
|
};
|
|
18988
19142
|
}
|
|
@@ -18990,10 +19144,12 @@ class MemoryModule {
|
|
|
18990
19144
|
return this.store;
|
|
18991
19145
|
}
|
|
18992
19146
|
}
|
|
19147
|
+
var MEMORY_MD_FILES;
|
|
18993
19148
|
var init_module8 = __esm(() => {
|
|
18994
19149
|
init_store2();
|
|
18995
19150
|
init_remember();
|
|
18996
19151
|
init_recall();
|
|
19152
|
+
MEMORY_MD_FILES = ["errors", "conventions", "decisions", "facts"];
|
|
18997
19153
|
});
|
|
18998
19154
|
|
|
18999
19155
|
// src/core/bootstrap.ts
|
|
@@ -19003,8 +19159,8 @@ __export(exports_bootstrap, {
|
|
|
19003
19159
|
bootstrap: () => bootstrap
|
|
19004
19160
|
});
|
|
19005
19161
|
import { homedir as homedir11 } from "os";
|
|
19006
|
-
import { join as
|
|
19007
|
-
import { existsSync as
|
|
19162
|
+
import { join as join34, resolve as resolve21 } from "path";
|
|
19163
|
+
import { existsSync as existsSync40, readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "fs";
|
|
19008
19164
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
19009
19165
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
19010
19166
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -19021,6 +19177,7 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
19021
19177
|
if (config.autoPlan) {
|
|
19022
19178
|
lines.push(`Plan rule (MANDATORY): any task creating files, installing packages, or requiring multiple actions MUST create a plan with the "plan" tool BEFORE starting. Each step = a concrete deliverable.`);
|
|
19023
19179
|
}
|
|
19180
|
+
lines.push(`Runtime verification: when a bug is described in terms of runtime behavior (what happens when the app runs), reproduce it — run the app / build / browser tool — and confirm the fix against actual runtime output before calling "plan update step=N status=done".`);
|
|
19024
19181
|
const hasMCP = config.mcpServers && Object.values(config.mcpServers).some((s) => s.enabled !== false);
|
|
19025
19182
|
if (hasMCP) {
|
|
19026
19183
|
lines.push(`MCP servers are available — use the named MCP tools (prefixed mcp__) to query external services.`);
|
|
@@ -19029,8 +19186,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
19029
19186
|
`);
|
|
19030
19187
|
}
|
|
19031
19188
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
19032
|
-
const dir = configDir ||
|
|
19033
|
-
const projectConfigPath = projectDir ?
|
|
19189
|
+
const dir = configDir || join34(homedir11(), ".mma");
|
|
19190
|
+
const projectConfigPath = projectDir ? join34(projectDir, ".mmrc") : join34(process.cwd(), ".mmrc");
|
|
19034
19191
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
19035
19192
|
setLocale(config.locale);
|
|
19036
19193
|
try {
|
|
@@ -19040,7 +19197,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19040
19197
|
}
|
|
19041
19198
|
} catch {}
|
|
19042
19199
|
const logger = new Logger(config.logLevel);
|
|
19043
|
-
logger.setLogDir(
|
|
19200
|
+
logger.setLogDir(join34(dir, "logs"));
|
|
19044
19201
|
logger.debug("MMA bootstrap", {
|
|
19045
19202
|
version: config.version,
|
|
19046
19203
|
model: config.model
|
|
@@ -19062,7 +19219,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19062
19219
|
logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
19063
19220
|
}
|
|
19064
19221
|
}
|
|
19065
|
-
const profile = new UserProfile(
|
|
19222
|
+
const profile = new UserProfile(join34(dir));
|
|
19066
19223
|
profile.load() || profile.collect();
|
|
19067
19224
|
profile.save();
|
|
19068
19225
|
const llmProvider = new OpenAICompatProvider({
|
|
@@ -19074,7 +19231,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19074
19231
|
rateLimits: config.security?.rateLimits
|
|
19075
19232
|
});
|
|
19076
19233
|
const baseDir = projectDir ? resolve21(projectDir) : process.cwd();
|
|
19077
|
-
const projectMapCacheDir =
|
|
19234
|
+
const projectMapCacheDir = join34(baseDir, ".mma");
|
|
19078
19235
|
const indexerModule = new IndexerModule({
|
|
19079
19236
|
baseDir,
|
|
19080
19237
|
cacheDir: projectMapCacheDir
|
|
@@ -19085,9 +19242,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19085
19242
|
logger.warn(`Project indexing failed: ${err.message}`);
|
|
19086
19243
|
}
|
|
19087
19244
|
const skillsLoader = new SkillsLoader;
|
|
19088
|
-
const builtinDir =
|
|
19089
|
-
const globalDir =
|
|
19090
|
-
const projectSkillsDir =
|
|
19245
|
+
const builtinDir = join34(import.meta.dirname, "skills", "builtin");
|
|
19246
|
+
const globalDir = join34(homedir11(), ".agents", "skills");
|
|
19247
|
+
const projectSkillsDir = join34(baseDir, ".mma", "skills");
|
|
19091
19248
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
19092
19249
|
const skillsBudget = Math.floor(config.contextWindow * config.skills.budget);
|
|
19093
19250
|
const skillsModule = new SkillsModule(availableSkills, skillsBudget);
|
|
@@ -19101,11 +19258,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19101
19258
|
essential: true,
|
|
19102
19259
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
19103
19260
|
};
|
|
19104
|
-
const agentsMdGlobal =
|
|
19105
|
-
if (!
|
|
19261
|
+
const agentsMdGlobal = join34(dir, "AGENTS.md");
|
|
19262
|
+
if (!existsSync40(agentsMdGlobal)) {
|
|
19106
19263
|
writeFileSync15(agentsMdGlobal, "", "utf-8");
|
|
19107
19264
|
}
|
|
19108
|
-
const sessionDir =
|
|
19265
|
+
const sessionDir = join34(dir, "sessions");
|
|
19109
19266
|
const sessionStore = new SessionStore(sessionDir);
|
|
19110
19267
|
sessionStore.init();
|
|
19111
19268
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -19172,7 +19329,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19172
19329
|
const mcpModule = new MCPModule(config);
|
|
19173
19330
|
await mcpModule.initialize();
|
|
19174
19331
|
moduleRegistry.register(mcpModule);
|
|
19175
|
-
const
|
|
19332
|
+
const memoryStore = new MemoryStore(join34(dir, "memory"));
|
|
19333
|
+
const memoryModule = new MemoryModule(memoryStore);
|
|
19176
19334
|
moduleRegistry.register(memoryModule);
|
|
19177
19335
|
if (config.browser.enabled) {
|
|
19178
19336
|
const browserModule = new BrowserModule;
|
|
@@ -19222,8 +19380,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19222
19380
|
pluginManager.register(plugin);
|
|
19223
19381
|
pluginManager.register(plugin2);
|
|
19224
19382
|
const pluginLoader = new PluginLoader;
|
|
19225
|
-
const globalPluginsDir =
|
|
19226
|
-
const projectPluginsDir =
|
|
19383
|
+
const globalPluginsDir = join34(homedir11(), ".mma", "plugins");
|
|
19384
|
+
const projectPluginsDir = join34(baseDir, ".mma", "plugins");
|
|
19227
19385
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
|
|
19228
19386
|
pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
|
|
19229
19387
|
contextManager.onCompact = (summary) => {
|
|
@@ -19241,12 +19399,12 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19241
19399
|
const skipAgentsMd = noAgentsMd === true;
|
|
19242
19400
|
if (!skipAgentsMd) {
|
|
19243
19401
|
const agentsMdCandidates = [
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19402
|
+
join34(baseDir, "AGENTS.md"),
|
|
19403
|
+
join34(baseDir, ".mma", "AGENTS.md"),
|
|
19404
|
+
join34(dir, "AGENTS.md")
|
|
19247
19405
|
];
|
|
19248
19406
|
for (const p of agentsMdCandidates) {
|
|
19249
|
-
if (
|
|
19407
|
+
if (existsSync40(p)) {
|
|
19250
19408
|
const content = readFileSync25(p, "utf-8").trim();
|
|
19251
19409
|
if (content) {
|
|
19252
19410
|
agentsMdBlocks.push({
|
|
@@ -19289,6 +19447,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
19289
19447
|
},
|
|
19290
19448
|
finalAudit: () => execModule.runFinalAudit(),
|
|
19291
19449
|
sessionManager,
|
|
19450
|
+
memoryStore,
|
|
19292
19451
|
exitOnComplete
|
|
19293
19452
|
};
|
|
19294
19453
|
const agent = new Agent(agentDeps);
|
|
@@ -19325,6 +19484,7 @@ var init_bootstrap = __esm(() => {
|
|
|
19325
19484
|
init_indexer();
|
|
19326
19485
|
init_mcp();
|
|
19327
19486
|
init_module8();
|
|
19487
|
+
init_store2();
|
|
19328
19488
|
init_i18n();
|
|
19329
19489
|
init_agent();
|
|
19330
19490
|
});
|
|
@@ -20099,12 +20259,12 @@ __export(exports_manifest, {
|
|
|
20099
20259
|
getCertMark: () => getCertMark,
|
|
20100
20260
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
20101
20261
|
});
|
|
20102
|
-
import { existsSync as
|
|
20262
|
+
import { existsSync as existsSync41, readFileSync as readFileSync26, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "fs";
|
|
20103
20263
|
import { homedir as homedir13 } from "os";
|
|
20104
|
-
import { join as
|
|
20264
|
+
import { join as join36 } from "path";
|
|
20105
20265
|
function readManifest(path = MANIFEST_PATH) {
|
|
20106
20266
|
try {
|
|
20107
|
-
if (
|
|
20267
|
+
if (existsSync41(path)) {
|
|
20108
20268
|
const raw = JSON.parse(readFileSync26(path, "utf-8"));
|
|
20109
20269
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
20110
20270
|
}
|
|
@@ -20112,7 +20272,7 @@ function readManifest(path = MANIFEST_PATH) {
|
|
|
20112
20272
|
return { version: 1, certifications: [] };
|
|
20113
20273
|
}
|
|
20114
20274
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
20115
|
-
mkdirSync18(
|
|
20275
|
+
mkdirSync18(join36(homedir13(), ".mma"), { recursive: true });
|
|
20116
20276
|
writeFileSync16(path, JSON.stringify(m, null, 2), "utf-8");
|
|
20117
20277
|
}
|
|
20118
20278
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
@@ -20147,7 +20307,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
|
|
|
20147
20307
|
}
|
|
20148
20308
|
var MANIFEST_PATH;
|
|
20149
20309
|
var init_manifest = __esm(() => {
|
|
20150
|
-
MANIFEST_PATH =
|
|
20310
|
+
MANIFEST_PATH = join36(homedir13(), ".mma", "certifications.json");
|
|
20151
20311
|
});
|
|
20152
20312
|
|
|
20153
20313
|
// node_modules/yaml/dist/nodes/identity.js
|
|
@@ -27270,8 +27430,8 @@ var init_scenarios = __esm(() => {
|
|
|
27270
27430
|
});
|
|
27271
27431
|
|
|
27272
27432
|
// src/modules/certification/loader.ts
|
|
27273
|
-
import { existsSync as
|
|
27274
|
-
import { join as
|
|
27433
|
+
import { existsSync as existsSync42, readdirSync as readdirSync14, readFileSync as readFileSync27 } from "fs";
|
|
27434
|
+
import { join as join37 } from "path";
|
|
27275
27435
|
function validateScenario(s) {
|
|
27276
27436
|
const errors2 = [];
|
|
27277
27437
|
const isSkip = s.mode === "skip";
|
|
@@ -27320,12 +27480,12 @@ function loadScenarios(userDir) {
|
|
|
27320
27480
|
else
|
|
27321
27481
|
scenarios.push(s);
|
|
27322
27482
|
}
|
|
27323
|
-
if (userDir &&
|
|
27483
|
+
if (userDir && existsSync42(userDir)) {
|
|
27324
27484
|
for (const file of readdirSync14(userDir)) {
|
|
27325
27485
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
27326
27486
|
continue;
|
|
27327
27487
|
try {
|
|
27328
|
-
const raw = readFileSync27(
|
|
27488
|
+
const raw = readFileSync27(join37(userDir, file), "utf-8");
|
|
27329
27489
|
const data = $parse(raw);
|
|
27330
27490
|
const parsed = normalizeScenario(data, file);
|
|
27331
27491
|
const errs = validateScenario(parsed);
|
|
@@ -27378,8 +27538,8 @@ var init_loader3 = __esm(() => {
|
|
|
27378
27538
|
});
|
|
27379
27539
|
|
|
27380
27540
|
// src/modules/certification/fact-checker.ts
|
|
27381
|
-
import { existsSync as
|
|
27382
|
-
import { join as
|
|
27541
|
+
import { existsSync as existsSync43, readFileSync as readFileSync28, statSync as statSync8 } from "fs";
|
|
27542
|
+
import { join as join38 } from "path";
|
|
27383
27543
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
27384
27544
|
const failures = [];
|
|
27385
27545
|
for (const check of checks) {
|
|
@@ -27396,13 +27556,13 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27396
27556
|
case "outputContains":
|
|
27397
27557
|
return output.includes(check.text);
|
|
27398
27558
|
case "fileExists":
|
|
27399
|
-
return isFile(
|
|
27559
|
+
return isFile(join38(sandboxDir, check.path));
|
|
27400
27560
|
case "fileNotExists":
|
|
27401
|
-
return !
|
|
27561
|
+
return !existsSync43(join38(sandboxDir, check.path));
|
|
27402
27562
|
case "dirExists":
|
|
27403
|
-
return isDir(
|
|
27563
|
+
return isDir(join38(sandboxDir, check.path));
|
|
27404
27564
|
case "fileContent": {
|
|
27405
|
-
const abs =
|
|
27565
|
+
const abs = join38(sandboxDir, check.path);
|
|
27406
27566
|
if (!isFile(abs))
|
|
27407
27567
|
return false;
|
|
27408
27568
|
const content = readFileSync28(abs, "utf-8");
|
|
@@ -27413,7 +27573,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27413
27573
|
return false;
|
|
27414
27574
|
}
|
|
27415
27575
|
case "fileRegex": {
|
|
27416
|
-
const abs =
|
|
27576
|
+
const abs = join38(sandboxDir, check.path);
|
|
27417
27577
|
if (!isFile(abs))
|
|
27418
27578
|
return false;
|
|
27419
27579
|
return new RegExp(check.pattern).test(readFileSync28(abs, "utf-8"));
|
|
@@ -27424,14 +27584,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
27424
27584
|
}
|
|
27425
27585
|
function isFile(p) {
|
|
27426
27586
|
try {
|
|
27427
|
-
return
|
|
27587
|
+
return existsSync43(p) && statSync8(p).isFile();
|
|
27428
27588
|
} catch {
|
|
27429
27589
|
return false;
|
|
27430
27590
|
}
|
|
27431
27591
|
}
|
|
27432
27592
|
function isDir(p) {
|
|
27433
27593
|
try {
|
|
27434
|
-
return
|
|
27594
|
+
return existsSync43(p) && statSync8(p).isDirectory();
|
|
27435
27595
|
} catch {
|
|
27436
27596
|
return false;
|
|
27437
27597
|
}
|
|
@@ -27462,9 +27622,9 @@ var init_fact_checker = () => {};
|
|
|
27462
27622
|
|
|
27463
27623
|
// src/modules/certification/runner.ts
|
|
27464
27624
|
import { spawn as spawn7 } from "child_process";
|
|
27465
|
-
import { existsSync as
|
|
27625
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync19, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
27466
27626
|
import { platform as platform7 } from "os";
|
|
27467
|
-
import { join as
|
|
27627
|
+
import { join as join39, resolve as resolve22, dirname as dirname12 } from "path";
|
|
27468
27628
|
async function runScenario(scenario, opts) {
|
|
27469
27629
|
if (scenario.mode === "skip") {
|
|
27470
27630
|
return {
|
|
@@ -27483,7 +27643,7 @@ async function runScenario(scenario, opts) {
|
|
|
27483
27643
|
let passed = 0;
|
|
27484
27644
|
let firstError;
|
|
27485
27645
|
for (let i = 1;i <= reps; i++) {
|
|
27486
|
-
const sandbox =
|
|
27646
|
+
const sandbox = join39(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
27487
27647
|
let failures = [];
|
|
27488
27648
|
let exitCode = -1;
|
|
27489
27649
|
let output = "";
|
|
@@ -27544,20 +27704,20 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
27544
27704
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
27545
27705
|
mkdirSync19(sandbox, { recursive: true });
|
|
27546
27706
|
for (const f of scenario.fixtures ?? []) {
|
|
27547
|
-
const src =
|
|
27548
|
-
if (!
|
|
27707
|
+
const src = join39(mmaRoot, f.source);
|
|
27708
|
+
if (!existsSync44(src)) {
|
|
27549
27709
|
throw new Error(`fixture missing: ${f.source}`);
|
|
27550
27710
|
}
|
|
27551
|
-
const dest =
|
|
27552
|
-
mkdirSync19(
|
|
27711
|
+
const dest = join39(sandbox, f.dest);
|
|
27712
|
+
mkdirSync19(dirname12(dest), { recursive: true });
|
|
27553
27713
|
cpSync2(src, dest);
|
|
27554
27714
|
}
|
|
27555
27715
|
}
|
|
27556
27716
|
function resolveMmaEntry(mmaRoot) {
|
|
27557
|
-
const dev =
|
|
27558
|
-
if (
|
|
27717
|
+
const dev = join39(mmaRoot, "src", "cli", "main.ts");
|
|
27718
|
+
if (existsSync44(dev))
|
|
27559
27719
|
return dev;
|
|
27560
|
-
return
|
|
27720
|
+
return join39(mmaRoot, "dist", "main.js");
|
|
27561
27721
|
}
|
|
27562
27722
|
function findMmaRoot(fromDir) {
|
|
27563
27723
|
const candidates = [
|
|
@@ -27565,7 +27725,7 @@ function findMmaRoot(fromDir) {
|
|
|
27565
27725
|
resolve22(fromDir, "..")
|
|
27566
27726
|
];
|
|
27567
27727
|
for (const c of candidates) {
|
|
27568
|
-
if (
|
|
27728
|
+
if (existsSync44(join39(c, "package.json")))
|
|
27569
27729
|
return c;
|
|
27570
27730
|
}
|
|
27571
27731
|
return process.cwd();
|
|
@@ -27633,13 +27793,13 @@ __export(exports_cli, {
|
|
|
27633
27793
|
});
|
|
27634
27794
|
import { rmSync as rmSync5 } from "fs";
|
|
27635
27795
|
import { homedir as homedir14 } from "os";
|
|
27636
|
-
import { join as
|
|
27796
|
+
import { join as join40, dirname as dirname13 } from "path";
|
|
27637
27797
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
27638
|
-
import { existsSync as
|
|
27798
|
+
import { existsSync as existsSync45, readFileSync as readFileSync29 } from "fs";
|
|
27639
27799
|
function readVersion() {
|
|
27640
|
-
const candidates = [
|
|
27800
|
+
const candidates = [join40(MMA_ROOT, "package.json")];
|
|
27641
27801
|
for (const p of candidates) {
|
|
27642
|
-
if (
|
|
27802
|
+
if (existsSync45(p)) {
|
|
27643
27803
|
try {
|
|
27644
27804
|
const raw = JSON.parse(readFileSync29(p, "utf-8"));
|
|
27645
27805
|
if (raw.version)
|
|
@@ -27677,7 +27837,7 @@ async function certify(opts) {
|
|
|
27677
27837
|
return;
|
|
27678
27838
|
}
|
|
27679
27839
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
27680
|
-
const sandboxBase =
|
|
27840
|
+
const sandboxBase = join40(process.cwd(), ".mma", "certification");
|
|
27681
27841
|
const results = [];
|
|
27682
27842
|
const total = selected.length;
|
|
27683
27843
|
let idx = 0;
|
|
@@ -27789,9 +27949,9 @@ var init_cli = __esm(() => {
|
|
|
27789
27949
|
init_loader3();
|
|
27790
27950
|
init_runner2();
|
|
27791
27951
|
init_manifest();
|
|
27792
|
-
HERE =
|
|
27952
|
+
HERE = dirname13(fileURLToPath2(import.meta.url));
|
|
27793
27953
|
MMA_ROOT = findMmaRoot(HERE);
|
|
27794
|
-
USER_SCENARIO_DIR =
|
|
27954
|
+
USER_SCENARIO_DIR = join40(homedir14(), ".mma", "certification", "scenarios");
|
|
27795
27955
|
});
|
|
27796
27956
|
|
|
27797
27957
|
// src/cli/repl-commands.ts
|
|
@@ -27800,18 +27960,18 @@ __export(exports_repl_commands, {
|
|
|
27800
27960
|
registerAllCommands: () => registerAllCommands,
|
|
27801
27961
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
27802
27962
|
});
|
|
27803
|
-
import { join as
|
|
27963
|
+
import { join as join42, dirname as dirname15 } from "path";
|
|
27804
27964
|
import { homedir as homedir16 } from "os";
|
|
27805
|
-
import { existsSync as
|
|
27965
|
+
import { existsSync as existsSync47, readFileSync as readFileSync31 } from "fs";
|
|
27806
27966
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
27807
27967
|
function readVersion3() {
|
|
27808
|
-
const here =
|
|
27968
|
+
const here = dirname15(fileURLToPath4(import.meta.url));
|
|
27809
27969
|
const candidates = [
|
|
27810
|
-
|
|
27811
|
-
|
|
27970
|
+
join42(here, "..", "..", "package.json"),
|
|
27971
|
+
join42(here, "..", "package.json")
|
|
27812
27972
|
];
|
|
27813
27973
|
for (const p of candidates) {
|
|
27814
|
-
if (
|
|
27974
|
+
if (existsSync47(p)) {
|
|
27815
27975
|
try {
|
|
27816
27976
|
const raw = JSON.parse(readFileSync31(p, "utf8"));
|
|
27817
27977
|
if (raw.version)
|
|
@@ -27877,7 +28037,7 @@ function registerMmaCommands(ctx) {
|
|
|
27877
28037
|
}
|
|
27878
28038
|
try {
|
|
27879
28039
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
27880
|
-
const { existsSync:
|
|
28040
|
+
const { existsSync: existsSync48 } = await import("fs");
|
|
27881
28041
|
const { resolve: resolve23 } = await import("path");
|
|
27882
28042
|
let dataUrl;
|
|
27883
28043
|
let label;
|
|
@@ -27897,7 +28057,7 @@ function registerMmaCommands(ctx) {
|
|
|
27897
28057
|
label = source;
|
|
27898
28058
|
} else {
|
|
27899
28059
|
const absPath = resolve23(process.cwd(), source);
|
|
27900
|
-
if (!
|
|
28060
|
+
if (!existsSync48(absPath)) {
|
|
27901
28061
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
27902
28062
|
return;
|
|
27903
28063
|
}
|
|
@@ -27976,7 +28136,7 @@ function registerMmaCommands(ctx) {
|
|
|
27976
28136
|
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
27977
28137
|
await ctx.withExclusiveInput(async () => {
|
|
27978
28138
|
const answers = await runSetup(ctx.rl);
|
|
27979
|
-
const configPath =
|
|
28139
|
+
const configPath = join42(homedir16(), ".mma", "config.json");
|
|
27980
28140
|
ctx.config.provider.type = answers.provider;
|
|
27981
28141
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
27982
28142
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -28030,7 +28190,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
28030
28190
|
return;
|
|
28031
28191
|
}
|
|
28032
28192
|
ctx.config.provider.type = name;
|
|
28033
|
-
const configPath =
|
|
28193
|
+
const configPath = join42(homedir16(), ".mma", "config.json");
|
|
28034
28194
|
saveConfig(ctx.config, configPath);
|
|
28035
28195
|
await ctx.agent.reconfigure(ctx.config);
|
|
28036
28196
|
console.log(pc2.green(t("repl.provider_set", { name })));
|
|
@@ -28086,7 +28246,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
28086
28246
|
return;
|
|
28087
28247
|
}
|
|
28088
28248
|
ctx.config.model = name;
|
|
28089
|
-
const configPath =
|
|
28249
|
+
const configPath = join42(homedir16(), ".mma", "config.json");
|
|
28090
28250
|
saveConfig(ctx.config, configPath);
|
|
28091
28251
|
await ctx.agent.reconfigure(ctx.config);
|
|
28092
28252
|
console.log(pc2.green(t("repl.model_set", { name })));
|
|
@@ -28111,7 +28271,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
28111
28271
|
return;
|
|
28112
28272
|
}
|
|
28113
28273
|
ctx.config.contextWindow = size;
|
|
28114
|
-
const configPath =
|
|
28274
|
+
const configPath = join42(homedir16(), ".mma", "config.json");
|
|
28115
28275
|
saveConfig(ctx.config, configPath);
|
|
28116
28276
|
await ctx.agent.reconfigure(ctx.config);
|
|
28117
28277
|
console.log(pc2.green(t("cli.context_set", { size })));
|
|
@@ -28130,10 +28290,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
28130
28290
|
ctx.agent.shutdown();
|
|
28131
28291
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
28132
28292
|
const { homedir: homedir17 } = await import("os");
|
|
28133
|
-
const { join:
|
|
28293
|
+
const { join: join43 } = await import("path");
|
|
28134
28294
|
const configDir = ctx.configDir;
|
|
28135
28295
|
const baseDir = ctx.baseDir;
|
|
28136
|
-
const projectConfigPath =
|
|
28296
|
+
const projectConfigPath = join43(baseDir, ".mmrc");
|
|
28137
28297
|
const freshConfig = loadConfig2({ configDir, projectConfigPath });
|
|
28138
28298
|
Object.assign(ctx.config, freshConfig);
|
|
28139
28299
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -28433,14 +28593,14 @@ init_bootstrap();
|
|
|
28433
28593
|
init_config2();
|
|
28434
28594
|
init_setup();
|
|
28435
28595
|
init_i18n();
|
|
28436
|
-
import { join as
|
|
28596
|
+
import { join as join41, dirname as dirname14 } from "path";
|
|
28437
28597
|
import { homedir as homedir15 } from "os";
|
|
28438
|
-
import { existsSync as
|
|
28598
|
+
import { existsSync as existsSync46, readFileSync as readFileSync30 } from "fs";
|
|
28439
28599
|
|
|
28440
28600
|
// src/cli/security-commands.ts
|
|
28441
28601
|
init_bootstrap();
|
|
28442
28602
|
init_config2();
|
|
28443
|
-
import { join as
|
|
28603
|
+
import { join as join35 } from "path";
|
|
28444
28604
|
import { homedir as homedir12 } from "os";
|
|
28445
28605
|
|
|
28446
28606
|
// src/modules/security/security-policies.ts
|
|
@@ -28970,7 +29130,7 @@ function createSecurityCommand(program2) {
|
|
|
28970
29130
|
}
|
|
28971
29131
|
});
|
|
28972
29132
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
28973
|
-
const configPath =
|
|
29133
|
+
const configPath = join35(homedir12(), ".mma", "config.json");
|
|
28974
29134
|
const { config: appConfig } = await bootstrap();
|
|
28975
29135
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
28976
29136
|
if (!validPresets.includes(preset)) {
|
|
@@ -28985,7 +29145,7 @@ function createSecurityCommand(program2) {
|
|
|
28985
29145
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
28986
29146
|
});
|
|
28987
29147
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
28988
|
-
const configPath =
|
|
29148
|
+
const configPath = join35(homedir12(), ".mma", "config.json");
|
|
28989
29149
|
const { config: appConfig } = await bootstrap();
|
|
28990
29150
|
appConfig.security = appConfig.security || {};
|
|
28991
29151
|
appConfig.security.sessionEncryption = {
|
|
@@ -28997,7 +29157,7 @@ function createSecurityCommand(program2) {
|
|
|
28997
29157
|
console.log(t("cli.security.encryption_enabled"));
|
|
28998
29158
|
});
|
|
28999
29159
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
29000
|
-
const configPath =
|
|
29160
|
+
const configPath = join35(homedir12(), ".mma", "config.json");
|
|
29001
29161
|
const { config: appConfig } = await bootstrap();
|
|
29002
29162
|
appConfig.security = appConfig.security || {};
|
|
29003
29163
|
appConfig.security.sessionEncryption = {
|
|
@@ -29009,7 +29169,7 @@ function createSecurityCommand(program2) {
|
|
|
29009
29169
|
console.log(t("cli.security.encryption_disabled"));
|
|
29010
29170
|
});
|
|
29011
29171
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
29012
|
-
const configPath =
|
|
29172
|
+
const configPath = join35(homedir12(), ".mma", "config.json");
|
|
29013
29173
|
const { config: appConfig } = await bootstrap();
|
|
29014
29174
|
appConfig.security = appConfig.security || {};
|
|
29015
29175
|
appConfig.security.auditNotifier = {
|
|
@@ -29023,7 +29183,7 @@ function createSecurityCommand(program2) {
|
|
|
29023
29183
|
console.log(t("cli.security.audit_enabled"));
|
|
29024
29184
|
});
|
|
29025
29185
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
29026
|
-
const configPath =
|
|
29186
|
+
const configPath = join35(homedir12(), ".mma", "config.json");
|
|
29027
29187
|
const { config: appConfig } = await bootstrap();
|
|
29028
29188
|
appConfig.security = appConfig.security || {};
|
|
29029
29189
|
appConfig.security.auditNotifier = {
|
|
@@ -29057,13 +29217,13 @@ function createSecurityCommand(program2) {
|
|
|
29057
29217
|
// src/cli/commands.ts
|
|
29058
29218
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
29059
29219
|
function readVersion2() {
|
|
29060
|
-
const here =
|
|
29220
|
+
const here = dirname14(fileURLToPath3(import.meta.url));
|
|
29061
29221
|
const candidates = [
|
|
29062
|
-
|
|
29063
|
-
|
|
29222
|
+
join41(here, "..", "..", "package.json"),
|
|
29223
|
+
join41(here, "..", "package.json")
|
|
29064
29224
|
];
|
|
29065
29225
|
for (const p of candidates) {
|
|
29066
|
-
if (
|
|
29226
|
+
if (existsSync46(p)) {
|
|
29067
29227
|
try {
|
|
29068
29228
|
const raw = JSON.parse(readFileSync30(p, "utf8"));
|
|
29069
29229
|
if (raw.version)
|
|
@@ -29078,7 +29238,7 @@ function createProgram() {
|
|
|
29078
29238
|
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"));
|
|
29079
29239
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
29080
29240
|
const answers = await runSetup();
|
|
29081
|
-
const configPath =
|
|
29241
|
+
const configPath = join41(homedir15(), ".mma", "config.json");
|
|
29082
29242
|
const { config } = await bootstrap();
|
|
29083
29243
|
config.provider.type = answers.provider;
|
|
29084
29244
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -29123,7 +29283,7 @@ function createProgram() {
|
|
|
29123
29283
|
});
|
|
29124
29284
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
29125
29285
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
29126
|
-
const configPath =
|
|
29286
|
+
const configPath = join41(homedir15(), ".mma", "config.json");
|
|
29127
29287
|
const { config } = await bootstrap();
|
|
29128
29288
|
const keys = key.split(".");
|
|
29129
29289
|
let obj = config;
|
|
@@ -29186,7 +29346,7 @@ function createProgram() {
|
|
|
29186
29346
|
console.log(t("cli.model_hint"));
|
|
29187
29347
|
});
|
|
29188
29348
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
29189
|
-
const configPath =
|
|
29349
|
+
const configPath = join41(homedir15(), ".mma", "config.json");
|
|
29190
29350
|
const { config } = await bootstrap();
|
|
29191
29351
|
config.model = name;
|
|
29192
29352
|
saveConfig(config, configPath);
|
|
@@ -29222,7 +29382,7 @@ function createProgram() {
|
|
|
29222
29382
|
await uncertify2(name, config);
|
|
29223
29383
|
});
|
|
29224
29384
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
29225
|
-
const configPath =
|
|
29385
|
+
const configPath = join41(homedir15(), ".mma", "config.json");
|
|
29226
29386
|
const { config } = await bootstrap();
|
|
29227
29387
|
const contextWindow = parseInt(size, 10);
|
|
29228
29388
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -29240,7 +29400,7 @@ function createProgram() {
|
|
|
29240
29400
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
29241
29401
|
});
|
|
29242
29402
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
29243
|
-
const configPath =
|
|
29403
|
+
const configPath = join41(homedir15(), ".mma", "config.json");
|
|
29244
29404
|
const { config } = await bootstrap();
|
|
29245
29405
|
config.provider.type = name;
|
|
29246
29406
|
saveConfig(config, configPath);
|
|
@@ -30010,8 +30170,8 @@ class LineEditor {
|
|
|
30010
30170
|
}
|
|
30011
30171
|
|
|
30012
30172
|
// src/cli/repl.ts
|
|
30013
|
-
import { existsSync as
|
|
30014
|
-
import { join as
|
|
30173
|
+
import { existsSync as existsSync48, readFileSync as readFileSync32, writeFileSync as writeFileSync17 } from "fs";
|
|
30174
|
+
import { join as join43, dirname as dirname16 } from "path";
|
|
30015
30175
|
import { homedir as homedir17 } from "os";
|
|
30016
30176
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
30017
30177
|
|
|
@@ -30515,13 +30675,13 @@ init_box();
|
|
|
30515
30675
|
init_i18n();
|
|
30516
30676
|
init_repl_commands();
|
|
30517
30677
|
function readVersion4() {
|
|
30518
|
-
const here =
|
|
30678
|
+
const here = dirname16(fileURLToPath5(import.meta.url));
|
|
30519
30679
|
const candidates = [
|
|
30520
|
-
|
|
30521
|
-
|
|
30680
|
+
join43(here, "..", "..", "package.json"),
|
|
30681
|
+
join43(here, "..", "package.json")
|
|
30522
30682
|
];
|
|
30523
30683
|
for (const p of candidates) {
|
|
30524
|
-
if (
|
|
30684
|
+
if (existsSync48(p)) {
|
|
30525
30685
|
try {
|
|
30526
30686
|
const raw = JSON.parse(readFileSync32(p, "utf8"));
|
|
30527
30687
|
if (raw.version)
|
|
@@ -30579,10 +30739,10 @@ class Repl {
|
|
|
30579
30739
|
this.skillsModule = skillsModule;
|
|
30580
30740
|
this.pluginManager = pluginManager;
|
|
30581
30741
|
this.logger = logger;
|
|
30582
|
-
this.configDir = configDir ||
|
|
30742
|
+
this.configDir = configDir || join43(homedir17(), ".mma");
|
|
30583
30743
|
this.baseDir = baseDir || process.cwd();
|
|
30584
30744
|
this.noAgentsMd = noAgentsMd === true;
|
|
30585
|
-
this.historyPath =
|
|
30745
|
+
this.historyPath = join43(homedir17(), ".mma", "repl-history");
|
|
30586
30746
|
this.loadHistory();
|
|
30587
30747
|
this.rl = process.stdin.isTTY ? new LineEditor({
|
|
30588
30748
|
input: process.stdin,
|
|
@@ -30615,7 +30775,7 @@ class Repl {
|
|
|
30615
30775
|
this.setupListeners();
|
|
30616
30776
|
}
|
|
30617
30777
|
loadHistory() {
|
|
30618
|
-
if (
|
|
30778
|
+
if (existsSync48(this.historyPath)) {
|
|
30619
30779
|
try {
|
|
30620
30780
|
const raw = readFileSync32(this.historyPath, "utf-8");
|
|
30621
30781
|
this.history = raw.split(`
|
|
@@ -30974,11 +31134,11 @@ ${t("image.clipboard_empty")}`));
|
|
|
30974
31134
|
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
30975
31135
|
} else {
|
|
30976
31136
|
const agentsMdCandidates = [
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
31137
|
+
join43(this.baseDir, "AGENTS.md"),
|
|
31138
|
+
join43(this.baseDir, ".mma", "AGENTS.md"),
|
|
31139
|
+
join43(this.configDir, "AGENTS.md")
|
|
30980
31140
|
];
|
|
30981
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
31141
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync48(p));
|
|
30982
31142
|
if (foundAgents.length > 0) {
|
|
30983
31143
|
for (const p of foundAgents) {
|
|
30984
31144
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -30989,7 +31149,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
30989
31149
|
}
|
|
30990
31150
|
const meta = this.sessionManager?.getActiveMeta();
|
|
30991
31151
|
if (meta) {
|
|
30992
|
-
const sessionPath =
|
|
31152
|
+
const sessionPath = join43(this.configDir, "sessions", meta.id);
|
|
30993
31153
|
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
30994
31154
|
}
|
|
30995
31155
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
@@ -31030,8 +31190,8 @@ init_setup();
|
|
|
31030
31190
|
init_config2();
|
|
31031
31191
|
init_i18n();
|
|
31032
31192
|
init_colors();
|
|
31033
|
-
import { existsSync as
|
|
31034
|
-
import { join as
|
|
31193
|
+
import { existsSync as existsSync49, readFileSync as readFileSync33 } from "fs";
|
|
31194
|
+
import { join as join44, dirname as dirname17 } from "path";
|
|
31035
31195
|
import { homedir as homedir18 } from "os";
|
|
31036
31196
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
31037
31197
|
|
|
@@ -31193,13 +31353,13 @@ class UpdaterModule {
|
|
|
31193
31353
|
}
|
|
31194
31354
|
// src/cli/main.ts
|
|
31195
31355
|
function readVersion5() {
|
|
31196
|
-
const here =
|
|
31356
|
+
const here = dirname17(fileURLToPath6(import.meta.url));
|
|
31197
31357
|
const candidates = [
|
|
31198
|
-
|
|
31199
|
-
|
|
31358
|
+
join44(here, "..", "..", "package.json"),
|
|
31359
|
+
join44(here, "..", "package.json")
|
|
31200
31360
|
];
|
|
31201
31361
|
for (const p of candidates) {
|
|
31202
|
-
if (
|
|
31362
|
+
if (existsSync49(p)) {
|
|
31203
31363
|
try {
|
|
31204
31364
|
const raw = JSON.parse(readFileSync33(p, "utf8"));
|
|
31205
31365
|
if (raw.version)
|
|
@@ -31272,15 +31432,15 @@ async function main() {
|
|
|
31272
31432
|
agent.shutdown();
|
|
31273
31433
|
process.exit(exitCode);
|
|
31274
31434
|
} else {
|
|
31275
|
-
const configPath =
|
|
31276
|
-
if (!
|
|
31435
|
+
const configPath = join44(homedir18(), ".mma", "config.json");
|
|
31436
|
+
if (!existsSync49(configPath)) {
|
|
31277
31437
|
console.log(pc2.yellow(`
|
|
31278
31438
|
` + t("cli.first_run") + `
|
|
31279
31439
|
`));
|
|
31280
31440
|
const answers = await runSetup();
|
|
31281
31441
|
const config2 = loadConfig({
|
|
31282
|
-
configDir:
|
|
31283
|
-
projectConfigPath: projectDir ?
|
|
31442
|
+
configDir: join44(homedir18(), ".mma"),
|
|
31443
|
+
projectConfigPath: projectDir ? join44(projectDir, ".mmrc") : join44(process.cwd(), ".mmrc")
|
|
31284
31444
|
});
|
|
31285
31445
|
config2.provider.type = answers.provider;
|
|
31286
31446
|
config2.provider.baseUrl = answers.apiBase;
|