micro-models-agent 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +214 -148
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -12948,8 +12948,53 @@ var init_auditor = __esm(() => {
|
|
|
12948
12948
|
init_i18n();
|
|
12949
12949
|
});
|
|
12950
12950
|
|
|
12951
|
+
// src/modules/execution/plan-persister.ts
|
|
12952
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync11, existsSync as existsSync25 } from "fs";
|
|
12953
|
+
import { join as join18 } from "path";
|
|
12954
|
+
|
|
12955
|
+
class PlanPersister {
|
|
12956
|
+
filePath;
|
|
12957
|
+
constructor(baseDir) {
|
|
12958
|
+
const mmaDir = join18(baseDir, ".mma");
|
|
12959
|
+
if (!existsSync25(mmaDir)) {
|
|
12960
|
+
mkdirSync11(mmaDir, { recursive: true });
|
|
12961
|
+
}
|
|
12962
|
+
this.filePath = join18(mmaDir, "plan.json");
|
|
12963
|
+
}
|
|
12964
|
+
save(plan) {
|
|
12965
|
+
const file = {
|
|
12966
|
+
title: plan.title,
|
|
12967
|
+
steps: plan.steps,
|
|
12968
|
+
createdAt: plan.createdAt,
|
|
12969
|
+
updatedAt: new Date().toISOString()
|
|
12970
|
+
};
|
|
12971
|
+
writeFileSync9(this.filePath, JSON.stringify(file, null, 2), "utf-8");
|
|
12972
|
+
}
|
|
12973
|
+
load() {
|
|
12974
|
+
if (!existsSync25(this.filePath))
|
|
12975
|
+
return null;
|
|
12976
|
+
try {
|
|
12977
|
+
const raw = readFileSync14(this.filePath, "utf-8");
|
|
12978
|
+
const file = JSON.parse(raw);
|
|
12979
|
+
return {
|
|
12980
|
+
title: file.title,
|
|
12981
|
+
steps: file.steps,
|
|
12982
|
+
createdAt: file.createdAt
|
|
12983
|
+
};
|
|
12984
|
+
} catch {
|
|
12985
|
+
return null;
|
|
12986
|
+
}
|
|
12987
|
+
}
|
|
12988
|
+
clear() {
|
|
12989
|
+
if (existsSync25(this.filePath)) {
|
|
12990
|
+
writeFileSync9(this.filePath, "", "utf-8");
|
|
12991
|
+
}
|
|
12992
|
+
}
|
|
12993
|
+
}
|
|
12994
|
+
var init_plan_persister = () => {};
|
|
12995
|
+
|
|
12951
12996
|
// src/modules/execution/module.ts
|
|
12952
|
-
import { existsSync as
|
|
12997
|
+
import { existsSync as existsSync26 } from "fs";
|
|
12953
12998
|
import { resolve as resolve14 } from "path";
|
|
12954
12999
|
|
|
12955
13000
|
class ExecutionModule {
|
|
@@ -12958,6 +13003,7 @@ class ExecutionModule {
|
|
|
12958
13003
|
verifier;
|
|
12959
13004
|
stuckDetector;
|
|
12960
13005
|
auditor;
|
|
13006
|
+
persister;
|
|
12961
13007
|
baseDir;
|
|
12962
13008
|
lastRecoveryIteration = -STUCK_RECOVERY_COOLDOWN;
|
|
12963
13009
|
constructor(baseDir, stuckThreshold = 8) {
|
|
@@ -12965,9 +13011,22 @@ class ExecutionModule {
|
|
|
12965
13011
|
this.verifier = new StepVerifier(baseDir);
|
|
12966
13012
|
this.stuckDetector = new StuckDetector(stuckThreshold);
|
|
12967
13013
|
this.auditor = new Auditor(baseDir);
|
|
13014
|
+
this.persister = new PlanPersister(baseDir);
|
|
12968
13015
|
}
|
|
12969
13016
|
setPlan(plan) {
|
|
12970
13017
|
this.tracker = new PlanTracker(plan);
|
|
13018
|
+
this.persister.save(plan);
|
|
13019
|
+
}
|
|
13020
|
+
restorePlan() {
|
|
13021
|
+
const plan = this.persister.load();
|
|
13022
|
+
if (!plan)
|
|
13023
|
+
return false;
|
|
13024
|
+
this.tracker = new PlanTracker(plan);
|
|
13025
|
+
while (this.tracker.getCurrentStep()?.status === "done" || this.tracker.getCurrentStep()?.status === "skipped") {
|
|
13026
|
+
if (!this.tracker.advance())
|
|
13027
|
+
break;
|
|
13028
|
+
}
|
|
13029
|
+
return true;
|
|
12971
13030
|
}
|
|
12972
13031
|
getTracker() {
|
|
12973
13032
|
return this.tracker;
|
|
@@ -13055,6 +13114,7 @@ ${display}`,
|
|
|
13055
13114
|
this.tracker.updateStepStatus(Number(args.step), args.status || "done");
|
|
13056
13115
|
if (args.note)
|
|
13057
13116
|
this.tracker.addNote(Number(args.step), String(args.note));
|
|
13117
|
+
this.persister.save(this.tracker.getPlan());
|
|
13058
13118
|
const progress = this.tracker.getProgressString();
|
|
13059
13119
|
const display = this.tracker.toPromptBlock();
|
|
13060
13120
|
return {
|
|
@@ -13066,6 +13126,7 @@ ${progress}`,
|
|
|
13066
13126
|
}
|
|
13067
13127
|
if (action === "abort") {
|
|
13068
13128
|
this.tracker = null;
|
|
13129
|
+
this.persister.clear();
|
|
13069
13130
|
return { success: true, output: t("plan.aborted") };
|
|
13070
13131
|
}
|
|
13071
13132
|
if (!this.tracker) {
|
|
@@ -13256,10 +13317,13 @@ Sub-tasks: ${note}`
|
|
|
13256
13317
|
const stepPaths = step.description.match(/\b[\w./\\-]+\.[a-z]+/gi) || [];
|
|
13257
13318
|
if (stepPaths.length === 0)
|
|
13258
13319
|
return;
|
|
13259
|
-
const allExist = stepPaths.every((p) =>
|
|
13320
|
+
const allExist = stepPaths.every((p) => existsSync26(resolve14(this.baseDir, p)));
|
|
13260
13321
|
if (allExist) {
|
|
13261
13322
|
this.tracker?.updateStepStatus(step.id, "done");
|
|
13262
13323
|
this.tracker?.advance();
|
|
13324
|
+
if (this.tracker) {
|
|
13325
|
+
this.persister.save(this.tracker.getPlan());
|
|
13326
|
+
}
|
|
13263
13327
|
}
|
|
13264
13328
|
}
|
|
13265
13329
|
}
|
|
@@ -13270,11 +13334,12 @@ var init_module = __esm(() => {
|
|
|
13270
13334
|
init_verifier();
|
|
13271
13335
|
init_stuck_detector();
|
|
13272
13336
|
init_auditor();
|
|
13337
|
+
init_plan_persister();
|
|
13273
13338
|
});
|
|
13274
13339
|
|
|
13275
13340
|
// src/modules/security/session-encryption.ts
|
|
13276
|
-
import { readFileSync as
|
|
13277
|
-
import { join as
|
|
13341
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync10, existsSync as existsSync27, readdirSync as readdirSync6, unlinkSync as unlinkSync3 } from "fs";
|
|
13342
|
+
import { join as join19 } from "path";
|
|
13278
13343
|
import { homedir as homedir8 } from "os";
|
|
13279
13344
|
|
|
13280
13345
|
class SessionFileEncryptor {
|
|
@@ -13283,7 +13348,7 @@ class SessionFileEncryptor {
|
|
|
13283
13348
|
constructor(config) {
|
|
13284
13349
|
this.config = { ...DEFAULT_SESSION_ENCRYPTION, ...config };
|
|
13285
13350
|
this.encryptor = new ConfigEncryptor({
|
|
13286
|
-
keyPath: config?.keyPath ||
|
|
13351
|
+
keyPath: config?.keyPath || join19(homedir8(), ".mma", ".session-encryption-key")
|
|
13287
13352
|
});
|
|
13288
13353
|
}
|
|
13289
13354
|
isEnabled() {
|
|
@@ -13323,23 +13388,23 @@ class SessionFileEncryptor {
|
|
|
13323
13388
|
return lines.map((line) => this.decryptFileContent(line));
|
|
13324
13389
|
}
|
|
13325
13390
|
readSessionFile(filePath) {
|
|
13326
|
-
const content =
|
|
13391
|
+
const content = readFileSync15(filePath, "utf8");
|
|
13327
13392
|
return this.decryptFileContent(content);
|
|
13328
13393
|
}
|
|
13329
13394
|
writeSessionFile(filePath, content) {
|
|
13330
13395
|
const encrypted = this.encryptFileContent(content);
|
|
13331
|
-
|
|
13396
|
+
writeFileSync10(filePath, encrypted, "utf8");
|
|
13332
13397
|
}
|
|
13333
13398
|
readSessionJSON(filePath) {
|
|
13334
|
-
const content =
|
|
13399
|
+
const content = readFileSync15(filePath, "utf8");
|
|
13335
13400
|
return this.decryptJSON(content);
|
|
13336
13401
|
}
|
|
13337
13402
|
writeSessionJSON(filePath, obj) {
|
|
13338
13403
|
const content = this.encryptJSON(obj);
|
|
13339
|
-
|
|
13404
|
+
writeFileSync10(filePath, content, "utf8");
|
|
13340
13405
|
}
|
|
13341
13406
|
readSessionJSONL(filePath) {
|
|
13342
|
-
const content =
|
|
13407
|
+
const content = readFileSync15(filePath, "utf8");
|
|
13343
13408
|
const lines = content.split(`
|
|
13344
13409
|
`).filter((line) => line.trim());
|
|
13345
13410
|
const decryptedLines = this.decryptJSONL(lines);
|
|
@@ -13347,7 +13412,7 @@ class SessionFileEncryptor {
|
|
|
13347
13412
|
}
|
|
13348
13413
|
appendToSessionJSONL(filePath, obj) {
|
|
13349
13414
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
13350
|
-
|
|
13415
|
+
writeFileSync10(filePath, encryptedLine + `
|
|
13351
13416
|
`, { flag: "a", encoding: "utf8" });
|
|
13352
13417
|
}
|
|
13353
13418
|
encryptSessionDirectory(sessionDir) {
|
|
@@ -13355,12 +13420,12 @@ class SessionFileEncryptor {
|
|
|
13355
13420
|
return;
|
|
13356
13421
|
const files = readdirSync6(sessionDir);
|
|
13357
13422
|
for (const file of files) {
|
|
13358
|
-
const filePath =
|
|
13359
|
-
if (
|
|
13423
|
+
const filePath = join19(sessionDir, file);
|
|
13424
|
+
if (existsSync27(filePath) && !file.endsWith(".enc")) {
|
|
13360
13425
|
try {
|
|
13361
|
-
const content =
|
|
13426
|
+
const content = readFileSync15(filePath, "utf8");
|
|
13362
13427
|
const encrypted = this.encryptFileContent(content);
|
|
13363
|
-
|
|
13428
|
+
writeFileSync10(filePath + ".enc", encrypted, "utf8");
|
|
13364
13429
|
unlinkSync3(filePath);
|
|
13365
13430
|
} catch {}
|
|
13366
13431
|
}
|
|
@@ -13372,12 +13437,12 @@ class SessionFileEncryptor {
|
|
|
13372
13437
|
const files = readdirSync6(sessionDir);
|
|
13373
13438
|
for (const file of files) {
|
|
13374
13439
|
if (file.endsWith(".enc")) {
|
|
13375
|
-
const encFilePath =
|
|
13440
|
+
const encFilePath = join19(sessionDir, file);
|
|
13376
13441
|
const decFilePath = encFilePath.slice(0, -4);
|
|
13377
13442
|
try {
|
|
13378
|
-
const content =
|
|
13443
|
+
const content = readFileSync15(encFilePath, "utf8");
|
|
13379
13444
|
const decrypted = this.decryptFileContent(content);
|
|
13380
|
-
|
|
13445
|
+
writeFileSync10(decFilePath, decrypted, "utf8");
|
|
13381
13446
|
unlinkSync3(encFilePath);
|
|
13382
13447
|
} catch {}
|
|
13383
13448
|
}
|
|
@@ -13397,15 +13462,15 @@ var init_session_encryption = __esm(() => {
|
|
|
13397
13462
|
|
|
13398
13463
|
// src/modules/session/store.ts
|
|
13399
13464
|
import {
|
|
13400
|
-
existsSync as
|
|
13401
|
-
mkdirSync as
|
|
13465
|
+
existsSync as existsSync28,
|
|
13466
|
+
mkdirSync as mkdirSync12,
|
|
13402
13467
|
readdirSync as readdirSync7,
|
|
13403
|
-
readFileSync as
|
|
13468
|
+
readFileSync as readFileSync16,
|
|
13404
13469
|
rmSync,
|
|
13405
|
-
writeFileSync as
|
|
13470
|
+
writeFileSync as writeFileSync11,
|
|
13406
13471
|
appendFileSync as appendFileSync5
|
|
13407
13472
|
} from "fs";
|
|
13408
|
-
import { join as
|
|
13473
|
+
import { join as join20 } from "path";
|
|
13409
13474
|
import { gzipSync } from "zlib";
|
|
13410
13475
|
|
|
13411
13476
|
class SessionStore {
|
|
@@ -13428,39 +13493,39 @@ class SessionStore {
|
|
|
13428
13493
|
return this.encryptor?.isEnabled() ?? false;
|
|
13429
13494
|
}
|
|
13430
13495
|
init() {
|
|
13431
|
-
|
|
13496
|
+
mkdirSync12(this.baseDir, { recursive: true });
|
|
13432
13497
|
}
|
|
13433
13498
|
sessionDir(id) {
|
|
13434
|
-
return
|
|
13499
|
+
return join20(this.baseDir, id);
|
|
13435
13500
|
}
|
|
13436
13501
|
metaPath(id) {
|
|
13437
|
-
return
|
|
13502
|
+
return join20(this.sessionDir(id), "meta.json");
|
|
13438
13503
|
}
|
|
13439
13504
|
historyPath(id) {
|
|
13440
|
-
return
|
|
13505
|
+
return join20(this.sessionDir(id), "history.jsonl");
|
|
13441
13506
|
}
|
|
13442
13507
|
sessionLogPath(id) {
|
|
13443
|
-
return
|
|
13508
|
+
return join20(this.sessionDir(id), "session.jsonl");
|
|
13444
13509
|
}
|
|
13445
13510
|
sessionExists(id) {
|
|
13446
|
-
return
|
|
13511
|
+
return existsSync28(this.metaPath(id));
|
|
13447
13512
|
}
|
|
13448
13513
|
saveMeta(id, meta) {
|
|
13449
13514
|
const dir = this.sessionDir(id);
|
|
13450
|
-
|
|
13515
|
+
mkdirSync12(dir, { recursive: true });
|
|
13451
13516
|
const content = JSON.stringify(meta, null, 2);
|
|
13452
13517
|
if (this.encryptor) {
|
|
13453
|
-
|
|
13518
|
+
writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
|
|
13454
13519
|
} else {
|
|
13455
|
-
|
|
13520
|
+
writeFileSync11(this.metaPath(id), content, "utf-8");
|
|
13456
13521
|
}
|
|
13457
13522
|
}
|
|
13458
13523
|
loadMeta(id) {
|
|
13459
13524
|
const path = this.metaPath(id);
|
|
13460
|
-
if (!
|
|
13525
|
+
if (!existsSync28(path))
|
|
13461
13526
|
return null;
|
|
13462
13527
|
try {
|
|
13463
|
-
const raw =
|
|
13528
|
+
const raw = readFileSync16(path, "utf-8");
|
|
13464
13529
|
const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
|
|
13465
13530
|
return JSON.parse(content);
|
|
13466
13531
|
} catch {
|
|
@@ -13469,7 +13534,7 @@ class SessionStore {
|
|
|
13469
13534
|
}
|
|
13470
13535
|
appendMessage(id, msg) {
|
|
13471
13536
|
const dir = this.sessionDir(id);
|
|
13472
|
-
|
|
13537
|
+
mkdirSync12(dir, { recursive: true });
|
|
13473
13538
|
const line = JSON.stringify(msg);
|
|
13474
13539
|
if (this.encryptor?.isEnabled()) {
|
|
13475
13540
|
appendFileSync5(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -13487,10 +13552,10 @@ class SessionStore {
|
|
|
13487
13552
|
}
|
|
13488
13553
|
loadHistory(id) {
|
|
13489
13554
|
const path = this.historyPath(id);
|
|
13490
|
-
if (!
|
|
13555
|
+
if (!existsSync28(path))
|
|
13491
13556
|
return [];
|
|
13492
13557
|
try {
|
|
13493
|
-
const raw =
|
|
13558
|
+
const raw = readFileSync16(path, "utf-8");
|
|
13494
13559
|
const lines = raw.split(`
|
|
13495
13560
|
`).filter(Boolean);
|
|
13496
13561
|
if (this.encryptor?.isEnabled()) {
|
|
@@ -13504,7 +13569,7 @@ class SessionStore {
|
|
|
13504
13569
|
}
|
|
13505
13570
|
appendSessionLog(id, entry) {
|
|
13506
13571
|
const dir = this.sessionDir(id);
|
|
13507
|
-
|
|
13572
|
+
mkdirSync12(dir, { recursive: true });
|
|
13508
13573
|
const line = JSON.stringify(entry);
|
|
13509
13574
|
if (this.encryptor?.isEnabled()) {
|
|
13510
13575
|
appendFileSync5(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -13516,10 +13581,10 @@ class SessionStore {
|
|
|
13516
13581
|
}
|
|
13517
13582
|
loadSessionLog(id) {
|
|
13518
13583
|
const path = this.sessionLogPath(id);
|
|
13519
|
-
if (!
|
|
13584
|
+
if (!existsSync28(path))
|
|
13520
13585
|
return [];
|
|
13521
13586
|
try {
|
|
13522
|
-
const raw =
|
|
13587
|
+
const raw = readFileSync16(path, "utf-8");
|
|
13523
13588
|
const lines = raw.split(`
|
|
13524
13589
|
`).filter(Boolean);
|
|
13525
13590
|
if (this.encryptor?.isEnabled()) {
|
|
@@ -13532,7 +13597,7 @@ class SessionStore {
|
|
|
13532
13597
|
}
|
|
13533
13598
|
}
|
|
13534
13599
|
listSessions() {
|
|
13535
|
-
if (!
|
|
13600
|
+
if (!existsSync28(this.baseDir))
|
|
13536
13601
|
return [];
|
|
13537
13602
|
const entries = readdirSync7(this.baseDir, { withFileTypes: true });
|
|
13538
13603
|
const sessions = [];
|
|
@@ -13548,7 +13613,7 @@ class SessionStore {
|
|
|
13548
13613
|
}
|
|
13549
13614
|
deleteSession(id) {
|
|
13550
13615
|
const dir = this.sessionDir(id);
|
|
13551
|
-
if (
|
|
13616
|
+
if (existsSync28(dir)) {
|
|
13552
13617
|
rmSync(dir, { recursive: true, force: true });
|
|
13553
13618
|
}
|
|
13554
13619
|
}
|
|
@@ -13560,11 +13625,11 @@ class SessionStore {
|
|
|
13560
13625
|
const updatedAt = new Date(session2.updatedAt);
|
|
13561
13626
|
if (updatedAt < thirtyDaysAgo) {
|
|
13562
13627
|
const historyPath = this.historyPath(session2.id);
|
|
13563
|
-
if (
|
|
13564
|
-
const content =
|
|
13628
|
+
if (existsSync28(historyPath)) {
|
|
13629
|
+
const content = readFileSync16(historyPath, "utf-8");
|
|
13565
13630
|
const compressed = gzipSync(content);
|
|
13566
|
-
const gzPath =
|
|
13567
|
-
|
|
13631
|
+
const gzPath = join20(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
13632
|
+
writeFileSync11(gzPath, compressed);
|
|
13568
13633
|
rmSync(historyPath);
|
|
13569
13634
|
}
|
|
13570
13635
|
}
|
|
@@ -13770,8 +13835,8 @@ class ProfileCompressor {
|
|
|
13770
13835
|
}
|
|
13771
13836
|
|
|
13772
13837
|
// src/modules/user-profile/profile.ts
|
|
13773
|
-
import { readFileSync as
|
|
13774
|
-
import { join as
|
|
13838
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync12, existsSync as existsSync29, mkdirSync as mkdirSync13 } from "fs";
|
|
13839
|
+
import { join as join21 } from "path";
|
|
13775
13840
|
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
13776
13841
|
import { env } from "process";
|
|
13777
13842
|
|
|
@@ -13795,17 +13860,17 @@ class UserProfile {
|
|
|
13795
13860
|
return this.info;
|
|
13796
13861
|
}
|
|
13797
13862
|
save() {
|
|
13798
|
-
if (!
|
|
13799
|
-
|
|
13863
|
+
if (!existsSync29(this.profileDir)) {
|
|
13864
|
+
mkdirSync13(this.profileDir, { recursive: true });
|
|
13800
13865
|
}
|
|
13801
|
-
|
|
13866
|
+
writeFileSync12(join21(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
13802
13867
|
}
|
|
13803
13868
|
load() {
|
|
13804
|
-
const path =
|
|
13805
|
-
if (!
|
|
13869
|
+
const path = join21(this.profileDir, "profile.json");
|
|
13870
|
+
if (!existsSync29(path))
|
|
13806
13871
|
return null;
|
|
13807
13872
|
try {
|
|
13808
|
-
const data = JSON.parse(
|
|
13873
|
+
const data = JSON.parse(readFileSync17(path, "utf-8"));
|
|
13809
13874
|
this.info = {
|
|
13810
13875
|
platform: data.platform,
|
|
13811
13876
|
os: data.os,
|
|
@@ -13840,12 +13905,12 @@ class UserProfile {
|
|
|
13840
13905
|
var init_profile = () => {};
|
|
13841
13906
|
|
|
13842
13907
|
// src/modules/skills/loader.ts
|
|
13843
|
-
import { readdirSync as readdirSync8, readFileSync as
|
|
13844
|
-
import { join as
|
|
13908
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSync18, existsSync as existsSync30, statSync as statSync5 } from "fs";
|
|
13909
|
+
import { join as join22 } from "path";
|
|
13845
13910
|
|
|
13846
13911
|
class SkillsLoader {
|
|
13847
13912
|
loadFromDir(dirPath) {
|
|
13848
|
-
if (!
|
|
13913
|
+
if (!existsSync30(dirPath))
|
|
13849
13914
|
return [];
|
|
13850
13915
|
const skills = [];
|
|
13851
13916
|
this.scanDir(dirPath, skills);
|
|
@@ -13854,7 +13919,7 @@ class SkillsLoader {
|
|
|
13854
13919
|
scanDir(dirPath, skills) {
|
|
13855
13920
|
const entries = readdirSync8(dirPath);
|
|
13856
13921
|
for (const entry of entries) {
|
|
13857
|
-
const fullPath =
|
|
13922
|
+
const fullPath = join22(dirPath, entry);
|
|
13858
13923
|
const stat = statSync5(fullPath);
|
|
13859
13924
|
if (stat.isDirectory()) {
|
|
13860
13925
|
this.scanDir(fullPath, skills);
|
|
@@ -13862,7 +13927,7 @@ class SkillsLoader {
|
|
|
13862
13927
|
}
|
|
13863
13928
|
if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
|
|
13864
13929
|
continue;
|
|
13865
|
-
const content =
|
|
13930
|
+
const content = readFileSync18(fullPath, "utf-8");
|
|
13866
13931
|
const parsed = this.parseSkillFile(content, fullPath);
|
|
13867
13932
|
if (parsed)
|
|
13868
13933
|
skills.push(parsed);
|
|
@@ -14134,8 +14199,8 @@ var init_browser2 = __esm(() => {
|
|
|
14134
14199
|
});
|
|
14135
14200
|
|
|
14136
14201
|
// src/modules/indexer/walker.ts
|
|
14137
|
-
import { readdirSync as readdirSync9, readFileSync as
|
|
14138
|
-
import { join as
|
|
14202
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync19, statSync as statSync6, existsSync as existsSync31, watch } from "fs";
|
|
14203
|
+
import { join as join23, relative, extname as extname5 } from "path";
|
|
14139
14204
|
|
|
14140
14205
|
class Indexer {
|
|
14141
14206
|
baseDir;
|
|
@@ -14162,7 +14227,7 @@ class Indexer {
|
|
|
14162
14227
|
let totalSize = 0;
|
|
14163
14228
|
let count = 0;
|
|
14164
14229
|
const walkDir = (dir) => {
|
|
14165
|
-
if (!
|
|
14230
|
+
if (!existsSync31(dir))
|
|
14166
14231
|
return;
|
|
14167
14232
|
let entries;
|
|
14168
14233
|
try {
|
|
@@ -14173,7 +14238,7 @@ class Indexer {
|
|
|
14173
14238
|
for (const entry of entries) {
|
|
14174
14239
|
if (count >= this.MAX_FILES)
|
|
14175
14240
|
return;
|
|
14176
|
-
const fullPath =
|
|
14241
|
+
const fullPath = join23(dir, entry);
|
|
14177
14242
|
const relPath = relative(this.baseDir, fullPath);
|
|
14178
14243
|
const stat = statSync6(fullPath);
|
|
14179
14244
|
if (stat.isDirectory()) {
|
|
@@ -14184,7 +14249,7 @@ class Indexer {
|
|
|
14184
14249
|
const ext = extname5(entry).toLowerCase();
|
|
14185
14250
|
const language = LANGUAGES[ext];
|
|
14186
14251
|
if (language) {
|
|
14187
|
-
const content =
|
|
14252
|
+
const content = readFileSync19(fullPath, "utf-8");
|
|
14188
14253
|
const exports = this.extractExports(content, language);
|
|
14189
14254
|
files.push({ path: relPath, language, exports, size: stat.size });
|
|
14190
14255
|
totalSize += stat.size;
|
|
@@ -14236,22 +14301,22 @@ var init_walker = __esm(() => {
|
|
|
14236
14301
|
});
|
|
14237
14302
|
|
|
14238
14303
|
// src/modules/indexer/cache.ts
|
|
14239
|
-
import { readFileSync as
|
|
14240
|
-
import { join as
|
|
14304
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync13, existsSync as existsSync32, mkdirSync as mkdirSync14, rmSync as rmSync2 } from "fs";
|
|
14305
|
+
import { join as join24 } from "path";
|
|
14241
14306
|
|
|
14242
14307
|
class IndexCache {
|
|
14243
14308
|
cachePath;
|
|
14244
14309
|
cache = null;
|
|
14245
14310
|
constructor(cacheDir) {
|
|
14246
|
-
this.cachePath =
|
|
14311
|
+
this.cachePath = join24(cacheDir, "index-cache.json");
|
|
14247
14312
|
}
|
|
14248
14313
|
load() {
|
|
14249
14314
|
if (this.cache)
|
|
14250
14315
|
return this.cache;
|
|
14251
|
-
if (!
|
|
14316
|
+
if (!existsSync32(this.cachePath))
|
|
14252
14317
|
return null;
|
|
14253
14318
|
try {
|
|
14254
|
-
this.cache = JSON.parse(
|
|
14319
|
+
this.cache = JSON.parse(readFileSync20(this.cachePath, "utf-8"));
|
|
14255
14320
|
return this.cache;
|
|
14256
14321
|
} catch {
|
|
14257
14322
|
return null;
|
|
@@ -14259,14 +14324,14 @@ class IndexCache {
|
|
|
14259
14324
|
}
|
|
14260
14325
|
save(result) {
|
|
14261
14326
|
this.cache = result;
|
|
14262
|
-
const dir =
|
|
14263
|
-
if (!
|
|
14264
|
-
|
|
14265
|
-
|
|
14327
|
+
const dir = join24(this.cachePath, "..");
|
|
14328
|
+
if (!existsSync32(dir))
|
|
14329
|
+
mkdirSync14(dir, { recursive: true });
|
|
14330
|
+
writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
|
|
14266
14331
|
}
|
|
14267
14332
|
invalidate() {
|
|
14268
14333
|
this.cache = null;
|
|
14269
|
-
if (
|
|
14334
|
+
if (existsSync32(this.cachePath)) {
|
|
14270
14335
|
try {
|
|
14271
14336
|
rmSync2(this.cachePath);
|
|
14272
14337
|
} catch {}
|
|
@@ -14276,7 +14341,7 @@ class IndexCache {
|
|
|
14276
14341
|
var init_cache = () => {};
|
|
14277
14342
|
|
|
14278
14343
|
// src/modules/indexer/module.ts
|
|
14279
|
-
import { dirname as
|
|
14344
|
+
import { dirname as dirname8 } from "path";
|
|
14280
14345
|
|
|
14281
14346
|
class IndexerModule {
|
|
14282
14347
|
name = "indexer";
|
|
@@ -14393,7 +14458,7 @@ ${t("indexer.and_more", { count: result.files.length - 100 })}` : "";
|
|
|
14393
14458
|
const counts = {};
|
|
14394
14459
|
for (const f of result.files) {
|
|
14395
14460
|
const normalized = f.path.replace(/\\/g, "/");
|
|
14396
|
-
const dir =
|
|
14461
|
+
const dir = dirname8(normalized);
|
|
14397
14462
|
const key = dir === "." ? "(root)" : dir;
|
|
14398
14463
|
counts[key] = (counts[key] || 0) + 1;
|
|
14399
14464
|
}
|
|
@@ -14624,13 +14689,13 @@ var init_mcp = __esm(() => {
|
|
|
14624
14689
|
|
|
14625
14690
|
// src/modules/memory/module.ts
|
|
14626
14691
|
import { homedir as homedir10 } from "os";
|
|
14627
|
-
import { join as
|
|
14692
|
+
import { join as join25 } from "path";
|
|
14628
14693
|
|
|
14629
14694
|
class MemoryModule {
|
|
14630
14695
|
name = "memory";
|
|
14631
14696
|
store;
|
|
14632
14697
|
constructor(memoryDir) {
|
|
14633
|
-
const dir = memoryDir ||
|
|
14698
|
+
const dir = memoryDir || join25(homedir10(), ".mma", "memory");
|
|
14634
14699
|
this.store = new MemoryStore(dir);
|
|
14635
14700
|
}
|
|
14636
14701
|
getSystemPromptBlock() {
|
|
@@ -14677,8 +14742,8 @@ __export(exports_bootstrap, {
|
|
|
14677
14742
|
bootstrap: () => bootstrap
|
|
14678
14743
|
});
|
|
14679
14744
|
import { homedir as homedir11 } from "os";
|
|
14680
|
-
import { join as
|
|
14681
|
-
import { existsSync as
|
|
14745
|
+
import { join as join26, resolve as resolve15 } from "path";
|
|
14746
|
+
import { existsSync as existsSync33, readFileSync as readFileSync21, writeFileSync as writeFileSync14 } from "fs";
|
|
14682
14747
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
14683
14748
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
14684
14749
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -14712,8 +14777,8 @@ function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
|
14712
14777
|
`);
|
|
14713
14778
|
}
|
|
14714
14779
|
async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
14715
|
-
const dir = configDir ||
|
|
14716
|
-
const projectConfigPath = projectDir ?
|
|
14780
|
+
const dir = configDir || join26(homedir11(), ".mma");
|
|
14781
|
+
const projectConfigPath = projectDir ? join26(projectDir, ".mmrc") : join26(process.cwd(), ".mmrc");
|
|
14717
14782
|
const config = loadConfig({ configDir: dir, projectConfigPath });
|
|
14718
14783
|
setLocale(config.locale);
|
|
14719
14784
|
try {
|
|
@@ -14723,7 +14788,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14723
14788
|
}
|
|
14724
14789
|
} catch {}
|
|
14725
14790
|
const logger = new Logger(config.logLevel);
|
|
14726
|
-
logger.setLogDir(
|
|
14791
|
+
logger.setLogDir(join26(dir, "logs"));
|
|
14727
14792
|
logger.debug("MMA bootstrap", {
|
|
14728
14793
|
version: config.version,
|
|
14729
14794
|
model: config.model
|
|
@@ -14745,7 +14810,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14745
14810
|
logger.info(`Model ${config.model} loaded in ${loadResult.loadTime}s`);
|
|
14746
14811
|
}
|
|
14747
14812
|
}
|
|
14748
|
-
const profile = new UserProfile(
|
|
14813
|
+
const profile = new UserProfile(join26(dir));
|
|
14749
14814
|
profile.load() || profile.collect();
|
|
14750
14815
|
profile.save();
|
|
14751
14816
|
const llmProvider = new OpenAICompatProvider({
|
|
@@ -14757,7 +14822,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14757
14822
|
rateLimits: config.security?.rateLimits
|
|
14758
14823
|
});
|
|
14759
14824
|
const baseDir = projectDir ? resolve15(projectDir) : process.cwd();
|
|
14760
|
-
const projectMapCacheDir =
|
|
14825
|
+
const projectMapCacheDir = join26(baseDir, ".mma");
|
|
14761
14826
|
const indexerModule = new IndexerModule({
|
|
14762
14827
|
baseDir,
|
|
14763
14828
|
cacheDir: projectMapCacheDir
|
|
@@ -14768,9 +14833,9 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14768
14833
|
logger.warn(`Project indexing failed: ${err.message}`);
|
|
14769
14834
|
}
|
|
14770
14835
|
const skillsLoader = new SkillsLoader;
|
|
14771
|
-
const builtinDir =
|
|
14772
|
-
const globalDir =
|
|
14773
|
-
const projectSkillsDir =
|
|
14836
|
+
const builtinDir = join26(import.meta.dirname, "skills", "builtin");
|
|
14837
|
+
const globalDir = join26(homedir11(), ".agents", "skills");
|
|
14838
|
+
const projectSkillsDir = join26(baseDir, ".mma", "skills");
|
|
14774
14839
|
const availableSkills = skillsLoader.loadFromAllSources(builtinDir, globalDir, projectSkillsDir);
|
|
14775
14840
|
const skillsMatcher = new SkillsMatcher;
|
|
14776
14841
|
const skillsBudget = Math.floor(config.contextWindow * 0.1);
|
|
@@ -14784,11 +14849,11 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14784
14849
|
essential: true,
|
|
14785
14850
|
estimatedTokens: 250
|
|
14786
14851
|
};
|
|
14787
|
-
const agentsMdGlobal =
|
|
14788
|
-
if (!
|
|
14789
|
-
|
|
14852
|
+
const agentsMdGlobal = join26(dir, "AGENTS.md");
|
|
14853
|
+
if (!existsSync33(agentsMdGlobal)) {
|
|
14854
|
+
writeFileSync14(agentsMdGlobal, "", "utf-8");
|
|
14790
14855
|
}
|
|
14791
|
-
const sessionDir =
|
|
14856
|
+
const sessionDir = join26(dir, "sessions");
|
|
14792
14857
|
const sessionStore = new SessionStore(sessionDir);
|
|
14793
14858
|
sessionStore.init();
|
|
14794
14859
|
const sessionManager = new SessionManager(sessionStore, {
|
|
@@ -14833,6 +14898,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14833
14898
|
const hallucinationDetector = new HallucinationDetector;
|
|
14834
14899
|
const moduleRegistry = new ModuleRegistry;
|
|
14835
14900
|
const execModule = new ExecutionModule(baseDir, config.stuckThreshold);
|
|
14901
|
+
execModule.restorePlan();
|
|
14836
14902
|
moduleRegistry.register(execModule);
|
|
14837
14903
|
const sessionModule = new SessionModule(sessionManager);
|
|
14838
14904
|
moduleRegistry.register(sessionModule);
|
|
@@ -14841,7 +14907,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14841
14907
|
const mcpModule = new MCPModule(config);
|
|
14842
14908
|
await mcpModule.initialize();
|
|
14843
14909
|
moduleRegistry.register(mcpModule);
|
|
14844
|
-
const memoryModule = new MemoryModule(
|
|
14910
|
+
const memoryModule = new MemoryModule(join26(dir, "memory"));
|
|
14845
14911
|
moduleRegistry.register(memoryModule);
|
|
14846
14912
|
if (config.browser.enabled) {
|
|
14847
14913
|
const browserModule = new BrowserModule;
|
|
@@ -14884,8 +14950,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14884
14950
|
pluginManager.register(plugin);
|
|
14885
14951
|
pluginManager.register(plugin2);
|
|
14886
14952
|
const pluginLoader = new PluginLoader;
|
|
14887
|
-
const globalPluginsDir =
|
|
14888
|
-
const projectPluginsDir =
|
|
14953
|
+
const globalPluginsDir = join26(homedir11(), ".mma", "plugins");
|
|
14954
|
+
const projectPluginsDir = join26(dir, ".mma", "plugins");
|
|
14889
14955
|
pluginLoader.loadFromDir(globalPluginsDir, pluginManager, logger);
|
|
14890
14956
|
pluginLoader.loadFromDir(projectPluginsDir, pluginManager, logger);
|
|
14891
14957
|
contextManager.onCompact = (summary) => {
|
|
@@ -14903,13 +14969,13 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
14903
14969
|
const skipAgentsMd = noAgentsMd === true;
|
|
14904
14970
|
if (!skipAgentsMd) {
|
|
14905
14971
|
const agentsMdCandidates = [
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14972
|
+
join26(baseDir, "AGENTS.md"),
|
|
14973
|
+
join26(baseDir, ".mma", "AGENTS.md"),
|
|
14974
|
+
join26(dir, "AGENTS.md")
|
|
14909
14975
|
];
|
|
14910
14976
|
for (const p of agentsMdCandidates) {
|
|
14911
|
-
if (
|
|
14912
|
-
const content =
|
|
14977
|
+
if (existsSync33(p)) {
|
|
14978
|
+
const content = readFileSync21(p, "utf-8").trim();
|
|
14913
14979
|
if (content) {
|
|
14914
14980
|
agentsMdBlocks.push({
|
|
14915
14981
|
content,
|
|
@@ -15742,14 +15808,14 @@ async function runSetup() {
|
|
|
15742
15808
|
|
|
15743
15809
|
// src/cli/commands.ts
|
|
15744
15810
|
init_i18n();
|
|
15745
|
-
import { join as
|
|
15811
|
+
import { join as join28, dirname as dirname9 } from "path";
|
|
15746
15812
|
import { homedir as homedir13 } from "os";
|
|
15747
|
-
import { existsSync as
|
|
15813
|
+
import { existsSync as existsSync34, readFileSync as readFileSync22 } from "fs";
|
|
15748
15814
|
|
|
15749
15815
|
// src/cli/security-commands.ts
|
|
15750
15816
|
init_bootstrap();
|
|
15751
15817
|
init_config();
|
|
15752
|
-
import { join as
|
|
15818
|
+
import { join as join27 } from "path";
|
|
15753
15819
|
import { homedir as homedir12 } from "os";
|
|
15754
15820
|
|
|
15755
15821
|
// src/modules/security/security-policies.ts
|
|
@@ -16251,7 +16317,7 @@ function createSecurityCommand(program2) {
|
|
|
16251
16317
|
}
|
|
16252
16318
|
});
|
|
16253
16319
|
securityCmd.command("set-policy").argument("<preset>", t("cli.security.preset")).description(t("cli.security.set_policy")).action(async (preset) => {
|
|
16254
|
-
const configPath =
|
|
16320
|
+
const configPath = join27(homedir12(), ".mma", "config.json");
|
|
16255
16321
|
const { config: appConfig } = await bootstrap();
|
|
16256
16322
|
const validPresets = ["strict", "balanced", "permissive"];
|
|
16257
16323
|
if (!validPresets.includes(preset)) {
|
|
@@ -16266,7 +16332,7 @@ function createSecurityCommand(program2) {
|
|
|
16266
16332
|
console.log(t("cli.security.policy_description", { description: policy.description }));
|
|
16267
16333
|
});
|
|
16268
16334
|
securityCmd.command("enable-encryption").description(t("cli.security.enable_encryption")).action(async () => {
|
|
16269
|
-
const configPath =
|
|
16335
|
+
const configPath = join27(homedir12(), ".mma", "config.json");
|
|
16270
16336
|
const { config: appConfig } = await bootstrap();
|
|
16271
16337
|
appConfig.security = appConfig.security || {};
|
|
16272
16338
|
appConfig.security.sessionEncryption = {
|
|
@@ -16278,7 +16344,7 @@ function createSecurityCommand(program2) {
|
|
|
16278
16344
|
console.log(t("cli.security.encryption_enabled"));
|
|
16279
16345
|
});
|
|
16280
16346
|
securityCmd.command("disable-encryption").description(t("cli.security.disable_encryption")).action(async () => {
|
|
16281
|
-
const configPath =
|
|
16347
|
+
const configPath = join27(homedir12(), ".mma", "config.json");
|
|
16282
16348
|
const { config: appConfig } = await bootstrap();
|
|
16283
16349
|
appConfig.security = appConfig.security || {};
|
|
16284
16350
|
appConfig.security.sessionEncryption = {
|
|
@@ -16290,7 +16356,7 @@ function createSecurityCommand(program2) {
|
|
|
16290
16356
|
console.log(t("cli.security.encryption_disabled"));
|
|
16291
16357
|
});
|
|
16292
16358
|
securityCmd.command("enable-audit").description(t("cli.security.enable_audit")).action(async () => {
|
|
16293
|
-
const configPath =
|
|
16359
|
+
const configPath = join27(homedir12(), ".mma", "config.json");
|
|
16294
16360
|
const { config: appConfig } = await bootstrap();
|
|
16295
16361
|
appConfig.security = appConfig.security || {};
|
|
16296
16362
|
appConfig.security.auditNotifier = {
|
|
@@ -16304,7 +16370,7 @@ function createSecurityCommand(program2) {
|
|
|
16304
16370
|
console.log(t("cli.security.audit_enabled"));
|
|
16305
16371
|
});
|
|
16306
16372
|
securityCmd.command("disable-audit").description(t("cli.security.disable_audit")).action(async () => {
|
|
16307
|
-
const configPath =
|
|
16373
|
+
const configPath = join27(homedir12(), ".mma", "config.json");
|
|
16308
16374
|
const { config: appConfig } = await bootstrap();
|
|
16309
16375
|
appConfig.security = appConfig.security || {};
|
|
16310
16376
|
appConfig.security.auditNotifier = {
|
|
@@ -16338,14 +16404,14 @@ function createSecurityCommand(program2) {
|
|
|
16338
16404
|
// src/cli/commands.ts
|
|
16339
16405
|
import { fileURLToPath } from "url";
|
|
16340
16406
|
function readVersion() {
|
|
16341
|
-
const here =
|
|
16407
|
+
const here = dirname9(fileURLToPath(import.meta.url));
|
|
16342
16408
|
const candidates = [
|
|
16343
|
-
|
|
16344
|
-
|
|
16409
|
+
join28(here, "..", "..", "package.json"),
|
|
16410
|
+
join28(here, "..", "package.json")
|
|
16345
16411
|
];
|
|
16346
16412
|
for (const p of candidates) {
|
|
16347
|
-
if (
|
|
16348
|
-
const raw = JSON.parse(
|
|
16413
|
+
if (existsSync34(p)) {
|
|
16414
|
+
const raw = JSON.parse(readFileSync22(p, "utf8"));
|
|
16349
16415
|
if (raw.version)
|
|
16350
16416
|
return raw.version;
|
|
16351
16417
|
}
|
|
@@ -16357,7 +16423,7 @@ function createProgram() {
|
|
|
16357
16423
|
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"));
|
|
16358
16424
|
program2.command("init").description(t("cli.init")).action(async () => {
|
|
16359
16425
|
const answers = await runSetup();
|
|
16360
|
-
const configPath =
|
|
16426
|
+
const configPath = join28(homedir13(), ".mma", "config.json");
|
|
16361
16427
|
const { config } = await bootstrap();
|
|
16362
16428
|
config.provider.type = answers.provider;
|
|
16363
16429
|
config.provider.baseUrl = answers.apiBase;
|
|
@@ -16371,7 +16437,7 @@ function createProgram() {
|
|
|
16371
16437
|
});
|
|
16372
16438
|
const configCmd = program2.command("config").description(t("cli.manage_config"));
|
|
16373
16439
|
configCmd.command("set").argument("<key>", t("cli.config_key")).argument("<value>", "Config value").description(t("cli.set_value")).action(async (key, value) => {
|
|
16374
|
-
const configPath =
|
|
16440
|
+
const configPath = join28(homedir13(), ".mma", "config.json");
|
|
16375
16441
|
const { config } = await bootstrap();
|
|
16376
16442
|
const keys = key.split(".");
|
|
16377
16443
|
let obj = config;
|
|
@@ -16431,14 +16497,14 @@ function createProgram() {
|
|
|
16431
16497
|
console.log(t("cli.model_hint"));
|
|
16432
16498
|
});
|
|
16433
16499
|
model.command("use").argument("<name>", "Model name").description(t("cli.set_model")).action(async (name) => {
|
|
16434
|
-
const configPath =
|
|
16500
|
+
const configPath = join28(homedir13(), ".mma", "config.json");
|
|
16435
16501
|
const { config } = await bootstrap();
|
|
16436
16502
|
config.model = name;
|
|
16437
16503
|
saveConfig(config, configPath);
|
|
16438
16504
|
console.log(t("cli.model_set", { name }));
|
|
16439
16505
|
});
|
|
16440
16506
|
program2.command("context").description(t("cli.manage_context")).argument("<size>", "Context window size in tokens").action(async (size) => {
|
|
16441
|
-
const configPath =
|
|
16507
|
+
const configPath = join28(homedir13(), ".mma", "config.json");
|
|
16442
16508
|
const { config } = await bootstrap();
|
|
16443
16509
|
const contextWindow = parseInt(size, 10);
|
|
16444
16510
|
if (isNaN(contextWindow) || contextWindow < 1024) {
|
|
@@ -16456,7 +16522,7 @@ function createProgram() {
|
|
|
16456
16522
|
console.log(t("cli.base_url"), config.provider.baseUrl);
|
|
16457
16523
|
});
|
|
16458
16524
|
provider.command("use").argument("<name>", "Provider name").description(t("cli.set_provider")).action(async (name) => {
|
|
16459
|
-
const configPath =
|
|
16525
|
+
const configPath = join28(homedir13(), ".mma", "config.json");
|
|
16460
16526
|
const { config } = await bootstrap();
|
|
16461
16527
|
config.provider.type = name;
|
|
16462
16528
|
saveConfig(config, configPath);
|
|
@@ -16508,8 +16574,8 @@ init_bootstrap();
|
|
|
16508
16574
|
// src/cli/repl.ts
|
|
16509
16575
|
init_colors();
|
|
16510
16576
|
import * as readline3 from "readline";
|
|
16511
|
-
import { existsSync as
|
|
16512
|
-
import { join as
|
|
16577
|
+
import { existsSync as existsSync35, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "fs";
|
|
16578
|
+
import { join as join29, dirname as dirname10 } from "path";
|
|
16513
16579
|
import { homedir as homedir14 } from "os";
|
|
16514
16580
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
16515
16581
|
|
|
@@ -16957,14 +17023,14 @@ init_table();
|
|
|
16957
17023
|
init_i18n();
|
|
16958
17024
|
init_config();
|
|
16959
17025
|
function readVersion2() {
|
|
16960
|
-
const here =
|
|
17026
|
+
const here = dirname10(fileURLToPath2(import.meta.url));
|
|
16961
17027
|
const candidates = [
|
|
16962
|
-
|
|
16963
|
-
|
|
17028
|
+
join29(here, "..", "..", "package.json"),
|
|
17029
|
+
join29(here, "..", "package.json")
|
|
16964
17030
|
];
|
|
16965
17031
|
for (const p of candidates) {
|
|
16966
|
-
if (
|
|
16967
|
-
const raw = JSON.parse(
|
|
17032
|
+
if (existsSync35(p)) {
|
|
17033
|
+
const raw = JSON.parse(readFileSync23(p, "utf8"));
|
|
16968
17034
|
if (raw.version)
|
|
16969
17035
|
return raw.version;
|
|
16970
17036
|
}
|
|
@@ -17028,10 +17094,10 @@ class Repl {
|
|
|
17028
17094
|
this.sessionManager = sessionManager;
|
|
17029
17095
|
this.skillsModule = skillsModule;
|
|
17030
17096
|
this.pluginManager = pluginManager;
|
|
17031
|
-
this.configDir = configDir ||
|
|
17097
|
+
this.configDir = configDir || join29(homedir14(), ".mma");
|
|
17032
17098
|
this.baseDir = baseDir || process.cwd();
|
|
17033
17099
|
this.noAgentsMd = noAgentsMd === true;
|
|
17034
|
-
this.historyPath =
|
|
17100
|
+
this.historyPath = join29(homedir14(), ".mma", "repl-history");
|
|
17035
17101
|
this.loadHistory();
|
|
17036
17102
|
this.registerBuiltinCommands();
|
|
17037
17103
|
this.registerMmaCommands();
|
|
@@ -17055,9 +17121,9 @@ class Repl {
|
|
|
17055
17121
|
this.setupListeners();
|
|
17056
17122
|
}
|
|
17057
17123
|
loadHistory() {
|
|
17058
|
-
if (
|
|
17124
|
+
if (existsSync35(this.historyPath)) {
|
|
17059
17125
|
try {
|
|
17060
|
-
const raw =
|
|
17126
|
+
const raw = readFileSync23(this.historyPath, "utf-8");
|
|
17061
17127
|
this.history = raw.split(`
|
|
17062
17128
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
17063
17129
|
} catch {
|
|
@@ -17067,7 +17133,7 @@ class Repl {
|
|
|
17067
17133
|
}
|
|
17068
17134
|
saveHistory() {
|
|
17069
17135
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
17070
|
-
|
|
17136
|
+
writeFileSync15(this.historyPath, allHistory.join(`
|
|
17071
17137
|
`), "utf-8");
|
|
17072
17138
|
}
|
|
17073
17139
|
registerBuiltinCommands() {
|
|
@@ -17120,7 +17186,7 @@ class Repl {
|
|
|
17120
17186
|
}
|
|
17121
17187
|
try {
|
|
17122
17188
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
17123
|
-
const { existsSync:
|
|
17189
|
+
const { existsSync: existsSync36 } = await import("fs");
|
|
17124
17190
|
const { resolve: resolve16 } = await import("path");
|
|
17125
17191
|
let dataUrl;
|
|
17126
17192
|
let label;
|
|
@@ -17140,7 +17206,7 @@ class Repl {
|
|
|
17140
17206
|
label = source;
|
|
17141
17207
|
} else {
|
|
17142
17208
|
const absPath = resolve16(process.cwd(), source);
|
|
17143
|
-
if (!
|
|
17209
|
+
if (!existsSync36(absPath)) {
|
|
17144
17210
|
console.log(pc.red(t("image.not_found", { path: source })));
|
|
17145
17211
|
return;
|
|
17146
17212
|
}
|
|
@@ -17217,7 +17283,7 @@ class Repl {
|
|
|
17217
17283
|
action: async () => {
|
|
17218
17284
|
console.log(pc.yellow(t("repl.wizard_running")));
|
|
17219
17285
|
const answers = await runSetup();
|
|
17220
|
-
const configPath =
|
|
17286
|
+
const configPath = join29(homedir14(), ".mma", "config.json");
|
|
17221
17287
|
this.config.provider.type = answers.provider;
|
|
17222
17288
|
this.config.provider.baseUrl = answers.apiBase;
|
|
17223
17289
|
this.config.provider.apiKey = answers.apiKey;
|
|
@@ -17247,7 +17313,7 @@ class Repl {
|
|
|
17247
17313
|
return;
|
|
17248
17314
|
}
|
|
17249
17315
|
this.config.provider.type = name;
|
|
17250
|
-
const configPath =
|
|
17316
|
+
const configPath = join29(homedir14(), ".mma", "config.json");
|
|
17251
17317
|
saveConfig(this.config, configPath);
|
|
17252
17318
|
console.log(pc.green(t("repl.provider_set", { name })));
|
|
17253
17319
|
return;
|
|
@@ -17299,7 +17365,7 @@ class Repl {
|
|
|
17299
17365
|
return;
|
|
17300
17366
|
}
|
|
17301
17367
|
this.config.model = name;
|
|
17302
|
-
const configPath =
|
|
17368
|
+
const configPath = join29(homedir14(), ".mma", "config.json");
|
|
17303
17369
|
saveConfig(this.config, configPath);
|
|
17304
17370
|
console.log(pc.green(t("repl.model_set", { name })));
|
|
17305
17371
|
return;
|
|
@@ -17323,7 +17389,7 @@ class Repl {
|
|
|
17323
17389
|
return;
|
|
17324
17390
|
}
|
|
17325
17391
|
this.config.contextWindow = size;
|
|
17326
|
-
const configPath =
|
|
17392
|
+
const configPath = join29(homedir14(), ".mma", "config.json");
|
|
17327
17393
|
saveConfig(this.config, configPath);
|
|
17328
17394
|
console.log(pc.green(t("cli.context_set", { size })));
|
|
17329
17395
|
}
|
|
@@ -17341,9 +17407,9 @@ class Repl {
|
|
|
17341
17407
|
this.agent.shutdown();
|
|
17342
17408
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
17343
17409
|
const { homedir: homedir15 } = await import("os");
|
|
17344
|
-
const { join:
|
|
17345
|
-
const configDir =
|
|
17346
|
-
const projectConfigPath =
|
|
17410
|
+
const { join: join30 } = await import("path");
|
|
17411
|
+
const configDir = join30(homedir15(), ".mma");
|
|
17412
|
+
const projectConfigPath = join30(process.cwd(), ".mmrc");
|
|
17347
17413
|
const freshConfig = loadConfig2({ configDir, projectConfigPath });
|
|
17348
17414
|
Object.assign(this.config, freshConfig);
|
|
17349
17415
|
const { bootstrap: bootstrap2 } = await Promise.resolve().then(() => (init_bootstrap(), exports_bootstrap));
|
|
@@ -17877,11 +17943,11 @@ ${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
|
|
|
17877
17943
|
row(t("repl.agents_label"), pc.red(t("repl.disabled")));
|
|
17878
17944
|
} else {
|
|
17879
17945
|
const agentsMdCandidates = [
|
|
17880
|
-
|
|
17881
|
-
|
|
17882
|
-
|
|
17946
|
+
join29(this.baseDir, "AGENTS.md"),
|
|
17947
|
+
join29(this.baseDir, ".mma", "AGENTS.md"),
|
|
17948
|
+
join29(this.configDir, "AGENTS.md")
|
|
17883
17949
|
];
|
|
17884
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
17950
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync35(p));
|
|
17885
17951
|
if (foundAgents.length > 0) {
|
|
17886
17952
|
for (const p of foundAgents) {
|
|
17887
17953
|
row(t("repl.agents_label"), pc.dim(p));
|
|
@@ -17892,7 +17958,7 @@ ${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
|
|
|
17892
17958
|
}
|
|
17893
17959
|
const meta = this.sessionManager?.getActiveMeta();
|
|
17894
17960
|
if (meta) {
|
|
17895
|
-
const sessionPath =
|
|
17961
|
+
const sessionPath = join29(this.configDir, "sessions", meta.id);
|
|
17896
17962
|
row(t("repl.session_label"), `${pc.cyan(meta.name)} ${pc.dim(`(${meta.id.slice(0, 12)})`)} — ${meta.messageCount} msgs ${pc.dim(sessionPath)}`);
|
|
17897
17963
|
}
|
|
17898
17964
|
const headerWidth = Math.max(50, Math.min(96, process.stdout.columns || 96));
|
|
@@ -17917,8 +17983,8 @@ ${t("image.attached", { source: "clipboard", size: `${sizeKb} KB` })}`));
|
|
|
17917
17983
|
init_config();
|
|
17918
17984
|
init_i18n();
|
|
17919
17985
|
init_colors();
|
|
17920
|
-
import { existsSync as
|
|
17921
|
-
import { join as
|
|
17986
|
+
import { existsSync as existsSync36 } from "fs";
|
|
17987
|
+
import { join as join30 } from "path";
|
|
17922
17988
|
import { homedir as homedir15 } from "os";
|
|
17923
17989
|
async function main() {
|
|
17924
17990
|
const program2 = createProgram();
|
|
@@ -17982,8 +18048,8 @@ async function main() {
|
|
|
17982
18048
|
}
|
|
17983
18049
|
agent.shutdown();
|
|
17984
18050
|
} else {
|
|
17985
|
-
const configPath =
|
|
17986
|
-
if (!
|
|
18051
|
+
const configPath = join30(homedir15(), ".mma", "config.json");
|
|
18052
|
+
if (!existsSync36(configPath)) {
|
|
17987
18053
|
console.log(pc.yellow(`
|
|
17988
18054
|
` + t("cli.first_run") + `
|
|
17989
18055
|
`));
|