micro-models-agent 0.28.17 → 0.29.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/cli/commands.js +3 -116
- package/dist/cli/main.js +8 -35
- package/dist/cli/repl.js +611 -110
- package/dist/cli/setup.js +12 -32
- package/dist/config/config.js +30 -46
- package/dist/config/defaults.js +1 -10
- package/dist/config/security.js +8 -15
- package/dist/core/agent-moe.js +12 -24
- package/dist/core/agent.js +47 -281
- package/dist/core/bootstrap.js +36 -52
- package/dist/core/session-logger.js +2 -35
- package/dist/i18n/en.json +15 -79
- package/dist/i18n/index.js +9 -12
- package/dist/i18n/ru.json +15 -79
- package/dist/index.js +13 -13
- package/dist/llm/openai-compat.js +10 -39
- package/dist/logger/app-logger.js +16 -83
- package/dist/main.js +624 -243
- package/dist/modules/browser/session.js +60 -108
- package/dist/modules/context/history.js +15 -0
- package/dist/modules/context/manager.js +10 -119
- package/dist/modules/execution/auditor.js +39 -33
- package/dist/modules/execution/index.js +6 -8
- package/dist/modules/execution/module.js +32 -474
- package/dist/modules/execution/moe-executor.js +40 -97
- package/dist/modules/execution/planner.js +13 -63
- package/dist/modules/execution/stuck-detector.js +39 -252
- package/dist/modules/execution/tracker.js +7 -21
- package/dist/modules/execution/verifier.js +17 -46
- package/dist/modules/hallucination/confidence.js +2 -7
- package/dist/modules/hallucination/consistency.js +42 -8
- package/dist/modules/hallucination/detector.js +21 -26
- package/dist/modules/hallucination/factual.js +150 -170
- package/dist/modules/hallucination/index.js +4 -5
- package/dist/modules/index.js +5 -5
- package/dist/modules/mcp/client.js +2 -8
- package/dist/modules/memory/store.js +0 -4
- package/dist/modules/plugins/builtin/lint-on-write.js +38 -143
- package/dist/modules/processes/detect.js +34 -0
- package/dist/modules/processes/index.js +2 -1
- package/dist/modules/processes/registry.js +35 -125
- package/dist/modules/processes/runner.js +110 -9
- package/dist/modules/security/audit-log.js +10 -30
- package/dist/modules/security/command-validator.js +16 -42
- package/dist/modules/security/content-scanner.js +8 -9
- package/dist/modules/security/network-validator.js +2 -2
- package/dist/modules/security/path-validator.js +10 -64
- package/dist/modules/security/security-policies.js +67 -221
- package/dist/modules/security/session-encryption.js +25 -42
- package/dist/modules/session/manager.js +10 -15
- package/dist/modules/session/store.js +8 -62
- package/dist/modules/skills/index.js +3 -2
- package/dist/modules/skills/matcher.js +27 -0
- package/dist/modules/skills/module.js +23 -10
- package/dist/tools/bash.js +90 -287
- package/dist/tools/create-dir.js +1 -0
- package/dist/tools/delete-file.js +1 -0
- package/dist/tools/edit-file.js +8 -10
- package/dist/tools/executor.js +7 -57
- package/dist/tools/grep-tool.js +29 -51
- package/dist/tools/index.js +40 -55
- package/dist/tools/load-skill.js +18 -14
- package/dist/tools/move-file.js +2 -3
- package/dist/tools/pipeline-run.js +1 -1
- package/dist/tools/read-file.js +5 -15
- package/dist/tools/search-history.js +22 -42
- package/dist/tools/subagent.js +12 -21
- package/dist/tools/web-browse.js +25 -54
- package/dist/tools/web-fetch.js +34 -60
- package/dist/tools/web-search.js +20 -39
- package/dist/tools/write-file.js +10 -13
- package/dist/ui/diff.js +16 -9
- package/dist/ui/renderer.js +6 -69
- package/package.json +1 -1
- package/dist/cli/repl-commands.js +0 -633
- package/dist/core/workspace.js +0 -76
- package/dist/logger/file-log.js +0 -151
- package/dist/modules/certification/cli.js +0 -176
- package/dist/modules/certification/fact-checker.js +0 -84
- package/dist/modules/certification/loader.js +0 -111
- package/dist/modules/certification/manifest.js +0 -50
- package/dist/modules/certification/runner.js +0 -162
- package/dist/modules/certification/scenarios.js +0 -124
- package/dist/modules/certification/types.js +0 -1
- package/dist/modules/execution/plan-coverage.js +0 -68
- package/dist/modules/execution/plan-persister.js +0 -46
- package/dist/modules/execution/plan-store.js +0 -159
- package/dist/modules/hallucination/js-identifiers.js +0 -72
- package/dist/modules/hallucination/llm-judge.js +0 -103
- package/dist/modules/lsp/client.js +0 -235
- package/dist/modules/lsp/config.js +0 -81
- package/dist/modules/lsp/index.js +0 -3
- package/dist/modules/lsp/module.js +0 -68
- package/dist/modules/lsp/types.js +0 -1
package/dist/main.js
CHANGED
|
@@ -2256,6 +2256,13 @@ var init_defaults = __esm(() => {
|
|
|
2256
2256
|
skills: {
|
|
2257
2257
|
budget: 0.15
|
|
2258
2258
|
},
|
|
2259
|
+
subagent: {
|
|
2260
|
+
resultMode: "text",
|
|
2261
|
+
maxSummaryChars: 2000,
|
|
2262
|
+
artifactsDir: ".mma/artifacts",
|
|
2263
|
+
stableSystemPrompt: true,
|
|
2264
|
+
maxParallelChunkQueries: 4
|
|
2265
|
+
},
|
|
2259
2266
|
lsp: DEFAULT_LSP_CONFIG
|
|
2260
2267
|
};
|
|
2261
2268
|
});
|
|
@@ -2367,6 +2374,10 @@ var init_en = __esm(() => {
|
|
|
2367
2374
|
"tool.friendly.mcp_call": "MCP call",
|
|
2368
2375
|
"tool.truncated": "[Truncated: {tokens} tokens removed]",
|
|
2369
2376
|
"tool.subagent_queued": "Sub-agent task queued: {task}",
|
|
2377
|
+
"tool.subagent_artifact": `Sub-agent completed. Full result saved to artifact: {path}
|
|
2378
|
+
Iterations: {iterations}
|
|
2379
|
+
Summary:
|
|
2380
|
+
{summary}`,
|
|
2370
2381
|
"tool.pipeline_started": 'Pipeline "{name}" execution started. Pipeline engine is a stub — run dispatched.',
|
|
2371
2382
|
"tool.mcp_call": "MCP call: {server}/{tool} with {args}",
|
|
2372
2383
|
"tool.action_required": "Action is required.",
|
|
@@ -2387,6 +2398,8 @@ var init_en = __esm(() => {
|
|
|
2387
2398
|
"tool.question.unanswered": "Unanswered",
|
|
2388
2399
|
"tool.question.answered": "User has answered your questions: {formatted}. You can now continue with the user's answers in mind.",
|
|
2389
2400
|
"tool.name_or_task": 'Provide either "name" or "task" parameter',
|
|
2401
|
+
"tool.chunk_query_no_query": "chunk_query: a query string is required.",
|
|
2402
|
+
"tool.chunk_query_no_input": "chunk_query: provide input_path or text.",
|
|
2390
2403
|
"tool.invalid_params": "Invalid parameters",
|
|
2391
2404
|
"tool.skill_budget": 'Skill "{name}" loaded ({tokens} tokens, {remaining} remaining in skills budget). Skill content is now in system prompt — no need to reload after context compaction.',
|
|
2392
2405
|
"tool.skill_available_hint": "Available skills",
|
|
@@ -2926,6 +2939,10 @@ var init_ru = __esm(() => {
|
|
|
2926
2939
|
"tool.friendly.mcp_call": "MCP вызов",
|
|
2927
2940
|
"tool.truncated": "[Обрезано: удалено {tokens} токенов]",
|
|
2928
2941
|
"tool.subagent_queued": "Задача подагенту добавлена: {task}",
|
|
2942
|
+
"tool.subagent_artifact": `Суб-агент завершён. Полный результат сохранён в артефакт: {path}
|
|
2943
|
+
Итераций: {iterations}
|
|
2944
|
+
Сводка:
|
|
2945
|
+
{summary}`,
|
|
2929
2946
|
"tool.pipeline_started": 'Пайплайн "{name}" запущен. Движок пайплайнов — заглушка, задача отправлена.',
|
|
2930
2947
|
"tool.mcp_call": "MCP вызов: {server}/{tool} с {args}",
|
|
2931
2948
|
"tool.action_required": "Требуется действие.",
|
|
@@ -2946,6 +2963,8 @@ var init_ru = __esm(() => {
|
|
|
2946
2963
|
"tool.question.unanswered": "Без ответа",
|
|
2947
2964
|
"tool.question.answered": "Пользователь ответил на ваши вопросы: {formatted}. Теперь продолжайте с учётом ответов.",
|
|
2948
2965
|
"tool.name_or_task": 'Укажите параметр "name" или "task"',
|
|
2966
|
+
"tool.chunk_query_no_query": "chunk_query: требуется строка запроса.",
|
|
2967
|
+
"tool.chunk_query_no_input": "chunk_query: укажите input_path или text.",
|
|
2949
2968
|
"tool.invalid_params": "Неверные параметры",
|
|
2950
2969
|
"tool.skill_budget": 'Скилл "{name}" загружен ({tokens} токенов, осталось {remaining} в бюджете скиллов). Контент скилла теперь в системном промпте — перезагрузка после компрессии не нужна.',
|
|
2951
2970
|
"tool.skill_available_hint": "Доступные скиллы",
|
|
@@ -4832,12 +4851,12 @@ class OpenAICompatProvider {
|
|
|
4832
4851
|
};
|
|
4833
4852
|
this.rateLimiter = createRateLimiter(config.rateLimits);
|
|
4834
4853
|
}
|
|
4835
|
-
async* chat(messages, tools, signal) {
|
|
4854
|
+
async* chat(messages, tools, signal, options) {
|
|
4836
4855
|
if (!this.rateLimiter.canMakeRequest()) {
|
|
4837
4856
|
throw new Error(`Rate limit exceeded: ${this.rateLimiter.getConfig().maxRequestsPerMinute} requests per minute`);
|
|
4838
4857
|
}
|
|
4839
4858
|
this.rateLimiter.recordRequest();
|
|
4840
|
-
const streamResult = this.doStream(messages, tools, signal);
|
|
4859
|
+
const streamResult = this.doStream(messages, tools, signal, options);
|
|
4841
4860
|
let hasToolCall = false;
|
|
4842
4861
|
let hasText = false;
|
|
4843
4862
|
let reasoningAcc = "";
|
|
@@ -4852,19 +4871,22 @@ class OpenAICompatProvider {
|
|
|
4852
4871
|
yield chunk;
|
|
4853
4872
|
}
|
|
4854
4873
|
if (!hasToolCall && !hasText) {
|
|
4855
|
-
const fallback = await this.doNonStreaming(messages, tools, signal);
|
|
4874
|
+
const fallback = await this.doNonStreaming(messages, tools, signal, options);
|
|
4856
4875
|
for (const chunk of fallback) {
|
|
4857
4876
|
yield chunk;
|
|
4858
4877
|
}
|
|
4859
4878
|
}
|
|
4860
4879
|
}
|
|
4861
|
-
async* doStream(messages, tools, signal) {
|
|
4880
|
+
async* doStream(messages, tools, signal, options) {
|
|
4862
4881
|
const body = {
|
|
4863
4882
|
model: this.model,
|
|
4864
4883
|
messages,
|
|
4865
4884
|
stream: true,
|
|
4866
|
-
max_tokens: this.config.maxCompletionTokens ?? 4096
|
|
4885
|
+
max_tokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096
|
|
4867
4886
|
};
|
|
4887
|
+
if (options?.reasoningEffort) {
|
|
4888
|
+
body.reasoning_effort = options.reasoningEffort;
|
|
4889
|
+
}
|
|
4868
4890
|
if (tools && tools.length > 0) {
|
|
4869
4891
|
body.tools = tools.map((t2) => ({
|
|
4870
4892
|
type: "function",
|
|
@@ -5000,13 +5022,16 @@ class OpenAICompatProvider {
|
|
|
5000
5022
|
reader.releaseLock();
|
|
5001
5023
|
}
|
|
5002
5024
|
}
|
|
5003
|
-
async doNonStreaming(messages, tools, signal) {
|
|
5025
|
+
async doNonStreaming(messages, tools, signal, options) {
|
|
5004
5026
|
const body = {
|
|
5005
5027
|
model: this.model,
|
|
5006
5028
|
messages,
|
|
5007
5029
|
stream: false,
|
|
5008
|
-
max_tokens: this.config.maxCompletionTokens ?? 4096
|
|
5030
|
+
max_tokens: options?.maxTokens ?? this.config.maxCompletionTokens ?? 4096
|
|
5009
5031
|
};
|
|
5032
|
+
if (options?.reasoningEffort) {
|
|
5033
|
+
body.reasoning_effort = options.reasoningEffort;
|
|
5034
|
+
}
|
|
5010
5035
|
if (tools && tools.length > 0) {
|
|
5011
5036
|
body.tools = tools.map((t2) => ({
|
|
5012
5037
|
type: "function",
|
|
@@ -5354,14 +5379,15 @@ class ToolExecutor {
|
|
|
5354
5379
|
if (tool.interactive) {
|
|
5355
5380
|
result = await tool.handler(this.ctx, call.arguments);
|
|
5356
5381
|
} else {
|
|
5382
|
+
const timeoutMs = tool.timeoutMs ?? TOOL_EXECUTION_TIMEOUT_MS;
|
|
5357
5383
|
const timeoutPromise = new Promise((_, reject) => {
|
|
5358
5384
|
setTimeout(() => {
|
|
5359
5385
|
killByCallId(call.id);
|
|
5360
5386
|
reject(new Error(t("tool.timeout", {
|
|
5361
5387
|
name: call.name,
|
|
5362
|
-
seconds:
|
|
5388
|
+
seconds: Math.round(timeoutMs / 1000)
|
|
5363
5389
|
})));
|
|
5364
|
-
},
|
|
5390
|
+
}, timeoutMs);
|
|
5365
5391
|
});
|
|
5366
5392
|
const racePromises = [
|
|
5367
5393
|
tool.handler(this.ctx, call.arguments),
|
|
@@ -7084,18 +7110,28 @@ function decodeLineToUtf8(buf) {
|
|
|
7084
7110
|
}
|
|
7085
7111
|
return buf.toString("latin1");
|
|
7086
7112
|
}
|
|
7113
|
+
function sleepSync(ms) {
|
|
7114
|
+
try {
|
|
7115
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
7116
|
+
} catch {}
|
|
7117
|
+
}
|
|
7118
|
+
function taskkillPid(pid) {
|
|
7119
|
+
try {
|
|
7120
|
+
spawnSync("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
7121
|
+
windowsHide: true,
|
|
7122
|
+
stdio: "ignore",
|
|
7123
|
+
timeout: 5000
|
|
7124
|
+
});
|
|
7125
|
+
} catch {}
|
|
7126
|
+
}
|
|
7087
7127
|
function killTree(child) {
|
|
7088
7128
|
const pid = child.pid;
|
|
7089
7129
|
if (!pid)
|
|
7090
7130
|
return;
|
|
7091
7131
|
if (platform() === "win32") {
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
stdio: "ignore",
|
|
7096
|
-
timeout: 3000
|
|
7097
|
-
});
|
|
7098
|
-
} catch {}
|
|
7132
|
+
taskkillPid(pid);
|
|
7133
|
+
sleepSync(150);
|
|
7134
|
+
taskkillPid(pid);
|
|
7099
7135
|
return;
|
|
7100
7136
|
}
|
|
7101
7137
|
try {
|
|
@@ -9424,6 +9460,59 @@ var init_stuck_detector = __esm(() => {
|
|
|
9424
9460
|
init_i18n();
|
|
9425
9461
|
});
|
|
9426
9462
|
|
|
9463
|
+
// src/modules/artifacts/store.ts
|
|
9464
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
|
|
9465
|
+
import { resolve as resolve10, relative, isAbsolute } from "node:path";
|
|
9466
|
+
|
|
9467
|
+
class ArtifactStore {
|
|
9468
|
+
root;
|
|
9469
|
+
constructor(opts) {
|
|
9470
|
+
const artifactsDir = opts.artifactsDir || ".mma/artifacts";
|
|
9471
|
+
this.root = resolve10(opts.baseDir, artifactsDir, opts.sessionId);
|
|
9472
|
+
}
|
|
9473
|
+
static sanitizeName(name) {
|
|
9474
|
+
const stripped = name.replace(/^(\.\.?[\\/])+/g, "").replace(/^\.{1,2}$/, "");
|
|
9475
|
+
const cleaned = stripped.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/_{2,}/g, "_").replace(/^_+|_+$/g, "");
|
|
9476
|
+
if (cleaned === "" || cleaned === "." || cleaned === "..") {
|
|
9477
|
+
return "artifact";
|
|
9478
|
+
}
|
|
9479
|
+
return cleaned;
|
|
9480
|
+
}
|
|
9481
|
+
static isInside(root, candidate) {
|
|
9482
|
+
const rel = relative(root, candidate);
|
|
9483
|
+
if (rel === "")
|
|
9484
|
+
return true;
|
|
9485
|
+
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
9486
|
+
}
|
|
9487
|
+
save(name, content, ext = "md") {
|
|
9488
|
+
const safe = ArtifactStore.sanitizeName(name);
|
|
9489
|
+
const dir = resolve10(this.root);
|
|
9490
|
+
mkdirSync11(dir, { recursive: true });
|
|
9491
|
+
const abs = resolve10(dir, `${safe}.${ext}`);
|
|
9492
|
+
if (!ArtifactStore.isInside(dir, abs)) {
|
|
9493
|
+
throw new Error(`Artifact path escapes root: ${abs}`);
|
|
9494
|
+
}
|
|
9495
|
+
writeFileSync7(abs, content, "utf8");
|
|
9496
|
+
return abs;
|
|
9497
|
+
}
|
|
9498
|
+
read(path) {
|
|
9499
|
+
const abs = resolve10(this.root, path);
|
|
9500
|
+
if (!ArtifactStore.isInside(this.root, abs))
|
|
9501
|
+
return null;
|
|
9502
|
+
if (!existsSync18(abs))
|
|
9503
|
+
return null;
|
|
9504
|
+
return readFileSync9(abs, "utf8");
|
|
9505
|
+
}
|
|
9506
|
+
summary(content, maxChars) {
|
|
9507
|
+
if (content.length <= maxChars)
|
|
9508
|
+
return content;
|
|
9509
|
+
const head = content.slice(0, maxChars).trimEnd();
|
|
9510
|
+
return `${head}
|
|
9511
|
+
…[truncated: ${content.length - maxChars} chars]`;
|
|
9512
|
+
}
|
|
9513
|
+
}
|
|
9514
|
+
var init_store = () => {};
|
|
9515
|
+
|
|
9427
9516
|
// src/modules/execution/moe-executor.ts
|
|
9428
9517
|
function isTransientError(error) {
|
|
9429
9518
|
return TRANSIENT_ERROR_PATTERNS.some((p) => error.includes(p));
|
|
@@ -9515,14 +9604,38 @@ ${(subtask.success_criteria || []).map((c) => `- ${c}`).join(`
|
|
|
9515
9604
|
read_only_files: readOnlyFiles,
|
|
9516
9605
|
tool_tags: expertConfig.tool_tags
|
|
9517
9606
|
};
|
|
9607
|
+
if (deps.config.subagent?.resultMode === "file") {
|
|
9608
|
+
subagentArgs.result_mode = "file";
|
|
9609
|
+
subagentArgs.artifact_name = subtask.id;
|
|
9610
|
+
}
|
|
9518
9611
|
const result = await subagentTool.handler({
|
|
9519
9612
|
config: deps.config,
|
|
9520
9613
|
baseDir: deps.baseDir,
|
|
9521
9614
|
logger: deps.logger,
|
|
9522
9615
|
llmProvider: deps.llmProvider,
|
|
9523
|
-
toolExecutor: deps.toolExecutor
|
|
9616
|
+
toolExecutor: deps.toolExecutor,
|
|
9617
|
+
sessionId: "moe"
|
|
9524
9618
|
}, subagentArgs);
|
|
9525
9619
|
if (result.success) {
|
|
9620
|
+
if (deps.config.subagent?.resultMode === "file") {
|
|
9621
|
+
const pathMatch = result.output.match(/saved to artifact: (.+)/);
|
|
9622
|
+
const abs = pathMatch ? pathMatch[1].trim() : "";
|
|
9623
|
+
if (abs) {
|
|
9624
|
+
const store = new ArtifactStore({
|
|
9625
|
+
baseDir: deps.baseDir,
|
|
9626
|
+
sessionId: "moe"
|
|
9627
|
+
});
|
|
9628
|
+
const full = store.read(abs.split(/[\\/]/).pop() || "");
|
|
9629
|
+
deps.logger.debug(`MoE subtask "${subtask.id}" attached artifact ${abs} (${full?.length ?? 0} chars) to Router`);
|
|
9630
|
+
return {
|
|
9631
|
+
subtaskId: subtask.id,
|
|
9632
|
+
success: true,
|
|
9633
|
+
summary: `Artifact: ${abs}`,
|
|
9634
|
+
result: full ?? result.output,
|
|
9635
|
+
durationMs: Date.now() - startTime
|
|
9636
|
+
};
|
|
9637
|
+
}
|
|
9638
|
+
}
|
|
9526
9639
|
return {
|
|
9527
9640
|
subtaskId: subtask.id,
|
|
9528
9641
|
success: true,
|
|
@@ -9682,6 +9795,7 @@ var TRANSIENT_ERROR_PATTERNS;
|
|
|
9682
9795
|
var init_moe_executor = __esm(() => {
|
|
9683
9796
|
init_stuck_detector();
|
|
9684
9797
|
init_i18n();
|
|
9798
|
+
init_store();
|
|
9685
9799
|
TRANSIENT_ERROR_PATTERNS = [
|
|
9686
9800
|
"timeout",
|
|
9687
9801
|
"Timeout",
|
|
@@ -9701,8 +9815,8 @@ var init_moe_executor = __esm(() => {
|
|
|
9701
9815
|
});
|
|
9702
9816
|
|
|
9703
9817
|
// src/modules/execution/verifier.ts
|
|
9704
|
-
import { existsSync as
|
|
9705
|
-
import { resolve as
|
|
9818
|
+
import { existsSync as existsSync19 } from "fs";
|
|
9819
|
+
import { resolve as resolve11, extname as extname2 } from "path";
|
|
9706
9820
|
import { spawn as spawn2 } from "child_process";
|
|
9707
9821
|
|
|
9708
9822
|
class StepVerifier {
|
|
@@ -9711,8 +9825,8 @@ class StepVerifier {
|
|
|
9711
9825
|
this.baseDir = baseDir;
|
|
9712
9826
|
}
|
|
9713
9827
|
async checkFileExists(path) {
|
|
9714
|
-
const resolved =
|
|
9715
|
-
const exists =
|
|
9828
|
+
const resolved = resolve11(this.baseDir, path);
|
|
9829
|
+
const exists = existsSync19(resolved);
|
|
9716
9830
|
return {
|
|
9717
9831
|
passed: exists,
|
|
9718
9832
|
message: exists ? t("verify.file_exists", { path }) : t("verify.file_not_found", { path })
|
|
@@ -9727,8 +9841,8 @@ class StepVerifier {
|
|
|
9727
9841
|
}
|
|
9728
9842
|
}
|
|
9729
9843
|
async runTypeCheck() {
|
|
9730
|
-
const tsconfigPath =
|
|
9731
|
-
if (!
|
|
9844
|
+
const tsconfigPath = resolve11(this.baseDir, "tsconfig.json");
|
|
9845
|
+
if (!existsSync19(tsconfigPath)) {
|
|
9732
9846
|
return { passed: true, message: "No tsconfig.json found — skipping type check" };
|
|
9733
9847
|
}
|
|
9734
9848
|
try {
|
|
@@ -9740,8 +9854,8 @@ class StepVerifier {
|
|
|
9740
9854
|
}
|
|
9741
9855
|
}
|
|
9742
9856
|
async runTests() {
|
|
9743
|
-
const pkgPath =
|
|
9744
|
-
if (!
|
|
9857
|
+
const pkgPath = resolve11(this.baseDir, "package.json");
|
|
9858
|
+
if (!existsSync19(pkgPath)) {
|
|
9745
9859
|
return { passed: true, message: "No package.json found — skipping tests" };
|
|
9746
9860
|
}
|
|
9747
9861
|
try {
|
|
@@ -9793,7 +9907,7 @@ class StepVerifier {
|
|
|
9793
9907
|
const result = await this.checkFileExists(filePath);
|
|
9794
9908
|
results.push(result);
|
|
9795
9909
|
if (result.passed) {
|
|
9796
|
-
const fullPath =
|
|
9910
|
+
const fullPath = resolve11(this.baseDir, filePath);
|
|
9797
9911
|
if (!await this.validateSyntax(fullPath)) {
|
|
9798
9912
|
syntaxValid = false;
|
|
9799
9913
|
results.push({ passed: false, message: t("verify.syntax_error", { path: filePath }) });
|
|
@@ -9834,7 +9948,7 @@ class StepVerifier {
|
|
|
9834
9948
|
return true;
|
|
9835
9949
|
}
|
|
9836
9950
|
runAsync(command, cwd, timeoutMs) {
|
|
9837
|
-
return new Promise((
|
|
9951
|
+
return new Promise((resolve12, reject) => {
|
|
9838
9952
|
const child = spawn2(command, {
|
|
9839
9953
|
cwd,
|
|
9840
9954
|
shell: true,
|
|
@@ -9860,7 +9974,7 @@ class StepVerifier {
|
|
|
9860
9974
|
child.on("close", (code) => {
|
|
9861
9975
|
clearTimeout(timer);
|
|
9862
9976
|
if (code === 0) {
|
|
9863
|
-
|
|
9977
|
+
resolve12({ stdout, stderr });
|
|
9864
9978
|
} else {
|
|
9865
9979
|
const err = new Error(`Command failed with exit code ${code}`);
|
|
9866
9980
|
err.stdout = stdout;
|
|
@@ -9991,7 +10105,7 @@ var init_agent_moe = __esm(() => {
|
|
|
9991
10105
|
});
|
|
9992
10106
|
|
|
9993
10107
|
// src/modules/memory/search.ts
|
|
9994
|
-
import { readFileSync as
|
|
10108
|
+
import { readFileSync as readFileSync10, existsSync as existsSync20 } from "fs";
|
|
9995
10109
|
import { join as join10 } from "path";
|
|
9996
10110
|
|
|
9997
10111
|
class MemorySearch {
|
|
@@ -10004,9 +10118,9 @@ class MemorySearch {
|
|
|
10004
10118
|
const lowerQuery = query.toLowerCase();
|
|
10005
10119
|
for (const name of MEMORY_FILES) {
|
|
10006
10120
|
const path = join10(this.memoryDir, `${name}.md`);
|
|
10007
|
-
if (!
|
|
10121
|
+
if (!existsSync20(path))
|
|
10008
10122
|
continue;
|
|
10009
|
-
const content =
|
|
10123
|
+
const content = readFileSync10(path, "utf-8");
|
|
10010
10124
|
const lines = content.split(`
|
|
10011
10125
|
`);
|
|
10012
10126
|
for (const line of lines) {
|
|
@@ -10016,9 +10130,9 @@ class MemorySearch {
|
|
|
10016
10130
|
}
|
|
10017
10131
|
}
|
|
10018
10132
|
const prefsPath = join10(this.memoryDir, "preferences.json");
|
|
10019
|
-
if (
|
|
10133
|
+
if (existsSync20(prefsPath)) {
|
|
10020
10134
|
try {
|
|
10021
|
-
const prefs = JSON.parse(
|
|
10135
|
+
const prefs = JSON.parse(readFileSync10(prefsPath, "utf-8"));
|
|
10022
10136
|
for (const [key, value] of Object.entries(prefs)) {
|
|
10023
10137
|
const searchStr = `${key}=${value}`;
|
|
10024
10138
|
if (searchStr.toLowerCase().includes(lowerQuery)) {
|
|
@@ -10036,7 +10150,7 @@ var init_search = __esm(() => {
|
|
|
10036
10150
|
});
|
|
10037
10151
|
|
|
10038
10152
|
// src/modules/memory/store.ts
|
|
10039
|
-
import { readFileSync as
|
|
10153
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, appendFileSync as appendFileSync5, existsSync as existsSync21, mkdirSync as mkdirSync12 } from "fs";
|
|
10040
10154
|
import { join as join11 } from "path";
|
|
10041
10155
|
|
|
10042
10156
|
class MemoryStore {
|
|
@@ -10046,23 +10160,23 @@ class MemoryStore {
|
|
|
10046
10160
|
this.ensureDir();
|
|
10047
10161
|
for (const name of MEMORY_FILES2) {
|
|
10048
10162
|
const path = join11(this.memoryDir, `${name}.md`);
|
|
10049
|
-
if (!
|
|
10050
|
-
|
|
10163
|
+
if (!existsSync21(path)) {
|
|
10164
|
+
writeFileSync8(path, `# ${name.charAt(0).toUpperCase() + name.slice(1)}
|
|
10051
10165
|
|
|
10052
10166
|
`, "utf-8");
|
|
10053
10167
|
}
|
|
10054
10168
|
}
|
|
10055
10169
|
}
|
|
10056
10170
|
ensureDir() {
|
|
10057
|
-
if (!
|
|
10058
|
-
|
|
10171
|
+
if (!existsSync21(this.memoryDir)) {
|
|
10172
|
+
mkdirSync12(this.memoryDir, { recursive: true });
|
|
10059
10173
|
}
|
|
10060
10174
|
}
|
|
10061
10175
|
read(name) {
|
|
10062
10176
|
const path = join11(this.memoryDir, `${name}.md`);
|
|
10063
|
-
if (!
|
|
10177
|
+
if (!existsSync21(path))
|
|
10064
10178
|
return "";
|
|
10065
|
-
return
|
|
10179
|
+
return readFileSync11(path, "utf-8");
|
|
10066
10180
|
}
|
|
10067
10181
|
append(name, entry) {
|
|
10068
10182
|
const path = join11(this.memoryDir, `${name}.md`);
|
|
@@ -10080,10 +10194,10 @@ class MemoryStore {
|
|
|
10080
10194
|
}
|
|
10081
10195
|
getPreferences() {
|
|
10082
10196
|
const path = this.prefsPath();
|
|
10083
|
-
if (!
|
|
10197
|
+
if (!existsSync21(path))
|
|
10084
10198
|
return {};
|
|
10085
10199
|
try {
|
|
10086
|
-
return JSON.parse(
|
|
10200
|
+
return JSON.parse(readFileSync11(path, "utf-8"));
|
|
10087
10201
|
} catch {
|
|
10088
10202
|
return {};
|
|
10089
10203
|
}
|
|
@@ -10091,14 +10205,14 @@ class MemoryStore {
|
|
|
10091
10205
|
setPreference(key, value) {
|
|
10092
10206
|
const prefs = this.getPreferences();
|
|
10093
10207
|
prefs[key] = value;
|
|
10094
|
-
|
|
10208
|
+
writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
10095
10209
|
}
|
|
10096
10210
|
deletePreference(key) {
|
|
10097
10211
|
const prefs = this.getPreferences();
|
|
10098
10212
|
if (!(key in prefs))
|
|
10099
10213
|
return false;
|
|
10100
10214
|
delete prefs[key];
|
|
10101
|
-
|
|
10215
|
+
writeFileSync8(this.prefsPath(), JSON.stringify(prefs, null, 2), "utf-8");
|
|
10102
10216
|
return true;
|
|
10103
10217
|
}
|
|
10104
10218
|
appendRule(category, pattern, cause, solution) {
|
|
@@ -10109,7 +10223,7 @@ class MemoryStore {
|
|
|
10109
10223
|
}
|
|
10110
10224
|
}
|
|
10111
10225
|
var MEMORY_FILES2;
|
|
10112
|
-
var
|
|
10226
|
+
var init_store2 = __esm(() => {
|
|
10113
10227
|
init_search();
|
|
10114
10228
|
MEMORY_FILES2 = ["conventions", "decisions", "errors", "facts"];
|
|
10115
10229
|
});
|
|
@@ -10784,7 +10898,7 @@ var init_agent = __esm(() => {
|
|
|
10784
10898
|
init_processes();
|
|
10785
10899
|
init_session_logger();
|
|
10786
10900
|
init_agent_moe();
|
|
10787
|
-
|
|
10901
|
+
init_store2();
|
|
10788
10902
|
init_verifier();
|
|
10789
10903
|
});
|
|
10790
10904
|
|
|
@@ -11244,8 +11358,8 @@ var init_js_identifiers = __esm(() => {
|
|
|
11244
11358
|
});
|
|
11245
11359
|
|
|
11246
11360
|
// src/modules/hallucination/factual.ts
|
|
11247
|
-
import { existsSync as
|
|
11248
|
-
import { resolve as
|
|
11361
|
+
import { existsSync as existsSync22, readdirSync as readdirSync5 } from "fs";
|
|
11362
|
+
import { resolve as resolve12, isAbsolute as isAbsolute2, join as join13 } from "path";
|
|
11249
11363
|
function looksLikeFilePath(s) {
|
|
11250
11364
|
const lower = s.toLowerCase();
|
|
11251
11365
|
if (TECH_NAMES.has(lower))
|
|
@@ -11290,15 +11404,15 @@ class FactualCheck {
|
|
|
11290
11404
|
return { status: "pass" };
|
|
11291
11405
|
}
|
|
11292
11406
|
pathExists(fp) {
|
|
11293
|
-
if (
|
|
11294
|
-
return
|
|
11407
|
+
if (isAbsolute2(fp))
|
|
11408
|
+
return existsSync22(fp);
|
|
11295
11409
|
if (!fp.includes("/") && !fp.includes("\\")) {
|
|
11296
11410
|
return this.bareNameExists(fp);
|
|
11297
11411
|
}
|
|
11298
|
-
return
|
|
11412
|
+
return existsSync22(resolve12(this.baseDir, fp));
|
|
11299
11413
|
}
|
|
11300
11414
|
bareNameExists(name) {
|
|
11301
|
-
if (
|
|
11415
|
+
if (existsSync22(resolve12(this.baseDir, name)))
|
|
11302
11416
|
return true;
|
|
11303
11417
|
if (this.indexHas(name))
|
|
11304
11418
|
return true;
|
|
@@ -11692,7 +11806,18 @@ class PluginManager {
|
|
|
11692
11806
|
}
|
|
11693
11807
|
|
|
11694
11808
|
// src/tools/subagent.ts
|
|
11695
|
-
|
|
11809
|
+
function buildSubagentSystemPrompt(context, stable) {
|
|
11810
|
+
if (stable)
|
|
11811
|
+
return SUBAGENT_SYSTEM_PROMPT_TEMPLATE;
|
|
11812
|
+
return `You are a sub-agent working on a specific task. ${context ? `Context: ${context}` : ""}`;
|
|
11813
|
+
}
|
|
11814
|
+
var SUBAGENT_SYSTEM_PROMPT_TEMPLATE = `You are a sub-agent working on a specific task. You have your own context window and tool set.
|
|
11815
|
+
|
|
11816
|
+
Workflow rules:
|
|
11817
|
+
- Prefer small, focused steps. Verify your own work (typecheck/tests) before finishing.
|
|
11818
|
+
- For large outputs, write the result to a file with write_file instead of reproducing it in your answer.
|
|
11819
|
+
- If the task is big and decomposable, delegate parts to the subagent tool instead of doing everything in one context.
|
|
11820
|
+
- When you finish, return a concise final answer; do not repeat file contents verbatim if you already wrote them to disk.`, subagentTool;
|
|
11696
11821
|
var init_subagent = __esm(() => {
|
|
11697
11822
|
init_i18n();
|
|
11698
11823
|
init_agent();
|
|
@@ -11700,6 +11825,7 @@ var init_subagent = __esm(() => {
|
|
|
11700
11825
|
init_detector();
|
|
11701
11826
|
init_audit_log();
|
|
11702
11827
|
init_session_isolation();
|
|
11828
|
+
init_store();
|
|
11703
11829
|
subagentTool = {
|
|
11704
11830
|
name: "subagent",
|
|
11705
11831
|
description: "Spawn an isolated sub-agent to work on a task independently. The sub-agent has its own context and executes autonomously. Use for parallel work or complex sub-tasks.",
|
|
@@ -11741,6 +11867,15 @@ var init_subagent = __esm(() => {
|
|
|
11741
11867
|
type: "array",
|
|
11742
11868
|
items: { type: "string" },
|
|
11743
11869
|
description: "Tool tags to expose to the sub-agent"
|
|
11870
|
+
},
|
|
11871
|
+
result_mode: {
|
|
11872
|
+
type: "string",
|
|
11873
|
+
enum: ["text", "file"],
|
|
11874
|
+
description: '"file": persist the full result to an artifact and return a path + summary (pass-by-reference). "text" (default): return the full text into context.'
|
|
11875
|
+
},
|
|
11876
|
+
artifact_name: {
|
|
11877
|
+
type: "string",
|
|
11878
|
+
description: "Artifact file name (sanitized). Default: subagent-<timestamp>."
|
|
11744
11879
|
}
|
|
11745
11880
|
},
|
|
11746
11881
|
required: ["task"]
|
|
@@ -11788,10 +11923,10 @@ var init_subagent = __esm(() => {
|
|
|
11788
11923
|
const parentScope = ctx.scope;
|
|
11789
11924
|
ctx.toolExecutor.setScope(scope || { allowed_files: [], read_only_files: [] });
|
|
11790
11925
|
const systemPrompt = {
|
|
11791
|
-
content:
|
|
11926
|
+
content: buildSubagentSystemPrompt(context, ctx.config.subagent?.stableSystemPrompt !== false),
|
|
11792
11927
|
priority: "critical",
|
|
11793
11928
|
essential: true,
|
|
11794
|
-
estimatedTokens:
|
|
11929
|
+
estimatedTokens: 150
|
|
11795
11930
|
};
|
|
11796
11931
|
const subDeps = {
|
|
11797
11932
|
config: ctx.config,
|
|
@@ -11814,16 +11949,38 @@ Context: ${context}` : task;
|
|
|
11814
11949
|
let scopeRestored = false;
|
|
11815
11950
|
try {
|
|
11816
11951
|
const result = await subAgent.run(fullTask);
|
|
11817
|
-
|
|
11952
|
+
if (!result.success) {
|
|
11953
|
+
return {
|
|
11954
|
+
success: false,
|
|
11955
|
+
output: `Sub-agent failed: ${result.error}
|
|
11956
|
+
Partial output: ${result.text}`
|
|
11957
|
+
};
|
|
11958
|
+
}
|
|
11959
|
+
const resultMode = args.result_mode || ctx.config.subagent?.resultMode || "text";
|
|
11960
|
+
if (resultMode === "file") {
|
|
11961
|
+
const store = new ArtifactStore({
|
|
11962
|
+
baseDir: ctx.baseDir,
|
|
11963
|
+
sessionId: ctx.sessionId || "default",
|
|
11964
|
+
artifactsDir: ctx.config.subagent?.artifactsDir
|
|
11965
|
+
});
|
|
11966
|
+
const abs = store.save(args.artifact_name || `subagent-${Date.now()}`, result.text, "md");
|
|
11967
|
+
const summary = store.summary(result.text, ctx.config.subagent?.maxSummaryChars ?? 2000);
|
|
11968
|
+
ctx.logger.debug(`subagent result persisted to artifact ${abs} (${result.text.length} chars, ${result.iterationCount} iterations)`);
|
|
11969
|
+
return {
|
|
11970
|
+
success: true,
|
|
11971
|
+
output: t("tool.subagent_artifact", {
|
|
11972
|
+
path: abs,
|
|
11973
|
+
iterations: String(result.iterationCount),
|
|
11974
|
+
summary
|
|
11975
|
+
})
|
|
11976
|
+
};
|
|
11977
|
+
}
|
|
11978
|
+
return {
|
|
11818
11979
|
success: true,
|
|
11819
11980
|
output: `Sub-agent completed:
|
|
11820
11981
|
${result.text}
|
|
11821
11982
|
|
|
11822
11983
|
Iterations: ${result.iterationCount}`
|
|
11823
|
-
} : {
|
|
11824
|
-
success: false,
|
|
11825
|
-
output: `Sub-agent failed: ${result.error}
|
|
11826
|
-
Partial output: ${result.text}`
|
|
11827
11984
|
};
|
|
11828
11985
|
} finally {
|
|
11829
11986
|
if (!scopeRestored) {
|
|
@@ -11837,6 +11994,228 @@ Partial output: ${result.text}`
|
|
|
11837
11994
|
};
|
|
11838
11995
|
});
|
|
11839
11996
|
|
|
11997
|
+
// src/tools/scope-check.ts
|
|
11998
|
+
import { resolve as resolve13, normalize as normalize4 } from "path";
|
|
11999
|
+
function isPathInScope2(baseDir, targetPath, scope) {
|
|
12000
|
+
const baseResolved = resolve13(baseDir);
|
|
12001
|
+
const targetResolved = resolve13(baseDir, normalize4(targetPath));
|
|
12002
|
+
if (!targetResolved.startsWith(baseResolved)) {
|
|
12003
|
+
return { allowed: false, reason: "Path is outside the base working directory" };
|
|
12004
|
+
}
|
|
12005
|
+
if (!scope)
|
|
12006
|
+
return { allowed: true };
|
|
12007
|
+
const isRead = scope.read_only_files.some((f) => targetResolved.startsWith(resolve13(baseDir, f)));
|
|
12008
|
+
const isWrite = scope.allowed_files.some((f) => targetResolved.startsWith(resolve13(baseDir, f)));
|
|
12009
|
+
if (isWrite)
|
|
12010
|
+
return { allowed: true };
|
|
12011
|
+
if (isRead)
|
|
12012
|
+
return { allowed: true, reason: "Read-only file" };
|
|
12013
|
+
return { allowed: false, reason: "Path is not within the allowed scope for this sub-agent" };
|
|
12014
|
+
}
|
|
12015
|
+
var init_scope_check = () => {};
|
|
12016
|
+
|
|
12017
|
+
// src/modules/context/chunk-query.ts
|
|
12018
|
+
function splitTextIntoChunks(text, chunkChars) {
|
|
12019
|
+
if (chunkChars <= 0)
|
|
12020
|
+
throw new Error("chunkChars must be > 0");
|
|
12021
|
+
if (text.length <= chunkChars)
|
|
12022
|
+
return [text];
|
|
12023
|
+
const lines = text.split(`
|
|
12024
|
+
`);
|
|
12025
|
+
const chunks = [];
|
|
12026
|
+
let current = [];
|
|
12027
|
+
let size = 0;
|
|
12028
|
+
for (const line of lines) {
|
|
12029
|
+
if (current.length > 0 && size + line.length + 1 > chunkChars) {
|
|
12030
|
+
chunks.push(current.join(`
|
|
12031
|
+
`));
|
|
12032
|
+
current = [];
|
|
12033
|
+
size = 0;
|
|
12034
|
+
}
|
|
12035
|
+
current.push(line);
|
|
12036
|
+
size += line.length + 1;
|
|
12037
|
+
}
|
|
12038
|
+
if (current.length > 0)
|
|
12039
|
+
chunks.push(current.join(`
|
|
12040
|
+
`));
|
|
12041
|
+
return chunks;
|
|
12042
|
+
}
|
|
12043
|
+
async function chatText(provider, messages, maxTokens, reasoningEffort) {
|
|
12044
|
+
let out = "";
|
|
12045
|
+
for await (const chunk of provider.chat(messages, undefined, undefined, {
|
|
12046
|
+
maxTokens,
|
|
12047
|
+
reasoningEffort
|
|
12048
|
+
})) {
|
|
12049
|
+
if (chunk.type === "text" && chunk.content)
|
|
12050
|
+
out += chunk.content;
|
|
12051
|
+
}
|
|
12052
|
+
return out;
|
|
12053
|
+
}
|
|
12054
|
+
async function runChunkQuery(provider, text, query, opts = {}) {
|
|
12055
|
+
const chunkChars = opts.chunkChars ?? 12000;
|
|
12056
|
+
const maxParallel = Math.max(1, opts.maxParallel ?? 4);
|
|
12057
|
+
const maxChunkTokens = opts.maxChunkTokens ?? 1024;
|
|
12058
|
+
const maxSynthesisTokens = opts.maxSynthesisTokens ?? 2048;
|
|
12059
|
+
const reasoningEffort = opts.reasoningEffort ?? "none";
|
|
12060
|
+
const chunks = splitTextIntoChunks(text, chunkChars);
|
|
12061
|
+
const answers = new Array(chunks.length);
|
|
12062
|
+
const chunkSystem = opts.querySystemPrompt ?? DEFAULT_CHUNK_SYSTEM_PROMPT;
|
|
12063
|
+
const logger = opts.logger;
|
|
12064
|
+
if (chunks.length === 1) {
|
|
12065
|
+
logger?.debug(`runChunkQuery: single chunk (${text.length} chars), no chunking needed`);
|
|
12066
|
+
} else {
|
|
12067
|
+
logger?.debug(`runChunkQuery: ${chunks.length} chunks over ${text.length} chars (chunkChars=${chunkChars}, maxParallel=${maxParallel})`);
|
|
12068
|
+
}
|
|
12069
|
+
let cursor = 0;
|
|
12070
|
+
let inFlight = 0;
|
|
12071
|
+
let maxParallelObserved = 0;
|
|
12072
|
+
const workers = Array.from({ length: Math.min(maxParallel, chunks.length) }, async () => {
|
|
12073
|
+
while (cursor < chunks.length) {
|
|
12074
|
+
const idx = cursor++;
|
|
12075
|
+
inFlight++;
|
|
12076
|
+
maxParallelObserved = Math.max(maxParallelObserved, inFlight);
|
|
12077
|
+
try {
|
|
12078
|
+
answers[idx] = await chatText(provider, [
|
|
12079
|
+
{ role: "system", content: chunkSystem },
|
|
12080
|
+
{ role: "user", content: `Query: ${query}
|
|
12081
|
+
|
|
12082
|
+
Text:
|
|
12083
|
+
${chunks[idx]}` }
|
|
12084
|
+
], maxChunkTokens, reasoningEffort);
|
|
12085
|
+
} finally {
|
|
12086
|
+
inFlight--;
|
|
12087
|
+
}
|
|
12088
|
+
}
|
|
12089
|
+
});
|
|
12090
|
+
await Promise.all(workers);
|
|
12091
|
+
let synthesis = "";
|
|
12092
|
+
if (opts.synthesize !== false && chunks.length > 0) {
|
|
12093
|
+
const joined = answers.map((a, i) => `--- Chunk ${i + 1}/${chunks.length} ---
|
|
12094
|
+
${a}`).join(`
|
|
12095
|
+
|
|
12096
|
+
`);
|
|
12097
|
+
logger?.debug(`runChunkQuery: synthesis pass over ${chunks.length} answers`);
|
|
12098
|
+
synthesis = await chatText(provider, [
|
|
12099
|
+
{
|
|
12100
|
+
role: "system",
|
|
12101
|
+
content: opts.synthesisSystemPrompt ?? DEFAULT_SYNTHESIS_SYSTEM_PROMPT
|
|
12102
|
+
},
|
|
12103
|
+
{ role: "user", content: `Query: ${query}
|
|
12104
|
+
|
|
12105
|
+
Chunk answers:
|
|
12106
|
+
${joined}` }
|
|
12107
|
+
], maxSynthesisTokens, reasoningEffort);
|
|
12108
|
+
}
|
|
12109
|
+
logger?.debug(`runChunkQuery: done, ${chunks.length} chunks, max parallel observed ${maxParallelObserved}, synthesis ${synthesis.length} chars`);
|
|
12110
|
+
return {
|
|
12111
|
+
chunks: chunks.length,
|
|
12112
|
+
answers,
|
|
12113
|
+
synthesis,
|
|
12114
|
+
totalChars: text.length,
|
|
12115
|
+
maxParallelObserved
|
|
12116
|
+
};
|
|
12117
|
+
}
|
|
12118
|
+
var DEFAULT_CHUNK_SYSTEM_PROMPT = 'Answer the query using ONLY the provided text. Be concise. If the text does not contain the answer, say "NO_EVIDENCE".', DEFAULT_SYNTHESIS_SYSTEM_PROMPT = "You are given a query and per-chunk answers over a large text. Produce the final answer to the query, combining evidence from the chunks. If no chunk had evidence, say so.";
|
|
12119
|
+
|
|
12120
|
+
// src/tools/chunk-query.ts
|
|
12121
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
12122
|
+
var chunkQueryTool;
|
|
12123
|
+
var init_chunk_query = __esm(() => {
|
|
12124
|
+
init_i18n();
|
|
12125
|
+
init_scope_check();
|
|
12126
|
+
chunkQueryTool = {
|
|
12127
|
+
name: "chunk_query",
|
|
12128
|
+
description: "Answer a query over a large text (file or inline) by splitting it into chunks and querying the model per chunk in parallel, then optionally synthesizing a final answer. Use when the input is too large for the context window.",
|
|
12129
|
+
tags: ["research", "code"],
|
|
12130
|
+
timeoutMs: 300000,
|
|
12131
|
+
parameters: {
|
|
12132
|
+
type: "object",
|
|
12133
|
+
properties: {
|
|
12134
|
+
query: {
|
|
12135
|
+
type: "string",
|
|
12136
|
+
description: "The question to answer over the text."
|
|
12137
|
+
},
|
|
12138
|
+
input_path: {
|
|
12139
|
+
type: "string",
|
|
12140
|
+
description: "Path to the large text file (scope-checked). Preferred over text."
|
|
12141
|
+
},
|
|
12142
|
+
text: {
|
|
12143
|
+
type: "string",
|
|
12144
|
+
description: "Inline text. Use only when a file path is not available."
|
|
12145
|
+
},
|
|
12146
|
+
chunk_chars: {
|
|
12147
|
+
type: "number",
|
|
12148
|
+
description: "Approximate chunk size in chars (default 12000)."
|
|
12149
|
+
},
|
|
12150
|
+
max_parallel: {
|
|
12151
|
+
type: "number",
|
|
12152
|
+
description: "Max parallel chunk queries (default from config.subagent.maxParallelChunkQueries)."
|
|
12153
|
+
},
|
|
12154
|
+
max_chunk_tokens: {
|
|
12155
|
+
type: "number",
|
|
12156
|
+
description: "Cap on generated tokens per chunk call (default 1024)."
|
|
12157
|
+
},
|
|
12158
|
+
max_synthesis_tokens: {
|
|
12159
|
+
type: "number",
|
|
12160
|
+
description: "Cap on generated tokens for the synthesis call (default 2048)."
|
|
12161
|
+
},
|
|
12162
|
+
reasoning_effort: {
|
|
12163
|
+
type: "string",
|
|
12164
|
+
enum: ["none", "low", "medium", "high"],
|
|
12165
|
+
description: 'Reasoning effort for chunk/synthesis calls (default "none"). "none" prevents long thinking chains from eating the token budget on reasoning models.'
|
|
12166
|
+
},
|
|
12167
|
+
synthesize: {
|
|
12168
|
+
type: "boolean",
|
|
12169
|
+
description: "Run a final synthesis call over chunk answers (default true)."
|
|
12170
|
+
}
|
|
12171
|
+
},
|
|
12172
|
+
required: ["query"]
|
|
12173
|
+
},
|
|
12174
|
+
handler: async (ctx, args) => {
|
|
12175
|
+
const query = String(args.query || "");
|
|
12176
|
+
const inputPath = args.input_path ? String(args.input_path) : undefined;
|
|
12177
|
+
const text = args.text ? String(args.text) : undefined;
|
|
12178
|
+
if (!query)
|
|
12179
|
+
return { success: false, output: t("tool.chunk_query_no_query") };
|
|
12180
|
+
if (!inputPath && !text)
|
|
12181
|
+
return { success: false, output: t("tool.chunk_query_no_input") };
|
|
12182
|
+
let content = text || "";
|
|
12183
|
+
if (inputPath) {
|
|
12184
|
+
const check = isPathInScope2(ctx.baseDir, inputPath, ctx.scope);
|
|
12185
|
+
if (!check.allowed) {
|
|
12186
|
+
return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
|
|
12187
|
+
}
|
|
12188
|
+
try {
|
|
12189
|
+
content = readFileSync12(inputPath, "utf8");
|
|
12190
|
+
} catch (e) {
|
|
12191
|
+
return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
|
|
12192
|
+
}
|
|
12193
|
+
}
|
|
12194
|
+
if (!ctx.llmProvider) {
|
|
12195
|
+
return { success: false, output: "chunk_query: missing llmProvider in context" };
|
|
12196
|
+
}
|
|
12197
|
+
const maxParallel = typeof args.max_parallel === "number" ? args.max_parallel : ctx.config.subagent?.maxParallelChunkQueries ?? 4;
|
|
12198
|
+
const res = await runChunkQuery(ctx.llmProvider, content, query, {
|
|
12199
|
+
chunkChars: typeof args.chunk_chars === "number" ? args.chunk_chars : undefined,
|
|
12200
|
+
maxParallel,
|
|
12201
|
+
synthesize: typeof args.synthesize === "boolean" ? args.synthesize : undefined,
|
|
12202
|
+
maxChunkTokens: typeof args.max_chunk_tokens === "number" ? args.max_chunk_tokens : undefined,
|
|
12203
|
+
maxSynthesisTokens: typeof args.max_synthesis_tokens === "number" ? args.max_synthesis_tokens : undefined,
|
|
12204
|
+
reasoningEffort: ["none", "low", "medium", "high"].includes(args.reasoning_effort) ? args.reasoning_effort : undefined,
|
|
12205
|
+
logger: ctx.logger
|
|
12206
|
+
});
|
|
12207
|
+
ctx.logger.debug(`chunk_query: ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}`);
|
|
12208
|
+
return {
|
|
12209
|
+
success: true,
|
|
12210
|
+
output: `[chunk_query] ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}
|
|
12211
|
+
|
|
12212
|
+
${res.synthesis || res.answers.join(`
|
|
12213
|
+
`)}`
|
|
12214
|
+
};
|
|
12215
|
+
}
|
|
12216
|
+
};
|
|
12217
|
+
});
|
|
12218
|
+
|
|
11840
12219
|
// src/modules/security/network-validator.ts
|
|
11841
12220
|
function isUrlAllowed(url, securityConfig) {
|
|
11842
12221
|
if (!securityConfig?.enabled) {
|
|
@@ -12586,7 +12965,7 @@ class MCPClient {
|
|
|
12586
12965
|
}
|
|
12587
12966
|
}
|
|
12588
12967
|
connectStdio() {
|
|
12589
|
-
return new Promise((
|
|
12968
|
+
return new Promise((resolve14, reject) => {
|
|
12590
12969
|
const child = spawn3(this.config.command, this.config.args || [], {
|
|
12591
12970
|
env: { ...process.env, ...this.config.env },
|
|
12592
12971
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -12610,7 +12989,7 @@ class MCPClient {
|
|
|
12610
12989
|
this._connected = true;
|
|
12611
12990
|
this.process = child;
|
|
12612
12991
|
_resolved = true;
|
|
12613
|
-
|
|
12992
|
+
resolve14();
|
|
12614
12993
|
});
|
|
12615
12994
|
});
|
|
12616
12995
|
}
|
|
@@ -12679,7 +13058,7 @@ class MCPClient {
|
|
|
12679
13058
|
if (!this.process) {
|
|
12680
13059
|
throw new Error("Not connected to MCP server");
|
|
12681
13060
|
}
|
|
12682
|
-
return new Promise((
|
|
13061
|
+
return new Promise((resolve14, reject) => {
|
|
12683
13062
|
const request = {
|
|
12684
13063
|
jsonrpc: "2.0",
|
|
12685
13064
|
id: Date.now(),
|
|
@@ -12703,7 +13082,7 @@ class MCPClient {
|
|
|
12703
13082
|
if (response.error) {
|
|
12704
13083
|
reject(new Error(response.error.message));
|
|
12705
13084
|
} else {
|
|
12706
|
-
|
|
13085
|
+
resolve14(response.result?.tools || []);
|
|
12707
13086
|
}
|
|
12708
13087
|
return;
|
|
12709
13088
|
}
|
|
@@ -12785,8 +13164,8 @@ class MCPClient {
|
|
|
12785
13164
|
arguments: args
|
|
12786
13165
|
}
|
|
12787
13166
|
};
|
|
12788
|
-
return new Promise((
|
|
12789
|
-
this.pendingResolve =
|
|
13167
|
+
return new Promise((resolve14, reject) => {
|
|
13168
|
+
this.pendingResolve = resolve14;
|
|
12790
13169
|
this.pendingReject = reject;
|
|
12791
13170
|
const timeout = this.config.timeout || 30000;
|
|
12792
13171
|
const timer = setTimeout(() => {
|
|
@@ -12813,7 +13192,7 @@ class MCPClient {
|
|
|
12813
13192
|
if (result.error) {
|
|
12814
13193
|
reject(new Error(result.error.message));
|
|
12815
13194
|
} else {
|
|
12816
|
-
|
|
13195
|
+
resolve14(result.result || result);
|
|
12817
13196
|
}
|
|
12818
13197
|
}).catch((err) => {
|
|
12819
13198
|
clearTimeout(timer);
|
|
@@ -12827,7 +13206,7 @@ class MCPClient {
|
|
|
12827
13206
|
if (!this.process) {
|
|
12828
13207
|
throw new Error("Not connected to MCP server");
|
|
12829
13208
|
}
|
|
12830
|
-
return new Promise((
|
|
13209
|
+
return new Promise((resolve14, reject) => {
|
|
12831
13210
|
const request = {
|
|
12832
13211
|
jsonrpc: "2.0",
|
|
12833
13212
|
id: Date.now(),
|
|
@@ -12855,7 +13234,7 @@ class MCPClient {
|
|
|
12855
13234
|
if (response.error) {
|
|
12856
13235
|
reject(new Error(response.error.message));
|
|
12857
13236
|
} else {
|
|
12858
|
-
|
|
13237
|
+
resolve14(response.result);
|
|
12859
13238
|
}
|
|
12860
13239
|
return;
|
|
12861
13240
|
}
|
|
@@ -13057,7 +13436,7 @@ import { join as join15 } from "path";
|
|
|
13057
13436
|
var CATEGORIES, rememberTool;
|
|
13058
13437
|
var init_remember = __esm(() => {
|
|
13059
13438
|
init_i18n();
|
|
13060
|
-
|
|
13439
|
+
init_store2();
|
|
13061
13440
|
CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
13062
13441
|
rememberTool = {
|
|
13063
13442
|
name: "remember",
|
|
@@ -13184,7 +13563,7 @@ function searchCategory(store, category, query) {
|
|
|
13184
13563
|
var CATEGORIES2, recallTool;
|
|
13185
13564
|
var init_recall = __esm(() => {
|
|
13186
13565
|
init_i18n();
|
|
13187
|
-
|
|
13566
|
+
init_store2();
|
|
13188
13567
|
CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
13189
13568
|
recallTool = {
|
|
13190
13569
|
name: "recall",
|
|
@@ -13883,7 +14262,7 @@ __export(exports_image_utils, {
|
|
|
13883
14262
|
detectMime: () => detectMime,
|
|
13884
14263
|
bufferToDataUrl: () => bufferToDataUrl
|
|
13885
14264
|
});
|
|
13886
|
-
import { readFileSync as
|
|
14265
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
13887
14266
|
import { extname as extname3 } from "path";
|
|
13888
14267
|
function detectMime(filePath) {
|
|
13889
14268
|
const ext = extname3(filePath).toLowerCase();
|
|
@@ -13904,7 +14283,7 @@ async function readClipboardImage() {
|
|
|
13904
14283
|
async function readClipboardFallback() {
|
|
13905
14284
|
const { platform: platform3 } = await import("os");
|
|
13906
14285
|
const { execSync } = await import("child_process");
|
|
13907
|
-
const { readFileSync:
|
|
14286
|
+
const { readFileSync: readFileSync15, unlinkSync: unlinkSync4 } = await import("fs");
|
|
13908
14287
|
const { join: join19 } = await import("path");
|
|
13909
14288
|
const tmpPath = join19(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
13910
14289
|
try {
|
|
@@ -13913,7 +14292,7 @@ async function readClipboardFallback() {
|
|
|
13913
14292
|
} else {
|
|
13914
14293
|
return null;
|
|
13915
14294
|
}
|
|
13916
|
-
const buf =
|
|
14295
|
+
const buf = readFileSync15(tmpPath);
|
|
13917
14296
|
unlinkSync4(tmpPath);
|
|
13918
14297
|
return buf.length > 0 ? buf : null;
|
|
13919
14298
|
} catch {
|
|
@@ -13924,7 +14303,7 @@ async function readClipboardFallback() {
|
|
|
13924
14303
|
}
|
|
13925
14304
|
}
|
|
13926
14305
|
async function loadFileAsDataUrl(filePath) {
|
|
13927
|
-
const buf =
|
|
14306
|
+
const buf = readFileSync14(filePath);
|
|
13928
14307
|
if (typeof Bun !== "undefined" && typeof Bun.Image !== "undefined") {
|
|
13929
14308
|
try {
|
|
13930
14309
|
const img = new Bun.Image(buf);
|
|
@@ -13984,8 +14363,8 @@ var init_image_utils = __esm(() => {
|
|
|
13984
14363
|
});
|
|
13985
14364
|
|
|
13986
14365
|
// src/tools/attach-image.ts
|
|
13987
|
-
import { existsSync as
|
|
13988
|
-
import { resolve as
|
|
14366
|
+
import { existsSync as existsSync24 } from "fs";
|
|
14367
|
+
import { resolve as resolve14 } from "path";
|
|
13989
14368
|
var attachImageTool;
|
|
13990
14369
|
var init_attach_image = __esm(() => {
|
|
13991
14370
|
init_i18n();
|
|
@@ -14026,16 +14405,16 @@ var init_attach_image = __esm(() => {
|
|
|
14026
14405
|
const result = await loadUrlAsDataUrl(source);
|
|
14027
14406
|
dataUrl = result.dataUrl;
|
|
14028
14407
|
} else {
|
|
14029
|
-
const absPath =
|
|
14030
|
-
if (!
|
|
14408
|
+
const absPath = resolve14(ctx.baseDir, source);
|
|
14409
|
+
if (!existsSync24(absPath)) {
|
|
14031
14410
|
return {
|
|
14032
14411
|
success: false,
|
|
14033
14412
|
output: t("image.not_found", { path: source })
|
|
14034
14413
|
};
|
|
14035
14414
|
}
|
|
14036
14415
|
if (ctx.scope) {
|
|
14037
|
-
const { isPathInScope:
|
|
14038
|
-
const validation =
|
|
14416
|
+
const { isPathInScope: isPathInScope3 } = await Promise.resolve().then(() => (init_path_validator(), exports_path_validator));
|
|
14417
|
+
const validation = isPathInScope3(ctx.baseDir, absPath, ctx.scope);
|
|
14039
14418
|
if (!validation.allowed) {
|
|
14040
14419
|
logSecurityBlock(ctx.sessionId, "file_read", validation.reason ?? "attach_image out of scope", absPath);
|
|
14041
14420
|
return {
|
|
@@ -14087,6 +14466,7 @@ function registerAllTools(registry2, skillsModule) {
|
|
|
14087
14466
|
fileInfoTool,
|
|
14088
14467
|
bashTool,
|
|
14089
14468
|
subagentTool,
|
|
14469
|
+
chunkQueryTool,
|
|
14090
14470
|
processListTool,
|
|
14091
14471
|
processLogTool,
|
|
14092
14472
|
processKillTool,
|
|
@@ -14122,6 +14502,7 @@ var init_tools = __esm(() => {
|
|
|
14122
14502
|
init_process_log();
|
|
14123
14503
|
init_process_kill();
|
|
14124
14504
|
init_subagent();
|
|
14505
|
+
init_chunk_query();
|
|
14125
14506
|
init_web_search();
|
|
14126
14507
|
init_web_fetch();
|
|
14127
14508
|
init_web_browse();
|
|
@@ -14183,12 +14564,12 @@ class ModuleRegistry {
|
|
|
14183
14564
|
}
|
|
14184
14565
|
|
|
14185
14566
|
// src/modules/plugins/loader.ts
|
|
14186
|
-
import { readdirSync as readdirSync7, existsSync as
|
|
14567
|
+
import { readdirSync as readdirSync7, existsSync as existsSync25, statSync as statSync5 } from "fs";
|
|
14187
14568
|
import { join as join19 } from "path";
|
|
14188
14569
|
|
|
14189
14570
|
class PluginLoader {
|
|
14190
14571
|
loadFromDir(dirPath, pluginManager, logger) {
|
|
14191
|
-
if (!
|
|
14572
|
+
if (!existsSync25(dirPath))
|
|
14192
14573
|
return;
|
|
14193
14574
|
const entries = readdirSync7(dirPath);
|
|
14194
14575
|
for (const entry of entries) {
|
|
@@ -14216,8 +14597,8 @@ var init_loader = __esm(() => {
|
|
|
14216
14597
|
|
|
14217
14598
|
// src/modules/plugins/builtin/lint-on-write.ts
|
|
14218
14599
|
import { spawn as spawn4, execSync } from "child_process";
|
|
14219
|
-
import { existsSync as
|
|
14220
|
-
import { resolve as
|
|
14600
|
+
import { existsSync as existsSync26, readFileSync as readFileSync15 } from "fs";
|
|
14601
|
+
import { resolve as resolve15, extname as extname4, join as join20 } from "path";
|
|
14221
14602
|
import { platform as platform3 } from "os";
|
|
14222
14603
|
function contentHash(content) {
|
|
14223
14604
|
let h = 5381;
|
|
@@ -14262,8 +14643,8 @@ class LintOnWritePlugin {
|
|
|
14262
14643
|
const path = String(call.arguments.path || "");
|
|
14263
14644
|
if (!path)
|
|
14264
14645
|
return;
|
|
14265
|
-
const fullPath =
|
|
14266
|
-
if (!
|
|
14646
|
+
const fullPath = resolve15(ctx.baseDir, path);
|
|
14647
|
+
if (!existsSync26(fullPath))
|
|
14267
14648
|
return;
|
|
14268
14649
|
const ext = extname4(fullPath);
|
|
14269
14650
|
const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir);
|
|
@@ -14280,7 +14661,7 @@ class LintOnWritePlugin {
|
|
|
14280
14661
|
if (ext === ".ts" || ext === ".tsx") {
|
|
14281
14662
|
let content = "";
|
|
14282
14663
|
try {
|
|
14283
|
-
content =
|
|
14664
|
+
content = readFileSync15(filePath, "utf-8");
|
|
14284
14665
|
} catch {
|
|
14285
14666
|
return null;
|
|
14286
14667
|
}
|
|
@@ -14320,10 +14701,10 @@ class LintOnWritePlugin {
|
|
|
14320
14701
|
async runProjectLint(ctx, result) {
|
|
14321
14702
|
try {
|
|
14322
14703
|
const packageJsonPath = join20(ctx.baseDir, "package.json");
|
|
14323
|
-
if (!
|
|
14704
|
+
if (!existsSync26(packageJsonPath)) {
|
|
14324
14705
|
return;
|
|
14325
14706
|
}
|
|
14326
|
-
const packageJson = JSON.parse(
|
|
14707
|
+
const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
|
|
14327
14708
|
const lintScript = packageJson.scripts?.lint;
|
|
14328
14709
|
if (!lintScript) {
|
|
14329
14710
|
return;
|
|
@@ -14340,7 +14721,7 @@ class LintOnWritePlugin {
|
|
|
14340
14721
|
}
|
|
14341
14722
|
async runProjectTypeCheck(ctx, result) {
|
|
14342
14723
|
const tsconfigPath = join20(ctx.baseDir, "tsconfig.json");
|
|
14343
|
-
if (!
|
|
14724
|
+
if (!existsSync26(tsconfigPath)) {
|
|
14344
14725
|
return;
|
|
14345
14726
|
}
|
|
14346
14727
|
const now = Date.now();
|
|
@@ -14381,7 +14762,7 @@ class LintOnWritePlugin {
|
|
|
14381
14762
|
}
|
|
14382
14763
|
}
|
|
14383
14764
|
function runAsync(command, cwd, timeoutMs) {
|
|
14384
|
-
return new Promise((
|
|
14765
|
+
return new Promise((resolve16, reject) => {
|
|
14385
14766
|
const child = spawn4(command, {
|
|
14386
14767
|
cwd,
|
|
14387
14768
|
shell: true,
|
|
@@ -14410,7 +14791,7 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
14410
14791
|
stdout += decoder.decode();
|
|
14411
14792
|
stderr += decoder.decode();
|
|
14412
14793
|
if (code === 0) {
|
|
14413
|
-
|
|
14794
|
+
resolve16({ stdout, stderr });
|
|
14414
14795
|
} else {
|
|
14415
14796
|
const err = new Error(`Command failed with exit code ${code}`);
|
|
14416
14797
|
err.stdout = stdout;
|
|
@@ -14582,8 +14963,8 @@ class PlanTracker {
|
|
|
14582
14963
|
var init_tracker = () => {};
|
|
14583
14964
|
|
|
14584
14965
|
// src/modules/execution/auditor.ts
|
|
14585
|
-
import { existsSync as
|
|
14586
|
-
import { resolve as
|
|
14966
|
+
import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
|
|
14967
|
+
import { resolve as resolve16, join as join21 } from "path";
|
|
14587
14968
|
function findTestFile(dir, depth = 0) {
|
|
14588
14969
|
if (depth > 5)
|
|
14589
14970
|
return null;
|
|
@@ -14673,8 +15054,8 @@ class Auditor {
|
|
|
14673
15054
|
const missingFiles = [];
|
|
14674
15055
|
const existingFiles = [];
|
|
14675
15056
|
for (const filePath of uniqueFiles) {
|
|
14676
|
-
const resolved =
|
|
14677
|
-
if (
|
|
15057
|
+
const resolved = resolve16(this.baseDir, filePath);
|
|
15058
|
+
if (existsSync27(resolved)) {
|
|
14678
15059
|
existingFiles.push(filePath);
|
|
14679
15060
|
} else {
|
|
14680
15061
|
missingFiles.push(filePath);
|
|
@@ -14753,11 +15134,11 @@ var init_auditor = __esm(() => {
|
|
|
14753
15134
|
});
|
|
14754
15135
|
|
|
14755
15136
|
// src/modules/execution/plan-store.ts
|
|
14756
|
-
import { readFileSync as
|
|
15137
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync13, existsSync as existsSync28, readdirSync as readdirSync9, rmSync } from "fs";
|
|
14757
15138
|
import { join as join22 } from "path";
|
|
14758
15139
|
function readPlanFile(path, fallbackBaseDir) {
|
|
14759
15140
|
try {
|
|
14760
|
-
const raw =
|
|
15141
|
+
const raw = readFileSync16(path, "utf-8");
|
|
14761
15142
|
if (!raw.trim())
|
|
14762
15143
|
return null;
|
|
14763
15144
|
const parsed = JSON.parse(raw);
|
|
@@ -14776,10 +15157,10 @@ function readPlanFile(path, fallbackBaseDir) {
|
|
|
14776
15157
|
}
|
|
14777
15158
|
}
|
|
14778
15159
|
function writePlanFile(path, plan) {
|
|
14779
|
-
|
|
15160
|
+
writeFileSync9(path, JSON.stringify(plan, null, 2), "utf-8");
|
|
14780
15161
|
}
|
|
14781
15162
|
function listDir(dir, baseDir) {
|
|
14782
|
-
if (!
|
|
15163
|
+
if (!existsSync28(dir))
|
|
14783
15164
|
return [];
|
|
14784
15165
|
const files = readdirSync9(dir).filter((f) => f.endsWith(".json"));
|
|
14785
15166
|
return files.map((f) => readPlanFile(join22(dir, f), baseDir)).filter((p) => p !== null);
|
|
@@ -14804,16 +15185,16 @@ class PlanStore {
|
|
|
14804
15185
|
legacyPath;
|
|
14805
15186
|
constructor(baseDir) {
|
|
14806
15187
|
const mmaDir = join22(baseDir, ".mma");
|
|
14807
|
-
if (!
|
|
14808
|
-
|
|
15188
|
+
if (!existsSync28(mmaDir))
|
|
15189
|
+
mkdirSync13(mmaDir, { recursive: true });
|
|
14809
15190
|
this.baseDir = baseDir;
|
|
14810
15191
|
this.plansDir = join22(mmaDir, "plans");
|
|
14811
15192
|
this.draftsDir = join22(this.plansDir, "drafts");
|
|
14812
15193
|
this.archiveDir = join22(this.plansDir, "archive");
|
|
14813
15194
|
this.legacyPath = join22(mmaDir, LEGACY_FILE);
|
|
14814
15195
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
14815
|
-
if (!
|
|
14816
|
-
|
|
15196
|
+
if (!existsSync28(dir))
|
|
15197
|
+
mkdirSync13(dir, { recursive: true });
|
|
14817
15198
|
}
|
|
14818
15199
|
}
|
|
14819
15200
|
activePath() {
|
|
@@ -14824,12 +15205,12 @@ class PlanStore {
|
|
|
14824
15205
|
}
|
|
14825
15206
|
loadActive() {
|
|
14826
15207
|
const activePath = this.activePath();
|
|
14827
|
-
if (
|
|
15208
|
+
if (existsSync28(activePath)) {
|
|
14828
15209
|
const plan = readPlanFile(activePath, this.baseDir);
|
|
14829
15210
|
if (plan)
|
|
14830
15211
|
return plan;
|
|
14831
15212
|
}
|
|
14832
|
-
if (
|
|
15213
|
+
if (existsSync28(this.legacyPath)) {
|
|
14833
15214
|
const legacy = readPlanFile(this.legacyPath, this.baseDir);
|
|
14834
15215
|
if (legacy) {
|
|
14835
15216
|
this.saveActive(legacy);
|
|
@@ -14843,7 +15224,7 @@ class PlanStore {
|
|
|
14843
15224
|
}
|
|
14844
15225
|
clearActive() {
|
|
14845
15226
|
const p = this.activePath();
|
|
14846
|
-
if (
|
|
15227
|
+
if (existsSync28(p))
|
|
14847
15228
|
rmSync(p, { force: true });
|
|
14848
15229
|
}
|
|
14849
15230
|
saveDraft(plan) {
|
|
@@ -14851,11 +15232,11 @@ class PlanStore {
|
|
|
14851
15232
|
}
|
|
14852
15233
|
loadDraft(id) {
|
|
14853
15234
|
const p = join22(this.draftsDir, `${id}.json`);
|
|
14854
|
-
return
|
|
15235
|
+
return existsSync28(p) ? readPlanFile(p, this.baseDir) : null;
|
|
14855
15236
|
}
|
|
14856
15237
|
removeDraft(id) {
|
|
14857
15238
|
const p = join22(this.draftsDir, `${id}.json`);
|
|
14858
|
-
if (
|
|
15239
|
+
if (existsSync28(p))
|
|
14859
15240
|
rmSync(p, { force: true });
|
|
14860
15241
|
}
|
|
14861
15242
|
listDrafts() {
|
|
@@ -14874,7 +15255,7 @@ class PlanStore {
|
|
|
14874
15255
|
}
|
|
14875
15256
|
removeArchived(id) {
|
|
14876
15257
|
const p = join22(this.archiveDir, `${id}.json`);
|
|
14877
|
-
if (
|
|
15258
|
+
if (existsSync28(p))
|
|
14878
15259
|
rmSync(p, { force: true });
|
|
14879
15260
|
}
|
|
14880
15261
|
listAll() {
|
|
@@ -14968,8 +15349,8 @@ var init_plan_coverage = __esm(() => {
|
|
|
14968
15349
|
});
|
|
14969
15350
|
|
|
14970
15351
|
// src/modules/execution/module.ts
|
|
14971
|
-
import { existsSync as
|
|
14972
|
-
import { resolve as
|
|
15352
|
+
import { existsSync as existsSync29, readFileSync as readFileSync17 } from "fs";
|
|
15353
|
+
import { resolve as resolve17 } from "path";
|
|
14973
15354
|
|
|
14974
15355
|
class ExecutionModule {
|
|
14975
15356
|
name = "execution";
|
|
@@ -15624,7 +16005,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
15624
16005
|
"poetry.lock",
|
|
15625
16006
|
"requirements.txt"
|
|
15626
16007
|
];
|
|
15627
|
-
const hasLockFile = lockFiles.some((f) =>
|
|
16008
|
+
const hasLockFile = lockFiles.some((f) => existsSync29(resolve17(this.baseDir, f)));
|
|
15628
16009
|
if (!hasLockFile) {
|
|
15629
16010
|
if (contextManager) {
|
|
15630
16011
|
const hints = this.depsGateHints.get(step.id) || 0;
|
|
@@ -15644,13 +16025,13 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
15644
16025
|
}
|
|
15645
16026
|
if (stepPaths.length === 0)
|
|
15646
16027
|
return;
|
|
15647
|
-
const allExist = stepPaths.every((p) =>
|
|
16028
|
+
const allExist = stepPaths.every((p) => existsSync29(resolve17(this.baseDir, p)));
|
|
15648
16029
|
if (!allExist)
|
|
15649
16030
|
return;
|
|
15650
16031
|
const emptyFiles = [];
|
|
15651
16032
|
for (const p of stepPaths) {
|
|
15652
16033
|
try {
|
|
15653
|
-
const content =
|
|
16034
|
+
const content = readFileSync17(resolve17(this.baseDir, p), "utf-8");
|
|
15654
16035
|
if (content.trim().length < 10) {
|
|
15655
16036
|
emptyFiles.push(p);
|
|
15656
16037
|
}
|
|
@@ -15707,9 +16088,9 @@ var init_module = __esm(() => {
|
|
|
15707
16088
|
|
|
15708
16089
|
// src/modules/security/session-encryption.ts
|
|
15709
16090
|
import {
|
|
15710
|
-
readFileSync as
|
|
15711
|
-
writeFileSync as
|
|
15712
|
-
existsSync as
|
|
16091
|
+
readFileSync as readFileSync18,
|
|
16092
|
+
writeFileSync as writeFileSync10,
|
|
16093
|
+
existsSync as existsSync30,
|
|
15713
16094
|
readdirSync as readdirSync10,
|
|
15714
16095
|
unlinkSync as unlinkSync4
|
|
15715
16096
|
} from "fs";
|
|
@@ -15767,23 +16148,23 @@ class SessionFileEncryptor {
|
|
|
15767
16148
|
return lines.map((line) => this.decryptFileContent(line));
|
|
15768
16149
|
}
|
|
15769
16150
|
readSessionFile(filePath) {
|
|
15770
|
-
const content =
|
|
16151
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15771
16152
|
return this.decryptFileContent(content);
|
|
15772
16153
|
}
|
|
15773
16154
|
writeSessionFile(filePath, content) {
|
|
15774
16155
|
const encrypted = this.encryptFileContent(content);
|
|
15775
|
-
|
|
16156
|
+
writeFileSync10(filePath, encrypted, "utf8");
|
|
15776
16157
|
}
|
|
15777
16158
|
readSessionJSON(filePath) {
|
|
15778
|
-
const content =
|
|
16159
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15779
16160
|
return this.decryptJSON(content);
|
|
15780
16161
|
}
|
|
15781
16162
|
writeSessionJSON(filePath, obj) {
|
|
15782
16163
|
const content = this.encryptJSON(obj);
|
|
15783
|
-
|
|
16164
|
+
writeFileSync10(filePath, content, "utf8");
|
|
15784
16165
|
}
|
|
15785
16166
|
readSessionJSONL(filePath) {
|
|
15786
|
-
const content =
|
|
16167
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15787
16168
|
const lines = content.split(`
|
|
15788
16169
|
`).filter((line) => line.trim());
|
|
15789
16170
|
const decryptedLines = this.decryptJSONL(lines);
|
|
@@ -15797,7 +16178,7 @@ class SessionFileEncryptor {
|
|
|
15797
16178
|
}
|
|
15798
16179
|
appendToSessionJSONL(filePath, obj) {
|
|
15799
16180
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
15800
|
-
|
|
16181
|
+
writeFileSync10(filePath, encryptedLine + `
|
|
15801
16182
|
`, {
|
|
15802
16183
|
flag: "a",
|
|
15803
16184
|
encoding: "utf8"
|
|
@@ -15809,11 +16190,11 @@ class SessionFileEncryptor {
|
|
|
15809
16190
|
const files = readdirSync10(sessionDir);
|
|
15810
16191
|
for (const file of files) {
|
|
15811
16192
|
const filePath = join23(sessionDir, file);
|
|
15812
|
-
if (
|
|
16193
|
+
if (existsSync30(filePath) && !file.endsWith(".enc")) {
|
|
15813
16194
|
try {
|
|
15814
|
-
const content =
|
|
16195
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15815
16196
|
const encrypted = this.encryptFileContent(content);
|
|
15816
|
-
|
|
16197
|
+
writeFileSync10(filePath + ".enc", encrypted, "utf8");
|
|
15817
16198
|
unlinkSync4(filePath);
|
|
15818
16199
|
} catch {}
|
|
15819
16200
|
}
|
|
@@ -15828,9 +16209,9 @@ class SessionFileEncryptor {
|
|
|
15828
16209
|
const encFilePath = join23(sessionDir, file);
|
|
15829
16210
|
const decFilePath = encFilePath.slice(0, -4);
|
|
15830
16211
|
try {
|
|
15831
|
-
const content =
|
|
16212
|
+
const content = readFileSync18(encFilePath, "utf8");
|
|
15832
16213
|
const decrypted = this.decryptFileContent(content);
|
|
15833
|
-
|
|
16214
|
+
writeFileSync10(decFilePath, decrypted, "utf8");
|
|
15834
16215
|
unlinkSync4(encFilePath);
|
|
15835
16216
|
} catch {}
|
|
15836
16217
|
}
|
|
@@ -15850,12 +16231,12 @@ var init_session_encryption = __esm(() => {
|
|
|
15850
16231
|
|
|
15851
16232
|
// src/modules/session/store.ts
|
|
15852
16233
|
import {
|
|
15853
|
-
existsSync as
|
|
15854
|
-
mkdirSync as
|
|
16234
|
+
existsSync as existsSync31,
|
|
16235
|
+
mkdirSync as mkdirSync14,
|
|
15855
16236
|
readdirSync as readdirSync11,
|
|
15856
|
-
readFileSync as
|
|
16237
|
+
readFileSync as readFileSync19,
|
|
15857
16238
|
rmSync as rmSync2,
|
|
15858
|
-
writeFileSync as
|
|
16239
|
+
writeFileSync as writeFileSync11,
|
|
15859
16240
|
appendFileSync as appendFileSync6
|
|
15860
16241
|
} from "fs";
|
|
15861
16242
|
import { join as join24 } from "path";
|
|
@@ -15885,7 +16266,7 @@ class SessionStore {
|
|
|
15885
16266
|
return this.encryptor?.isEnabled() ?? false;
|
|
15886
16267
|
}
|
|
15887
16268
|
init() {
|
|
15888
|
-
|
|
16269
|
+
mkdirSync14(this.baseDir, { recursive: true });
|
|
15889
16270
|
}
|
|
15890
16271
|
sessionDir(id) {
|
|
15891
16272
|
return join24(this.baseDir, id);
|
|
@@ -15900,17 +16281,17 @@ class SessionStore {
|
|
|
15900
16281
|
return join24(this.sessionDir(id), "session.jsonl");
|
|
15901
16282
|
}
|
|
15902
16283
|
sessionExists(id) {
|
|
15903
|
-
return
|
|
16284
|
+
return existsSync31(this.metaPath(id));
|
|
15904
16285
|
}
|
|
15905
16286
|
saveMeta(id, meta) {
|
|
15906
16287
|
this._metaCache.set(id, meta);
|
|
15907
16288
|
const dir = this.sessionDir(id);
|
|
15908
|
-
|
|
16289
|
+
mkdirSync14(dir, { recursive: true });
|
|
15909
16290
|
const content = JSON.stringify(meta, null, 2);
|
|
15910
16291
|
if (this.encryptor) {
|
|
15911
|
-
|
|
16292
|
+
writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
|
|
15912
16293
|
} else {
|
|
15913
|
-
|
|
16294
|
+
writeFileSync11(this.metaPath(id), content, "utf-8");
|
|
15914
16295
|
}
|
|
15915
16296
|
}
|
|
15916
16297
|
loadMeta(id) {
|
|
@@ -15918,10 +16299,10 @@ class SessionStore {
|
|
|
15918
16299
|
if (cached)
|
|
15919
16300
|
return cached;
|
|
15920
16301
|
const path = this.metaPath(id);
|
|
15921
|
-
if (!
|
|
16302
|
+
if (!existsSync31(path))
|
|
15922
16303
|
return null;
|
|
15923
16304
|
try {
|
|
15924
|
-
const raw =
|
|
16305
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15925
16306
|
const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
|
|
15926
16307
|
const meta = JSON.parse(content);
|
|
15927
16308
|
this._metaCache.set(id, meta);
|
|
@@ -15932,7 +16313,7 @@ class SessionStore {
|
|
|
15932
16313
|
}
|
|
15933
16314
|
appendMessage(id, msg) {
|
|
15934
16315
|
const dir = this.sessionDir(id);
|
|
15935
|
-
|
|
16316
|
+
mkdirSync14(dir, { recursive: true });
|
|
15936
16317
|
const line = JSON.stringify(msg);
|
|
15937
16318
|
if (this.encryptor?.isEnabled()) {
|
|
15938
16319
|
appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -15950,10 +16331,10 @@ class SessionStore {
|
|
|
15950
16331
|
}
|
|
15951
16332
|
loadHistory(id) {
|
|
15952
16333
|
const path = this.historyPath(id);
|
|
15953
|
-
if (!
|
|
16334
|
+
if (!existsSync31(path))
|
|
15954
16335
|
return [];
|
|
15955
16336
|
try {
|
|
15956
|
-
const raw =
|
|
16337
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15957
16338
|
const lines = raw.split(`
|
|
15958
16339
|
`).filter(Boolean);
|
|
15959
16340
|
const parseLine = (line) => {
|
|
@@ -15979,7 +16360,7 @@ class SessionStore {
|
|
|
15979
16360
|
}
|
|
15980
16361
|
appendSessionLog(id, entry) {
|
|
15981
16362
|
const dir = this.sessionDir(id);
|
|
15982
|
-
|
|
16363
|
+
mkdirSync14(dir, { recursive: true });
|
|
15983
16364
|
const line = JSON.stringify(entry);
|
|
15984
16365
|
if (this.encryptor?.isEnabled()) {
|
|
15985
16366
|
appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -15991,10 +16372,10 @@ class SessionStore {
|
|
|
15991
16372
|
}
|
|
15992
16373
|
loadSessionLog(id) {
|
|
15993
16374
|
const path = this.sessionLogPath(id);
|
|
15994
|
-
if (!
|
|
16375
|
+
if (!existsSync31(path))
|
|
15995
16376
|
return [];
|
|
15996
16377
|
try {
|
|
15997
|
-
const raw =
|
|
16378
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15998
16379
|
const lines = raw.split(`
|
|
15999
16380
|
`).filter(Boolean);
|
|
16000
16381
|
const parseLine = (line) => {
|
|
@@ -16019,7 +16400,7 @@ class SessionStore {
|
|
|
16019
16400
|
}
|
|
16020
16401
|
}
|
|
16021
16402
|
listSessions() {
|
|
16022
|
-
if (!
|
|
16403
|
+
if (!existsSync31(this.baseDir))
|
|
16023
16404
|
return [];
|
|
16024
16405
|
const entries = readdirSync11(this.baseDir, { withFileTypes: true });
|
|
16025
16406
|
const sessions = [];
|
|
@@ -16036,7 +16417,7 @@ class SessionStore {
|
|
|
16036
16417
|
deleteSession(id) {
|
|
16037
16418
|
this._metaCache.delete(id);
|
|
16038
16419
|
const dir = this.sessionDir(id);
|
|
16039
|
-
if (
|
|
16420
|
+
if (existsSync31(dir)) {
|
|
16040
16421
|
rmSync2(dir, { recursive: true, force: true });
|
|
16041
16422
|
}
|
|
16042
16423
|
}
|
|
@@ -16048,18 +16429,18 @@ class SessionStore {
|
|
|
16048
16429
|
const updatedAt = new Date(session2.updatedAt);
|
|
16049
16430
|
if (updatedAt < thirtyDaysAgo) {
|
|
16050
16431
|
const historyPath = this.historyPath(session2.id);
|
|
16051
|
-
if (
|
|
16052
|
-
const content =
|
|
16432
|
+
if (existsSync31(historyPath)) {
|
|
16433
|
+
const content = readFileSync19(historyPath, "utf-8");
|
|
16053
16434
|
const compressed = gzipSync(content);
|
|
16054
16435
|
const gzPath = join24(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
16055
|
-
|
|
16436
|
+
writeFileSync11(gzPath, compressed);
|
|
16056
16437
|
rmSync2(historyPath);
|
|
16057
16438
|
}
|
|
16058
16439
|
}
|
|
16059
16440
|
}
|
|
16060
16441
|
}
|
|
16061
16442
|
}
|
|
16062
|
-
var
|
|
16443
|
+
var init_store3 = __esm(() => {
|
|
16063
16444
|
init_session_encryption();
|
|
16064
16445
|
});
|
|
16065
16446
|
|
|
@@ -16239,7 +16620,7 @@ var init_module2 = __esm(() => {
|
|
|
16239
16620
|
|
|
16240
16621
|
// src/modules/session/index.ts
|
|
16241
16622
|
var init_session2 = __esm(() => {
|
|
16242
|
-
|
|
16623
|
+
init_store3();
|
|
16243
16624
|
init_manager2();
|
|
16244
16625
|
init_module2();
|
|
16245
16626
|
});
|
|
@@ -16261,7 +16642,7 @@ class ProfileCompressor {
|
|
|
16261
16642
|
}
|
|
16262
16643
|
|
|
16263
16644
|
// src/modules/user-profile/profile.ts
|
|
16264
|
-
import { readFileSync as
|
|
16645
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync12, existsSync as existsSync32, mkdirSync as mkdirSync15 } from "fs";
|
|
16265
16646
|
import { join as join25 } from "path";
|
|
16266
16647
|
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
16267
16648
|
import { env } from "process";
|
|
@@ -16286,17 +16667,17 @@ class UserProfile {
|
|
|
16286
16667
|
return this.info;
|
|
16287
16668
|
}
|
|
16288
16669
|
save() {
|
|
16289
|
-
if (!
|
|
16290
|
-
|
|
16670
|
+
if (!existsSync32(this.profileDir)) {
|
|
16671
|
+
mkdirSync15(this.profileDir, { recursive: true });
|
|
16291
16672
|
}
|
|
16292
|
-
|
|
16673
|
+
writeFileSync12(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
16293
16674
|
}
|
|
16294
16675
|
load() {
|
|
16295
16676
|
const path = join25(this.profileDir, "profile.json");
|
|
16296
|
-
if (!
|
|
16677
|
+
if (!existsSync32(path))
|
|
16297
16678
|
return null;
|
|
16298
16679
|
try {
|
|
16299
|
-
const data = JSON.parse(
|
|
16680
|
+
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
16300
16681
|
this.info = {
|
|
16301
16682
|
platform: data.platform,
|
|
16302
16683
|
os: data.os,
|
|
@@ -16331,12 +16712,12 @@ class UserProfile {
|
|
|
16331
16712
|
var init_profile = () => {};
|
|
16332
16713
|
|
|
16333
16714
|
// src/modules/skills/loader.ts
|
|
16334
|
-
import { readdirSync as readdirSync12, readFileSync as
|
|
16715
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync33, statSync as statSync6 } from "fs";
|
|
16335
16716
|
import { join as join26 } from "path";
|
|
16336
16717
|
|
|
16337
16718
|
class SkillsLoader {
|
|
16338
16719
|
loadFromDir(dirPath) {
|
|
16339
|
-
if (!
|
|
16720
|
+
if (!existsSync33(dirPath))
|
|
16340
16721
|
return [];
|
|
16341
16722
|
const skills = [];
|
|
16342
16723
|
this.scanDir(dirPath, skills);
|
|
@@ -16353,7 +16734,7 @@ class SkillsLoader {
|
|
|
16353
16734
|
}
|
|
16354
16735
|
if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
|
|
16355
16736
|
continue;
|
|
16356
|
-
const content =
|
|
16737
|
+
const content = readFileSync21(fullPath, "utf-8");
|
|
16357
16738
|
const parsed = this.parseSkillFile(content, fullPath);
|
|
16358
16739
|
if (parsed)
|
|
16359
16740
|
skills.push(parsed);
|
|
@@ -16587,7 +16968,7 @@ var init_browser2 = __esm(() => {
|
|
|
16587
16968
|
|
|
16588
16969
|
// src/modules/lsp/client.ts
|
|
16589
16970
|
import { spawn as spawn5, execSync as execSync2 } from "child_process";
|
|
16590
|
-
import { resolve as
|
|
16971
|
+
import { resolve as resolve18 } from "path";
|
|
16591
16972
|
|
|
16592
16973
|
class LspClient {
|
|
16593
16974
|
process = null;
|
|
@@ -16603,7 +16984,7 @@ class LspClient {
|
|
|
16603
16984
|
const timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
16604
16985
|
try {
|
|
16605
16986
|
await this.startServer(config, baseDir);
|
|
16606
|
-
const rootUri = this.pathToUri(
|
|
16987
|
+
const rootUri = this.pathToUri(resolve18(baseDir));
|
|
16607
16988
|
const initResult = await this.sendRequest("initialize", {
|
|
16608
16989
|
processId: process.pid,
|
|
16609
16990
|
rootUri,
|
|
@@ -16612,11 +16993,11 @@ class LspClient {
|
|
|
16612
16993
|
}, timeout);
|
|
16613
16994
|
this.initialized = true;
|
|
16614
16995
|
this.sendNotification("initialized", {});
|
|
16615
|
-
const uri = this.pathToUri(
|
|
16996
|
+
const uri = this.pathToUri(resolve18(filePath));
|
|
16616
16997
|
const fs2 = await import("fs");
|
|
16617
16998
|
const content = fs2.readFileSync(filePath, "utf-8");
|
|
16618
|
-
const diagPromise = new Promise((
|
|
16619
|
-
this.diagnosticsResolve =
|
|
16999
|
+
const diagPromise = new Promise((resolve19) => {
|
|
17000
|
+
this.diagnosticsResolve = resolve19;
|
|
16620
17001
|
this.diagnostics = [];
|
|
16621
17002
|
this.diagnosticsTimer = setTimeout(() => {
|
|
16622
17003
|
if (this.diagnosticsResolve) {
|
|
@@ -16648,7 +17029,7 @@ class LspClient {
|
|
|
16648
17029
|
throw new Error(`${config.command} not found in PATH`);
|
|
16649
17030
|
}
|
|
16650
17031
|
}
|
|
16651
|
-
return new Promise((
|
|
17032
|
+
return new Promise((resolve19, reject) => {
|
|
16652
17033
|
const args = config.args ?? [];
|
|
16653
17034
|
const proc = spawn5(config.command, args, {
|
|
16654
17035
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -16661,7 +17042,7 @@ class LspClient {
|
|
|
16661
17042
|
});
|
|
16662
17043
|
proc.stderr.on("data", () => {});
|
|
16663
17044
|
proc.once("spawn", () => {
|
|
16664
|
-
|
|
17045
|
+
resolve19();
|
|
16665
17046
|
});
|
|
16666
17047
|
this.process = proc;
|
|
16667
17048
|
setTimeout(() => {
|
|
@@ -16738,9 +17119,9 @@ class LspClient {
|
|
|
16738
17119
|
}
|
|
16739
17120
|
}
|
|
16740
17121
|
sendRequest(method, params, timeout) {
|
|
16741
|
-
return new Promise((
|
|
17122
|
+
return new Promise((resolve19, reject) => {
|
|
16742
17123
|
const id = ++this.requestId;
|
|
16743
|
-
this.pending.set(id, { resolve:
|
|
17124
|
+
this.pending.set(id, { resolve: resolve19, reject });
|
|
16744
17125
|
const message = JSON.stringify({ jsonrpc: "2.0", id, method, params });
|
|
16745
17126
|
this.write(message);
|
|
16746
17127
|
setTimeout(() => {
|
|
@@ -16818,8 +17199,8 @@ var DEFAULT_TIMEOUT = 15000;
|
|
|
16818
17199
|
var init_client2 = () => {};
|
|
16819
17200
|
|
|
16820
17201
|
// src/modules/lsp/module.ts
|
|
16821
|
-
import { existsSync as
|
|
16822
|
-
import { resolve as
|
|
17202
|
+
import { existsSync as existsSync34 } from "fs";
|
|
17203
|
+
import { resolve as resolve19 } from "path";
|
|
16823
17204
|
|
|
16824
17205
|
class LspModule {
|
|
16825
17206
|
name = "lsp";
|
|
@@ -16843,8 +17224,8 @@ class LspModule {
|
|
|
16843
17224
|
const filePath = String(call.arguments.path ?? "");
|
|
16844
17225
|
if (!filePath)
|
|
16845
17226
|
return;
|
|
16846
|
-
const fullPath =
|
|
16847
|
-
if (!
|
|
17227
|
+
const fullPath = resolve19(_ctx.baseDir, filePath);
|
|
17228
|
+
if (!existsSync34(fullPath))
|
|
16848
17229
|
return;
|
|
16849
17230
|
const serverConfig = getServerForFile(fullPath, self.config);
|
|
16850
17231
|
if (!serverConfig)
|
|
@@ -16902,8 +17283,8 @@ var init_lsp = __esm(() => {
|
|
|
16902
17283
|
});
|
|
16903
17284
|
|
|
16904
17285
|
// src/modules/indexer/walker.ts
|
|
16905
|
-
import { readdirSync as readdirSync13, readFileSync as
|
|
16906
|
-
import { join as join27, relative, extname as extname5 } from "path";
|
|
17286
|
+
import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync35, watch } from "fs";
|
|
17287
|
+
import { join as join27, relative as relative2, extname as extname5 } from "path";
|
|
16907
17288
|
|
|
16908
17289
|
class Indexer {
|
|
16909
17290
|
baseDir;
|
|
@@ -16930,7 +17311,7 @@ class Indexer {
|
|
|
16930
17311
|
let totalSize = 0;
|
|
16931
17312
|
let count = 0;
|
|
16932
17313
|
const walkDir = (dir) => {
|
|
16933
|
-
if (!
|
|
17314
|
+
if (!existsSync35(dir))
|
|
16934
17315
|
return;
|
|
16935
17316
|
let entries;
|
|
16936
17317
|
try {
|
|
@@ -16942,7 +17323,7 @@ class Indexer {
|
|
|
16942
17323
|
if (count >= this.MAX_FILES)
|
|
16943
17324
|
return;
|
|
16944
17325
|
const fullPath = join27(dir, entry);
|
|
16945
|
-
const relPath =
|
|
17326
|
+
const relPath = relative2(this.baseDir, fullPath);
|
|
16946
17327
|
const stat = statSync7(fullPath);
|
|
16947
17328
|
if (stat.isDirectory()) {
|
|
16948
17329
|
if (!IGNORE_DIRS.has(entry)) {
|
|
@@ -16952,7 +17333,7 @@ class Indexer {
|
|
|
16952
17333
|
const ext = extname5(entry).toLowerCase();
|
|
16953
17334
|
const language = LANGUAGES[ext];
|
|
16954
17335
|
if (language) {
|
|
16955
|
-
const content =
|
|
17336
|
+
const content = readFileSync22(fullPath, "utf-8");
|
|
16956
17337
|
const exports = this.extractExports(content, language);
|
|
16957
17338
|
files.push({ path: relPath, language, exports, size: stat.size });
|
|
16958
17339
|
totalSize += stat.size;
|
|
@@ -17004,7 +17385,7 @@ var init_walker = __esm(() => {
|
|
|
17004
17385
|
});
|
|
17005
17386
|
|
|
17006
17387
|
// src/modules/indexer/cache.ts
|
|
17007
|
-
import { readFileSync as
|
|
17388
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync13, existsSync as existsSync36, mkdirSync as mkdirSync16, rmSync as rmSync3 } from "fs";
|
|
17008
17389
|
import { join as join28 } from "path";
|
|
17009
17390
|
|
|
17010
17391
|
class IndexCache {
|
|
@@ -17016,10 +17397,10 @@ class IndexCache {
|
|
|
17016
17397
|
load() {
|
|
17017
17398
|
if (this.cache)
|
|
17018
17399
|
return this.cache;
|
|
17019
|
-
if (!
|
|
17400
|
+
if (!existsSync36(this.cachePath))
|
|
17020
17401
|
return null;
|
|
17021
17402
|
try {
|
|
17022
|
-
this.cache = JSON.parse(
|
|
17403
|
+
this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
|
|
17023
17404
|
return this.cache;
|
|
17024
17405
|
} catch {
|
|
17025
17406
|
return null;
|
|
@@ -17028,13 +17409,13 @@ class IndexCache {
|
|
|
17028
17409
|
save(result) {
|
|
17029
17410
|
this.cache = result;
|
|
17030
17411
|
const dir = join28(this.cachePath, "..");
|
|
17031
|
-
if (!
|
|
17032
|
-
|
|
17033
|
-
|
|
17412
|
+
if (!existsSync36(dir))
|
|
17413
|
+
mkdirSync16(dir, { recursive: true });
|
|
17414
|
+
writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
|
|
17034
17415
|
}
|
|
17035
17416
|
invalidate() {
|
|
17036
17417
|
this.cache = null;
|
|
17037
|
-
if (
|
|
17418
|
+
if (existsSync36(this.cachePath)) {
|
|
17038
17419
|
try {
|
|
17039
17420
|
rmSync3(this.cachePath);
|
|
17040
17421
|
} catch {}
|
|
@@ -17434,7 +17815,7 @@ class MemoryModule {
|
|
|
17434
17815
|
}
|
|
17435
17816
|
}
|
|
17436
17817
|
var init_module8 = __esm(() => {
|
|
17437
|
-
|
|
17818
|
+
init_store2();
|
|
17438
17819
|
init_remember();
|
|
17439
17820
|
init_recall();
|
|
17440
17821
|
});
|
|
@@ -17446,8 +17827,8 @@ __export(exports_bootstrap, {
|
|
|
17446
17827
|
bootstrap: () => bootstrap
|
|
17447
17828
|
});
|
|
17448
17829
|
import { homedir as homedir11 } from "os";
|
|
17449
|
-
import { join as join30, resolve as
|
|
17450
|
-
import { existsSync as
|
|
17830
|
+
import { join as join30, resolve as resolve20 } from "path";
|
|
17831
|
+
import { existsSync as existsSync37, readFileSync as readFileSync24, writeFileSync as writeFileSync14 } from "fs";
|
|
17451
17832
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
17452
17833
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
17453
17834
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -17516,7 +17897,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17516
17897
|
retry: config.retry,
|
|
17517
17898
|
rateLimits: config.security?.rateLimits
|
|
17518
17899
|
});
|
|
17519
|
-
const baseDir = projectDir ?
|
|
17900
|
+
const baseDir = projectDir ? resolve20(projectDir) : process.cwd();
|
|
17520
17901
|
const projectMapCacheDir = join30(baseDir, ".mma");
|
|
17521
17902
|
const indexerModule = new IndexerModule({
|
|
17522
17903
|
baseDir,
|
|
@@ -17545,8 +17926,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17545
17926
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
17546
17927
|
};
|
|
17547
17928
|
const agentsMdGlobal = join30(dir, "AGENTS.md");
|
|
17548
|
-
if (!
|
|
17549
|
-
|
|
17929
|
+
if (!existsSync37(agentsMdGlobal)) {
|
|
17930
|
+
writeFileSync14(agentsMdGlobal, "", "utf-8");
|
|
17550
17931
|
}
|
|
17551
17932
|
const sessionDir = join30(dir, "sessions");
|
|
17552
17933
|
const sessionStore = new SessionStore(sessionDir);
|
|
@@ -17689,8 +18070,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17689
18070
|
join30(dir, "AGENTS.md")
|
|
17690
18071
|
];
|
|
17691
18072
|
for (const p of agentsMdCandidates) {
|
|
17692
|
-
if (
|
|
17693
|
-
const content =
|
|
18073
|
+
if (existsSync37(p)) {
|
|
18074
|
+
const content = readFileSync24(p, "utf-8").trim();
|
|
17694
18075
|
if (content) {
|
|
17695
18076
|
agentsMdBlocks.push({
|
|
17696
18077
|
content,
|
|
@@ -18317,10 +18698,10 @@ function menuList(items) {
|
|
|
18317
18698
|
console.log(l);
|
|
18318
18699
|
}
|
|
18319
18700
|
function ask(rl, question, defaultValue) {
|
|
18320
|
-
return new Promise((
|
|
18701
|
+
return new Promise((resolve21) => {
|
|
18321
18702
|
const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
18322
18703
|
rl.question(prompt, (answer) => {
|
|
18323
|
-
|
|
18704
|
+
resolve21(answer.trim() || defaultValue || "");
|
|
18324
18705
|
});
|
|
18325
18706
|
});
|
|
18326
18707
|
}
|
|
@@ -18539,21 +18920,21 @@ __export(exports_manifest, {
|
|
|
18539
18920
|
getCertMark: () => getCertMark,
|
|
18540
18921
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
18541
18922
|
});
|
|
18542
|
-
import { existsSync as
|
|
18923
|
+
import { existsSync as existsSync38, readFileSync as readFileSync25, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
18543
18924
|
import { homedir as homedir13 } from "os";
|
|
18544
18925
|
import { join as join32 } from "path";
|
|
18545
18926
|
function readManifest(path = MANIFEST_PATH) {
|
|
18546
18927
|
try {
|
|
18547
|
-
if (
|
|
18548
|
-
const raw = JSON.parse(
|
|
18928
|
+
if (existsSync38(path)) {
|
|
18929
|
+
const raw = JSON.parse(readFileSync25(path, "utf-8"));
|
|
18549
18930
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
18550
18931
|
}
|
|
18551
18932
|
} catch {}
|
|
18552
18933
|
return { version: 1, certifications: [] };
|
|
18553
18934
|
}
|
|
18554
18935
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
18555
|
-
|
|
18556
|
-
|
|
18936
|
+
mkdirSync17(join32(homedir13(), ".mma"), { recursive: true });
|
|
18937
|
+
writeFileSync15(path, JSON.stringify(m, null, 2), "utf-8");
|
|
18557
18938
|
}
|
|
18558
18939
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
18559
18940
|
const m = readManifest(path);
|
|
@@ -25710,7 +26091,7 @@ var init_scenarios = __esm(() => {
|
|
|
25710
26091
|
});
|
|
25711
26092
|
|
|
25712
26093
|
// src/modules/certification/loader.ts
|
|
25713
|
-
import { existsSync as
|
|
26094
|
+
import { existsSync as existsSync39, readdirSync as readdirSync14, readFileSync as readFileSync26 } from "fs";
|
|
25714
26095
|
import { join as join33 } from "path";
|
|
25715
26096
|
function validateScenario(s) {
|
|
25716
26097
|
const errors2 = [];
|
|
@@ -25760,12 +26141,12 @@ function loadScenarios(userDir) {
|
|
|
25760
26141
|
else
|
|
25761
26142
|
scenarios.push(s);
|
|
25762
26143
|
}
|
|
25763
|
-
if (userDir &&
|
|
26144
|
+
if (userDir && existsSync39(userDir)) {
|
|
25764
26145
|
for (const file of readdirSync14(userDir)) {
|
|
25765
26146
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
25766
26147
|
continue;
|
|
25767
26148
|
try {
|
|
25768
|
-
const raw =
|
|
26149
|
+
const raw = readFileSync26(join33(userDir, file), "utf-8");
|
|
25769
26150
|
const data = $parse(raw);
|
|
25770
26151
|
const parsed = normalizeScenario(data, file);
|
|
25771
26152
|
const errs = validateScenario(parsed);
|
|
@@ -25818,7 +26199,7 @@ var init_loader3 = __esm(() => {
|
|
|
25818
26199
|
});
|
|
25819
26200
|
|
|
25820
26201
|
// src/modules/certification/fact-checker.ts
|
|
25821
|
-
import { existsSync as
|
|
26202
|
+
import { existsSync as existsSync40, readFileSync as readFileSync27, statSync as statSync8 } from "fs";
|
|
25822
26203
|
import { join as join34 } from "path";
|
|
25823
26204
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
25824
26205
|
const failures = [];
|
|
@@ -25838,14 +26219,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25838
26219
|
case "fileExists":
|
|
25839
26220
|
return isFile(join34(sandboxDir, check.path));
|
|
25840
26221
|
case "fileNotExists":
|
|
25841
|
-
return !
|
|
26222
|
+
return !existsSync40(join34(sandboxDir, check.path));
|
|
25842
26223
|
case "dirExists":
|
|
25843
26224
|
return isDir(join34(sandboxDir, check.path));
|
|
25844
26225
|
case "fileContent": {
|
|
25845
26226
|
const abs = join34(sandboxDir, check.path);
|
|
25846
26227
|
if (!isFile(abs))
|
|
25847
26228
|
return false;
|
|
25848
|
-
const content =
|
|
26229
|
+
const content = readFileSync27(abs, "utf-8");
|
|
25849
26230
|
if (check.contains !== undefined)
|
|
25850
26231
|
return content.includes(check.contains);
|
|
25851
26232
|
if (check.equals !== undefined)
|
|
@@ -25856,7 +26237,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25856
26237
|
const abs = join34(sandboxDir, check.path);
|
|
25857
26238
|
if (!isFile(abs))
|
|
25858
26239
|
return false;
|
|
25859
|
-
return new RegExp(check.pattern).test(
|
|
26240
|
+
return new RegExp(check.pattern).test(readFileSync27(abs, "utf-8"));
|
|
25860
26241
|
}
|
|
25861
26242
|
default:
|
|
25862
26243
|
return false;
|
|
@@ -25864,14 +26245,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25864
26245
|
}
|
|
25865
26246
|
function isFile(p) {
|
|
25866
26247
|
try {
|
|
25867
|
-
return
|
|
26248
|
+
return existsSync40(p) && statSync8(p).isFile();
|
|
25868
26249
|
} catch {
|
|
25869
26250
|
return false;
|
|
25870
26251
|
}
|
|
25871
26252
|
}
|
|
25872
26253
|
function isDir(p) {
|
|
25873
26254
|
try {
|
|
25874
|
-
return
|
|
26255
|
+
return existsSync40(p) && statSync8(p).isDirectory();
|
|
25875
26256
|
} catch {
|
|
25876
26257
|
return false;
|
|
25877
26258
|
}
|
|
@@ -25902,9 +26283,9 @@ var init_fact_checker = () => {};
|
|
|
25902
26283
|
|
|
25903
26284
|
// src/modules/certification/runner.ts
|
|
25904
26285
|
import { spawn as spawn6 } from "child_process";
|
|
25905
|
-
import { existsSync as
|
|
26286
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync18, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
25906
26287
|
import { platform as platform5 } from "os";
|
|
25907
|
-
import { join as join35, resolve as
|
|
26288
|
+
import { join as join35, resolve as resolve21, dirname as dirname8 } from "path";
|
|
25908
26289
|
async function runScenario(scenario, opts) {
|
|
25909
26290
|
if (scenario.mode === "skip") {
|
|
25910
26291
|
return {
|
|
@@ -25982,30 +26363,30 @@ ${res.stderr}`;
|
|
|
25982
26363
|
}
|
|
25983
26364
|
function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
25984
26365
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
25985
|
-
|
|
26366
|
+
mkdirSync18(sandbox, { recursive: true });
|
|
25986
26367
|
for (const f of scenario.fixtures ?? []) {
|
|
25987
26368
|
const src = join35(mmaRoot, f.source);
|
|
25988
|
-
if (!
|
|
26369
|
+
if (!existsSync41(src)) {
|
|
25989
26370
|
throw new Error(`fixture missing: ${f.source}`);
|
|
25990
26371
|
}
|
|
25991
26372
|
const dest = join35(sandbox, f.dest);
|
|
25992
|
-
|
|
26373
|
+
mkdirSync18(dirname8(dest), { recursive: true });
|
|
25993
26374
|
cpSync2(src, dest);
|
|
25994
26375
|
}
|
|
25995
26376
|
}
|
|
25996
26377
|
function resolveMmaEntry(mmaRoot) {
|
|
25997
26378
|
const dev = join35(mmaRoot, "src", "cli", "main.ts");
|
|
25998
|
-
if (
|
|
26379
|
+
if (existsSync41(dev))
|
|
25999
26380
|
return dev;
|
|
26000
26381
|
return join35(mmaRoot, "dist", "main.js");
|
|
26001
26382
|
}
|
|
26002
26383
|
function findMmaRoot(fromDir) {
|
|
26003
26384
|
const candidates = [
|
|
26004
|
-
|
|
26005
|
-
|
|
26385
|
+
resolve21(fromDir, "..", "..", ".."),
|
|
26386
|
+
resolve21(fromDir, "..")
|
|
26006
26387
|
];
|
|
26007
26388
|
for (const c of candidates) {
|
|
26008
|
-
if (
|
|
26389
|
+
if (existsSync41(join35(c, "package.json")))
|
|
26009
26390
|
return c;
|
|
26010
26391
|
}
|
|
26011
26392
|
return process.cwd();
|
|
@@ -26075,13 +26456,13 @@ import { rmSync as rmSync5 } from "fs";
|
|
|
26075
26456
|
import { homedir as homedir14 } from "os";
|
|
26076
26457
|
import { join as join36, dirname as dirname9 } from "path";
|
|
26077
26458
|
import { fileURLToPath } from "url";
|
|
26078
|
-
import { existsSync as
|
|
26459
|
+
import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
|
|
26079
26460
|
function readVersion() {
|
|
26080
26461
|
const candidates = [join36(MMA_ROOT, "package.json")];
|
|
26081
26462
|
for (const p of candidates) {
|
|
26082
|
-
if (
|
|
26463
|
+
if (existsSync42(p)) {
|
|
26083
26464
|
try {
|
|
26084
|
-
const raw = JSON.parse(
|
|
26465
|
+
const raw = JSON.parse(readFileSync28(p, "utf-8"));
|
|
26085
26466
|
if (raw.version)
|
|
26086
26467
|
return raw.version;
|
|
26087
26468
|
} catch {}
|
|
@@ -26242,7 +26623,7 @@ __export(exports_repl_commands, {
|
|
|
26242
26623
|
});
|
|
26243
26624
|
import { join as join38, dirname as dirname11 } from "path";
|
|
26244
26625
|
import { homedir as homedir16 } from "os";
|
|
26245
|
-
import { existsSync as
|
|
26626
|
+
import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
|
|
26246
26627
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
26247
26628
|
function readVersion3() {
|
|
26248
26629
|
const here = dirname11(fileURLToPath3(import.meta.url));
|
|
@@ -26251,9 +26632,9 @@ function readVersion3() {
|
|
|
26251
26632
|
join38(here, "..", "package.json")
|
|
26252
26633
|
];
|
|
26253
26634
|
for (const p of candidates) {
|
|
26254
|
-
if (
|
|
26635
|
+
if (existsSync44(p)) {
|
|
26255
26636
|
try {
|
|
26256
|
-
const raw = JSON.parse(
|
|
26637
|
+
const raw = JSON.parse(readFileSync30(p, "utf8"));
|
|
26257
26638
|
if (raw.version)
|
|
26258
26639
|
return raw.version;
|
|
26259
26640
|
} catch {}
|
|
@@ -26317,8 +26698,8 @@ function registerMmaCommands(ctx) {
|
|
|
26317
26698
|
}
|
|
26318
26699
|
try {
|
|
26319
26700
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
26320
|
-
const { existsSync:
|
|
26321
|
-
const { resolve:
|
|
26701
|
+
const { existsSync: existsSync45 } = await import("fs");
|
|
26702
|
+
const { resolve: resolve22 } = await import("path");
|
|
26322
26703
|
let dataUrl;
|
|
26323
26704
|
let label;
|
|
26324
26705
|
if (source.toLowerCase() === "clipboard") {
|
|
@@ -26336,8 +26717,8 @@ function registerMmaCommands(ctx) {
|
|
|
26336
26717
|
dataUrl = result.dataUrl;
|
|
26337
26718
|
label = source;
|
|
26338
26719
|
} else {
|
|
26339
|
-
const absPath =
|
|
26340
|
-
if (!
|
|
26720
|
+
const absPath = resolve22(process.cwd(), source);
|
|
26721
|
+
if (!existsSync45(absPath)) {
|
|
26341
26722
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
26342
26723
|
return;
|
|
26343
26724
|
}
|
|
@@ -26875,7 +27256,7 @@ init_setup();
|
|
|
26875
27256
|
init_i18n();
|
|
26876
27257
|
import { join as join37, dirname as dirname10 } from "path";
|
|
26877
27258
|
import { homedir as homedir15 } from "os";
|
|
26878
|
-
import { existsSync as
|
|
27259
|
+
import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
|
|
26879
27260
|
|
|
26880
27261
|
// src/cli/security-commands.ts
|
|
26881
27262
|
init_bootstrap();
|
|
@@ -27503,9 +27884,9 @@ function readVersion2() {
|
|
|
27503
27884
|
join37(here, "..", "package.json")
|
|
27504
27885
|
];
|
|
27505
27886
|
for (const p of candidates) {
|
|
27506
|
-
if (
|
|
27887
|
+
if (existsSync43(p)) {
|
|
27507
27888
|
try {
|
|
27508
|
-
const raw = JSON.parse(
|
|
27889
|
+
const raw = JSON.parse(readFileSync29(p, "utf8"));
|
|
27509
27890
|
if (raw.version)
|
|
27510
27891
|
return raw.version;
|
|
27511
27892
|
} catch {}
|
|
@@ -27732,7 +28113,7 @@ init_bootstrap();
|
|
|
27732
28113
|
// src/cli/repl.ts
|
|
27733
28114
|
init_colors();
|
|
27734
28115
|
import * as readline2 from "readline";
|
|
27735
|
-
import { existsSync as
|
|
28116
|
+
import { existsSync as existsSync45, readFileSync as readFileSync31, writeFileSync as writeFileSync16 } from "fs";
|
|
27736
28117
|
import { join as join39, dirname as dirname12 } from "path";
|
|
27737
28118
|
import { homedir as homedir17 } from "os";
|
|
27738
28119
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -28251,9 +28632,9 @@ function readVersion4() {
|
|
|
28251
28632
|
join39(here, "..", "package.json")
|
|
28252
28633
|
];
|
|
28253
28634
|
for (const p of candidates) {
|
|
28254
|
-
if (
|
|
28635
|
+
if (existsSync45(p)) {
|
|
28255
28636
|
try {
|
|
28256
|
-
const raw = JSON.parse(
|
|
28637
|
+
const raw = JSON.parse(readFileSync31(p, "utf8"));
|
|
28257
28638
|
if (raw.version)
|
|
28258
28639
|
return raw.version;
|
|
28259
28640
|
} catch {}
|
|
@@ -28331,9 +28712,9 @@ class Repl {
|
|
|
28331
28712
|
this.setupListeners();
|
|
28332
28713
|
}
|
|
28333
28714
|
loadHistory() {
|
|
28334
|
-
if (
|
|
28715
|
+
if (existsSync45(this.historyPath)) {
|
|
28335
28716
|
try {
|
|
28336
|
-
const raw =
|
|
28717
|
+
const raw = readFileSync31(this.historyPath, "utf-8");
|
|
28337
28718
|
this.history = raw.split(`
|
|
28338
28719
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
28339
28720
|
} catch {
|
|
@@ -28343,7 +28724,7 @@ class Repl {
|
|
|
28343
28724
|
}
|
|
28344
28725
|
saveHistory() {
|
|
28345
28726
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
28346
|
-
|
|
28727
|
+
writeFileSync16(this.historyPath, allHistory.join(`
|
|
28347
28728
|
`), "utf-8");
|
|
28348
28729
|
}
|
|
28349
28730
|
setupCompleter() {
|
|
@@ -28668,7 +29049,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
28668
29049
|
join39(this.baseDir, ".mma", "AGENTS.md"),
|
|
28669
29050
|
join39(this.configDir, "AGENTS.md")
|
|
28670
29051
|
];
|
|
28671
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
29052
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync45(p));
|
|
28672
29053
|
if (foundAgents.length > 0) {
|
|
28673
29054
|
for (const p of foundAgents) {
|
|
28674
29055
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -28705,7 +29086,7 @@ init_setup();
|
|
|
28705
29086
|
init_config2();
|
|
28706
29087
|
init_i18n();
|
|
28707
29088
|
init_colors();
|
|
28708
|
-
import { existsSync as
|
|
29089
|
+
import { existsSync as existsSync46 } from "fs";
|
|
28709
29090
|
import { join as join40 } from "path";
|
|
28710
29091
|
import { homedir as homedir18 } from "os";
|
|
28711
29092
|
async function main() {
|
|
@@ -28774,7 +29155,7 @@ async function main() {
|
|
|
28774
29155
|
agent.shutdown();
|
|
28775
29156
|
} else {
|
|
28776
29157
|
const configPath = join40(homedir18(), ".mma", "config.json");
|
|
28777
|
-
if (!
|
|
29158
|
+
if (!existsSync46(configPath)) {
|
|
28778
29159
|
console.log(pc2.yellow(`
|
|
28779
29160
|
` + t("cli.first_run") + `
|
|
28780
29161
|
`));
|