micro-models-agent 0.28.1 → 0.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +573 -465
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2210,7 +2210,7 @@ var init_defaults = __esm(() => {
|
|
|
2210
2210
|
maxDelay: 30000
|
|
2211
2211
|
},
|
|
2212
2212
|
maxToolIterations: 1000,
|
|
2213
|
-
stuckThreshold:
|
|
2213
|
+
stuckThreshold: 6,
|
|
2214
2214
|
autoPlan: true,
|
|
2215
2215
|
showReasoning: false,
|
|
2216
2216
|
logLevel: "info",
|
|
@@ -3921,14 +3921,88 @@ var init_data_sanitizer = __esm(() => {
|
|
|
3921
3921
|
];
|
|
3922
3922
|
});
|
|
3923
3923
|
|
|
3924
|
+
// node_modules/picocolors/picocolors.js
|
|
3925
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
3926
|
+
var p = process || {};
|
|
3927
|
+
var argv = p.argv || [];
|
|
3928
|
+
var env = p.env || {};
|
|
3929
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
3930
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
3931
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
3932
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
3933
|
+
};
|
|
3934
|
+
var replaceClose = (string, close, replace, index) => {
|
|
3935
|
+
let result = "", cursor = 0;
|
|
3936
|
+
do {
|
|
3937
|
+
result += string.substring(cursor, index) + replace;
|
|
3938
|
+
cursor = index + close.length;
|
|
3939
|
+
index = string.indexOf(close, cursor);
|
|
3940
|
+
} while (~index);
|
|
3941
|
+
return result + string.substring(cursor);
|
|
3942
|
+
};
|
|
3943
|
+
var createColors = (enabled = isColorSupported) => {
|
|
3944
|
+
let f = enabled ? formatter : () => String;
|
|
3945
|
+
return {
|
|
3946
|
+
isColorSupported: enabled,
|
|
3947
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
3948
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
3949
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
3950
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
3951
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
3952
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
3953
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
3954
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
3955
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
3956
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
3957
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
3958
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
3959
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
3960
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
3961
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
3962
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
3963
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
3964
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
3965
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
3966
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
3967
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
3968
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
3969
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
3970
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
3971
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
3972
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
3973
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
3974
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
3975
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
3976
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
3977
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
3978
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
3979
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
3980
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
3981
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
3982
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
3983
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
3984
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
3985
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
3986
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
3987
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
3988
|
+
};
|
|
3989
|
+
};
|
|
3990
|
+
module.exports = createColors();
|
|
3991
|
+
module.exports.createColors = createColors;
|
|
3992
|
+
});
|
|
3993
|
+
|
|
3924
3994
|
// src/logger/app-logger.ts
|
|
3925
3995
|
import { appendFileSync, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
|
|
3926
3996
|
import { join as join5 } from "path";
|
|
3997
|
+
function isColorEnabled() {
|
|
3998
|
+
return !process.env.NO_COLOR && !process.env.CI && process.stdout.isTTY === true;
|
|
3999
|
+
}
|
|
3927
4000
|
|
|
3928
4001
|
class Logger {
|
|
3929
4002
|
level;
|
|
3930
4003
|
prefix;
|
|
3931
4004
|
logDir = null;
|
|
4005
|
+
sessionDir = null;
|
|
3932
4006
|
constructor(level = "info", prefix = "") {
|
|
3933
4007
|
this.level = level;
|
|
3934
4008
|
this.prefix = prefix;
|
|
@@ -3942,10 +4016,21 @@ class Logger {
|
|
|
3942
4016
|
mkdirSync3(dir, { recursive: true });
|
|
3943
4017
|
}
|
|
3944
4018
|
}
|
|
4019
|
+
setSessionDir(dir) {
|
|
4020
|
+
this.sessionDir = dir;
|
|
4021
|
+
if (!existsSync5(dir)) {
|
|
4022
|
+
mkdirSync3(dir, { recursive: true });
|
|
4023
|
+
}
|
|
4024
|
+
}
|
|
4025
|
+
clearSessionDir() {
|
|
4026
|
+
this.sessionDir = null;
|
|
4027
|
+
}
|
|
3945
4028
|
child(prefix) {
|
|
3946
4029
|
const childLogger = new Logger(this.level, this.prefix ? `${this.prefix}:${prefix}` : prefix);
|
|
3947
4030
|
if (this.logDir)
|
|
3948
4031
|
childLogger.setLogDir(this.logDir);
|
|
4032
|
+
if (this.sessionDir)
|
|
4033
|
+
childLogger.setSessionDir(this.sessionDir);
|
|
3949
4034
|
return childLogger;
|
|
3950
4035
|
}
|
|
3951
4036
|
debug(msg, meta) {
|
|
@@ -3969,10 +4054,17 @@ class Logger {
|
|
|
3969
4054
|
const prefix = this.prefix ? ` [${this.prefix}]` : "";
|
|
3970
4055
|
const metaStr = sanitizedMeta ? ` ${JSON.stringify(sanitizedMeta)}` : "";
|
|
3971
4056
|
const line = `[${level.toUpperCase()}]${prefix} ${ts} — ${sanitizedMsg}${metaStr}`;
|
|
3972
|
-
console.log(line);
|
|
3973
|
-
|
|
4057
|
+
console.log(isColorEnabled() ? LEVEL_COLORS[level](line) : line);
|
|
4058
|
+
const logTarget = this.sessionDir ?? this.logDir;
|
|
4059
|
+
if (logTarget) {
|
|
3974
4060
|
try {
|
|
3975
|
-
appendFileSync(join5(
|
|
4061
|
+
appendFileSync(join5(logTarget, "app.jsonl"), JSON.stringify({
|
|
4062
|
+
level,
|
|
4063
|
+
ts,
|
|
4064
|
+
prefix: this.prefix,
|
|
4065
|
+
msg: sanitizedMsg,
|
|
4066
|
+
meta: sanitizedMeta ?? null
|
|
4067
|
+
}) + `
|
|
3976
4068
|
`, "utf-8");
|
|
3977
4069
|
} catch {}
|
|
3978
4070
|
}
|
|
@@ -3991,10 +4083,17 @@ class Logger {
|
|
|
3991
4083
|
return sanitized;
|
|
3992
4084
|
}
|
|
3993
4085
|
}
|
|
3994
|
-
var LEVELS;
|
|
4086
|
+
var import_picocolors, LEVELS, LEVEL_COLORS;
|
|
3995
4087
|
var init_app_logger = __esm(() => {
|
|
3996
4088
|
init_data_sanitizer();
|
|
4089
|
+
import_picocolors = __toESM(require_picocolors(), 1);
|
|
3997
4090
|
LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
4091
|
+
LEVEL_COLORS = {
|
|
4092
|
+
debug: (s) => import_picocolors.default.dim(s),
|
|
4093
|
+
info: (s) => s,
|
|
4094
|
+
warn: (s) => import_picocolors.default.yellow(s),
|
|
4095
|
+
error: (s) => import_picocolors.default.red(s)
|
|
4096
|
+
};
|
|
3998
4097
|
});
|
|
3999
4098
|
|
|
4000
4099
|
// node_modules/base64-js/index.js
|
|
@@ -5533,18 +5632,25 @@ var init_audit_notifier = __esm(() => {
|
|
|
5533
5632
|
|
|
5534
5633
|
// src/modules/security/audit-log.ts
|
|
5535
5634
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5, appendFileSync as appendFileSync3 } from "fs";
|
|
5536
|
-
import { resolve as resolve2 } from "path";
|
|
5635
|
+
import { resolve as resolve2, join as join7 } from "path";
|
|
5537
5636
|
import { homedir as homedir3 } from "os";
|
|
5538
|
-
function
|
|
5539
|
-
|
|
5540
|
-
|
|
5637
|
+
function getAuditDir() {
|
|
5638
|
+
return _sessionAuditDir ?? _globalAuditDir;
|
|
5639
|
+
}
|
|
5640
|
+
function setAuditSessionDir(dir) {
|
|
5641
|
+
_sessionAuditDir = dir;
|
|
5642
|
+
if (!existsSync7(dir)) {
|
|
5643
|
+
mkdirSync5(dir, { recursive: true, mode: 448 });
|
|
5541
5644
|
}
|
|
5542
5645
|
}
|
|
5543
5646
|
function logAudit(entry) {
|
|
5544
|
-
|
|
5647
|
+
const dir = getAuditDir();
|
|
5648
|
+
if (!existsSync7(dir)) {
|
|
5649
|
+
mkdirSync5(dir, { recursive: true, mode: 448 });
|
|
5650
|
+
}
|
|
5545
5651
|
try {
|
|
5546
5652
|
const logEntry = JSON.stringify(entry);
|
|
5547
|
-
appendFileSync3(
|
|
5653
|
+
appendFileSync3(join7(dir, "audit.jsonl"), logEntry + `
|
|
5548
5654
|
`, "utf8");
|
|
5549
5655
|
} catch {}
|
|
5550
5656
|
try {
|
|
@@ -5601,11 +5707,10 @@ function logSecurityBlock(sessionId, action, reason, details) {
|
|
|
5601
5707
|
details
|
|
5602
5708
|
});
|
|
5603
5709
|
}
|
|
5604
|
-
var
|
|
5710
|
+
var _globalAuditDir, _sessionAuditDir = null;
|
|
5605
5711
|
var init_audit_log = __esm(() => {
|
|
5606
5712
|
init_audit_notifier();
|
|
5607
|
-
|
|
5608
|
-
AUDIT_LOG_PATH = resolve2(AUDIT_LOG_DIR, "audit.jsonl");
|
|
5713
|
+
_globalAuditDir = resolve2(homedir3(), ".mma", "logs");
|
|
5609
5714
|
});
|
|
5610
5715
|
|
|
5611
5716
|
// src/tools/path-utils.ts
|
|
@@ -5781,13 +5886,13 @@ var init_content_scanner = __esm(() => {
|
|
|
5781
5886
|
});
|
|
5782
5887
|
|
|
5783
5888
|
// src/modules/security/session-isolation.ts
|
|
5784
|
-
import { join as
|
|
5889
|
+
import { join as join8, resolve as resolve5 } from "path";
|
|
5785
5890
|
import { homedir as homedir4 } from "os";
|
|
5786
5891
|
import { mkdirSync as mkdirSync6, existsSync as existsSync10 } from "fs";
|
|
5787
5892
|
function createSessionContext(sessionId, projectDir, isolationConfig, securityOverrides) {
|
|
5788
5893
|
const config = { ...DEFAULT_SESSION_ISOLATION, ...isolationConfig };
|
|
5789
|
-
const baseDir = config.baseDir ||
|
|
5790
|
-
const tempDir =
|
|
5894
|
+
const baseDir = config.baseDir || join8(homedir4(), ".mma", "sessions", sessionId);
|
|
5895
|
+
const tempDir = join8(baseDir, "temp");
|
|
5791
5896
|
if (config.isolateTempFiles && !existsSync10(tempDir)) {
|
|
5792
5897
|
try {
|
|
5793
5898
|
mkdirSync6(tempDir, { recursive: true, mode: 448 });
|
|
@@ -5826,82 +5931,12 @@ var init_session_isolation = __esm(() => {
|
|
|
5826
5931
|
};
|
|
5827
5932
|
});
|
|
5828
5933
|
|
|
5829
|
-
// node_modules/picocolors/picocolors.js
|
|
5830
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
5831
|
-
var p = process || {};
|
|
5832
|
-
var argv = p.argv || [];
|
|
5833
|
-
var env = p.env || {};
|
|
5834
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
5835
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
5836
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
5837
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
5838
|
-
};
|
|
5839
|
-
var replaceClose = (string, close, replace, index) => {
|
|
5840
|
-
let result = "", cursor = 0;
|
|
5841
|
-
do {
|
|
5842
|
-
result += string.substring(cursor, index) + replace;
|
|
5843
|
-
cursor = index + close.length;
|
|
5844
|
-
index = string.indexOf(close, cursor);
|
|
5845
|
-
} while (~index);
|
|
5846
|
-
return result + string.substring(cursor);
|
|
5847
|
-
};
|
|
5848
|
-
var createColors = (enabled = isColorSupported) => {
|
|
5849
|
-
let f = enabled ? formatter : () => String;
|
|
5850
|
-
return {
|
|
5851
|
-
isColorSupported: enabled,
|
|
5852
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
5853
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
5854
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
5855
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
5856
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
5857
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
5858
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
5859
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
5860
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
5861
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
5862
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
5863
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
5864
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
5865
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
5866
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
5867
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
5868
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
5869
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
5870
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
5871
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
5872
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
5873
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
5874
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
5875
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
5876
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
5877
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
5878
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
5879
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
5880
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
5881
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
5882
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
5883
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
5884
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
5885
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
5886
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
5887
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
5888
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
5889
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
5890
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
5891
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
5892
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
5893
|
-
};
|
|
5894
|
-
};
|
|
5895
|
-
module.exports = createColors();
|
|
5896
|
-
module.exports.createColors = createColors;
|
|
5897
|
-
});
|
|
5898
|
-
|
|
5899
5934
|
// src/ui/colors.ts
|
|
5900
|
-
var
|
|
5935
|
+
var import_picocolors2, isTty = () => process.stdout.isTTY === true, enabled, pc2;
|
|
5901
5936
|
var init_colors = __esm(() => {
|
|
5902
|
-
|
|
5937
|
+
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
5903
5938
|
enabled = isTty() && !process.env.CI && !process.env.NO_COLOR;
|
|
5904
|
-
|
|
5939
|
+
pc2 = import_picocolors2.createColors(enabled);
|
|
5905
5940
|
});
|
|
5906
5941
|
|
|
5907
5942
|
// src/ui/diff.ts
|
|
@@ -6011,11 +6046,11 @@ function formatLine(line, maxNumWidth) {
|
|
|
6011
6046
|
const num = line.type === "remove" ? line.oldNum : line.newNum;
|
|
6012
6047
|
const numStr = num !== null ? String(num).padStart(maxNumWidth) : " ".repeat(maxNumWidth);
|
|
6013
6048
|
if (line.type === "remove") {
|
|
6014
|
-
return `${numStr} ${
|
|
6049
|
+
return `${numStr} ${pc2.red("-")} ${line.content}`;
|
|
6015
6050
|
} else if (line.type === "add") {
|
|
6016
|
-
return `${numStr} ${
|
|
6051
|
+
return `${numStr} ${pc2.green("+")} ${line.content}`;
|
|
6017
6052
|
} else if (line.content === "...") {
|
|
6018
|
-
return
|
|
6053
|
+
return pc2.dim(` ${" ".repeat(maxNumWidth)}...`);
|
|
6019
6054
|
} else {
|
|
6020
6055
|
return ` ${numStr} ${line.content}`;
|
|
6021
6056
|
}
|
|
@@ -6038,7 +6073,7 @@ function generateDiff(oldContent, newContent) {
|
|
|
6038
6073
|
let lines = diff.map((l) => formatLine(l, maxNumWidth));
|
|
6039
6074
|
if (lines.length > MAX_DIFF_LINES) {
|
|
6040
6075
|
const truncated = lines.slice(0, MAX_DIFF_LINES);
|
|
6041
|
-
truncated.push(
|
|
6076
|
+
truncated.push(pc2.dim(` ... (${lines.length - MAX_DIFF_LINES} more lines)`));
|
|
6042
6077
|
lines = truncated;
|
|
6043
6078
|
}
|
|
6044
6079
|
return lines.join(`
|
|
@@ -6051,11 +6086,11 @@ function generateNewFileDiff(content) {
|
|
|
6051
6086
|
const diffLines = [];
|
|
6052
6087
|
for (let i = 0;i < lines.length; i++) {
|
|
6053
6088
|
const numStr = String(i + 1).padStart(maxNumWidth);
|
|
6054
|
-
diffLines.push(`${numStr} ${
|
|
6089
|
+
diffLines.push(`${numStr} ${pc2.green("+")} ${lines[i]}`);
|
|
6055
6090
|
}
|
|
6056
6091
|
if (diffLines.length > MAX_DIFF_LINES) {
|
|
6057
6092
|
const truncated = diffLines.slice(0, MAX_DIFF_LINES);
|
|
6058
|
-
truncated.push(
|
|
6093
|
+
truncated.push(pc2.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
|
|
6059
6094
|
return truncated.join(`
|
|
6060
6095
|
`);
|
|
6061
6096
|
}
|
|
@@ -6069,11 +6104,11 @@ function generateDeleteDiff(content) {
|
|
|
6069
6104
|
const diffLines = [];
|
|
6070
6105
|
for (let i = 0;i < lines.length; i++) {
|
|
6071
6106
|
const numStr = String(i + 1).padStart(maxNumWidth);
|
|
6072
|
-
diffLines.push(`${numStr} ${
|
|
6107
|
+
diffLines.push(`${numStr} ${pc2.red("-")} ${lines[i]}`);
|
|
6073
6108
|
}
|
|
6074
6109
|
if (diffLines.length > MAX_DIFF_LINES) {
|
|
6075
6110
|
const truncated = diffLines.slice(0, MAX_DIFF_LINES);
|
|
6076
|
-
truncated.push(
|
|
6111
|
+
truncated.push(pc2.dim(` ... (${diffLines.length - MAX_DIFF_LINES} more lines)`));
|
|
6077
6112
|
return truncated.join(`
|
|
6078
6113
|
`);
|
|
6079
6114
|
}
|
|
@@ -6081,7 +6116,7 @@ function generateDeleteDiff(content) {
|
|
|
6081
6116
|
`);
|
|
6082
6117
|
}
|
|
6083
6118
|
function generateMoveDiff(fromPath, toPath) {
|
|
6084
|
-
return [
|
|
6119
|
+
return [pc2.red(` - ${fromPath}`), pc2.green(` + ${toPath}`)].join(`
|
|
6085
6120
|
`);
|
|
6086
6121
|
}
|
|
6087
6122
|
var CONTEXT_LINES = 3, MAX_DIFF_LINES = 100;
|
|
@@ -6090,7 +6125,7 @@ var init_diff = __esm(() => {
|
|
|
6090
6125
|
});
|
|
6091
6126
|
|
|
6092
6127
|
// src/tools/write-file.ts
|
|
6093
|
-
import { writeFileSync as
|
|
6128
|
+
import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync7, existsSync as existsSync11, readFileSync as readFileSync6 } from "fs";
|
|
6094
6129
|
import { dirname as dirname4 } from "path";
|
|
6095
6130
|
var writeFileTool;
|
|
6096
6131
|
var init_write_file = __esm(() => {
|
|
@@ -6154,7 +6189,7 @@ var init_write_file = __esm(() => {
|
|
|
6154
6189
|
if (fileExists) {
|
|
6155
6190
|
oldContent = readFileSync6(resolved, "utf-8");
|
|
6156
6191
|
}
|
|
6157
|
-
|
|
6192
|
+
writeFileSync5(resolved, content, "utf-8");
|
|
6158
6193
|
const diff = fileExists ? generateDiff(oldContent, content) : generateNewFileDiff(content);
|
|
6159
6194
|
ctx.fileOperationsCount = currentCount + 1;
|
|
6160
6195
|
logFileWrite(ctx.sessionId, path, true, `File ${fileExists ? "updated" : "created"}`);
|
|
@@ -6164,7 +6199,7 @@ var init_write_file = __esm(() => {
|
|
|
6164
6199
|
});
|
|
6165
6200
|
|
|
6166
6201
|
// src/tools/edit-file.ts
|
|
6167
|
-
import { readFileSync as readFileSync7, writeFileSync as
|
|
6202
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
6168
6203
|
var editFileTool;
|
|
6169
6204
|
var init_edit_file = __esm(() => {
|
|
6170
6205
|
init_i18n();
|
|
@@ -6228,7 +6263,7 @@ var init_edit_file = __esm(() => {
|
|
|
6228
6263
|
output: `[SECURITY BLOCKED] ${scanResult.reason}`
|
|
6229
6264
|
};
|
|
6230
6265
|
}
|
|
6231
|
-
|
|
6266
|
+
writeFileSync6(resolved, updated, "utf-8");
|
|
6232
6267
|
const diff = generateDiff(content, updated);
|
|
6233
6268
|
ctx.fileOperationsCount = currentCount + 1;
|
|
6234
6269
|
logFileWrite(ctx.sessionId, path, true, "File edited");
|
|
@@ -6861,16 +6896,16 @@ class ProcessRegistry {
|
|
|
6861
6896
|
const decoder = platform() === "win32" ? (() => {
|
|
6862
6897
|
try {
|
|
6863
6898
|
const cpOut = __require("child_process").execSync("chcp.com", {
|
|
6864
|
-
encoding: "
|
|
6899
|
+
encoding: "buffer",
|
|
6865
6900
|
timeout: 2000,
|
|
6866
6901
|
windowsHide: true
|
|
6867
|
-
}).toString();
|
|
6902
|
+
}).toString("latin1");
|
|
6868
6903
|
const m = cpOut.match(/(\d+)/);
|
|
6869
6904
|
if (m)
|
|
6870
6905
|
return new TextDecoder("ibm" + m[1]);
|
|
6871
6906
|
} catch {}
|
|
6872
|
-
return
|
|
6873
|
-
})() :
|
|
6907
|
+
return new TextDecoder("ibm866");
|
|
6908
|
+
})() : new TextDecoder("utf-8");
|
|
6874
6909
|
let buf = "";
|
|
6875
6910
|
const pushLine = (line) => {
|
|
6876
6911
|
if (entry.log.length >= MAX_LOG_LINES) {
|
|
@@ -6879,7 +6914,7 @@ class ProcessRegistry {
|
|
|
6879
6914
|
entry.log.push(line);
|
|
6880
6915
|
};
|
|
6881
6916
|
const append = (chunk) => {
|
|
6882
|
-
const decoded = decoder
|
|
6917
|
+
const decoded = decoder.decode(chunk, { stream: true });
|
|
6883
6918
|
buf += decoded;
|
|
6884
6919
|
const lines = buf.split(/\r?\n/);
|
|
6885
6920
|
buf = lines.pop() ?? "";
|
|
@@ -6888,9 +6923,7 @@ class ProcessRegistry {
|
|
|
6888
6923
|
}
|
|
6889
6924
|
};
|
|
6890
6925
|
const flush = () => {
|
|
6891
|
-
|
|
6892
|
-
buf += decoder.decode();
|
|
6893
|
-
}
|
|
6926
|
+
buf += decoder.decode();
|
|
6894
6927
|
if (buf) {
|
|
6895
6928
|
pushLine(buf);
|
|
6896
6929
|
buf = "";
|
|
@@ -7018,6 +7051,9 @@ import { platform as platform2 } from "os";
|
|
|
7018
7051
|
function adaptCommandForWindows(command) {
|
|
7019
7052
|
if (platform2() !== "win32")
|
|
7020
7053
|
return command;
|
|
7054
|
+
if (/\|\|\s*true\b/.test(command)) {
|
|
7055
|
+
command = command.replace(/\s*\|\|\s*true\b/g, "; exit 0");
|
|
7056
|
+
}
|
|
7021
7057
|
const trimmed = command.trim();
|
|
7022
7058
|
if (trimmed.startsWith("mkdir -p ")) {
|
|
7023
7059
|
return trimmed.replace(/^mkdir -p /, "mkdir ");
|
|
@@ -7073,30 +7109,30 @@ var init_bash = __esm(() => {
|
|
|
7073
7109
|
init_i18n();
|
|
7074
7110
|
bashGraceMs = BASH_GRACE_MS;
|
|
7075
7111
|
UNIX_TO_WIN_HINTS = {
|
|
7076
|
-
ls:
|
|
7077
|
-
pwd:
|
|
7078
|
-
cat:
|
|
7079
|
-
cp:
|
|
7080
|
-
mv:
|
|
7081
|
-
rm:
|
|
7082
|
-
grep:
|
|
7083
|
-
chmod: "Use
|
|
7084
|
-
touch: "Use
|
|
7085
|
-
find:
|
|
7112
|
+
ls: "Use the list_dir tool instead.",
|
|
7113
|
+
pwd: "Use the file_info tool instead.",
|
|
7114
|
+
cat: "Use the read_file tool instead.",
|
|
7115
|
+
cp: "Use the move_file tool instead.",
|
|
7116
|
+
mv: "Use the move_file tool instead.",
|
|
7117
|
+
rm: "Use the delete_file tool instead.",
|
|
7118
|
+
grep: "Use the grep tool instead.",
|
|
7119
|
+
chmod: "Use the chmod tool instead.",
|
|
7120
|
+
touch: "Use the write_file tool instead.",
|
|
7121
|
+
find: "Use the glob tool instead.",
|
|
7086
7122
|
head: "Use the read_file tool with offset/limit instead.",
|
|
7087
7123
|
tail: "Use the read_file tool instead.",
|
|
7088
7124
|
wc: "Use the read_file tool instead.",
|
|
7089
7125
|
diff: "Use the diff tool instead.",
|
|
7090
7126
|
which: 'Use "where" instead.',
|
|
7091
7127
|
echo: "echo works on Windows, but avoid pipes (|).",
|
|
7092
|
-
"Get-Content":
|
|
7093
|
-
"Select-Object": "
|
|
7128
|
+
"Get-Content": "Use the read_file tool instead.",
|
|
7129
|
+
"Select-Object": "Use the read_file tool with offset/limit instead."
|
|
7094
7130
|
};
|
|
7095
7131
|
UNIX_TO_WIN_TRANSLATE = {
|
|
7096
|
-
ls: "
|
|
7097
|
-
pwd: "
|
|
7098
|
-
cat: "
|
|
7099
|
-
wc:
|
|
7132
|
+
ls: "Get-ChildItem",
|
|
7133
|
+
pwd: "Get-Location",
|
|
7134
|
+
cat: "Get-Content",
|
|
7135
|
+
wc: "@(Get-Content).Count"
|
|
7100
7136
|
};
|
|
7101
7137
|
bashTool = {
|
|
7102
7138
|
name: "bash",
|
|
@@ -7106,8 +7142,14 @@ var init_bash = __esm(() => {
|
|
|
7106
7142
|
type: "object",
|
|
7107
7143
|
properties: {
|
|
7108
7144
|
command: { type: "string", description: "Shell command to execute" },
|
|
7109
|
-
workdir: {
|
|
7110
|
-
|
|
7145
|
+
workdir: {
|
|
7146
|
+
type: "string",
|
|
7147
|
+
description: "Working directory (default: baseDir)"
|
|
7148
|
+
},
|
|
7149
|
+
background: {
|
|
7150
|
+
type: "boolean",
|
|
7151
|
+
description: "Return a process id immediately without waiting (default: commands still running after a few seconds are auto-promoted to the background)"
|
|
7152
|
+
}
|
|
7111
7153
|
},
|
|
7112
7154
|
required: ["command"]
|
|
7113
7155
|
},
|
|
@@ -7387,8 +7429,21 @@ var init_prompt_builder = __esm(() => {
|
|
|
7387
7429
|
// src/core/session-logger.ts
|
|
7388
7430
|
class SessionLogger {
|
|
7389
7431
|
session;
|
|
7390
|
-
|
|
7432
|
+
logger;
|
|
7433
|
+
constructor(session, logger) {
|
|
7391
7434
|
this.session = session;
|
|
7435
|
+
this.logger = logger;
|
|
7436
|
+
this.bindSessionDir();
|
|
7437
|
+
}
|
|
7438
|
+
bindSessionDir() {
|
|
7439
|
+
const meta = this.session?.getActiveMeta();
|
|
7440
|
+
if (!meta)
|
|
7441
|
+
return;
|
|
7442
|
+
const dir = this.session.getSessionDirectory(meta.id);
|
|
7443
|
+
if (this.logger) {
|
|
7444
|
+
this.logger.setSessionDir(dir);
|
|
7445
|
+
}
|
|
7446
|
+
setAuditSessionDir(dir);
|
|
7392
7447
|
}
|
|
7393
7448
|
get active() {
|
|
7394
7449
|
return !!this.session?.getActive();
|
|
@@ -7425,7 +7480,13 @@ class SessionLogger {
|
|
|
7425
7480
|
ts: new Date().toISOString(),
|
|
7426
7481
|
type: "assistant",
|
|
7427
7482
|
content,
|
|
7428
|
-
...toolCalls ? {
|
|
7483
|
+
...toolCalls ? {
|
|
7484
|
+
tool_calls: toolCalls.map((tc) => ({
|
|
7485
|
+
id: tc.id,
|
|
7486
|
+
name: tc.name,
|
|
7487
|
+
arguments: tc.arguments
|
|
7488
|
+
}))
|
|
7489
|
+
} : {},
|
|
7429
7490
|
iteration
|
|
7430
7491
|
});
|
|
7431
7492
|
}
|
|
@@ -7509,6 +7570,9 @@ class SessionLogger {
|
|
|
7509
7570
|
});
|
|
7510
7571
|
}
|
|
7511
7572
|
}
|
|
7573
|
+
var init_session_logger = __esm(() => {
|
|
7574
|
+
init_audit_log();
|
|
7575
|
+
});
|
|
7512
7576
|
|
|
7513
7577
|
// node_modules/jsonrepair/lib/esm/utils/JSONRepairError.js
|
|
7514
7578
|
var JSONRepairError;
|
|
@@ -8651,7 +8715,7 @@ class StuckDetector {
|
|
|
8651
8715
|
escalationThreshold = 3;
|
|
8652
8716
|
fileRewriteCount = new Map;
|
|
8653
8717
|
fileRewriteThreshold = 3;
|
|
8654
|
-
constructor(threshold =
|
|
8718
|
+
constructor(threshold = 6, errorThreshold = 3) {
|
|
8655
8719
|
this.threshold = threshold;
|
|
8656
8720
|
this.errorThreshold = errorThreshold;
|
|
8657
8721
|
}
|
|
@@ -9497,7 +9561,7 @@ var init_agent_moe = __esm(() => {
|
|
|
9497
9561
|
|
|
9498
9562
|
// src/modules/memory/search.ts
|
|
9499
9563
|
import { readFileSync as readFileSync9, existsSync as existsSync18 } from "fs";
|
|
9500
|
-
import { join as
|
|
9564
|
+
import { join as join9 } from "path";
|
|
9501
9565
|
|
|
9502
9566
|
class MemorySearch {
|
|
9503
9567
|
memoryDir;
|
|
@@ -9508,7 +9572,7 @@ class MemorySearch {
|
|
|
9508
9572
|
const results = [];
|
|
9509
9573
|
const lowerQuery = query.toLowerCase();
|
|
9510
9574
|
for (const name of MEMORY_FILES) {
|
|
9511
|
-
const path =
|
|
9575
|
+
const path = join9(this.memoryDir, `${name}.md`);
|
|
9512
9576
|
if (!existsSync18(path))
|
|
9513
9577
|
continue;
|
|
9514
9578
|
const content = readFileSync9(path, "utf-8");
|
|
@@ -9520,7 +9584,7 @@ class MemorySearch {
|
|
|
9520
9584
|
}
|
|
9521
9585
|
}
|
|
9522
9586
|
}
|
|
9523
|
-
const prefsPath =
|
|
9587
|
+
const prefsPath = join9(this.memoryDir, "preferences.json");
|
|
9524
9588
|
if (existsSync18(prefsPath)) {
|
|
9525
9589
|
try {
|
|
9526
9590
|
const prefs = JSON.parse(readFileSync9(prefsPath, "utf-8"));
|
|
@@ -9541,8 +9605,8 @@ var init_search = __esm(() => {
|
|
|
9541
9605
|
});
|
|
9542
9606
|
|
|
9543
9607
|
// src/modules/memory/store.ts
|
|
9544
|
-
import { readFileSync as readFileSync10, writeFileSync as
|
|
9545
|
-
import { join as
|
|
9608
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, appendFileSync as appendFileSync4, existsSync as existsSync19, mkdirSync as mkdirSync10 } from "fs";
|
|
9609
|
+
import { join as join10 } from "path";
|
|
9546
9610
|
|
|
9547
9611
|
class MemoryStore {
|
|
9548
9612
|
memoryDir;
|
|
@@ -9550,9 +9614,9 @@ class MemoryStore {
|
|
|
9550
9614
|
this.memoryDir = memoryDir;
|
|
9551
9615
|
this.ensureDir();
|
|
9552
9616
|
for (const name of MEMORY_FILES2) {
|
|
9553
|
-
const path =
|
|
9617
|
+
const path = join10(this.memoryDir, `${name}.md`);
|
|
9554
9618
|
if (!existsSync19(path)) {
|
|
9555
|
-
|
|
9619
|
+
writeFileSync7(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
9556
9620
|
|
|
9557
9621
|
`, "utf-8");
|
|
9558
9622
|
}
|
|
@@ -9564,13 +9628,13 @@ class MemoryStore {
|
|
|
9564
9628
|
}
|
|
9565
9629
|
}
|
|
9566
9630
|
read(name) {
|
|
9567
|
-
const path =
|
|
9631
|
+
const path = join10(this.memoryDir, `${name}.md`);
|
|
9568
9632
|
if (!existsSync19(path))
|
|
9569
9633
|
return "";
|
|
9570
9634
|
return readFileSync10(path, "utf-8");
|
|
9571
9635
|
}
|
|
9572
9636
|
append(name, entry) {
|
|
9573
|
-
const path =
|
|
9637
|
+
const path = join10(this.memoryDir, `${name}.md`);
|
|
9574
9638
|
const timestamp = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
9575
9639
|
const formatted = `- **${timestamp}** — ${entry}
|
|
9576
9640
|
`;
|
|
@@ -9581,7 +9645,7 @@ class MemoryStore {
|
|
|
9581
9645
|
return searchModule.query(query);
|
|
9582
9646
|
}
|
|
9583
9647
|
prefsPath() {
|
|
9584
|
-
return
|
|
9648
|
+
return join10(this.memoryDir, "preferences.json");
|
|
9585
9649
|
}
|
|
9586
9650
|
getPreferences() {
|
|
9587
9651
|
const path = this.prefsPath();
|
|
@@ -9596,14 +9660,14 @@ class MemoryStore {
|
|
|
9596
9660
|
setPreference(key, value) {
|
|
9597
9661
|
const prefs = this.getPreferences();
|
|
9598
9662
|
prefs[key] = value;
|
|
9599
|
-
|
|
9663
|
+
writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
9600
9664
|
}
|
|
9601
9665
|
deletePreference(key) {
|
|
9602
9666
|
const prefs = this.getPreferences();
|
|
9603
9667
|
if (!(key in prefs))
|
|
9604
9668
|
return false;
|
|
9605
9669
|
delete prefs[key];
|
|
9606
|
-
|
|
9670
|
+
writeFileSync7(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
9607
9671
|
return true;
|
|
9608
9672
|
}
|
|
9609
9673
|
appendRule(category, pattern, cause, solution) {
|
|
@@ -9620,7 +9684,7 @@ var init_store = __esm(() => {
|
|
|
9620
9684
|
});
|
|
9621
9685
|
|
|
9622
9686
|
// src/core/agent.ts
|
|
9623
|
-
import { join as
|
|
9687
|
+
import { join as join11 } from "path";
|
|
9624
9688
|
function isToolCallJson(text) {
|
|
9625
9689
|
const trimmed = text.trim();
|
|
9626
9690
|
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
@@ -9710,7 +9774,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9710
9774
|
sessionManager,
|
|
9711
9775
|
baseDir
|
|
9712
9776
|
} = this.deps;
|
|
9713
|
-
const slog = new SessionLogger(sessionManager);
|
|
9777
|
+
const slog = new SessionLogger(sessionManager, logger);
|
|
9714
9778
|
if (sessionManager && !sessionManager.getActive()) {
|
|
9715
9779
|
sessionManager.create();
|
|
9716
9780
|
logger.debug(`Session started: ${sessionManager.getActive()}`);
|
|
@@ -9732,7 +9796,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9732
9796
|
verifier.runTypeCheck().then((tc) => {
|
|
9733
9797
|
if (!tc.passed) {
|
|
9734
9798
|
logger.warn(`Baseline typecheck has issues: ${tc.message?.slice(0, 500)}`);
|
|
9735
|
-
onMeta?.(
|
|
9799
|
+
onMeta?.(pc2.yellow(`
|
|
9736
9800
|
⚠ Baseline typecheck has issues
|
|
9737
9801
|
`));
|
|
9738
9802
|
}
|
|
@@ -9764,7 +9828,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9764
9828
|
sessionManager,
|
|
9765
9829
|
baseDir
|
|
9766
9830
|
} = this.deps;
|
|
9767
|
-
const slog = new SessionLogger(sessionManager);
|
|
9831
|
+
const slog = new SessionLogger(sessionManager, logger);
|
|
9768
9832
|
this.abortController = new AbortController;
|
|
9769
9833
|
let iteration = 0;
|
|
9770
9834
|
let lastText = "";
|
|
@@ -9837,7 +9901,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9837
9901
|
if (config.showReasoning) {
|
|
9838
9902
|
const metaOut = pluginManager.runOnMeta({ iteration, logger }, chunk.content);
|
|
9839
9903
|
if (metaOut) {
|
|
9840
|
-
onMeta?.(
|
|
9904
|
+
onMeta?.(pc2.dim(metaOut));
|
|
9841
9905
|
}
|
|
9842
9906
|
emittedReasoning = true;
|
|
9843
9907
|
}
|
|
@@ -9955,7 +10019,7 @@ ${t("tool.truncated", { tokens: Math.ceil(removedChars / 2) })}`;
|
|
|
9955
10019
|
} else {
|
|
9956
10020
|
const metaOut = pluginManager.runOnMeta({ iteration, logger }, result.output);
|
|
9957
10021
|
onMeta?.(`
|
|
9958
|
-
` +
|
|
10022
|
+
` + pc2.dim(metaOut) + `
|
|
9959
10023
|
`);
|
|
9960
10024
|
}
|
|
9961
10025
|
if (result.diff) {
|
|
@@ -10012,7 +10076,7 @@ ${taskReminder}</system-summary>`
|
|
|
10012
10076
|
if (sessionManager) {
|
|
10013
10077
|
const activeSession = sessionManager.getActiveMeta();
|
|
10014
10078
|
if (activeSession) {
|
|
10015
|
-
const memDir =
|
|
10079
|
+
const memDir = join11(baseDir, ".mma", "memory");
|
|
10016
10080
|
const memStore = new MemoryStore(memDir);
|
|
10017
10081
|
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");
|
|
10018
10082
|
}
|
|
@@ -10028,13 +10092,13 @@ ${taskReminder}</system-summary>`
|
|
|
10028
10092
|
const ctxPct = Math.min(100, Math.round(ctxTokens / ctxBudget.history * 100));
|
|
10029
10093
|
const barLen = 10;
|
|
10030
10094
|
const filled = Math.round(ctxPct / 100 * barLen);
|
|
10031
|
-
const ctxBar =
|
|
10032
|
-
const pctColor = ctxPct >= 75 ?
|
|
10095
|
+
const ctxBar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
|
|
10096
|
+
const pctColor = ctxPct >= 75 ? pc2.yellow : pc2.dim;
|
|
10033
10097
|
const compCount = contextManager.getCompactionCount();
|
|
10034
10098
|
const quality2 = contextManager.getQuality();
|
|
10035
|
-
const qualityColor = quality2 >= 70 ?
|
|
10099
|
+
const qualityColor = quality2 >= 70 ? pc2.green : quality2 >= 40 ? pc2.yellow : pc2.red;
|
|
10036
10100
|
onMeta?.(`
|
|
10037
|
-
${ctxBar} ${pctColor(`${ctxPct}%`)} ${
|
|
10101
|
+
${ctxBar} ${pctColor(`${ctxPct}%`)} ${pc2.dim(`ctx: ${ctxTokens}/${ctxBudget.history}`)} ${pc2.dim(`compactions: ${compCount}`)} ${qualityColor(`quality: ${quality2}%`)}
|
|
10038
10102
|
`);
|
|
10039
10103
|
continue;
|
|
10040
10104
|
}
|
|
@@ -10217,6 +10281,7 @@ var init_agent = __esm(() => {
|
|
|
10217
10281
|
init_colors();
|
|
10218
10282
|
init_prompt_builder();
|
|
10219
10283
|
init_processes();
|
|
10284
|
+
init_session_logger();
|
|
10220
10285
|
init_agent_moe();
|
|
10221
10286
|
init_store();
|
|
10222
10287
|
init_verifier();
|
|
@@ -12193,7 +12258,7 @@ ${JSON.stringify(result, null, 2)}`
|
|
|
12193
12258
|
|
|
12194
12259
|
// src/tools/search-history.ts
|
|
12195
12260
|
import * as fs from "fs";
|
|
12196
|
-
import { join as
|
|
12261
|
+
import { join as join12 } from "path";
|
|
12197
12262
|
import { homedir as homedir5 } from "os";
|
|
12198
12263
|
function searchFile(filePath, query, maxResults, results) {
|
|
12199
12264
|
if (!fs.existsSync(filePath))
|
|
@@ -12237,7 +12302,7 @@ var init_search_history = __esm(() => {
|
|
|
12237
12302
|
const query = String(args.query || "").toLowerCase();
|
|
12238
12303
|
const maxResults = Number(args.maxResults) || 5;
|
|
12239
12304
|
const sessionId = args.sessionId ? String(args.sessionId) : null;
|
|
12240
|
-
const sessionDir =
|
|
12305
|
+
const sessionDir = join12(homedir5(), ".mma", "sessions");
|
|
12241
12306
|
const results = [];
|
|
12242
12307
|
try {
|
|
12243
12308
|
if (!fs.existsSync(sessionDir)) {
|
|
@@ -12252,7 +12317,7 @@ var init_search_history = __esm(() => {
|
|
|
12252
12317
|
continue;
|
|
12253
12318
|
if (sessionId && entry.name !== sessionId)
|
|
12254
12319
|
continue;
|
|
12255
|
-
const historyFile =
|
|
12320
|
+
const historyFile = join12(sessionDir, entry.name, "history.jsonl");
|
|
12256
12321
|
searchFile(historyFile, query, maxResults, results);
|
|
12257
12322
|
if (results.length >= maxResults)
|
|
12258
12323
|
break;
|
|
@@ -12280,7 +12345,7 @@ var init_search_history = __esm(() => {
|
|
|
12280
12345
|
|
|
12281
12346
|
// src/tools/remember.ts
|
|
12282
12347
|
import { homedir as homedir6 } from "os";
|
|
12283
|
-
import { join as
|
|
12348
|
+
import { join as join13 } from "path";
|
|
12284
12349
|
var CATEGORIES, rememberTool;
|
|
12285
12350
|
var init_remember = __esm(() => {
|
|
12286
12351
|
init_i18n();
|
|
@@ -12318,7 +12383,7 @@ var init_remember = __esm(() => {
|
|
|
12318
12383
|
if (!CATEGORIES.includes(category)) {
|
|
12319
12384
|
return { success: false, output: t("tool.invalid_params") };
|
|
12320
12385
|
}
|
|
12321
|
-
const memoryDir =
|
|
12386
|
+
const memoryDir = join13(homedir6(), ".mma", "memory");
|
|
12322
12387
|
const store = new MemoryStore(memoryDir);
|
|
12323
12388
|
try {
|
|
12324
12389
|
if (category === "preferences") {
|
|
@@ -12351,7 +12416,7 @@ var init_remember = __esm(() => {
|
|
|
12351
12416
|
|
|
12352
12417
|
// src/tools/recall.ts
|
|
12353
12418
|
import { homedir as homedir7 } from "os";
|
|
12354
|
-
import { join as
|
|
12419
|
+
import { join as join14 } from "path";
|
|
12355
12420
|
function formatAll(store) {
|
|
12356
12421
|
const parts = [];
|
|
12357
12422
|
const prefs = store.getPreferences();
|
|
@@ -12434,7 +12499,7 @@ var init_recall = __esm(() => {
|
|
|
12434
12499
|
handler: async (_ctx, args) => {
|
|
12435
12500
|
const query = args.query ? String(args.query) : "";
|
|
12436
12501
|
const category = args.category ? String(args.category) : "";
|
|
12437
|
-
const memoryDir =
|
|
12502
|
+
const memoryDir = join14(homedir7(), ".mma", "memory");
|
|
12438
12503
|
const store = new MemoryStore(memoryDir);
|
|
12439
12504
|
try {
|
|
12440
12505
|
if (!query && !category) {
|
|
@@ -12630,15 +12695,15 @@ function buildIndexInjectionScript() {
|
|
|
12630
12695
|
|
|
12631
12696
|
// src/modules/browser/cookie-store.ts
|
|
12632
12697
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
12633
|
-
import { join as
|
|
12698
|
+
import { join as join15 } from "path";
|
|
12634
12699
|
|
|
12635
12700
|
class CookieStore {
|
|
12636
12701
|
filePath;
|
|
12637
12702
|
constructor(cookieDir) {
|
|
12638
|
-
this.filePath =
|
|
12703
|
+
this.filePath = join15(cookieDir, "cookies.json");
|
|
12639
12704
|
}
|
|
12640
12705
|
async save(cookies) {
|
|
12641
|
-
await mkdir(
|
|
12706
|
+
await mkdir(join15(this.filePath, ".."), { recursive: true });
|
|
12642
12707
|
await writeFile(this.filePath, JSON.stringify(cookies, null, 2), "utf-8");
|
|
12643
12708
|
}
|
|
12644
12709
|
async load() {
|
|
@@ -12958,10 +13023,10 @@ var init_types = __esm(() => {
|
|
|
12958
13023
|
});
|
|
12959
13024
|
|
|
12960
13025
|
// src/tools/browser.ts
|
|
12961
|
-
import { join as
|
|
13026
|
+
import { join as join16 } from "path";
|
|
12962
13027
|
function getSession(ctx) {
|
|
12963
13028
|
if (!session) {
|
|
12964
|
-
const cookieDir =
|
|
13029
|
+
const cookieDir = join16(ctx.baseDir, ".mma", "browser");
|
|
12965
13030
|
session = new BrowserSession({
|
|
12966
13031
|
...DEFAULT_BROWSER_CONFIG,
|
|
12967
13032
|
headless: ctx.config.browser?.headless ?? true,
|
|
@@ -13091,8 +13156,8 @@ async function readClipboardFallback() {
|
|
|
13091
13156
|
const { platform: platform3 } = await import("os");
|
|
13092
13157
|
const { execSync } = await import("child_process");
|
|
13093
13158
|
const { readFileSync: readFileSync13, unlinkSync: unlinkSync3 } = await import("fs");
|
|
13094
|
-
const { join:
|
|
13095
|
-
const tmpPath =
|
|
13159
|
+
const { join: join17 } = await import("path");
|
|
13160
|
+
const tmpPath = join17(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
13096
13161
|
try {
|
|
13097
13162
|
if (platform3() === "linux") {
|
|
13098
13163
|
execSync(`xclip -selection clipboard -t image/png -o > "${tmpPath}" 2>/dev/null`, { timeout: 5000 });
|
|
@@ -13370,7 +13435,7 @@ class ModuleRegistry {
|
|
|
13370
13435
|
|
|
13371
13436
|
// src/modules/plugins/loader.ts
|
|
13372
13437
|
import { readdirSync as readdirSync5, existsSync as existsSync23, statSync as statSync4 } from "fs";
|
|
13373
|
-
import { join as
|
|
13438
|
+
import { join as join17 } from "path";
|
|
13374
13439
|
|
|
13375
13440
|
class PluginLoader {
|
|
13376
13441
|
loadFromDir(dirPath, pluginManager, logger) {
|
|
@@ -13378,7 +13443,7 @@ class PluginLoader {
|
|
|
13378
13443
|
return;
|
|
13379
13444
|
const entries = readdirSync5(dirPath);
|
|
13380
13445
|
for (const entry of entries) {
|
|
13381
|
-
const fullPath =
|
|
13446
|
+
const fullPath = join17(dirPath, entry);
|
|
13382
13447
|
if (!statSync4(fullPath).isFile())
|
|
13383
13448
|
continue;
|
|
13384
13449
|
if (!entry.endsWith(".ts") && !entry.endsWith(".js"))
|
|
@@ -13401,9 +13466,30 @@ var init_loader = __esm(() => {
|
|
|
13401
13466
|
});
|
|
13402
13467
|
|
|
13403
13468
|
// src/modules/plugins/builtin/lint-on-write.ts
|
|
13404
|
-
import { spawn as spawn4 } from "child_process";
|
|
13469
|
+
import { spawn as spawn4, execSync } from "child_process";
|
|
13405
13470
|
import { existsSync as existsSync24, readFileSync as readFileSync13 } from "fs";
|
|
13406
|
-
import { resolve as resolve13, extname as extname4, join as
|
|
13471
|
+
import { resolve as resolve13, extname as extname4, join as join18 } from "path";
|
|
13472
|
+
import { platform as platform3 } from "os";
|
|
13473
|
+
function getWinDecoder() {
|
|
13474
|
+
if (_winDecoder === undefined) {
|
|
13475
|
+
if (platform3() !== "win32") {
|
|
13476
|
+
_winDecoder = null;
|
|
13477
|
+
} else {
|
|
13478
|
+
try {
|
|
13479
|
+
const cpOut = execSync("chcp.com", {
|
|
13480
|
+
encoding: "buffer",
|
|
13481
|
+
timeout: 2000,
|
|
13482
|
+
windowsHide: true
|
|
13483
|
+
}).toString("latin1");
|
|
13484
|
+
const m = cpOut.match(/(\d+)/);
|
|
13485
|
+
_winDecoder = m ? new TextDecoder("ibm" + m[1]) : null;
|
|
13486
|
+
} catch {
|
|
13487
|
+
_winDecoder = null;
|
|
13488
|
+
}
|
|
13489
|
+
}
|
|
13490
|
+
}
|
|
13491
|
+
return _winDecoder ?? new TextDecoder("utf-8");
|
|
13492
|
+
}
|
|
13407
13493
|
|
|
13408
13494
|
class LintOnWritePlugin {
|
|
13409
13495
|
name = "lint-on-write";
|
|
@@ -13467,7 +13553,7 @@ class LintOnWritePlugin {
|
|
|
13467
13553
|
}
|
|
13468
13554
|
async runProjectLint(ctx, result) {
|
|
13469
13555
|
try {
|
|
13470
|
-
const packageJsonPath =
|
|
13556
|
+
const packageJsonPath = join18(ctx.baseDir, "package.json");
|
|
13471
13557
|
if (!existsSync24(packageJsonPath)) {
|
|
13472
13558
|
return;
|
|
13473
13559
|
}
|
|
@@ -13487,7 +13573,7 @@ class LintOnWritePlugin {
|
|
|
13487
13573
|
}
|
|
13488
13574
|
}
|
|
13489
13575
|
async runProjectTypeCheck(ctx, result) {
|
|
13490
|
-
const tsconfigPath =
|
|
13576
|
+
const tsconfigPath = join18(ctx.baseDir, "tsconfig.json");
|
|
13491
13577
|
if (!existsSync24(tsconfigPath)) {
|
|
13492
13578
|
return;
|
|
13493
13579
|
}
|
|
@@ -13538,11 +13624,12 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
13538
13624
|
});
|
|
13539
13625
|
let stdout = "";
|
|
13540
13626
|
let stderr = "";
|
|
13627
|
+
const decoder = getWinDecoder();
|
|
13541
13628
|
child.stdout?.on("data", (d) => {
|
|
13542
|
-
stdout +=
|
|
13629
|
+
stdout += decoder.decode(d, { stream: true });
|
|
13543
13630
|
});
|
|
13544
13631
|
child.stderr?.on("data", (d) => {
|
|
13545
|
-
stderr +=
|
|
13632
|
+
stderr += decoder.decode(d, { stream: true });
|
|
13546
13633
|
});
|
|
13547
13634
|
const timer = setTimeout(() => {
|
|
13548
13635
|
child.kill();
|
|
@@ -13554,6 +13641,8 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
13554
13641
|
});
|
|
13555
13642
|
child.on("close", (code) => {
|
|
13556
13643
|
clearTimeout(timer);
|
|
13644
|
+
stdout += decoder.decode();
|
|
13645
|
+
stderr += decoder.decode();
|
|
13557
13646
|
if (code === 0) {
|
|
13558
13647
|
resolve14({ stdout, stderr });
|
|
13559
13648
|
} else {
|
|
@@ -13566,7 +13655,7 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
13566
13655
|
});
|
|
13567
13656
|
});
|
|
13568
13657
|
}
|
|
13569
|
-
var TYPE_CHECK_DEBOUNCE_MS = 2000, plugin;
|
|
13658
|
+
var TYPE_CHECK_DEBOUNCE_MS = 2000, _winDecoder, plugin;
|
|
13570
13659
|
var init_lint_on_write = __esm(() => {
|
|
13571
13660
|
plugin = new LintOnWritePlugin;
|
|
13572
13661
|
});
|
|
@@ -13758,17 +13847,17 @@ var init_auditor = __esm(() => {
|
|
|
13758
13847
|
});
|
|
13759
13848
|
|
|
13760
13849
|
// src/modules/execution/plan-persister.ts
|
|
13761
|
-
import { readFileSync as readFileSync14, writeFileSync as
|
|
13762
|
-
import { join as
|
|
13850
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, mkdirSync as mkdirSync11, existsSync as existsSync26 } from "fs";
|
|
13851
|
+
import { join as join19 } from "path";
|
|
13763
13852
|
|
|
13764
13853
|
class PlanPersister {
|
|
13765
13854
|
filePath;
|
|
13766
13855
|
constructor(baseDir) {
|
|
13767
|
-
const mmaDir =
|
|
13856
|
+
const mmaDir = join19(baseDir, ".mma");
|
|
13768
13857
|
if (!existsSync26(mmaDir)) {
|
|
13769
13858
|
mkdirSync11(mmaDir, { recursive: true });
|
|
13770
13859
|
}
|
|
13771
|
-
this.filePath =
|
|
13860
|
+
this.filePath = join19(mmaDir, "plan.json");
|
|
13772
13861
|
}
|
|
13773
13862
|
save(plan) {
|
|
13774
13863
|
const file = {
|
|
@@ -13779,7 +13868,7 @@ class PlanPersister {
|
|
|
13779
13868
|
updatedAt: new Date().toISOString(),
|
|
13780
13869
|
baseDir: plan.baseDir
|
|
13781
13870
|
};
|
|
13782
|
-
|
|
13871
|
+
writeFileSync8(this.filePath, JSON.stringify(file, null, 2), "utf-8");
|
|
13783
13872
|
}
|
|
13784
13873
|
load() {
|
|
13785
13874
|
if (!existsSync26(this.filePath))
|
|
@@ -13800,7 +13889,7 @@ class PlanPersister {
|
|
|
13800
13889
|
}
|
|
13801
13890
|
clear() {
|
|
13802
13891
|
if (existsSync26(this.filePath)) {
|
|
13803
|
-
|
|
13892
|
+
writeFileSync8(this.filePath, "", "utf-8");
|
|
13804
13893
|
}
|
|
13805
13894
|
}
|
|
13806
13895
|
}
|
|
@@ -13885,7 +13974,7 @@ class ExecutionModule {
|
|
|
13885
13974
|
consecutivePlanWarnings = 0;
|
|
13886
13975
|
lastStepId = -1;
|
|
13887
13976
|
_auditSkipsRemaining = 0;
|
|
13888
|
-
constructor(baseDir, stuckThreshold =
|
|
13977
|
+
constructor(baseDir, stuckThreshold = 6) {
|
|
13889
13978
|
this.baseDir = baseDir;
|
|
13890
13979
|
this.verifier = new StepVerifier(baseDir);
|
|
13891
13980
|
this.stuckDetector = new StuckDetector(stuckThreshold);
|
|
@@ -14168,6 +14257,19 @@ Sub-tasks: ${note}`
|
|
|
14168
14257
|
this.stuckDetector.reset();
|
|
14169
14258
|
this.consecutivePlanWarnings = 0;
|
|
14170
14259
|
this.lastStepId = -1;
|
|
14260
|
+
const iter = typeof ctx.iteration === "number" ? ctx.iteration : 0;
|
|
14261
|
+
if (iter === 3 && !this.tracker && ctx.contextManager) {
|
|
14262
|
+
ctx.contextManager.addMessage({
|
|
14263
|
+
role: "user",
|
|
14264
|
+
content: `<system-summary>You have made 3 tool calls without creating a plan. For any task that involves creating files, installing packages, or multiple steps — you MUST use plan create BEFORE continuing. Use the plan tool now with concrete steps (exact filenames, commands, deliverables). Do NOT make any more write/edit/bash calls until you have a plan.</system-summary>`
|
|
14265
|
+
});
|
|
14266
|
+
}
|
|
14267
|
+
if (iter >= 6 && !this.tracker && ctx.contextManager) {
|
|
14268
|
+
ctx.contextManager.addMessage({
|
|
14269
|
+
role: "user",
|
|
14270
|
+
content: `<system-summary>STOP. ${iter} iterations without a plan. You MUST call plan create RIGHT NOW. No more tool calls until you create a plan.</system-summary>`
|
|
14271
|
+
});
|
|
14272
|
+
}
|
|
14171
14273
|
}
|
|
14172
14274
|
const stuckReason = this.stuckDetector.getStuckReason();
|
|
14173
14275
|
if (stuckReason) {
|
|
@@ -14219,7 +14321,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
14219
14321
|
const step2 = this.tracker?.getCurrentStep();
|
|
14220
14322
|
ctx.contextManager.addMessage({
|
|
14221
14323
|
role: "user",
|
|
14222
|
-
content: `<system-summary>
|
|
14324
|
+
content: `<system-summary>STOP. Step ${step2?.id ?? "?"} ("${step2?.description ?? ""}") took ${this.stuckDetector.getIterationsOnCurrentStep()} iterations with no progress. DO NOT continue this step. Immediately call: plan update step=${step2?.id ?? "?"} status=done (if code works despite warnings) OR plan update step=${step2?.id ?? "?"} status=skipped note="reason". Do NOT make any other tool calls before updating the plan.</system-summary>`
|
|
14223
14325
|
});
|
|
14224
14326
|
}
|
|
14225
14327
|
}
|
|
@@ -14417,7 +14519,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
14417
14519
|
return getMessageText(firstUser.content).trim();
|
|
14418
14520
|
}
|
|
14419
14521
|
}
|
|
14420
|
-
var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD =
|
|
14522
|
+
var STUCK_RECOVERY_COOLDOWN = 5, MAX_PLAN_WARNINGS_BEFORE_BLOCK = 3, FORCE_SKIP_THRESHOLD = 10;
|
|
14421
14523
|
var init_module = __esm(() => {
|
|
14422
14524
|
init_i18n();
|
|
14423
14525
|
init_tracker();
|
|
@@ -14430,8 +14532,8 @@ var init_module = __esm(() => {
|
|
|
14430
14532
|
});
|
|
14431
14533
|
|
|
14432
14534
|
// src/modules/security/session-encryption.ts
|
|
14433
|
-
import { readFileSync as readFileSync16, writeFileSync as
|
|
14434
|
-
import { join as
|
|
14535
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, existsSync as existsSync28, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
14536
|
+
import { join as join20 } from "path";
|
|
14435
14537
|
import { homedir as homedir8 } from "os";
|
|
14436
14538
|
|
|
14437
14539
|
class SessionFileEncryptor {
|
|
@@ -14440,7 +14542,7 @@ class SessionFileEncryptor {
|
|
|
14440
14542
|
constructor(config) {
|
|
14441
14543
|
this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
|
|
14442
14544
|
this.encryptor = new ConfigEncryptor({
|
|
14443
|
-
keyPath: config?.keyPath ||
|
|
14545
|
+
keyPath: config?.keyPath || join20(homedir8(), ".mma", ".session-encryption-key")
|
|
14444
14546
|
});
|
|
14445
14547
|
}
|
|
14446
14548
|
isEnabled() {
|
|
@@ -14485,7 +14587,7 @@ class SessionFileEncryptor {
|
|
|
14485
14587
|
}
|
|
14486
14588
|
writeSessionFile(filePath, content) {
|
|
14487
14589
|
const encrypted = this.encryptFileContent(content);
|
|
14488
|
-
|
|
14590
|
+
writeFileSync9(filePath, encrypted, "utf8");
|
|
14489
14591
|
}
|
|
14490
14592
|
readSessionJSON(filePath) {
|
|
14491
14593
|
const content = readFileSync16(filePath, "utf8");
|
|
@@ -14493,7 +14595,7 @@ class SessionFileEncryptor {
|
|
|
14493
14595
|
}
|
|
14494
14596
|
writeSessionJSON(filePath, obj) {
|
|
14495
14597
|
const content = this.encryptJSON(obj);
|
|
14496
|
-
|
|
14598
|
+
writeFileSync9(filePath, content, "utf8");
|
|
14497
14599
|
}
|
|
14498
14600
|
readSessionJSONL(filePath) {
|
|
14499
14601
|
const content = readFileSync16(filePath, "utf8");
|
|
@@ -14504,7 +14606,7 @@ class SessionFileEncryptor {
|
|
|
14504
14606
|
}
|
|
14505
14607
|
appendToSessionJSONL(filePath, obj) {
|
|
14506
14608
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
14507
|
-
|
|
14609
|
+
writeFileSync9(filePath, encryptedLine + `
|
|
14508
14610
|
`, { flag: "a", encoding: "utf8" });
|
|
14509
14611
|
}
|
|
14510
14612
|
encryptSessionDirectory(sessionDir) {
|
|
@@ -14512,12 +14614,12 @@ class SessionFileEncryptor {
|
|
|
14512
14614
|
return;
|
|
14513
14615
|
const files = readdirSync6(sessionDir);
|
|
14514
14616
|
for (const file of files) {
|
|
14515
|
-
const filePath =
|
|
14617
|
+
const filePath = join20(sessionDir, file);
|
|
14516
14618
|
if (existsSync28(filePath) && !file.endsWith(".enc")) {
|
|
14517
14619
|
try {
|
|
14518
14620
|
const content = readFileSync16(filePath, "utf8");
|
|
14519
14621
|
const encrypted = this.encryptFileContent(content);
|
|
14520
|
-
|
|
14622
|
+
writeFileSync9(filePath + ".enc", encrypted, "utf8");
|
|
14521
14623
|
unlinkSync3(filePath);
|
|
14522
14624
|
} catch {}
|
|
14523
14625
|
}
|
|
@@ -14529,12 +14631,12 @@ class SessionFileEncryptor {
|
|
|
14529
14631
|
const files = readdirSync6(sessionDir);
|
|
14530
14632
|
for (const file of files) {
|
|
14531
14633
|
if (file.endsWith(".enc")) {
|
|
14532
|
-
const encFilePath =
|
|
14634
|
+
const encFilePath = join20(sessionDir, file);
|
|
14533
14635
|
const decFilePath = encFilePath.slice(0, -4);
|
|
14534
14636
|
try {
|
|
14535
14637
|
const content = readFileSync16(encFilePath, "utf8");
|
|
14536
14638
|
const decrypted = this.decryptFileContent(content);
|
|
14537
|
-
|
|
14639
|
+
writeFileSync9(decFilePath, decrypted, "utf8");
|
|
14538
14640
|
unlinkSync3(encFilePath);
|
|
14539
14641
|
} catch {}
|
|
14540
14642
|
}
|
|
@@ -14559,10 +14661,10 @@ import {
|
|
|
14559
14661
|
readdirSync as readdirSync7,
|
|
14560
14662
|
readFileSync as readFileSync17,
|
|
14561
14663
|
rmSync,
|
|
14562
|
-
writeFileSync as
|
|
14664
|
+
writeFileSync as writeFileSync10,
|
|
14563
14665
|
appendFileSync as appendFileSync5
|
|
14564
14666
|
} from "fs";
|
|
14565
|
-
import { join as
|
|
14667
|
+
import { join as join21 } from "path";
|
|
14566
14668
|
import { gzipSync } from "zlib";
|
|
14567
14669
|
|
|
14568
14670
|
class SessionStore {
|
|
@@ -14575,6 +14677,9 @@ class SessionStore {
|
|
|
14575
14677
|
this.encryptor = new SessionFileEncryptor(encryptionConfig);
|
|
14576
14678
|
}
|
|
14577
14679
|
}
|
|
14680
|
+
getSessionDir(id) {
|
|
14681
|
+
return join21(this.baseDir, id);
|
|
14682
|
+
}
|
|
14578
14683
|
updateEncryption(config) {
|
|
14579
14684
|
if (config?.enabled) {
|
|
14580
14685
|
this.encryptor = new SessionFileEncryptor(config);
|
|
@@ -14589,16 +14694,16 @@ class SessionStore {
|
|
|
14589
14694
|
mkdirSync12(this.baseDir, { recursive: true });
|
|
14590
14695
|
}
|
|
14591
14696
|
sessionDir(id) {
|
|
14592
|
-
return
|
|
14697
|
+
return join21(this.baseDir, id);
|
|
14593
14698
|
}
|
|
14594
14699
|
metaPath(id) {
|
|
14595
|
-
return
|
|
14700
|
+
return join21(this.sessionDir(id), "meta.json");
|
|
14596
14701
|
}
|
|
14597
14702
|
historyPath(id) {
|
|
14598
|
-
return
|
|
14703
|
+
return join21(this.sessionDir(id), "history.jsonl");
|
|
14599
14704
|
}
|
|
14600
14705
|
sessionLogPath(id) {
|
|
14601
|
-
return
|
|
14706
|
+
return join21(this.sessionDir(id), "session.jsonl");
|
|
14602
14707
|
}
|
|
14603
14708
|
sessionExists(id) {
|
|
14604
14709
|
return existsSync29(this.metaPath(id));
|
|
@@ -14609,9 +14714,9 @@ class SessionStore {
|
|
|
14609
14714
|
mkdirSync12(dir, { recursive: true });
|
|
14610
14715
|
const content = JSON.stringify(meta, null, 2);
|
|
14611
14716
|
if (this.encryptor) {
|
|
14612
|
-
|
|
14717
|
+
writeFileSync10(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
|
|
14613
14718
|
} else {
|
|
14614
|
-
|
|
14719
|
+
writeFileSync10(this.metaPath(id), content, "utf-8");
|
|
14615
14720
|
}
|
|
14616
14721
|
}
|
|
14617
14722
|
loadMeta(id) {
|
|
@@ -14752,8 +14857,8 @@ class SessionStore {
|
|
|
14752
14857
|
if (existsSync29(historyPath)) {
|
|
14753
14858
|
const content = readFileSync17(historyPath, "utf-8");
|
|
14754
14859
|
const compressed = gzipSync(content);
|
|
14755
|
-
const gzPath =
|
|
14756
|
-
|
|
14860
|
+
const gzPath = join21(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
14861
|
+
writeFileSync10(gzPath, compressed);
|
|
14757
14862
|
rmSync(historyPath);
|
|
14758
14863
|
}
|
|
14759
14864
|
}
|
|
@@ -14863,6 +14968,9 @@ class SessionManager {
|
|
|
14863
14968
|
return;
|
|
14864
14969
|
return this.getSessionContextById(this.activeId);
|
|
14865
14970
|
}
|
|
14971
|
+
getSessionDirectory(id) {
|
|
14972
|
+
return this.store.getSessionDir(id);
|
|
14973
|
+
}
|
|
14866
14974
|
getSessionContextById(sessionId) {
|
|
14867
14975
|
if (!this.sessionContexts.has(sessionId)) {
|
|
14868
14976
|
const meta = this.store.loadMeta(sessionId);
|
|
@@ -14959,9 +15067,9 @@ class ProfileCompressor {
|
|
|
14959
15067
|
}
|
|
14960
15068
|
|
|
14961
15069
|
// src/modules/user-profile/profile.ts
|
|
14962
|
-
import { readFileSync as readFileSync18, writeFileSync as
|
|
14963
|
-
import { join as
|
|
14964
|
-
import { homedir as homedir9, hostname, platform as
|
|
15070
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync11, existsSync as existsSync30, mkdirSync as mkdirSync13 } from "fs";
|
|
15071
|
+
import { join as join22 } from "path";
|
|
15072
|
+
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
14965
15073
|
import { env } from "process";
|
|
14966
15074
|
|
|
14967
15075
|
class UserProfile {
|
|
@@ -14973,7 +15081,7 @@ class UserProfile {
|
|
|
14973
15081
|
}
|
|
14974
15082
|
collect() {
|
|
14975
15083
|
this.info = {
|
|
14976
|
-
platform:
|
|
15084
|
+
platform: platform4(),
|
|
14977
15085
|
os: `${type()} ${hostname()}`,
|
|
14978
15086
|
hostname: hostname(),
|
|
14979
15087
|
shell: env.SHELL || env.ComSpec || "unknown",
|
|
@@ -14987,10 +15095,10 @@ class UserProfile {
|
|
|
14987
15095
|
if (!existsSync30(this.profileDir)) {
|
|
14988
15096
|
mkdirSync13(this.profileDir, { recursive: true });
|
|
14989
15097
|
}
|
|
14990
|
-
|
|
15098
|
+
writeFileSync11(join22(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
14991
15099
|
}
|
|
14992
15100
|
load() {
|
|
14993
|
-
const path =
|
|
15101
|
+
const path = join22(this.profileDir, "profile.json");
|
|
14994
15102
|
if (!existsSync30(path))
|
|
14995
15103
|
return null;
|
|
14996
15104
|
try {
|
|
@@ -15030,7 +15138,7 @@ var init_profile = () => {};
|
|
|
15030
15138
|
|
|
15031
15139
|
// src/modules/skills/loader.ts
|
|
15032
15140
|
import { readdirSync as readdirSync8, readFileSync as readFileSync19, existsSync as existsSync31, statSync as statSync5 } from "fs";
|
|
15033
|
-
import { join as
|
|
15141
|
+
import { join as join23 } from "path";
|
|
15034
15142
|
|
|
15035
15143
|
class SkillsLoader {
|
|
15036
15144
|
loadFromDir(dirPath) {
|
|
@@ -15043,7 +15151,7 @@ class SkillsLoader {
|
|
|
15043
15151
|
scanDir(dirPath, skills) {
|
|
15044
15152
|
const entries = readdirSync8(dirPath);
|
|
15045
15153
|
for (const entry of entries) {
|
|
15046
|
-
const fullPath =
|
|
15154
|
+
const fullPath = join23(dirPath, entry);
|
|
15047
15155
|
const stat = statSync5(fullPath);
|
|
15048
15156
|
if (stat.isDirectory()) {
|
|
15049
15157
|
this.scanDir(fullPath, skills);
|
|
@@ -15323,7 +15431,7 @@ var init_browser2 = __esm(() => {
|
|
|
15323
15431
|
});
|
|
15324
15432
|
|
|
15325
15433
|
// src/modules/lsp/client.ts
|
|
15326
|
-
import { spawn as spawn5, execSync } from "child_process";
|
|
15434
|
+
import { spawn as spawn5, execSync as execSync2 } from "child_process";
|
|
15327
15435
|
import { resolve as resolve16 } from "path";
|
|
15328
15436
|
|
|
15329
15437
|
class LspClient {
|
|
@@ -15380,7 +15488,7 @@ class LspClient {
|
|
|
15380
15488
|
async startServer(config, baseDir) {
|
|
15381
15489
|
if (config.autoInstall === false) {
|
|
15382
15490
|
try {
|
|
15383
|
-
|
|
15491
|
+
execSync2(`where ${config.command}`, { stdio: "pipe", timeout: 3000 });
|
|
15384
15492
|
} catch {
|
|
15385
15493
|
throw new Error(`${config.command} not found in PATH`);
|
|
15386
15494
|
}
|
|
@@ -15640,7 +15748,7 @@ var init_lsp = __esm(() => {
|
|
|
15640
15748
|
|
|
15641
15749
|
// src/modules/indexer/walker.ts
|
|
15642
15750
|
import { readdirSync as readdirSync9, readFileSync as readFileSync20, statSync as statSync6, existsSync as existsSync33, watch } from "fs";
|
|
15643
|
-
import { join as
|
|
15751
|
+
import { join as join24, relative, extname as extname5 } from "path";
|
|
15644
15752
|
|
|
15645
15753
|
class Indexer {
|
|
15646
15754
|
baseDir;
|
|
@@ -15678,7 +15786,7 @@ class Indexer {
|
|
|
15678
15786
|
for (const entry of entries) {
|
|
15679
15787
|
if (count >= this.MAX_FILES)
|
|
15680
15788
|
return;
|
|
15681
|
-
const fullPath =
|
|
15789
|
+
const fullPath = join24(dir, entry);
|
|
15682
15790
|
const relPath = relative(this.baseDir, fullPath);
|
|
15683
15791
|
const stat = statSync6(fullPath);
|
|
15684
15792
|
if (stat.isDirectory()) {
|
|
@@ -15741,14 +15849,14 @@ var init_walker = __esm(() => {
|
|
|
15741
15849
|
});
|
|
15742
15850
|
|
|
15743
15851
|
// src/modules/indexer/cache.ts
|
|
15744
|
-
import { readFileSync as readFileSync21, writeFileSync as
|
|
15745
|
-
import { join as
|
|
15852
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, existsSync as existsSync34, mkdirSync as mkdirSync14, rmSync as rmSync2 } from "fs";
|
|
15853
|
+
import { join as join25 } from "path";
|
|
15746
15854
|
|
|
15747
15855
|
class IndexCache {
|
|
15748
15856
|
cachePath;
|
|
15749
15857
|
cache = null;
|
|
15750
15858
|
constructor(cacheDir) {
|
|
15751
|
-
this.cachePath =
|
|
15859
|
+
this.cachePath = join25(cacheDir, "index-cache.json");
|
|
15752
15860
|
}
|
|
15753
15861
|
load() {
|
|
15754
15862
|
if (this.cache)
|
|
@@ -15764,10 +15872,10 @@ class IndexCache {
|
|
|
15764
15872
|
}
|
|
15765
15873
|
save(result) {
|
|
15766
15874
|
this.cache = result;
|
|
15767
|
-
const dir =
|
|
15875
|
+
const dir = join25(this.cachePath, "..");
|
|
15768
15876
|
if (!existsSync34(dir))
|
|
15769
15877
|
mkdirSync14(dir, { recursive: true });
|
|
15770
|
-
|
|
15878
|
+
writeFileSync12(this.cachePath, JSON.stringify(result), "utf-8");
|
|
15771
15879
|
}
|
|
15772
15880
|
invalidate() {
|
|
15773
15881
|
this.cache = null;
|
|
@@ -16129,13 +16237,13 @@ var init_mcp = __esm(() => {
|
|
|
16129
16237
|
|
|
16130
16238
|
// src/modules/memory/module.ts
|
|
16131
16239
|
import { homedir as homedir10 } from "os";
|
|
16132
|
-
import { join as
|
|
16240
|
+
import { join as join26 } from "path";
|
|
16133
16241
|
|
|
16134
16242
|
class MemoryModule {
|
|
16135
16243
|
name = "memory";
|
|
16136
16244
|
store;
|
|
16137
16245
|
constructor(memoryDir) {
|
|
16138
|
-
const dir = memoryDir ||
|
|
16246
|
+
const dir = memoryDir || join26(homedir10(), ".mma", "memory");
|
|
16139
16247
|
this.store = new MemoryStore(dir);
|
|
16140
16248
|
}
|
|
16141
16249
|
getSystemPromptBlock() {
|
|
@@ -16182,8 +16290,8 @@ __export(exports_bootstrap, {
|
|
|
16182
16290
|
bootstrap: () => bootstrap
|
|
16183
16291
|
});
|
|
16184
16292
|
import { homedir as homedir11 } from "os";
|
|
16185
|
-
import { join as
|
|
16186
|
-
import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as
|
|
16293
|
+
import { join as join27, resolve as resolve18 } from "path";
|
|
16294
|
+
import { existsSync as existsSync35, readFileSync as readFileSync22, writeFileSync as writeFileSync13 } from "fs";
|
|
16187
16295
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
16188
16296
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
16189
16297
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -16202,7 +16310,7 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
16202
16310
|
`- DRY: Do not duplicate code, logic, or configuration — reuse existing utilities and patterns.`
|
|
16203
16311
|
];
|
|
16204
16312
|
if (isWin) {
|
|
16205
|
-
lines.push(``, `Windows environment —
|
|
16313
|
+
lines.push(``, `Windows environment — the shell is PowerShell. Use these rules:`, `- For file listings, prefer the list_dir tool over "dir".`, `- For reading files, prefer the read_file tool over "type".`, `- For deleting files, prefer the delete_file tool over "del".`, `- For creating directories, prefer the create_dir tool over "mkdir".`, `- Do NOT use PowerShell cmdlets (Get-Content, Select-Object, Write-Output) — use dedicated tools instead.`, `- Do not use "head", "tail", "grep", "cat" — they are Unix commands. Use the read_file and grep tools instead.`, `- Use forward slashes (/) or escaped backslashes (\\\\) in file paths.`, `- Your working directory is: ${baseDir}`);
|
|
16206
16314
|
}
|
|
16207
16315
|
lines.push(``, `Bash tool rules:`, `- Use the "workdir" parameter to run commands in a specific directory. Prefer workdir over "cd dir && cmd" chaining.`, `- Run one command per tool call. Split multi-step shell operations into separate bash calls.`, `- Dev servers, watchers and other long-running processes: pass "background: true" to get a process id immediately. Without it, any command still running after a few seconds is automatically moved to the background — check output with process_log.`);
|
|
16208
16316
|
lines.push(``, `=== DEVELOPMENT RULES — follow these strictly ===`, ``, `1. DEPENDENCIES FIRST: Before writing any source code, ALWAYS install project dependencies (e.g., "npm install", "pip install -r requirements.txt", "cargo build", "go mod tidy"). Verify the package manager's lock file or dependency directory exists. Never write code that imports/uses packages that aren't installed yet.`, `2. TOOLKIT/FWK FIRST: If the task specifies a framework or UI library, initialize and configure it BEFORE writing application code. Run its project init command first, then add components/modules. Never write your own version of what the framework already provides.`, `3. ONE STEP AT A TIME: Follow the plan sequentially. Complete step N before starting step N+1. When a step is done: verify the deliverables exist and have real content (not empty), then call "plan update step=N status=done". Do not redo completed work.`, `4. VERIFY YOUR WORK: After creating/modifying files, verify they exist on disk. After installing dependencies, verify the package manager completed successfully. After any command, check its output for errors. Don't assume operations succeeded.`, `5. NO PREMATURE WORK: Do not create files for future steps. Do not add imports/references to packages or modules that haven't been installed yet. Do not reference files or components that don't exist yet. Build incrementally — one layer at a time.`, `6. WHEN STUCK: If a command fails 2+ times, STOP and try a different approach. Write files directly instead of using commands. Ask the user for help. Never repeat the same failing command more than twice.`, ``, `=== PLAN QUALITY RULES — your plan MUST follow these ===`, ``, `- Each step must describe CONCRETE deliverables: exact filenames with paths, exact packages to install, exact CLI commands to run. Avoid vague steps — be specific.`, `- A step like "Настройка проекта" or "Setup the project" is too vague — describe what exactly needs to be configured or set up.`, `- A step like "Создать src/components/Header.tsx с навигацией и логотипом, добавить в src/App.tsx импорт <Header />" is GOOD.`, `- Include file extensions (.tsx, .css, .json) and directory paths. Every step must mention at least one file or command.`, `- The plan must cover EVERYTHING needed: init → deps → framework setup → code → verification.`, `- Number of steps: 5-8 for a typical task. Too few means you're being vague. Too many means you're over-splitting.`);
|
|
@@ -16217,8 +16325,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
16217
16325
|
`);
|
|
16218
16326
|
}
|
|
16219
16327
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
16220
|
-
const dir = configDir ||
|
|
16221
|
-
const projectConfigPath = projectDir ?
|
|
16328
|
+
const dir = configDir || join27(homedir11(), ".mma");
|
|
16329
|
+
const projectConfigPath = projectDir ? join27(projectDir, ".mmrc") : join27(process.cwd(), ".mmrc");
|
|
16222
16330
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
16223
16331
|
setLocale(config.locale);
|
|
16224
16332
|
try {
|
|
@@ -16228,7 +16336,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16228
16336
|
}
|
|
16229
16337
|
} catch {}
|
|
16230
16338
|
const logger = new Logger(config.logLevel);
|
|
16231
|
-
logger.setLogDir(
|
|
16339
|
+
logger.setLogDir(join27(dir, "logs"));
|
|
16232
16340
|
logger.debug("MMA bootstrap", {
|
|
16233
16341
|
version: config.version,
|
|
16234
16342
|
model: config.model
|
|
@@ -16250,7 +16358,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16250
16358
|
logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
16251
16359
|
}
|
|
16252
16360
|
}
|
|
16253
|
-
const profile = new UserProfile(
|
|
16361
|
+
const profile = new UserProfile(join27(dir));
|
|
16254
16362
|
profile.load() || profile.collect();
|
|
16255
16363
|
profile.save();
|
|
16256
16364
|
const llmProvider = new OpenAICompatProvider({
|
|
@@ -16262,7 +16370,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16262
16370
|
rateLimits: config.security?.rateLimits
|
|
16263
16371
|
});
|
|
16264
16372
|
const baseDir = projectDir ? resolve18(projectDir) : process.cwd();
|
|
16265
|
-
const projectMapCacheDir =
|
|
16373
|
+
const projectMapCacheDir = join27(baseDir, ".mma");
|
|
16266
16374
|
const indexerModule = new IndexerModule({
|
|
16267
16375
|
baseDir,
|
|
16268
16376
|
cacheDir: projectMapCacheDir
|
|
@@ -16273,9 +16381,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16273
16381
|
logger.warn(`Project indexing failed: ${err.message}`);
|
|
16274
16382
|
}
|
|
16275
16383
|
const skillsLoader = new SkillsLoader;
|
|
16276
|
-
const builtinDir =
|
|
16277
|
-
const globalDir =
|
|
16278
|
-
const projectSkillsDir =
|
|
16384
|
+
const builtinDir = join27(import.meta.dirname, "skills", "builtin");
|
|
16385
|
+
const globalDir = join27(homedir11(), ".agents", "skills");
|
|
16386
|
+
const projectSkillsDir = join27(baseDir, ".mma", "skills");
|
|
16279
16387
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
16280
16388
|
const skillsMatcher = new SkillsMatcher;
|
|
16281
16389
|
const skillsBudget = Math.floor(config.contextWindow * 0.1);
|
|
@@ -16289,11 +16397,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16289
16397
|
essential: true,
|
|
16290
16398
|
estimatedTokens: 250
|
|
16291
16399
|
};
|
|
16292
|
-
const agentsMdGlobal =
|
|
16400
|
+
const agentsMdGlobal = join27(dir, "AGENTS.md");
|
|
16293
16401
|
if (!existsSync35(agentsMdGlobal)) {
|
|
16294
|
-
|
|
16402
|
+
writeFileSync13(agentsMdGlobal, "", "utf-8");
|
|
16295
16403
|
}
|
|
16296
|
-
const sessionDir =
|
|
16404
|
+
const sessionDir = join27(dir, "sessions");
|
|
16297
16405
|
const sessionStore = new SessionStore(sessionDir);
|
|
16298
16406
|
sessionStore.init();
|
|
16299
16407
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -16361,7 +16469,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16361
16469
|
const mcpModule = new MCPModule(config);
|
|
16362
16470
|
await mcpModule.initialize();
|
|
16363
16471
|
moduleRegistry.register(mcpModule);
|
|
16364
|
-
const memoryModule = new MemoryModule(
|
|
16472
|
+
const memoryModule = new MemoryModule(join27(dir, "memory"));
|
|
16365
16473
|
moduleRegistry.register(memoryModule);
|
|
16366
16474
|
if (config.browser.enabled) {
|
|
16367
16475
|
const browserModule = new BrowserModule;
|
|
@@ -16411,8 +16519,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16411
16519
|
pluginManager.register(plugin);
|
|
16412
16520
|
pluginManager.register(plugin2);
|
|
16413
16521
|
const pluginLoader = new PluginLoader;
|
|
16414
|
-
const globalPluginsDir =
|
|
16415
|
-
const projectPluginsDir =
|
|
16522
|
+
const globalPluginsDir = join27(homedir11(), ".mma", "plugins");
|
|
16523
|
+
const projectPluginsDir = join27(baseDir, ".mma", "plugins");
|
|
16416
16524
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
|
|
16417
16525
|
pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
|
|
16418
16526
|
contextManager.onCompact = (summary) => {
|
|
@@ -16430,9 +16538,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
16430
16538
|
const skipAgentsMd = noAgentsMd === true;
|
|
16431
16539
|
if (!skipAgentsMd) {
|
|
16432
16540
|
const agentsMdCandidates = [
|
|
16433
|
-
|
|
16434
|
-
|
|
16435
|
-
|
|
16541
|
+
join27(baseDir, "AGENTS.md"),
|
|
16542
|
+
join27(baseDir, ".mma", "AGENTS.md"),
|
|
16543
|
+
join27(dir, "AGENTS.md")
|
|
16436
16544
|
];
|
|
16437
16545
|
for (const p of agentsMdCandidates) {
|
|
16438
16546
|
if (existsSync35(p)) {
|
|
@@ -16780,12 +16888,12 @@ function formatTable(tableLines, opts = {}) {
|
|
|
16780
16888
|
const a = isHeader && align[c] === undefined ? "center" : align[c] ?? "left";
|
|
16781
16889
|
cells.push(pad(cell, widths[c], a));
|
|
16782
16890
|
}
|
|
16783
|
-
const content = cells.map((c) =>
|
|
16784
|
-
return isHeader ?
|
|
16891
|
+
const content = cells.map((c) => pc2.dim("│ ") + c).join("") + pc2.dim("│");
|
|
16892
|
+
return isHeader ? pc2.bold(content) : content;
|
|
16785
16893
|
};
|
|
16786
16894
|
const border = (l, m, r) => {
|
|
16787
16895
|
const seg = widths.map((w) => "─".repeat(w + 2)).join(m);
|
|
16788
|
-
return
|
|
16896
|
+
return pc2.dim(l + seg + r);
|
|
16789
16897
|
};
|
|
16790
16898
|
const out = [];
|
|
16791
16899
|
out.push(border("┌", "┬", "┐"));
|
|
@@ -16883,7 +16991,7 @@ class Spinner {
|
|
|
16883
16991
|
return;
|
|
16884
16992
|
const frame = FRAMES[this.frame % FRAMES.length];
|
|
16885
16993
|
this.frame++;
|
|
16886
|
-
this.stream.write("\r" +
|
|
16994
|
+
this.stream.write("\r" + pc2.cyan(frame) + " " + this.message + "\x1B[K");
|
|
16887
16995
|
}
|
|
16888
16996
|
}
|
|
16889
16997
|
var FRAMES;
|
|
@@ -16950,19 +17058,19 @@ function box(lines, opts = {}) {
|
|
|
16950
17058
|
const title = opts.title ?? "";
|
|
16951
17059
|
if (title) {
|
|
16952
17060
|
const head = `─ ${title} `;
|
|
16953
|
-
out.push(
|
|
17061
|
+
out.push(pc2.dim(`┌${head}${"─".repeat(Math.max(0, width - 2 - stringWidth(head)))}┐`));
|
|
16954
17062
|
} else {
|
|
16955
|
-
out.push(
|
|
17063
|
+
out.push(pc2.dim(`┌${"─".repeat(width - 2)}┐`));
|
|
16956
17064
|
}
|
|
16957
17065
|
for (const line of wrapped) {
|
|
16958
|
-
out.push(
|
|
17066
|
+
out.push(pc2.dim("│") + " ".repeat(pad2) + padTo(line, inner) + " ".repeat(pad2) + pc2.dim("│"));
|
|
16959
17067
|
}
|
|
16960
|
-
out.push(
|
|
17068
|
+
out.push(pc2.dim(`└${"─".repeat(width - 2)}┘`));
|
|
16961
17069
|
return out;
|
|
16962
17070
|
}
|
|
16963
17071
|
function divider(width) {
|
|
16964
17072
|
const w = Math.min(width ?? getTerminalWidth(), 60);
|
|
16965
|
-
return
|
|
17073
|
+
return pc2.dim("─".repeat(w));
|
|
16966
17074
|
}
|
|
16967
17075
|
var init_box = __esm(() => {
|
|
16968
17076
|
init_string_width();
|
|
@@ -16982,7 +17090,7 @@ async function withSpinner(message, fn) {
|
|
|
16982
17090
|
}
|
|
16983
17091
|
}
|
|
16984
17092
|
function menuList(items) {
|
|
16985
|
-
const lines = items.map((it, i) => ` ${
|
|
17093
|
+
const lines = items.map((it, i) => ` ${pc2.cyan(`[${i + 1}]`)} ${it.label}${it.url ? ` ${pc2.dim(it.url)}` : ""}`);
|
|
16986
17094
|
for (const l of box(lines, { width: 72 }))
|
|
16987
17095
|
console.log(l);
|
|
16988
17096
|
}
|
|
@@ -17117,15 +17225,15 @@ async function runSetup(externalRl) {
|
|
|
17117
17225
|
}
|
|
17118
17226
|
const connected = await withSpinner(t("setup.testing_spinner", { model }), () => testChat(apiBase, apiKey, model));
|
|
17119
17227
|
if (connected) {
|
|
17120
|
-
console.log(
|
|
17228
|
+
console.log(pc2.green(t("setup.ok")));
|
|
17121
17229
|
} else {
|
|
17122
|
-
console.log(
|
|
17230
|
+
console.log(pc2.yellow(t("setup.warning")));
|
|
17123
17231
|
}
|
|
17124
17232
|
console.log(t("setup.agent_settings"));
|
|
17125
17233
|
const contextWindow = parseInt(await ask(rl, t("setup.context_window"), "32768"));
|
|
17126
17234
|
const maxIterations = parseInt(await ask(rl, t("setup.max_iters"), "1000"));
|
|
17127
17235
|
console.log(t("setup.security_header"));
|
|
17128
|
-
console.log(
|
|
17236
|
+
console.log(pc2.dim(t("setup.security_status_off")));
|
|
17129
17237
|
const configureSecurity = await ask(rl, t("setup.security_configure"), "n");
|
|
17130
17238
|
let securityBashBlock = false;
|
|
17131
17239
|
let securityFlagsBlock = false;
|
|
@@ -17149,7 +17257,7 @@ async function runSetup(externalRl) {
|
|
|
17149
17257
|
securityFlagsBlock,
|
|
17150
17258
|
securityPathsDeny
|
|
17151
17259
|
};
|
|
17152
|
-
console.log(
|
|
17260
|
+
console.log(pc2.green(pc2.bold(t("setup.complete"))));
|
|
17153
17261
|
const summary = renderTable([
|
|
17154
17262
|
t("setup.summary_setting"),
|
|
17155
17263
|
t("setup.summary_value"),
|
|
@@ -17209,9 +17317,9 @@ __export(exports_manifest, {
|
|
|
17209
17317
|
getCertMark: () => getCertMark,
|
|
17210
17318
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
17211
17319
|
});
|
|
17212
|
-
import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as
|
|
17320
|
+
import { existsSync as existsSync36, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync14 } from "fs";
|
|
17213
17321
|
import { homedir as homedir13 } from "os";
|
|
17214
|
-
import { join as
|
|
17322
|
+
import { join as join29 } from "path";
|
|
17215
17323
|
function readManifest(path = MANIFEST_PATH) {
|
|
17216
17324
|
try {
|
|
17217
17325
|
if (existsSync36(path)) {
|
|
@@ -17222,8 +17330,8 @@ function readManifest(path = MANIFEST_PATH) {
|
|
|
17222
17330
|
return { version: 1, certifications: [] };
|
|
17223
17331
|
}
|
|
17224
17332
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
17225
|
-
mkdirSync15(
|
|
17226
|
-
|
|
17333
|
+
mkdirSync15(join29(homedir13(), ".mma"), { recursive: true });
|
|
17334
|
+
writeFileSync14(path, JSON.stringify(m, null, 2), "utf-8");
|
|
17227
17335
|
}
|
|
17228
17336
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
17229
17337
|
const m = readManifest(path);
|
|
@@ -17257,7 +17365,7 @@ function getCertMark(model, providerUrl, currentVersion, path = MANIFEST_PATH) {
|
|
|
17257
17365
|
}
|
|
17258
17366
|
var MANIFEST_PATH;
|
|
17259
17367
|
var init_manifest = __esm(() => {
|
|
17260
|
-
MANIFEST_PATH =
|
|
17368
|
+
MANIFEST_PATH = join29(homedir13(), ".mma", "certifications.json");
|
|
17261
17369
|
});
|
|
17262
17370
|
|
|
17263
17371
|
// node_modules/yaml/dist/nodes/identity.js
|
|
@@ -24381,7 +24489,7 @@ var init_scenarios = __esm(() => {
|
|
|
24381
24489
|
|
|
24382
24490
|
// src/modules/certification/loader.ts
|
|
24383
24491
|
import { existsSync as existsSync37, readdirSync as readdirSync10, readFileSync as readFileSync24 } from "fs";
|
|
24384
|
-
import { join as
|
|
24492
|
+
import { join as join30 } from "path";
|
|
24385
24493
|
function validateScenario(s) {
|
|
24386
24494
|
const errors2 = [];
|
|
24387
24495
|
const isSkip = s.mode === "skip";
|
|
@@ -24435,7 +24543,7 @@ function loadScenarios(userDir) {
|
|
|
24435
24543
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
24436
24544
|
continue;
|
|
24437
24545
|
try {
|
|
24438
|
-
const raw = readFileSync24(
|
|
24546
|
+
const raw = readFileSync24(join30(userDir, file), "utf-8");
|
|
24439
24547
|
const data = $parse(raw);
|
|
24440
24548
|
const parsed = normalizeScenario(data, file);
|
|
24441
24549
|
const errs = validateScenario(parsed);
|
|
@@ -24489,7 +24597,7 @@ var init_loader3 = __esm(() => {
|
|
|
24489
24597
|
|
|
24490
24598
|
// src/modules/certification/fact-checker.ts
|
|
24491
24599
|
import { existsSync as existsSync38, readFileSync as readFileSync25, statSync as statSync7 } from "fs";
|
|
24492
|
-
import { join as
|
|
24600
|
+
import { join as join31 } from "path";
|
|
24493
24601
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
24494
24602
|
const failures = [];
|
|
24495
24603
|
for (const check of checks) {
|
|
@@ -24506,13 +24614,13 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
24506
24614
|
case "outputContains":
|
|
24507
24615
|
return output.includes(check.text);
|
|
24508
24616
|
case "fileExists":
|
|
24509
|
-
return isFile(
|
|
24617
|
+
return isFile(join31(sandboxDir, check.path));
|
|
24510
24618
|
case "fileNotExists":
|
|
24511
|
-
return !existsSync38(
|
|
24619
|
+
return !existsSync38(join31(sandboxDir, check.path));
|
|
24512
24620
|
case "dirExists":
|
|
24513
|
-
return isDir(
|
|
24621
|
+
return isDir(join31(sandboxDir, check.path));
|
|
24514
24622
|
case "fileContent": {
|
|
24515
|
-
const abs =
|
|
24623
|
+
const abs = join31(sandboxDir, check.path);
|
|
24516
24624
|
if (!isFile(abs))
|
|
24517
24625
|
return false;
|
|
24518
24626
|
const content = readFileSync25(abs, "utf-8");
|
|
@@ -24523,7 +24631,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
24523
24631
|
return false;
|
|
24524
24632
|
}
|
|
24525
24633
|
case "fileRegex": {
|
|
24526
|
-
const abs =
|
|
24634
|
+
const abs = join31(sandboxDir, check.path);
|
|
24527
24635
|
if (!isFile(abs))
|
|
24528
24636
|
return false;
|
|
24529
24637
|
return new RegExp(check.pattern).test(readFileSync25(abs, "utf-8"));
|
|
@@ -24573,8 +24681,8 @@ var init_fact_checker = () => {};
|
|
|
24573
24681
|
// src/modules/certification/runner.ts
|
|
24574
24682
|
import { spawn as spawn6 } from "child_process";
|
|
24575
24683
|
import { existsSync as existsSync39, mkdirSync as mkdirSync16, rmSync as rmSync3, cpSync as cpSync2 } from "fs";
|
|
24576
|
-
import { platform as
|
|
24577
|
-
import { join as
|
|
24684
|
+
import { platform as platform5 } from "os";
|
|
24685
|
+
import { join as join32, resolve as resolve19, dirname as dirname9 } from "path";
|
|
24578
24686
|
async function runScenario(scenario, opts) {
|
|
24579
24687
|
if (scenario.mode === "skip") {
|
|
24580
24688
|
return {
|
|
@@ -24593,7 +24701,7 @@ async function runScenario(scenario, opts) {
|
|
|
24593
24701
|
let passed = 0;
|
|
24594
24702
|
let firstError;
|
|
24595
24703
|
for (let i = 1;i <= reps; i++) {
|
|
24596
|
-
const sandbox =
|
|
24704
|
+
const sandbox = join32(opts.sandboxBase, `run-${scenario.id}-${i}`);
|
|
24597
24705
|
let failures = [];
|
|
24598
24706
|
let exitCode = -1;
|
|
24599
24707
|
let output = "";
|
|
@@ -24654,20 +24762,20 @@ function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
|
24654
24762
|
rmSync3(sandbox, { recursive: true, force: true });
|
|
24655
24763
|
mkdirSync16(sandbox, { recursive: true });
|
|
24656
24764
|
for (const f of scenario.fixtures ?? []) {
|
|
24657
|
-
const src =
|
|
24765
|
+
const src = join32(mmaRoot, f.source);
|
|
24658
24766
|
if (!existsSync39(src)) {
|
|
24659
24767
|
throw new Error(`fixture missing: ${f.source}`);
|
|
24660
24768
|
}
|
|
24661
|
-
const dest =
|
|
24769
|
+
const dest = join32(sandbox, f.dest);
|
|
24662
24770
|
mkdirSync16(dirname9(dest), { recursive: true });
|
|
24663
24771
|
cpSync2(src, dest);
|
|
24664
24772
|
}
|
|
24665
24773
|
}
|
|
24666
24774
|
function resolveMmaEntry(mmaRoot) {
|
|
24667
|
-
const dev =
|
|
24775
|
+
const dev = join32(mmaRoot, "src", "cli", "main.ts");
|
|
24668
24776
|
if (existsSync39(dev))
|
|
24669
24777
|
return dev;
|
|
24670
|
-
return
|
|
24778
|
+
return join32(mmaRoot, "dist", "main.js");
|
|
24671
24779
|
}
|
|
24672
24780
|
function findMmaRoot(fromDir) {
|
|
24673
24781
|
const candidates = [
|
|
@@ -24675,7 +24783,7 @@ function findMmaRoot(fromDir) {
|
|
|
24675
24783
|
resolve19(fromDir, "..")
|
|
24676
24784
|
];
|
|
24677
24785
|
for (const c of candidates) {
|
|
24678
|
-
if (existsSync39(
|
|
24786
|
+
if (existsSync39(join32(c, "package.json")))
|
|
24679
24787
|
return c;
|
|
24680
24788
|
}
|
|
24681
24789
|
return process.cwd();
|
|
@@ -24684,7 +24792,7 @@ function killTree2(child) {
|
|
|
24684
24792
|
const pid = child.pid;
|
|
24685
24793
|
if (!pid)
|
|
24686
24794
|
return;
|
|
24687
|
-
if (
|
|
24795
|
+
if (platform5() === "win32") {
|
|
24688
24796
|
spawn6("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
24689
24797
|
windowsHide: true,
|
|
24690
24798
|
stdio: "ignore"
|
|
@@ -24743,12 +24851,12 @@ __export(exports_cli, {
|
|
|
24743
24851
|
});
|
|
24744
24852
|
import { rmSync as rmSync4 } from "fs";
|
|
24745
24853
|
import { homedir as homedir14 } from "os";
|
|
24746
|
-
import { join as
|
|
24854
|
+
import { join as join33, dirname as dirname10 } from "path";
|
|
24747
24855
|
import { fileURLToPath } from "url";
|
|
24748
24856
|
import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
|
|
24749
24857
|
function readVersion() {
|
|
24750
24858
|
const candidates = [
|
|
24751
|
-
|
|
24859
|
+
join33(MMA_ROOT, "package.json")
|
|
24752
24860
|
];
|
|
24753
24861
|
for (const p of candidates) {
|
|
24754
24862
|
if (existsSync40(p)) {
|
|
@@ -24765,36 +24873,36 @@ function parseTags(s) {
|
|
|
24765
24873
|
async function certify(opts) {
|
|
24766
24874
|
const providerUrl = opts.providerUrl || opts.config.provider.baseUrl;
|
|
24767
24875
|
if (opts.tags.includes("security") && !opts.config.security?.enabled) {
|
|
24768
|
-
console.error(
|
|
24876
|
+
console.error(pc2.red(t("cli.cert_security_required")));
|
|
24769
24877
|
process.exitCode = 1;
|
|
24770
24878
|
return;
|
|
24771
24879
|
}
|
|
24772
24880
|
const { scenarios, errors: errors2 } = loadScenarios(USER_SCENARIO_DIR);
|
|
24773
24881
|
for (const e of errors2)
|
|
24774
|
-
console.error(
|
|
24882
|
+
console.error(pc2.yellow(` ${e}`));
|
|
24775
24883
|
const selected = filterByTags(scenarios, opts.tags);
|
|
24776
24884
|
if (selected.length === 0) {
|
|
24777
|
-
console.error(
|
|
24885
|
+
console.error(pc2.red(t("cli.cert_no_scenarios", { tags: opts.tags.join(",") })));
|
|
24778
24886
|
process.exitCode = 1;
|
|
24779
24887
|
return;
|
|
24780
24888
|
}
|
|
24781
24889
|
const manifest = readManifest();
|
|
24782
24890
|
const existing = manifest.certifications.find((e) => e.model === opts.name && e.providerUrl === providerUrl);
|
|
24783
24891
|
if (existing && !opts.force) {
|
|
24784
|
-
console.error(
|
|
24785
|
-
console.error(
|
|
24892
|
+
console.error(pc2.yellow(t("cli.cert_exists", { model: opts.name })));
|
|
24893
|
+
console.error(pc2.yellow(t("cli.cert_exists_hint")));
|
|
24786
24894
|
process.exitCode = 1;
|
|
24787
24895
|
return;
|
|
24788
24896
|
}
|
|
24789
24897
|
console.log(t("cli.cert_started", { model: opts.name, provider: providerUrl }));
|
|
24790
|
-
const sandboxBase =
|
|
24898
|
+
const sandboxBase = join33(process.cwd(), ".mma", "certification");
|
|
24791
24899
|
const results = [];
|
|
24792
24900
|
const total = selected.length;
|
|
24793
24901
|
let idx = 0;
|
|
24794
24902
|
for (const scenario of selected) {
|
|
24795
24903
|
idx++;
|
|
24796
24904
|
if (scenario.mode === "skip") {
|
|
24797
|
-
console.log(
|
|
24905
|
+
console.log(pc2.dim(`[${idx}/${total}] ${scenario.id} ... skipped`));
|
|
24798
24906
|
results.push({ id: scenario.id, title: scenario.title, status: "skipped", passed: 0, of: 0 });
|
|
24799
24907
|
continue;
|
|
24800
24908
|
}
|
|
@@ -24808,10 +24916,10 @@ async function certify(opts) {
|
|
|
24808
24916
|
defaultReps: opts.reps,
|
|
24809
24917
|
defaultThreshold: 2,
|
|
24810
24918
|
onRep: (id, rep, reps, passed, failures) => {
|
|
24811
|
-
const word = passed ?
|
|
24919
|
+
const word = passed ? pc2.green(t("cli.cert_rep_pass")) : pc2.red(t("cli.cert_rep_fail"));
|
|
24812
24920
|
console.log(`[${idx}/${total}] ${id} (${rep}/${reps})... ${word}`);
|
|
24813
24921
|
if (!passed)
|
|
24814
|
-
console.log(` ${
|
|
24922
|
+
console.log(` ${pc2.dim(failures.join("; "))}`);
|
|
24815
24923
|
}
|
|
24816
24924
|
});
|
|
24817
24925
|
results.push(res);
|
|
@@ -24859,7 +24967,7 @@ async function certList() {
|
|
|
24859
24967
|
return;
|
|
24860
24968
|
}
|
|
24861
24969
|
for (const e of m.certifications) {
|
|
24862
|
-
console.log(` ${
|
|
24970
|
+
console.log(` ${pc2.green("✔")} ${e.model} ${pc2.dim(e.providerUrl)} ${e.mmaVersion} ${e.certifiedAt.slice(0, 10)} ${e.suite.passed}/${e.suite.total} pass`);
|
|
24863
24971
|
}
|
|
24864
24972
|
}
|
|
24865
24973
|
async function uncertify(name, config) {
|
|
@@ -24879,11 +24987,11 @@ function summarize(results) {
|
|
|
24879
24987
|
}
|
|
24880
24988
|
function printResults(results) {
|
|
24881
24989
|
for (const r of results) {
|
|
24882
|
-
const icon = r.status === "pass" ?
|
|
24883
|
-
const detail = r.status === "skipped" ?
|
|
24990
|
+
const icon = r.status === "pass" ? pc2.green("✔") : r.status === "fail" ? pc2.red("✘") : r.status === "skipped" ? pc2.dim("–") : pc2.yellow("!");
|
|
24991
|
+
const detail = r.status === "skipped" ? pc2.dim(r.title) : `${r.passed}/${r.of}`;
|
|
24884
24992
|
console.log(` ${icon} ${r.id} ${detail}`);
|
|
24885
24993
|
if (r.error)
|
|
24886
|
-
console.log(` ${
|
|
24994
|
+
console.log(` ${pc2.dim(r.error)}`);
|
|
24887
24995
|
}
|
|
24888
24996
|
}
|
|
24889
24997
|
var HERE, MMA_ROOT, USER_SCENARIO_DIR;
|
|
@@ -24895,7 +25003,7 @@ var init_cli = __esm(() => {
|
|
|
24895
25003
|
init_manifest();
|
|
24896
25004
|
HERE = dirname10(fileURLToPath(import.meta.url));
|
|
24897
25005
|
MMA_ROOT = findMmaRoot(HERE);
|
|
24898
|
-
USER_SCENARIO_DIR =
|
|
25006
|
+
USER_SCENARIO_DIR = join33(homedir14(), ".mma", "certification", "scenarios");
|
|
24899
25007
|
});
|
|
24900
25008
|
|
|
24901
25009
|
// src/cli/repl-commands.ts
|
|
@@ -24904,15 +25012,15 @@ __export(exports_repl_commands, {
|
|
|
24904
25012
|
registerAllCommands: () => registerAllCommands,
|
|
24905
25013
|
COMMAND_GROUPS: () => COMMAND_GROUPS
|
|
24906
25014
|
});
|
|
24907
|
-
import { join as
|
|
25015
|
+
import { join as join35, dirname as dirname12 } from "path";
|
|
24908
25016
|
import { homedir as homedir16 } from "os";
|
|
24909
25017
|
import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
|
|
24910
25018
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
24911
25019
|
function readVersion3() {
|
|
24912
25020
|
const here = dirname12(fileURLToPath3(import.meta.url));
|
|
24913
25021
|
const candidates = [
|
|
24914
|
-
|
|
24915
|
-
|
|
25022
|
+
join35(here, "..", "..", "package.json"),
|
|
25023
|
+
join35(here, "..", "package.json")
|
|
24916
25024
|
];
|
|
24917
25025
|
for (const p of candidates) {
|
|
24918
25026
|
if (existsSync42(p)) {
|
|
@@ -24986,7 +25094,7 @@ function registerMmaCommands(ctx) {
|
|
|
24986
25094
|
if (source.toLowerCase() === "clipboard") {
|
|
24987
25095
|
const clipBuf = await readClipboardImage2();
|
|
24988
25096
|
if (!clipBuf) {
|
|
24989
|
-
console.log(
|
|
25097
|
+
console.log(pc2.yellow(t("image.clipboard_empty")));
|
|
24990
25098
|
return;
|
|
24991
25099
|
}
|
|
24992
25100
|
const { bufferToDataUrl: bufferToDataUrl2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
@@ -25000,7 +25108,7 @@ function registerMmaCommands(ctx) {
|
|
|
25000
25108
|
} else {
|
|
25001
25109
|
const absPath = resolve20(process.cwd(), source);
|
|
25002
25110
|
if (!existsSync43(absPath)) {
|
|
25003
|
-
console.log(
|
|
25111
|
+
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
25004
25112
|
return;
|
|
25005
25113
|
}
|
|
25006
25114
|
const result = await loadFileAsDataUrl2(absPath);
|
|
@@ -25009,7 +25117,7 @@ function registerMmaCommands(ctx) {
|
|
|
25009
25117
|
}
|
|
25010
25118
|
const contextManager = ctx.agent.contextManager;
|
|
25011
25119
|
if (!contextManager) {
|
|
25012
|
-
console.log(
|
|
25120
|
+
console.log(pc2.red(t("image.no_context")));
|
|
25013
25121
|
return;
|
|
25014
25122
|
}
|
|
25015
25123
|
contextManager.addPendingImage({
|
|
@@ -25017,9 +25125,9 @@ function registerMmaCommands(ctx) {
|
|
|
25017
25125
|
image_url: { url: dataUrl }
|
|
25018
25126
|
});
|
|
25019
25127
|
const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
|
|
25020
|
-
console.log(
|
|
25128
|
+
console.log(pc2.green(t("image.attached", { source: label, size: `${sizeKb} KB` })));
|
|
25021
25129
|
} catch (err) {
|
|
25022
|
-
console.log(
|
|
25130
|
+
console.log(pc2.red(t("image.error", { message: err.message })));
|
|
25023
25131
|
}
|
|
25024
25132
|
}
|
|
25025
25133
|
});
|
|
@@ -25037,7 +25145,7 @@ function registerMmaCommands(ctx) {
|
|
|
25037
25145
|
console.log(`${t("repl.context")} ${ctxW} (sys:${sys} res:${res} hist:${ctxW - sys - res})`);
|
|
25038
25146
|
console.log(`${t("repl.max_iters")} ${cfg.maxToolIterations}`);
|
|
25039
25147
|
console.log(`${t("repl.stuck_thresh")} ${cfg.stuckThreshold}`);
|
|
25040
|
-
console.log(`${t("repl.reasoning_label")} ${cfg.showReasoning ?
|
|
25148
|
+
console.log(`${t("repl.reasoning_label")} ${cfg.showReasoning ? pc2.green(t("repl.show")) : pc2.dim(t("repl.hide"))}`);
|
|
25041
25149
|
console.log(`${t("repl.log_level")} ${cfg.logLevel}`);
|
|
25042
25150
|
console.log(`${t("repl.locale")} ${cfg.locale}`);
|
|
25043
25151
|
const meta = ctx.sessionManager?.getActiveMeta();
|
|
@@ -25052,7 +25160,7 @@ function registerMmaCommands(ctx) {
|
|
|
25052
25160
|
usage: t("repl.reasoning_usage"),
|
|
25053
25161
|
action: () => {
|
|
25054
25162
|
ctx.config.showReasoning = !ctx.config.showReasoning;
|
|
25055
|
-
const status = ctx.config.showReasoning ?
|
|
25163
|
+
const status = ctx.config.showReasoning ? pc2.green(t("repl.show")) : pc2.dim(t("repl.hide"));
|
|
25056
25164
|
console.log(t("repl.reasoning_status", { status }));
|
|
25057
25165
|
}
|
|
25058
25166
|
});
|
|
@@ -25075,10 +25183,10 @@ function registerMmaCommands(ctx) {
|
|
|
25075
25183
|
aliases: ["setup"],
|
|
25076
25184
|
usage: t("repl.wizard_usage"),
|
|
25077
25185
|
action: async () => {
|
|
25078
|
-
console.log(
|
|
25186
|
+
console.log(pc2.yellow(t("repl.wizard_running")));
|
|
25079
25187
|
await ctx.withExclusiveInput(async () => {
|
|
25080
25188
|
const answers = await runSetup(ctx.rl);
|
|
25081
|
-
const configPath =
|
|
25189
|
+
const configPath = join35(homedir16(), ".mma", "config.json");
|
|
25082
25190
|
ctx.config.provider.type = answers.provider;
|
|
25083
25191
|
ctx.config.provider.baseUrl = answers.apiBase;
|
|
25084
25192
|
ctx.config.provider.apiKey = answers.apiKey;
|
|
@@ -25088,7 +25196,7 @@ function registerMmaCommands(ctx) {
|
|
|
25088
25196
|
ctx.config.locale = answers.locale;
|
|
25089
25197
|
saveConfig(ctx.config, configPath);
|
|
25090
25198
|
await ctx.agent.reconfigure(ctx.config);
|
|
25091
|
-
console.log(
|
|
25199
|
+
console.log(pc2.green(t("cli.config_saved")));
|
|
25092
25200
|
});
|
|
25093
25201
|
}
|
|
25094
25202
|
});
|
|
@@ -25098,18 +25206,18 @@ function registerMmaCommands(ctx) {
|
|
|
25098
25206
|
usage: t("repl.sysprompt_desc"),
|
|
25099
25207
|
action: () => {
|
|
25100
25208
|
const info = ctx.agent.getSystemPromptInfo();
|
|
25101
|
-
console.log(
|
|
25102
|
-
console.log(
|
|
25209
|
+
console.log(pc2.bold(`System prompt (${info.tokenCount} tokens):`));
|
|
25210
|
+
console.log(pc2.dim("─".repeat(60)));
|
|
25103
25211
|
for (const line of info.text.split(`
|
|
25104
25212
|
`)) {
|
|
25105
25213
|
console.log(line);
|
|
25106
25214
|
}
|
|
25107
|
-
console.log(
|
|
25215
|
+
console.log(pc2.dim("─".repeat(60)));
|
|
25108
25216
|
if (info.excluded.length > 0) {
|
|
25109
|
-
console.log(
|
|
25217
|
+
console.log(pc2.yellow(`
|
|
25110
25218
|
Excluded blocks: ${info.excluded.length}`));
|
|
25111
25219
|
for (const e of info.excluded) {
|
|
25112
|
-
console.log(
|
|
25220
|
+
console.log(pc2.dim(` - ${e.slice(0, 80)}${e.length > 80 ? "..." : ""}`));
|
|
25113
25221
|
}
|
|
25114
25222
|
}
|
|
25115
25223
|
}
|
|
@@ -25132,10 +25240,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25132
25240
|
return;
|
|
25133
25241
|
}
|
|
25134
25242
|
ctx.config.provider.type = name;
|
|
25135
|
-
const configPath =
|
|
25243
|
+
const configPath = join35(homedir16(), ".mma", "config.json");
|
|
25136
25244
|
saveConfig(ctx.config, configPath);
|
|
25137
25245
|
await ctx.agent.reconfigure(ctx.config);
|
|
25138
|
-
console.log(
|
|
25246
|
+
console.log(pc2.green(t("repl.provider_set", { name })));
|
|
25139
25247
|
return;
|
|
25140
25248
|
}
|
|
25141
25249
|
console.log(t("repl.provider_usage"));
|
|
@@ -25166,9 +25274,9 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25166
25274
|
console.log(t("cli.available_models"));
|
|
25167
25275
|
const { getCertMark: getCertMark2 } = await Promise.resolve().then(() => (init_manifest(), exports_manifest));
|
|
25168
25276
|
for (const m of models) {
|
|
25169
|
-
const marker = m === ctx.config.model ?
|
|
25277
|
+
const marker = m === ctx.config.model ? pc2.green("* ") : " ";
|
|
25170
25278
|
const mark = getCertMark2(m, ctx.config.provider.baseUrl, version2);
|
|
25171
|
-
const cert = mark === "certified" ?
|
|
25279
|
+
const cert = mark === "certified" ? pc2.green("✔") : mark === "stale" ? pc2.yellow("○") : pc2.dim("·");
|
|
25172
25280
|
console.log(` ${marker}${cert} ${m}`);
|
|
25173
25281
|
}
|
|
25174
25282
|
} else {
|
|
@@ -25188,10 +25296,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25188
25296
|
return;
|
|
25189
25297
|
}
|
|
25190
25298
|
ctx.config.model = name;
|
|
25191
|
-
const configPath =
|
|
25299
|
+
const configPath = join35(homedir16(), ".mma", "config.json");
|
|
25192
25300
|
saveConfig(ctx.config, configPath);
|
|
25193
25301
|
await ctx.agent.reconfigure(ctx.config);
|
|
25194
|
-
console.log(
|
|
25302
|
+
console.log(pc2.green(t("repl.model_set", { name })));
|
|
25195
25303
|
return;
|
|
25196
25304
|
}
|
|
25197
25305
|
console.log(t("repl.model_usage"));
|
|
@@ -25213,10 +25321,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25213
25321
|
return;
|
|
25214
25322
|
}
|
|
25215
25323
|
ctx.config.contextWindow = size;
|
|
25216
|
-
const configPath =
|
|
25324
|
+
const configPath = join35(homedir16(), ".mma", "config.json");
|
|
25217
25325
|
saveConfig(ctx.config, configPath);
|
|
25218
25326
|
await ctx.agent.reconfigure(ctx.config);
|
|
25219
|
-
console.log(
|
|
25327
|
+
console.log(pc2.green(t("cli.context_set", { size })));
|
|
25220
25328
|
}
|
|
25221
25329
|
});
|
|
25222
25330
|
ctx.registerCommand({
|
|
@@ -25224,7 +25332,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25224
25332
|
description: t("repl.reload"),
|
|
25225
25333
|
usage: t("repl.reload_usage"),
|
|
25226
25334
|
action: async () => {
|
|
25227
|
-
console.log(
|
|
25335
|
+
console.log(pc2.yellow(t("repl.reloading")));
|
|
25228
25336
|
if (ctx.sessionManager && ctx.config.session.autoSave) {
|
|
25229
25337
|
const active = ctx.sessionManager.getActiveMeta();
|
|
25230
25338
|
if (active) {}
|
|
@@ -25232,10 +25340,10 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25232
25340
|
ctx.agent.shutdown();
|
|
25233
25341
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
25234
25342
|
const { homedir: homedir17 } = await import("os");
|
|
25235
|
-
const { join:
|
|
25343
|
+
const { join: join36 } = await import("path");
|
|
25236
25344
|
const configDir = ctx.configDir;
|
|
25237
25345
|
const baseDir = ctx.baseDir;
|
|
25238
|
-
const projectConfigPath =
|
|
25346
|
+
const projectConfigPath = join36(baseDir, ".mmrc");
|
|
25239
25347
|
const freshConfig = loadConfig2({ configDir, projectConfigPath });
|
|
25240
25348
|
Object.assign(ctx.config, freshConfig);
|
|
25241
25349
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -25245,7 +25353,7 @@ Excluded blocks: ${info.excluded.length}`));
|
|
|
25245
25353
|
ctx.skillsModule = result.skillsModule;
|
|
25246
25354
|
ctx.pluginManager = result.pluginManager;
|
|
25247
25355
|
ctx.setupCompleter();
|
|
25248
|
-
console.log(
|
|
25356
|
+
console.log(pc2.green(t("repl.reloaded")));
|
|
25249
25357
|
console.log(`${t("repl.model")} ${ctx.config.model}`);
|
|
25250
25358
|
console.log(`${t("repl.context")} ${ctx.config.contextWindow}`);
|
|
25251
25359
|
console.log(`${t("repl.provider")} ${ctx.config.provider.type} @ ${ctx.config.provider.baseUrl}`);
|
|
@@ -25268,7 +25376,7 @@ function registerSessionCommands(ctx) {
|
|
|
25268
25376
|
return;
|
|
25269
25377
|
}
|
|
25270
25378
|
const rows = sessions.map((s) => [
|
|
25271
|
-
s.id === active ?
|
|
25379
|
+
s.id === active ? pc2.green("●") : "",
|
|
25272
25380
|
s.id.slice(0, 12),
|
|
25273
25381
|
s.name,
|
|
25274
25382
|
s.updatedAt.slice(0, 19).replace("T", " "),
|
|
@@ -25283,7 +25391,7 @@ function registerSessionCommands(ctx) {
|
|
|
25283
25391
|
], rows)) {
|
|
25284
25392
|
console.log(line);
|
|
25285
25393
|
}
|
|
25286
|
-
console.log(
|
|
25394
|
+
console.log(pc2.dim(`
|
|
25287
25395
|
${t("repl.resume_hint")}`));
|
|
25288
25396
|
}
|
|
25289
25397
|
});
|
|
@@ -25297,8 +25405,8 @@ function registerSessionCommands(ctx) {
|
|
|
25297
25405
|
const meta = ctx.sessionManager.create(name);
|
|
25298
25406
|
ctx.agent.clearContext();
|
|
25299
25407
|
console.clear();
|
|
25300
|
-
console.log(`${t("session.created", { name: meta.name })} (${
|
|
25301
|
-
console.log(
|
|
25408
|
+
console.log(`${t("session.created", { name: meta.name })} (${pc2.dim(meta.id.slice(0, 12))})`);
|
|
25409
|
+
console.log(pc2.dim(` ${t("session.chat_cleared")}
|
|
25302
25410
|
`));
|
|
25303
25411
|
}
|
|
25304
25412
|
});
|
|
@@ -25311,13 +25419,13 @@ function registerSessionCommands(ctx) {
|
|
|
25311
25419
|
const query = args.join(" ");
|
|
25312
25420
|
const sessions = ctx.sessionManager.list();
|
|
25313
25421
|
if (!query) {
|
|
25314
|
-
console.log(
|
|
25422
|
+
console.log(pc2.dim(t("session.available")));
|
|
25315
25423
|
const active = ctx.sessionManager.getActive();
|
|
25316
25424
|
for (const s of sessions) {
|
|
25317
|
-
const marker = s.id === active ?
|
|
25318
|
-
console.log(
|
|
25425
|
+
const marker = s.id === active ? pc2.green(" *") : " ";
|
|
25426
|
+
console.log(pc2.dim(` ${marker} ${s.id.slice(0, 12)} ${s.name}`));
|
|
25319
25427
|
}
|
|
25320
|
-
console.log(
|
|
25428
|
+
console.log(pc2.dim(`
|
|
25321
25429
|
${t("repl.resume_usage")}`));
|
|
25322
25430
|
return;
|
|
25323
25431
|
}
|
|
@@ -25330,27 +25438,27 @@ function registerSessionCommands(ctx) {
|
|
|
25330
25438
|
const history = ctx.sessionManager.loadHistory();
|
|
25331
25439
|
ctx.agent.setContext(history);
|
|
25332
25440
|
console.clear();
|
|
25333
|
-
console.log(
|
|
25334
|
-
console.log(
|
|
25441
|
+
console.log(pc2.bold(pc2.green(t("session.resumed", { name: match.name }))) + " " + pc2.dim(`(${match.id.slice(0, 12)})`) + " — " + match.messageCount + " msgs");
|
|
25442
|
+
console.log(pc2.dim("─".repeat(50)));
|
|
25335
25443
|
if (history.length === 0) {
|
|
25336
|
-
console.log(
|
|
25444
|
+
console.log(pc2.dim(t("session.no_history")));
|
|
25337
25445
|
} else {
|
|
25338
|
-
console.log(
|
|
25446
|
+
console.log(pc2.dim(t("session.chat_history")));
|
|
25339
25447
|
console.log();
|
|
25340
25448
|
for (const msg of history) {
|
|
25341
25449
|
if (msg.role === "user") {
|
|
25342
|
-
console.log(
|
|
25450
|
+
console.log(pc2.cyan(t("session.user_label") + ":"));
|
|
25343
25451
|
console.log(getMessageText(msg.content));
|
|
25344
25452
|
console.log();
|
|
25345
25453
|
} else if (msg.role === "assistant") {
|
|
25346
|
-
console.log(
|
|
25454
|
+
console.log(pc2.green(t("session.assistant_label") + ":"));
|
|
25347
25455
|
console.log(getMessageText(msg.content));
|
|
25348
25456
|
console.log();
|
|
25349
25457
|
}
|
|
25350
25458
|
}
|
|
25351
25459
|
}
|
|
25352
|
-
console.log(
|
|
25353
|
-
console.log(
|
|
25460
|
+
console.log(pc2.dim("─".repeat(50)));
|
|
25461
|
+
console.log(pc2.dim(` ${t("session.chat_loaded")}`));
|
|
25354
25462
|
}
|
|
25355
25463
|
});
|
|
25356
25464
|
ctx.registerCommand({
|
|
@@ -25410,12 +25518,12 @@ function registerSkillCommands(ctx) {
|
|
|
25410
25518
|
console.log(t("repl.no_skills"));
|
|
25411
25519
|
return;
|
|
25412
25520
|
}
|
|
25413
|
-
console.log(
|
|
25521
|
+
console.log(pc2.bold(t("repl.available_skills")));
|
|
25414
25522
|
for (const skill of available) {
|
|
25415
25523
|
const tokens = Math.ceil(skill.content.length / 4);
|
|
25416
25524
|
const loaded = ctx.skillsModule.getLoaded().some((s) => s.name === skill.name);
|
|
25417
|
-
const marker = loaded ?
|
|
25418
|
-
console.log(` ${
|
|
25525
|
+
const marker = loaded ? pc2.green(" [loaded]") : "";
|
|
25526
|
+
console.log(` ${pc2.cyan(skill.name)}${marker} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
25419
25527
|
}
|
|
25420
25528
|
return;
|
|
25421
25529
|
}
|
|
@@ -25426,12 +25534,12 @@ function registerSkillCommands(ctx) {
|
|
|
25426
25534
|
console.log(t("repl.no_loaded"));
|
|
25427
25535
|
return;
|
|
25428
25536
|
}
|
|
25429
|
-
console.log(
|
|
25537
|
+
console.log(pc2.bold(t("repl.loaded_skills")));
|
|
25430
25538
|
for (const skill of loaded) {
|
|
25431
25539
|
const tokens = Math.ceil(skill.content.length / 4);
|
|
25432
|
-
console.log(` ${
|
|
25540
|
+
console.log(` ${pc2.cyan(skill.name)} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
25433
25541
|
}
|
|
25434
|
-
console.log(
|
|
25542
|
+
console.log(pc2.dim(`
|
|
25435
25543
|
${t("repl.budget", { used: budget.used, total: budget.total, remaining: budget.remaining })}`));
|
|
25436
25544
|
return;
|
|
25437
25545
|
}
|
|
@@ -25442,9 +25550,9 @@ function registerSkillCommands(ctx) {
|
|
|
25442
25550
|
}
|
|
25443
25551
|
const result = ctx.skillsModule.loadByName(arg);
|
|
25444
25552
|
if (result.success) {
|
|
25445
|
-
console.log(
|
|
25553
|
+
console.log(pc2.green(result.message));
|
|
25446
25554
|
} else {
|
|
25447
|
-
console.log(
|
|
25555
|
+
console.log(pc2.red(result.message));
|
|
25448
25556
|
}
|
|
25449
25557
|
return;
|
|
25450
25558
|
}
|
|
@@ -25454,9 +25562,9 @@ function registerSkillCommands(ctx) {
|
|
|
25454
25562
|
return;
|
|
25455
25563
|
}
|
|
25456
25564
|
if (ctx.skillsModule.unload(arg)) {
|
|
25457
|
-
console.log(
|
|
25565
|
+
console.log(pc2.green(t("repl.skill_unloaded", { name: arg })));
|
|
25458
25566
|
} else {
|
|
25459
|
-
console.log(
|
|
25567
|
+
console.log(pc2.red(t("repl.skill_not_loaded", { name: arg })));
|
|
25460
25568
|
}
|
|
25461
25569
|
return;
|
|
25462
25570
|
}
|
|
@@ -25470,14 +25578,14 @@ function registerSkillCommands(ctx) {
|
|
|
25470
25578
|
console.log(t("repl.no_skill_match", { query: arg }));
|
|
25471
25579
|
return;
|
|
25472
25580
|
}
|
|
25473
|
-
console.log(
|
|
25581
|
+
console.log(pc2.bold(t("repl.skills_matching", { query: arg })));
|
|
25474
25582
|
for (const skill of results) {
|
|
25475
25583
|
const tokens = Math.ceil(skill.content.length / 4);
|
|
25476
|
-
console.log(` ${
|
|
25584
|
+
console.log(` ${pc2.cyan(skill.name)} ${pc2.dim(`(${tokens} tokens)`)} ${skill.description.slice(0, 60)}`);
|
|
25477
25585
|
}
|
|
25478
25586
|
return;
|
|
25479
25587
|
}
|
|
25480
|
-
console.log(
|
|
25588
|
+
console.log(pc2.red(t("repl.skill_unknown_sub", { subcmd })));
|
|
25481
25589
|
console.log(t("repl.skill_usage"));
|
|
25482
25590
|
}
|
|
25483
25591
|
});
|
|
@@ -25535,14 +25643,14 @@ init_bootstrap();
|
|
|
25535
25643
|
init_config2();
|
|
25536
25644
|
init_setup();
|
|
25537
25645
|
init_i18n();
|
|
25538
|
-
import { join as
|
|
25646
|
+
import { join as join34, dirname as dirname11 } from "path";
|
|
25539
25647
|
import { homedir as homedir15 } from "os";
|
|
25540
25648
|
import { existsSync as existsSync41, readFileSync as readFileSync27 } from "fs";
|
|
25541
25649
|
|
|
25542
25650
|
// src/cli/security-commands.ts
|
|
25543
25651
|
init_bootstrap();
|
|
25544
25652
|
init_config2();
|
|
25545
|
-
import { join as
|
|
25653
|
+
import { join as join28 } from "path";
|
|
25546
25654
|
import { homedir as homedir12 } from "os";
|
|
25547
25655
|
|
|
25548
25656
|
// src/modules/security/security-policies.ts
|
|
@@ -26072,7 +26180,7 @@ function createSecurityCommand(program2) {
|
|
|
26072
26180
|
}
|
|
26073
26181
|
});
|
|
26074
26182
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
26075
|
-
const configPath =
|
|
26183
|
+
const configPath = join28(homedir12(), ".mma", "config.json");
|
|
26076
26184
|
const { config: appConfig } = await bootstrap();
|
|
26077
26185
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
26078
26186
|
if (!validPresets.includes(preset)) {
|
|
@@ -26087,7 +26195,7 @@ function createSecurityCommand(program2) {
|
|
|
26087
26195
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
26088
26196
|
});
|
|
26089
26197
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
26090
|
-
const configPath =
|
|
26198
|
+
const configPath = join28(homedir12(), ".mma", "config.json");
|
|
26091
26199
|
const { config: appConfig } = await bootstrap();
|
|
26092
26200
|
appConfig.security = appConfig.security || {};
|
|
26093
26201
|
appConfig.security.sessionEncryption = {
|
|
@@ -26099,7 +26207,7 @@ function createSecurityCommand(program2) {
|
|
|
26099
26207
|
console.log(t("cli.security.encryption_enabled"));
|
|
26100
26208
|
});
|
|
26101
26209
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
26102
|
-
const configPath =
|
|
26210
|
+
const configPath = join28(homedir12(), ".mma", "config.json");
|
|
26103
26211
|
const { config: appConfig } = await bootstrap();
|
|
26104
26212
|
appConfig.security = appConfig.security || {};
|
|
26105
26213
|
appConfig.security.sessionEncryption = {
|
|
@@ -26111,7 +26219,7 @@ function createSecurityCommand(program2) {
|
|
|
26111
26219
|
console.log(t("cli.security.encryption_disabled"));
|
|
26112
26220
|
});
|
|
26113
26221
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
26114
|
-
const configPath =
|
|
26222
|
+
const configPath = join28(homedir12(), ".mma", "config.json");
|
|
26115
26223
|
const { config: appConfig } = await bootstrap();
|
|
26116
26224
|
appConfig.security = appConfig.security || {};
|
|
26117
26225
|
appConfig.security.auditNotifier = {
|
|
@@ -26125,7 +26233,7 @@ function createSecurityCommand(program2) {
|
|
|
26125
26233
|
console.log(t("cli.security.audit_enabled"));
|
|
26126
26234
|
});
|
|
26127
26235
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
26128
|
-
const configPath =
|
|
26236
|
+
const configPath = join28(homedir12(), ".mma", "config.json");
|
|
26129
26237
|
const { config: appConfig } = await bootstrap();
|
|
26130
26238
|
appConfig.security = appConfig.security || {};
|
|
26131
26239
|
appConfig.security.auditNotifier = {
|
|
@@ -26161,8 +26269,8 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
26161
26269
|
function readVersion2() {
|
|
26162
26270
|
const here = dirname11(fileURLToPath2(import.meta.url));
|
|
26163
26271
|
const candidates = [
|
|
26164
|
-
|
|
26165
|
-
|
|
26272
|
+
join34(here, "..", "..", "package.json"),
|
|
26273
|
+
join34(here, "..", "package.json")
|
|
26166
26274
|
];
|
|
26167
26275
|
for (const p of candidates) {
|
|
26168
26276
|
if (existsSync41(p)) {
|
|
@@ -26178,7 +26286,7 @@ function createProgram() {
|
|
|
26178
26286
|
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"));
|
|
26179
26287
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
26180
26288
|
const answers = await runSetup();
|
|
26181
|
-
const configPath =
|
|
26289
|
+
const configPath = join34(homedir15(), ".mma", "config.json");
|
|
26182
26290
|
const { config } = await bootstrap();
|
|
26183
26291
|
config.provider.type = answers.provider;
|
|
26184
26292
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -26223,7 +26331,7 @@ function createProgram() {
|
|
|
26223
26331
|
});
|
|
26224
26332
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
26225
26333
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
26226
|
-
const configPath =
|
|
26334
|
+
const configPath = join34(homedir15(), ".mma", "config.json");
|
|
26227
26335
|
const { config } = await bootstrap();
|
|
26228
26336
|
const keys = key.split(".");
|
|
26229
26337
|
let obj = config;
|
|
@@ -26286,7 +26394,7 @@ function createProgram() {
|
|
|
26286
26394
|
console.log(t("cli.model_hint"));
|
|
26287
26395
|
});
|
|
26288
26396
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
26289
|
-
const configPath =
|
|
26397
|
+
const configPath = join34(homedir15(), ".mma", "config.json");
|
|
26290
26398
|
const { config } = await bootstrap();
|
|
26291
26399
|
config.model = name;
|
|
26292
26400
|
saveConfig(config, configPath);
|
|
@@ -26322,7 +26430,7 @@ function createProgram() {
|
|
|
26322
26430
|
await uncertify2(name, config);
|
|
26323
26431
|
});
|
|
26324
26432
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
26325
|
-
const configPath =
|
|
26433
|
+
const configPath = join34(homedir15(), ".mma", "config.json");
|
|
26326
26434
|
const { config } = await bootstrap();
|
|
26327
26435
|
const contextWindow = parseInt(size, 10);
|
|
26328
26436
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -26340,7 +26448,7 @@ function createProgram() {
|
|
|
26340
26448
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
26341
26449
|
});
|
|
26342
26450
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
26343
|
-
const configPath =
|
|
26451
|
+
const configPath = join34(homedir15(), ".mma", "config.json");
|
|
26344
26452
|
const { config } = await bootstrap();
|
|
26345
26453
|
config.provider.type = name;
|
|
26346
26454
|
saveConfig(config, configPath);
|
|
@@ -26392,8 +26500,8 @@ init_bootstrap();
|
|
|
26392
26500
|
// src/cli/repl.ts
|
|
26393
26501
|
init_colors();
|
|
26394
26502
|
import * as readline2 from "readline";
|
|
26395
|
-
import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as
|
|
26396
|
-
import { join as
|
|
26503
|
+
import { existsSync as existsSync43, readFileSync as readFileSync29, writeFileSync as writeFileSync15 } from "fs";
|
|
26504
|
+
import { join as join36, dirname as dirname13 } from "path";
|
|
26397
26505
|
import { homedir as homedir17 } from "os";
|
|
26398
26506
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
26399
26507
|
|
|
@@ -26511,24 +26619,24 @@ var TAG = /<\/?([A-Z][a-zA-Z0-9]*|[a-z][a-zA-Z0-9-]*)/g;
|
|
|
26511
26619
|
var ATTR = /\b([a-zA-Z-]+=)"([^"]*)"/g;
|
|
26512
26620
|
function highlight(code, lang) {
|
|
26513
26621
|
if (lang === "html" || lang === "xml" || lang === "svg") {
|
|
26514
|
-
code = code.replace(COMMENT, (m) =>
|
|
26515
|
-
code = code.replace(ATTR, (_m, attr, val) =>
|
|
26516
|
-
code = code.replace(TAG, (_m, tag) => "<" +
|
|
26622
|
+
code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
|
|
26623
|
+
code = code.replace(ATTR, (_m, attr, val) => pc2.yellow(attr) + "=" + pc2.green('"' + val + '"'));
|
|
26624
|
+
code = code.replace(TAG, (_m, tag) => "<" + pc2.cyan(tag));
|
|
26517
26625
|
} else if (lang === "css" || lang === "scss" || lang === "less") {
|
|
26518
|
-
code = code.replace(COMMENT, (m) =>
|
|
26519
|
-
code = code.replace(STRING, (m) =>
|
|
26520
|
-
code = code.replace(NUMBER, (m) =>
|
|
26626
|
+
code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
|
|
26627
|
+
code = code.replace(STRING, (m) => pc2.green(m));
|
|
26628
|
+
code = code.replace(NUMBER, (m) => pc2.yellow(m));
|
|
26521
26629
|
} else if (lang === "bash" || lang === "sh" || lang === "shell" || lang === "zsh") {
|
|
26522
|
-
code = code.replace(COMMENT, (m) =>
|
|
26523
|
-
code = code.replace(STRING, (m) =>
|
|
26630
|
+
code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
|
|
26631
|
+
code = code.replace(STRING, (m) => pc2.green(m));
|
|
26524
26632
|
} else if (lang === "json") {
|
|
26525
|
-
code = code.replace(STRING, (m) =>
|
|
26526
|
-
code = code.replace(NUMBER, (m) =>
|
|
26633
|
+
code = code.replace(STRING, (m) => pc2.green(m));
|
|
26634
|
+
code = code.replace(NUMBER, (m) => pc2.yellow(m));
|
|
26527
26635
|
} else {
|
|
26528
|
-
code = code.replace(COMMENT, (m) =>
|
|
26529
|
-
code = code.replace(STRING, (m) =>
|
|
26530
|
-
code = code.replace(KW, (m) =>
|
|
26531
|
-
code = code.replace(NUMBER, (m) =>
|
|
26636
|
+
code = code.replace(COMMENT, (m) => pc2.dim(pc2.green(m)));
|
|
26637
|
+
code = code.replace(STRING, (m) => pc2.green(m));
|
|
26638
|
+
code = code.replace(KW, (m) => pc2.magenta(m));
|
|
26639
|
+
code = code.replace(NUMBER, (m) => pc2.yellow(m));
|
|
26532
26640
|
}
|
|
26533
26641
|
return code;
|
|
26534
26642
|
}
|
|
@@ -26629,13 +26737,13 @@ class FormattingStream {
|
|
|
26629
26737
|
`);
|
|
26630
26738
|
const highlighted = highlight(code, this.codeLang);
|
|
26631
26739
|
const lang = this.codeLang ? ` ${this.codeLang} ` : " ";
|
|
26632
|
-
const top =
|
|
26740
|
+
const top = pc2.dim(`┌─${lang}${"─".repeat(Math.max(0, this.width - 3 - lang.length))}┐`);
|
|
26633
26741
|
this.onWrite(top);
|
|
26634
26742
|
for (const l of highlighted.split(`
|
|
26635
26743
|
`)) {
|
|
26636
|
-
this.onWrite(
|
|
26744
|
+
this.onWrite(pc2.dim("│ ") + l);
|
|
26637
26745
|
}
|
|
26638
|
-
this.onWrite(
|
|
26746
|
+
this.onWrite(pc2.dim(`└${"─".repeat(Math.max(0, this.width - 1))}┘`));
|
|
26639
26747
|
}
|
|
26640
26748
|
this.codeLines = [];
|
|
26641
26749
|
this.codeLang = "";
|
|
@@ -26647,47 +26755,47 @@ class FormattingStream {
|
|
|
26647
26755
|
const level = heading[1].length;
|
|
26648
26756
|
const content = this.formatInline(heading[2]);
|
|
26649
26757
|
if (level === 1)
|
|
26650
|
-
return
|
|
26651
|
-
return
|
|
26758
|
+
return pc2.cyan(pc2.bold(pc2.underline(content)));
|
|
26759
|
+
return pc2.cyan(pc2.bold(content));
|
|
26652
26760
|
}
|
|
26653
26761
|
if (isHorizontalRule(result)) {
|
|
26654
|
-
return
|
|
26762
|
+
return pc2.dim("─".repeat(Math.max(0, Math.min(this.width, 60))));
|
|
26655
26763
|
}
|
|
26656
26764
|
const quote = result.match(/^(>+)\s?(.*)$/);
|
|
26657
26765
|
if (quote) {
|
|
26658
26766
|
const depth = Math.min(quote[1].length, 4);
|
|
26659
|
-
const marker =
|
|
26767
|
+
const marker = pc2.dim("▍".repeat(depth));
|
|
26660
26768
|
return `${marker} ${this.formatInline(quote[2])}`;
|
|
26661
26769
|
}
|
|
26662
26770
|
const checkbox = result.match(/^[-*]\s+\[([ xX])\]\s+(.+)$/);
|
|
26663
26771
|
if (checkbox) {
|
|
26664
26772
|
const checked = checkbox[1].toLowerCase() === "x";
|
|
26665
|
-
const mark = checked ?
|
|
26773
|
+
const mark = checked ? pc2.green("✓") : pc2.dim("☐");
|
|
26666
26774
|
return ` ${mark} ${this.formatInline(checkbox[2])}`;
|
|
26667
26775
|
}
|
|
26668
26776
|
const ordered = result.match(/^(\d+)[.)]\s+(.+)$/);
|
|
26669
26777
|
if (ordered) {
|
|
26670
|
-
return ` ${
|
|
26778
|
+
return ` ${pc2.yellow(ordered[1])}. ${this.formatInline(ordered[2])}`;
|
|
26671
26779
|
}
|
|
26672
26780
|
const bullet = result.match(/^[-*]\s+(.+)$/);
|
|
26673
26781
|
if (bullet) {
|
|
26674
|
-
return ` ${
|
|
26782
|
+
return ` ${pc2.dim("•")} ${this.formatInline(bullet[1])}`;
|
|
26675
26783
|
}
|
|
26676
26784
|
return this.formatInline(result);
|
|
26677
26785
|
}
|
|
26678
26786
|
formatInline(text) {
|
|
26679
26787
|
const codeSpans = [];
|
|
26680
26788
|
let result = text.replace(/`([^`]+)`/g, (_m, c) => {
|
|
26681
|
-
codeSpans.push(
|
|
26789
|
+
codeSpans.push(pc2.yellow(c));
|
|
26682
26790
|
return `\x00${codeSpans.length - 1}\x00`;
|
|
26683
26791
|
});
|
|
26684
|
-
result = result.replace(/\*\*(.+?)\*\*/g, (_, s) =>
|
|
26685
|
-
result = result.replace(/~~(.+?)~~/g, (_, s) =>
|
|
26686
|
-
result = result.replace(/\*([^*]+)\*/g, (_, s) =>
|
|
26687
|
-
result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre +
|
|
26792
|
+
result = result.replace(/\*\*(.+?)\*\*/g, (_, s) => pc2.bold(s));
|
|
26793
|
+
result = result.replace(/~~(.+?)~~/g, (_, s) => pc2.strikethrough(s));
|
|
26794
|
+
result = result.replace(/\*([^*]+)\*/g, (_, s) => pc2.italic(s));
|
|
26795
|
+
result = result.replace(/(^|\s)_([^_\n]+)_(?=\s|$)/g, (_m, pre, s) => pre + pc2.italic(s));
|
|
26688
26796
|
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, url) => {
|
|
26689
26797
|
const short = url.length > 80 ? url.slice(0, 77) + "…" : url;
|
|
26690
|
-
return `${
|
|
26798
|
+
return `${pc2.cyan(label)} ${pc2.dim(`(${short})`)}`;
|
|
26691
26799
|
});
|
|
26692
26800
|
result = result.replace(/\u0000(\d+)\u0000/g, (_m, i) => codeSpans[Number(i)]);
|
|
26693
26801
|
return result;
|
|
@@ -26802,7 +26910,7 @@ class Renderer {
|
|
|
26802
26910
|
}
|
|
26803
26911
|
reasoning(chunk) {
|
|
26804
26912
|
this.spinner.stop();
|
|
26805
|
-
this.out.write(
|
|
26913
|
+
this.out.write(pc2.dim(chunk));
|
|
26806
26914
|
}
|
|
26807
26915
|
thinkingStart() {
|
|
26808
26916
|
this.spinner.start(t("ui.thinking"));
|
|
@@ -26816,7 +26924,7 @@ class Renderer {
|
|
|
26816
26924
|
const summary = summarizeArgs2(args);
|
|
26817
26925
|
if (!this.rich) {
|
|
26818
26926
|
this.out.write(`
|
|
26819
|
-
${
|
|
26927
|
+
${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
26820
26928
|
`);
|
|
26821
26929
|
return;
|
|
26822
26930
|
}
|
|
@@ -26824,18 +26932,18 @@ ${pc.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
|
|
|
26824
26932
|
if (this.toolStyle === "inline") {
|
|
26825
26933
|
const marker = toolMarker(tool);
|
|
26826
26934
|
this.out.write(`
|
|
26827
|
-
${
|
|
26935
|
+
${pc2.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}
|
|
26828
26936
|
`);
|
|
26829
26937
|
return;
|
|
26830
26938
|
}
|
|
26831
|
-
this.spinner.start(`${
|
|
26939
|
+
this.spinner.start(`${pc2.dim("⚙")} ${friendlyTool(tool)}${summary ? ` ${pc2.dim(summary)}` : ""}`);
|
|
26832
26940
|
}
|
|
26833
26941
|
toolEnd(_tool, duration, error, ctxDelta) {
|
|
26834
26942
|
this.spinner.stop();
|
|
26835
26943
|
if (!this.rich) {
|
|
26836
26944
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
26837
|
-
const deltaStr = ctxDelta > 0 ?
|
|
26838
|
-
this.out.write(`${
|
|
26945
|
+
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
26946
|
+
this.out.write(`${pc2.dim("ctx")} ${deltaStr}
|
|
26839
26947
|
`);
|
|
26840
26948
|
}
|
|
26841
26949
|
return;
|
|
@@ -26843,11 +26951,11 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
|
|
|
26843
26951
|
if (!this.card)
|
|
26844
26952
|
return;
|
|
26845
26953
|
const { tool, args, body } = this.card;
|
|
26846
|
-
const marker = error ?
|
|
26847
|
-
let footer = `${marker} ${
|
|
26954
|
+
const marker = error ? pc2.red("✗") : pc2.green("✓");
|
|
26955
|
+
let footer = `${marker} ${pc2.dim(`${duration}ms`)}`;
|
|
26848
26956
|
if (ctxDelta !== undefined && ctxDelta !== 0) {
|
|
26849
|
-
const deltaStr = ctxDelta > 0 ?
|
|
26850
|
-
footer += ` ${
|
|
26957
|
+
const deltaStr = ctxDelta > 0 ? pc2.green(`+${ctxDelta}`) : pc2.yellow(`${ctxDelta} ↓`);
|
|
26958
|
+
footer += ` ${pc2.dim("ctx")} ${deltaStr}`;
|
|
26851
26959
|
}
|
|
26852
26960
|
if (this.toolStyle === "inline") {
|
|
26853
26961
|
this.out.write(`${GUTTER}${footer}
|
|
@@ -26860,7 +26968,7 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
|
|
|
26860
26968
|
const lines = [];
|
|
26861
26969
|
const summary = summarizeArgs2(args);
|
|
26862
26970
|
if (summary)
|
|
26863
|
-
lines.push(
|
|
26971
|
+
lines.push(pc2.dim(summary));
|
|
26864
26972
|
for (const chunk of body) {
|
|
26865
26973
|
for (const line of chunk.split(`
|
|
26866
26974
|
`)) {
|
|
@@ -26884,7 +26992,7 @@ ${pc.dim(marker)} ${friendlyTool(tool)}${summary ? ` ${pc.dim(summary)}` : ""}
|
|
|
26884
26992
|
error(text) {
|
|
26885
26993
|
this.endCard();
|
|
26886
26994
|
this.spinner.stop();
|
|
26887
|
-
this.err.write(`${
|
|
26995
|
+
this.err.write(`${pc2.red(text)}
|
|
26888
26996
|
`);
|
|
26889
26997
|
}
|
|
26890
26998
|
flush() {
|
|
@@ -26907,8 +27015,8 @@ init_repl_commands();
|
|
|
26907
27015
|
function readVersion4() {
|
|
26908
27016
|
const here = dirname13(fileURLToPath4(import.meta.url));
|
|
26909
27017
|
const candidates = [
|
|
26910
|
-
|
|
26911
|
-
|
|
27018
|
+
join36(here, "..", "..", "package.json"),
|
|
27019
|
+
join36(here, "..", "package.json")
|
|
26912
27020
|
];
|
|
26913
27021
|
for (const p of candidates) {
|
|
26914
27022
|
if (existsSync43(p)) {
|
|
@@ -26924,14 +27032,14 @@ function formatContextBar(used, limit, compactions, quality) {
|
|
|
26924
27032
|
const pct = Math.min(100, Math.round(used / limit * 100));
|
|
26925
27033
|
const barLen = 20;
|
|
26926
27034
|
const filled = Math.round(pct / 100 * barLen);
|
|
26927
|
-
const bar =
|
|
26928
|
-
const pctStr = pct >= 75 ?
|
|
26929
|
-
let line = ` ${bar} ${pctStr} ${
|
|
27035
|
+
const bar = pc2.green("█".repeat(filled)) + pc2.dim("░".repeat(barLen - filled));
|
|
27036
|
+
const pctStr = pct >= 75 ? pc2.yellow(`${pct}%`) : pc2.dim(`${pct}%`);
|
|
27037
|
+
let line = ` ${bar} ${pctStr} ${pc2.dim(`(${used} / ${limit} tokens)`)}`;
|
|
26930
27038
|
if (compactions !== undefined) {
|
|
26931
|
-
line +=
|
|
27039
|
+
line += pc2.dim(` compactions: ${compactions}`);
|
|
26932
27040
|
}
|
|
26933
27041
|
if (quality !== undefined) {
|
|
26934
|
-
const qColor = quality >= 70 ?
|
|
27042
|
+
const qColor = quality >= 70 ? pc2.green : quality >= 40 ? pc2.yellow : pc2.red;
|
|
26935
27043
|
line += ` ${qColor(`quality: ${quality}%`)}`;
|
|
26936
27044
|
}
|
|
26937
27045
|
return line;
|
|
@@ -26963,15 +27071,15 @@ class Repl {
|
|
|
26963
27071
|
this.sessionManager = sessionManager;
|
|
26964
27072
|
this.skillsModule = skillsModule;
|
|
26965
27073
|
this.pluginManager = pluginManager;
|
|
26966
|
-
this.configDir = configDir ||
|
|
27074
|
+
this.configDir = configDir || join36(homedir17(), ".mma");
|
|
26967
27075
|
this.baseDir = baseDir || process.cwd();
|
|
26968
27076
|
this.noAgentsMd = noAgentsMd === true;
|
|
26969
|
-
this.historyPath =
|
|
27077
|
+
this.historyPath = join36(homedir17(), ".mma", "repl-history");
|
|
26970
27078
|
this.loadHistory();
|
|
26971
27079
|
this.rl = readline2.createInterface({
|
|
26972
27080
|
input: process.stdin,
|
|
26973
27081
|
output: process.stdout,
|
|
26974
|
-
prompt:
|
|
27082
|
+
prompt: pc2.cyan("> "),
|
|
26975
27083
|
history: this.history,
|
|
26976
27084
|
historySize: this.maxHistory,
|
|
26977
27085
|
tabSize: 2,
|
|
@@ -26999,7 +27107,7 @@ class Repl {
|
|
|
26999
27107
|
}
|
|
27000
27108
|
saveHistory() {
|
|
27001
27109
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
27002
|
-
|
|
27110
|
+
writeFileSync15(this.historyPath, allHistory.join(`
|
|
27003
27111
|
`), "utf-8");
|
|
27004
27112
|
}
|
|
27005
27113
|
setupCompleter() {
|
|
@@ -27054,11 +27162,11 @@ class Repl {
|
|
|
27054
27162
|
}
|
|
27055
27163
|
}
|
|
27056
27164
|
if (this.running) {
|
|
27057
|
-
this.rl.setPrompt(
|
|
27165
|
+
this.rl.setPrompt(pc2.cyan("> "));
|
|
27058
27166
|
this.rl.prompt();
|
|
27059
27167
|
}
|
|
27060
27168
|
} else {
|
|
27061
|
-
this.rl.setPrompt(
|
|
27169
|
+
this.rl.setPrompt(pc2.cyan("... "));
|
|
27062
27170
|
this.rl.prompt();
|
|
27063
27171
|
}
|
|
27064
27172
|
return;
|
|
@@ -27066,7 +27174,7 @@ class Repl {
|
|
|
27066
27174
|
if (this.isMultiLineInput(trimmed)) {
|
|
27067
27175
|
inMultiLine = true;
|
|
27068
27176
|
multiLineBuffer = trimmed;
|
|
27069
|
-
this.rl.setPrompt(
|
|
27177
|
+
this.rl.setPrompt(pc2.cyan("... "));
|
|
27070
27178
|
this.rl.prompt();
|
|
27071
27179
|
return;
|
|
27072
27180
|
}
|
|
@@ -27097,7 +27205,7 @@ class Repl {
|
|
|
27097
27205
|
if (escBytes >= 2 || withinWindow) {
|
|
27098
27206
|
this.lastEscTime = 0;
|
|
27099
27207
|
if (this.agentRunning) {
|
|
27100
|
-
process.stdout.write(
|
|
27208
|
+
process.stdout.write(pc2.yellow(`
|
|
27101
27209
|
${t("repl.interrupt")}
|
|
27102
27210
|
`));
|
|
27103
27211
|
this.agent.shutdown();
|
|
@@ -27113,11 +27221,11 @@ ${t("repl.interrupt")}
|
|
|
27113
27221
|
const { dataUrl } = await bufferToDataUrl2(clipBuf);
|
|
27114
27222
|
this.pendingClipboardImage = dataUrl;
|
|
27115
27223
|
const sizeKb = Math.round(dataUrl.length * 3 / 4 / 1024);
|
|
27116
|
-
console.log(
|
|
27224
|
+
console.log(pc2.green(`
|
|
27117
27225
|
${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
|
|
27118
27226
|
this.rl.prompt();
|
|
27119
27227
|
} else {
|
|
27120
|
-
console.log(
|
|
27228
|
+
console.log(pc2.yellow(`
|
|
27121
27229
|
${t("image.clipboard_empty")}`));
|
|
27122
27230
|
this.rl.prompt();
|
|
27123
27231
|
}
|
|
@@ -27128,7 +27236,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
27128
27236
|
let forceExitTimer = null;
|
|
27129
27237
|
process.on("SIGINT", () => {
|
|
27130
27238
|
if (this.agentRunning) {
|
|
27131
|
-
console.log(
|
|
27239
|
+
console.log(pc2.yellow(`
|
|
27132
27240
|
[Ctrl+C] Остановка агента... (ещё раз — принудительно)`));
|
|
27133
27241
|
this.agent.shutdown();
|
|
27134
27242
|
this.agentRunning = false;
|
|
@@ -27165,7 +27273,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
27165
27273
|
this.pendingClipboardImage = null;
|
|
27166
27274
|
}
|
|
27167
27275
|
process.stdout.write(`
|
|
27168
|
-
` +
|
|
27276
|
+
` + pc2.green(t("repl.agent")));
|
|
27169
27277
|
const renderer = new Renderer({
|
|
27170
27278
|
spinner: this.config.ui?.spinner ?? true,
|
|
27171
27279
|
toolStyle: this.config.ui?.toolStyle ?? "inline"
|
|
@@ -27187,7 +27295,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
27187
27295
|
process.stdout.write(`
|
|
27188
27296
|
`);
|
|
27189
27297
|
if (!result.success) {
|
|
27190
|
-
console.error(
|
|
27298
|
+
console.error(pc2.red(`${t("error.prefix")}${result.error}`));
|
|
27191
27299
|
}
|
|
27192
27300
|
this.showContextBar(result);
|
|
27193
27301
|
} finally {
|
|
@@ -27217,13 +27325,13 @@ ${t("image.clipboard_empty")}`));
|
|
|
27217
27325
|
const args = parts.slice(1);
|
|
27218
27326
|
const cmd = this.commands.get(name);
|
|
27219
27327
|
if (!cmd) {
|
|
27220
|
-
console.log(
|
|
27328
|
+
console.log(pc2.red(t("cli.unknown_cmd", { name })), t("cli.help_hint"));
|
|
27221
27329
|
return;
|
|
27222
27330
|
}
|
|
27223
27331
|
try {
|
|
27224
27332
|
await cmd.action(args);
|
|
27225
27333
|
} catch (err) {
|
|
27226
|
-
console.error(
|
|
27334
|
+
console.error(pc2.red(t("error.command_error", {
|
|
27227
27335
|
message: err instanceof Error ? err.message : String(err)
|
|
27228
27336
|
})));
|
|
27229
27337
|
}
|
|
@@ -27247,12 +27355,12 @@ ${t("image.clipboard_empty")}`));
|
|
|
27247
27355
|
}
|
|
27248
27356
|
if (cmds.length === 0)
|
|
27249
27357
|
continue;
|
|
27250
|
-
console.log(
|
|
27358
|
+
console.log(pc2.bold(t(`repl.group.${groupKey}`)));
|
|
27251
27359
|
for (const cmd of cmds) {
|
|
27252
|
-
const aliases = cmd.aliases?.length ? ` (${
|
|
27253
|
-
console.log(` ${
|
|
27360
|
+
const aliases = cmd.aliases?.length ? ` (${pc2.dim(cmd.aliases.join(", "))})` : "";
|
|
27361
|
+
console.log(` ${pc2.cyan("/" + cmd.name)}${aliases} ${pc2.dim(cmd.description)}`);
|
|
27254
27362
|
if (cmd.usage) {
|
|
27255
|
-
console.log(` ${
|
|
27363
|
+
console.log(` ${pc2.dim(cmd.usage)}`);
|
|
27256
27364
|
}
|
|
27257
27365
|
}
|
|
27258
27366
|
console.log();
|
|
@@ -27264,7 +27372,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
27264
27372
|
const ctxLine = formatContextBar(result.contextUsed, result.contextLimit, result.compactionCount, result.contextQuality);
|
|
27265
27373
|
console.log(ctxLine);
|
|
27266
27374
|
if (result.totalTokens !== undefined && result.totalTokens > 0) {
|
|
27267
|
-
const apiLine =
|
|
27375
|
+
const apiLine = pc2.dim(` API: ${result.promptTokens} prompt + ${result.completionTokens} completion = ${result.totalTokens} total`);
|
|
27268
27376
|
console.log(apiLine);
|
|
27269
27377
|
}
|
|
27270
27378
|
}
|
|
@@ -27273,57 +27381,57 @@ ${t("image.clipboard_empty")}`));
|
|
|
27273
27381
|
this.running = true;
|
|
27274
27382
|
const info = [];
|
|
27275
27383
|
const row = (label, value) => {
|
|
27276
|
-
info.push(` ${
|
|
27384
|
+
info.push(` ${pc2.yellow(label)} ${value}`);
|
|
27277
27385
|
};
|
|
27278
27386
|
const ctx = this.config.contextWindow;
|
|
27279
27387
|
const sysBudget = Math.floor(ctx * this.config.contextBudget.systemPrompt);
|
|
27280
27388
|
const resBudget = Math.floor(ctx * this.config.contextBudget.responseReserve);
|
|
27281
27389
|
const histBudget = ctx - sysBudget - resBudget;
|
|
27282
|
-
row(t("repl.model"),
|
|
27283
|
-
row(t("repl.provider"), `${this.config.provider.type} → ${
|
|
27284
|
-
row(t("repl.context"), `${
|
|
27390
|
+
row(t("repl.model"), pc2.white(this.config.model));
|
|
27391
|
+
row(t("repl.provider"), `${this.config.provider.type} → ${pc2.dim(this.config.provider.baseUrl)}`);
|
|
27392
|
+
row(t("repl.context"), `${pc2.white(String(ctx))} ${pc2.dim(`(sys:${sysBudget} res:${resBudget} hist:${histBudget})`)}`);
|
|
27285
27393
|
const si = this.agent.getSystemPromptInfo();
|
|
27286
|
-
row(t("repl.sysprompt_label"),
|
|
27394
|
+
row(t("repl.sysprompt_label"), pc2.dim(t("repl.sysprompt_size", { used: si.tokenCount, budget: sysBudget })));
|
|
27287
27395
|
if (this.skillsModule) {
|
|
27288
27396
|
const budget = this.skillsModule.getBudget();
|
|
27289
|
-
row(t("repl.skills_label"), `${
|
|
27397
|
+
row(t("repl.skills_label"), `${pc2.white(String(this.skillsModule.getAvailable().length))} available, ${pc2.dim(`budget: ${budget.total} tokens`)}`);
|
|
27290
27398
|
}
|
|
27291
27399
|
if (this.pluginManager) {
|
|
27292
27400
|
const plugins = this.pluginManager.getAllPlugins().filter((p) => !p.isBuiltin);
|
|
27293
27401
|
if (plugins.length > 0) {
|
|
27294
27402
|
const pluginNames = plugins.map((p) => p.name).join(", ");
|
|
27295
|
-
row(t("repl.plugins_label"), `${
|
|
27403
|
+
row(t("repl.plugins_label"), `${pc2.white(String(plugins.length))} active ${pc2.dim(`(${pluginNames})`)}`);
|
|
27296
27404
|
}
|
|
27297
27405
|
}
|
|
27298
27406
|
const mcpServers = this.config.mcpServers || {};
|
|
27299
27407
|
const enabledServers = Object.entries(mcpServers).filter(([, s]) => s.enabled !== false);
|
|
27300
27408
|
if (enabledServers.length > 0) {
|
|
27301
27409
|
const names = enabledServers.map(([name]) => name).join(", ");
|
|
27302
|
-
row(t("repl.mcp_label"), `${
|
|
27410
|
+
row(t("repl.mcp_label"), `${pc2.white(String(enabledServers.length))} ${pc2.dim(`(${names})`)}`);
|
|
27303
27411
|
}
|
|
27304
27412
|
const cwd = process.cwd();
|
|
27305
|
-
row(t("repl.work_dir"),
|
|
27413
|
+
row(t("repl.work_dir"), pc2.dim(cwd));
|
|
27306
27414
|
if (this.noAgentsMd) {
|
|
27307
|
-
row(t("repl.agents_label"),
|
|
27415
|
+
row(t("repl.agents_label"), pc2.red(t("repl.disabled")));
|
|
27308
27416
|
} else {
|
|
27309
27417
|
const agentsMdCandidates = [
|
|
27310
|
-
|
|
27311
|
-
|
|
27312
|
-
|
|
27418
|
+
join36(this.baseDir, "AGENTS.md"),
|
|
27419
|
+
join36(this.baseDir, ".mma", "AGENTS.md"),
|
|
27420
|
+
join36(this.configDir, "AGENTS.md")
|
|
27313
27421
|
];
|
|
27314
27422
|
const foundAgents = agentsMdCandidates.filter((p) => existsSync43(p));
|
|
27315
27423
|
if (foundAgents.length > 0) {
|
|
27316
27424
|
for (const p of foundAgents) {
|
|
27317
|
-
row(t("repl.agents_label"),
|
|
27425
|
+
row(t("repl.agents_label"), pc2.dim(p));
|
|
27318
27426
|
}
|
|
27319
27427
|
} else {
|
|
27320
|
-
row(t("repl.agents_label"),
|
|
27428
|
+
row(t("repl.agents_label"), pc2.dim(t("repl.not_found")));
|
|
27321
27429
|
}
|
|
27322
27430
|
}
|
|
27323
27431
|
const meta = this.sessionManager?.getActiveMeta();
|
|
27324
27432
|
if (meta) {
|
|
27325
|
-
const sessionPath =
|
|
27326
|
-
row(t("repl.session_label"), `${
|
|
27433
|
+
const sessionPath = join36(this.configDir, "sessions", meta.id);
|
|
27434
|
+
row(t("repl.session_label"), `${pc2.cyan(meta.name)} ${pc2.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc2.dim(sessionPath)}`);
|
|
27327
27435
|
}
|
|
27328
27436
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
27329
27437
|
for (const line of box(info, {
|
|
@@ -27349,7 +27457,7 @@ init_config2();
|
|
|
27349
27457
|
init_i18n();
|
|
27350
27458
|
init_colors();
|
|
27351
27459
|
import { existsSync as existsSync44 } from "fs";
|
|
27352
|
-
import { join as
|
|
27460
|
+
import { join as join37 } from "path";
|
|
27353
27461
|
import { homedir as homedir18 } from "os";
|
|
27354
27462
|
async function main() {
|
|
27355
27463
|
const program2 = createProgram();
|
|
@@ -27405,7 +27513,7 @@ async function main() {
|
|
|
27405
27513
|
renderer.flush();
|
|
27406
27514
|
if (result.success) {
|
|
27407
27515
|
if (!result.text) {
|
|
27408
|
-
console.log(
|
|
27516
|
+
console.log(pc2.yellow(t("cli.no_output")));
|
|
27409
27517
|
}
|
|
27410
27518
|
} else {
|
|
27411
27519
|
console.error(`${t("error.prefix")}${result.error}`);
|
|
@@ -27416,15 +27524,15 @@ async function main() {
|
|
|
27416
27524
|
}
|
|
27417
27525
|
agent.shutdown();
|
|
27418
27526
|
} else {
|
|
27419
|
-
const configPath =
|
|
27527
|
+
const configPath = join37(homedir18(), ".mma", "config.json");
|
|
27420
27528
|
if (!existsSync44(configPath)) {
|
|
27421
|
-
console.log(
|
|
27529
|
+
console.log(pc2.yellow(`
|
|
27422
27530
|
` + t("cli.first_run") + `
|
|
27423
27531
|
`));
|
|
27424
27532
|
const answers = await runSetup();
|
|
27425
27533
|
const config2 = loadConfig({
|
|
27426
|
-
configDir:
|
|
27427
|
-
projectConfigPath: projectDir ?
|
|
27534
|
+
configDir: join37(homedir18(), ".mma"),
|
|
27535
|
+
projectConfigPath: projectDir ? join37(projectDir, ".mmrc") : join37(process.cwd(), ".mmrc")
|
|
27428
27536
|
});
|
|
27429
27537
|
config2.provider.type = answers.provider;
|
|
27430
27538
|
config2.provider.baseUrl = answers.apiBase;
|