micro-models-agent 0.28.17 → 0.29.1
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 +625 -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,229 @@ 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
|
+
import { resolve as resolve14 } from "node:path";
|
|
12123
|
+
var chunkQueryTool;
|
|
12124
|
+
var init_chunk_query = __esm(() => {
|
|
12125
|
+
init_i18n();
|
|
12126
|
+
init_scope_check();
|
|
12127
|
+
chunkQueryTool = {
|
|
12128
|
+
name: "chunk_query",
|
|
12129
|
+
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.",
|
|
12130
|
+
tags: ["research", "code"],
|
|
12131
|
+
timeoutMs: 300000,
|
|
12132
|
+
parameters: {
|
|
12133
|
+
type: "object",
|
|
12134
|
+
properties: {
|
|
12135
|
+
query: {
|
|
12136
|
+
type: "string",
|
|
12137
|
+
description: "The question to answer over the text."
|
|
12138
|
+
},
|
|
12139
|
+
input_path: {
|
|
12140
|
+
type: "string",
|
|
12141
|
+
description: "Path to the large text file (scope-checked). Preferred over text."
|
|
12142
|
+
},
|
|
12143
|
+
text: {
|
|
12144
|
+
type: "string",
|
|
12145
|
+
description: "Inline text. Use only when a file path is not available."
|
|
12146
|
+
},
|
|
12147
|
+
chunk_chars: {
|
|
12148
|
+
type: "number",
|
|
12149
|
+
description: "Approximate chunk size in chars (default 12000)."
|
|
12150
|
+
},
|
|
12151
|
+
max_parallel: {
|
|
12152
|
+
type: "number",
|
|
12153
|
+
description: "Max parallel chunk queries (default from config.subagent.maxParallelChunkQueries)."
|
|
12154
|
+
},
|
|
12155
|
+
max_chunk_tokens: {
|
|
12156
|
+
type: "number",
|
|
12157
|
+
description: "Cap on generated tokens per chunk call (default 1024)."
|
|
12158
|
+
},
|
|
12159
|
+
max_synthesis_tokens: {
|
|
12160
|
+
type: "number",
|
|
12161
|
+
description: "Cap on generated tokens for the synthesis call (default 2048)."
|
|
12162
|
+
},
|
|
12163
|
+
reasoning_effort: {
|
|
12164
|
+
type: "string",
|
|
12165
|
+
enum: ["none", "low", "medium", "high"],
|
|
12166
|
+
description: 'Reasoning effort for chunk/synthesis calls (default "none"). "none" prevents long thinking chains from eating the token budget on reasoning models.'
|
|
12167
|
+
},
|
|
12168
|
+
synthesize: {
|
|
12169
|
+
type: "boolean",
|
|
12170
|
+
description: "Run a final synthesis call over chunk answers (default true)."
|
|
12171
|
+
}
|
|
12172
|
+
},
|
|
12173
|
+
required: ["query"]
|
|
12174
|
+
},
|
|
12175
|
+
handler: async (ctx, args) => {
|
|
12176
|
+
const query = String(args.query || "");
|
|
12177
|
+
const inputPath = args.input_path ? String(args.input_path) : undefined;
|
|
12178
|
+
const text = args.text ? String(args.text) : undefined;
|
|
12179
|
+
if (!query)
|
|
12180
|
+
return { success: false, output: t("tool.chunk_query_no_query") };
|
|
12181
|
+
if (!inputPath && !text)
|
|
12182
|
+
return { success: false, output: t("tool.chunk_query_no_input") };
|
|
12183
|
+
let content = text || "";
|
|
12184
|
+
if (inputPath) {
|
|
12185
|
+
const check = isPathInScope2(ctx.baseDir, inputPath, ctx.scope);
|
|
12186
|
+
if (!check.allowed) {
|
|
12187
|
+
return { success: false, output: `[SCOPE] ${check.reason || "Path not allowed"}` };
|
|
12188
|
+
}
|
|
12189
|
+
try {
|
|
12190
|
+
content = readFileSync12(resolve14(ctx.baseDir, inputPath), "utf8");
|
|
12191
|
+
} catch (e) {
|
|
12192
|
+
return { success: false, output: `Cannot read ${inputPath}: ${e.message}` };
|
|
12193
|
+
}
|
|
12194
|
+
}
|
|
12195
|
+
if (!ctx.llmProvider) {
|
|
12196
|
+
return { success: false, output: "chunk_query: missing llmProvider in context" };
|
|
12197
|
+
}
|
|
12198
|
+
const maxParallel = typeof args.max_parallel === "number" ? args.max_parallel : ctx.config.subagent?.maxParallelChunkQueries ?? 4;
|
|
12199
|
+
const res = await runChunkQuery(ctx.llmProvider, content, query, {
|
|
12200
|
+
chunkChars: typeof args.chunk_chars === "number" ? args.chunk_chars : undefined,
|
|
12201
|
+
maxParallel,
|
|
12202
|
+
synthesize: typeof args.synthesize === "boolean" ? args.synthesize : undefined,
|
|
12203
|
+
maxChunkTokens: typeof args.max_chunk_tokens === "number" ? args.max_chunk_tokens : undefined,
|
|
12204
|
+
maxSynthesisTokens: typeof args.max_synthesis_tokens === "number" ? args.max_synthesis_tokens : undefined,
|
|
12205
|
+
reasoningEffort: ["none", "low", "medium", "high"].includes(args.reasoning_effort) ? args.reasoning_effort : undefined,
|
|
12206
|
+
logger: ctx.logger
|
|
12207
|
+
});
|
|
12208
|
+
ctx.logger.debug(`chunk_query: ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}`);
|
|
12209
|
+
return {
|
|
12210
|
+
success: true,
|
|
12211
|
+
output: `[chunk_query] ${res.chunks} chunk(s), ${res.totalChars} chars, max parallel ${res.maxParallelObserved}
|
|
12212
|
+
|
|
12213
|
+
${res.synthesis || res.answers.join(`
|
|
12214
|
+
`)}`
|
|
12215
|
+
};
|
|
12216
|
+
}
|
|
12217
|
+
};
|
|
12218
|
+
});
|
|
12219
|
+
|
|
11840
12220
|
// src/modules/security/network-validator.ts
|
|
11841
12221
|
function isUrlAllowed(url, securityConfig) {
|
|
11842
12222
|
if (!securityConfig?.enabled) {
|
|
@@ -12586,7 +12966,7 @@ class MCPClient {
|
|
|
12586
12966
|
}
|
|
12587
12967
|
}
|
|
12588
12968
|
connectStdio() {
|
|
12589
|
-
return new Promise((
|
|
12969
|
+
return new Promise((resolve15, reject) => {
|
|
12590
12970
|
const child = spawn3(this.config.command, this.config.args || [], {
|
|
12591
12971
|
env: { ...process.env, ...this.config.env },
|
|
12592
12972
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -12610,7 +12990,7 @@ class MCPClient {
|
|
|
12610
12990
|
this._connected = true;
|
|
12611
12991
|
this.process = child;
|
|
12612
12992
|
_resolved = true;
|
|
12613
|
-
|
|
12993
|
+
resolve15();
|
|
12614
12994
|
});
|
|
12615
12995
|
});
|
|
12616
12996
|
}
|
|
@@ -12679,7 +13059,7 @@ class MCPClient {
|
|
|
12679
13059
|
if (!this.process) {
|
|
12680
13060
|
throw new Error("Not connected to MCP server");
|
|
12681
13061
|
}
|
|
12682
|
-
return new Promise((
|
|
13062
|
+
return new Promise((resolve15, reject) => {
|
|
12683
13063
|
const request = {
|
|
12684
13064
|
jsonrpc: "2.0",
|
|
12685
13065
|
id: Date.now(),
|
|
@@ -12703,7 +13083,7 @@ class MCPClient {
|
|
|
12703
13083
|
if (response.error) {
|
|
12704
13084
|
reject(new Error(response.error.message));
|
|
12705
13085
|
} else {
|
|
12706
|
-
|
|
13086
|
+
resolve15(response.result?.tools || []);
|
|
12707
13087
|
}
|
|
12708
13088
|
return;
|
|
12709
13089
|
}
|
|
@@ -12785,8 +13165,8 @@ class MCPClient {
|
|
|
12785
13165
|
arguments: args
|
|
12786
13166
|
}
|
|
12787
13167
|
};
|
|
12788
|
-
return new Promise((
|
|
12789
|
-
this.pendingResolve =
|
|
13168
|
+
return new Promise((resolve15, reject) => {
|
|
13169
|
+
this.pendingResolve = resolve15;
|
|
12790
13170
|
this.pendingReject = reject;
|
|
12791
13171
|
const timeout = this.config.timeout || 30000;
|
|
12792
13172
|
const timer = setTimeout(() => {
|
|
@@ -12813,7 +13193,7 @@ class MCPClient {
|
|
|
12813
13193
|
if (result.error) {
|
|
12814
13194
|
reject(new Error(result.error.message));
|
|
12815
13195
|
} else {
|
|
12816
|
-
|
|
13196
|
+
resolve15(result.result || result);
|
|
12817
13197
|
}
|
|
12818
13198
|
}).catch((err) => {
|
|
12819
13199
|
clearTimeout(timer);
|
|
@@ -12827,7 +13207,7 @@ class MCPClient {
|
|
|
12827
13207
|
if (!this.process) {
|
|
12828
13208
|
throw new Error("Not connected to MCP server");
|
|
12829
13209
|
}
|
|
12830
|
-
return new Promise((
|
|
13210
|
+
return new Promise((resolve15, reject) => {
|
|
12831
13211
|
const request = {
|
|
12832
13212
|
jsonrpc: "2.0",
|
|
12833
13213
|
id: Date.now(),
|
|
@@ -12855,7 +13235,7 @@ class MCPClient {
|
|
|
12855
13235
|
if (response.error) {
|
|
12856
13236
|
reject(new Error(response.error.message));
|
|
12857
13237
|
} else {
|
|
12858
|
-
|
|
13238
|
+
resolve15(response.result);
|
|
12859
13239
|
}
|
|
12860
13240
|
return;
|
|
12861
13241
|
}
|
|
@@ -13057,7 +13437,7 @@ import { join as join15 } from "path";
|
|
|
13057
13437
|
var CATEGORIES, rememberTool;
|
|
13058
13438
|
var init_remember = __esm(() => {
|
|
13059
13439
|
init_i18n();
|
|
13060
|
-
|
|
13440
|
+
init_store2();
|
|
13061
13441
|
CATEGORIES = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
13062
13442
|
rememberTool = {
|
|
13063
13443
|
name: "remember",
|
|
@@ -13184,7 +13564,7 @@ function searchCategory(store, category, query) {
|
|
|
13184
13564
|
var CATEGORIES2, recallTool;
|
|
13185
13565
|
var init_recall = __esm(() => {
|
|
13186
13566
|
init_i18n();
|
|
13187
|
-
|
|
13567
|
+
init_store2();
|
|
13188
13568
|
CATEGORIES2 = ["preferences", "conventions", "decisions", "errors", "facts"];
|
|
13189
13569
|
recallTool = {
|
|
13190
13570
|
name: "recall",
|
|
@@ -13883,7 +14263,7 @@ __export(exports_image_utils, {
|
|
|
13883
14263
|
detectMime: () => detectMime,
|
|
13884
14264
|
bufferToDataUrl: () => bufferToDataUrl
|
|
13885
14265
|
});
|
|
13886
|
-
import { readFileSync as
|
|
14266
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
13887
14267
|
import { extname as extname3 } from "path";
|
|
13888
14268
|
function detectMime(filePath) {
|
|
13889
14269
|
const ext = extname3(filePath).toLowerCase();
|
|
@@ -13904,7 +14284,7 @@ async function readClipboardImage() {
|
|
|
13904
14284
|
async function readClipboardFallback() {
|
|
13905
14285
|
const { platform: platform3 } = await import("os");
|
|
13906
14286
|
const { execSync } = await import("child_process");
|
|
13907
|
-
const { readFileSync:
|
|
14287
|
+
const { readFileSync: readFileSync15, unlinkSync: unlinkSync4 } = await import("fs");
|
|
13908
14288
|
const { join: join19 } = await import("path");
|
|
13909
14289
|
const tmpPath = join19(process.env.TEMP || process.env.TMP || "/tmp", `mma-clip-${Date.now()}.png`);
|
|
13910
14290
|
try {
|
|
@@ -13913,7 +14293,7 @@ async function readClipboardFallback() {
|
|
|
13913
14293
|
} else {
|
|
13914
14294
|
return null;
|
|
13915
14295
|
}
|
|
13916
|
-
const buf =
|
|
14296
|
+
const buf = readFileSync15(tmpPath);
|
|
13917
14297
|
unlinkSync4(tmpPath);
|
|
13918
14298
|
return buf.length > 0 ? buf : null;
|
|
13919
14299
|
} catch {
|
|
@@ -13924,7 +14304,7 @@ async function readClipboardFallback() {
|
|
|
13924
14304
|
}
|
|
13925
14305
|
}
|
|
13926
14306
|
async function loadFileAsDataUrl(filePath) {
|
|
13927
|
-
const buf =
|
|
14307
|
+
const buf = readFileSync14(filePath);
|
|
13928
14308
|
if (typeof Bun !== "undefined" && typeof Bun.Image !== "undefined") {
|
|
13929
14309
|
try {
|
|
13930
14310
|
const img = new Bun.Image(buf);
|
|
@@ -13984,8 +14364,8 @@ var init_image_utils = __esm(() => {
|
|
|
13984
14364
|
});
|
|
13985
14365
|
|
|
13986
14366
|
// src/tools/attach-image.ts
|
|
13987
|
-
import { existsSync as
|
|
13988
|
-
import { resolve as
|
|
14367
|
+
import { existsSync as existsSync24 } from "fs";
|
|
14368
|
+
import { resolve as resolve15 } from "path";
|
|
13989
14369
|
var attachImageTool;
|
|
13990
14370
|
var init_attach_image = __esm(() => {
|
|
13991
14371
|
init_i18n();
|
|
@@ -14026,16 +14406,16 @@ var init_attach_image = __esm(() => {
|
|
|
14026
14406
|
const result = await loadUrlAsDataUrl(source);
|
|
14027
14407
|
dataUrl = result.dataUrl;
|
|
14028
14408
|
} else {
|
|
14029
|
-
const absPath =
|
|
14030
|
-
if (!
|
|
14409
|
+
const absPath = resolve15(ctx.baseDir, source);
|
|
14410
|
+
if (!existsSync24(absPath)) {
|
|
14031
14411
|
return {
|
|
14032
14412
|
success: false,
|
|
14033
14413
|
output: t("image.not_found", { path: source })
|
|
14034
14414
|
};
|
|
14035
14415
|
}
|
|
14036
14416
|
if (ctx.scope) {
|
|
14037
|
-
const { isPathInScope:
|
|
14038
|
-
const validation =
|
|
14417
|
+
const { isPathInScope: isPathInScope3 } = await Promise.resolve().then(() => (init_path_validator(), exports_path_validator));
|
|
14418
|
+
const validation = isPathInScope3(ctx.baseDir, absPath, ctx.scope);
|
|
14039
14419
|
if (!validation.allowed) {
|
|
14040
14420
|
logSecurityBlock(ctx.sessionId, "file_read", validation.reason ?? "attach_image out of scope", absPath);
|
|
14041
14421
|
return {
|
|
@@ -14087,6 +14467,7 @@ function registerAllTools(registry2, skillsModule) {
|
|
|
14087
14467
|
fileInfoTool,
|
|
14088
14468
|
bashTool,
|
|
14089
14469
|
subagentTool,
|
|
14470
|
+
chunkQueryTool,
|
|
14090
14471
|
processListTool,
|
|
14091
14472
|
processLogTool,
|
|
14092
14473
|
processKillTool,
|
|
@@ -14122,6 +14503,7 @@ var init_tools = __esm(() => {
|
|
|
14122
14503
|
init_process_log();
|
|
14123
14504
|
init_process_kill();
|
|
14124
14505
|
init_subagent();
|
|
14506
|
+
init_chunk_query();
|
|
14125
14507
|
init_web_search();
|
|
14126
14508
|
init_web_fetch();
|
|
14127
14509
|
init_web_browse();
|
|
@@ -14183,12 +14565,12 @@ class ModuleRegistry {
|
|
|
14183
14565
|
}
|
|
14184
14566
|
|
|
14185
14567
|
// src/modules/plugins/loader.ts
|
|
14186
|
-
import { readdirSync as readdirSync7, existsSync as
|
|
14568
|
+
import { readdirSync as readdirSync7, existsSync as existsSync25, statSync as statSync5 } from "fs";
|
|
14187
14569
|
import { join as join19 } from "path";
|
|
14188
14570
|
|
|
14189
14571
|
class PluginLoader {
|
|
14190
14572
|
loadFromDir(dirPath, pluginManager, logger) {
|
|
14191
|
-
if (!
|
|
14573
|
+
if (!existsSync25(dirPath))
|
|
14192
14574
|
return;
|
|
14193
14575
|
const entries = readdirSync7(dirPath);
|
|
14194
14576
|
for (const entry of entries) {
|
|
@@ -14216,8 +14598,8 @@ var init_loader = __esm(() => {
|
|
|
14216
14598
|
|
|
14217
14599
|
// src/modules/plugins/builtin/lint-on-write.ts
|
|
14218
14600
|
import { spawn as spawn4, execSync } from "child_process";
|
|
14219
|
-
import { existsSync as
|
|
14220
|
-
import { resolve as
|
|
14601
|
+
import { existsSync as existsSync26, readFileSync as readFileSync15 } from "fs";
|
|
14602
|
+
import { resolve as resolve16, extname as extname4, join as join20 } from "path";
|
|
14221
14603
|
import { platform as platform3 } from "os";
|
|
14222
14604
|
function contentHash(content) {
|
|
14223
14605
|
let h = 5381;
|
|
@@ -14262,8 +14644,8 @@ class LintOnWritePlugin {
|
|
|
14262
14644
|
const path = String(call.arguments.path || "");
|
|
14263
14645
|
if (!path)
|
|
14264
14646
|
return;
|
|
14265
|
-
const fullPath =
|
|
14266
|
-
if (!
|
|
14647
|
+
const fullPath = resolve16(ctx.baseDir, path);
|
|
14648
|
+
if (!existsSync26(fullPath))
|
|
14267
14649
|
return;
|
|
14268
14650
|
const ext = extname4(fullPath);
|
|
14269
14651
|
const syntaxError = await this.checkSyntax(fullPath, ext, ctx.baseDir);
|
|
@@ -14280,7 +14662,7 @@ class LintOnWritePlugin {
|
|
|
14280
14662
|
if (ext === ".ts" || ext === ".tsx") {
|
|
14281
14663
|
let content = "";
|
|
14282
14664
|
try {
|
|
14283
|
-
content =
|
|
14665
|
+
content = readFileSync15(filePath, "utf-8");
|
|
14284
14666
|
} catch {
|
|
14285
14667
|
return null;
|
|
14286
14668
|
}
|
|
@@ -14320,10 +14702,10 @@ class LintOnWritePlugin {
|
|
|
14320
14702
|
async runProjectLint(ctx, result) {
|
|
14321
14703
|
try {
|
|
14322
14704
|
const packageJsonPath = join20(ctx.baseDir, "package.json");
|
|
14323
|
-
if (!
|
|
14705
|
+
if (!existsSync26(packageJsonPath)) {
|
|
14324
14706
|
return;
|
|
14325
14707
|
}
|
|
14326
|
-
const packageJson = JSON.parse(
|
|
14708
|
+
const packageJson = JSON.parse(readFileSync15(packageJsonPath, "utf-8"));
|
|
14327
14709
|
const lintScript = packageJson.scripts?.lint;
|
|
14328
14710
|
if (!lintScript) {
|
|
14329
14711
|
return;
|
|
@@ -14340,7 +14722,7 @@ class LintOnWritePlugin {
|
|
|
14340
14722
|
}
|
|
14341
14723
|
async runProjectTypeCheck(ctx, result) {
|
|
14342
14724
|
const tsconfigPath = join20(ctx.baseDir, "tsconfig.json");
|
|
14343
|
-
if (!
|
|
14725
|
+
if (!existsSync26(tsconfigPath)) {
|
|
14344
14726
|
return;
|
|
14345
14727
|
}
|
|
14346
14728
|
const now = Date.now();
|
|
@@ -14381,7 +14763,7 @@ class LintOnWritePlugin {
|
|
|
14381
14763
|
}
|
|
14382
14764
|
}
|
|
14383
14765
|
function runAsync(command, cwd, timeoutMs) {
|
|
14384
|
-
return new Promise((
|
|
14766
|
+
return new Promise((resolve17, reject) => {
|
|
14385
14767
|
const child = spawn4(command, {
|
|
14386
14768
|
cwd,
|
|
14387
14769
|
shell: true,
|
|
@@ -14410,7 +14792,7 @@ function runAsync(command, cwd, timeoutMs) {
|
|
|
14410
14792
|
stdout += decoder.decode();
|
|
14411
14793
|
stderr += decoder.decode();
|
|
14412
14794
|
if (code === 0) {
|
|
14413
|
-
|
|
14795
|
+
resolve17({ stdout, stderr });
|
|
14414
14796
|
} else {
|
|
14415
14797
|
const err = new Error(`Command failed with exit code ${code}`);
|
|
14416
14798
|
err.stdout = stdout;
|
|
@@ -14582,8 +14964,8 @@ class PlanTracker {
|
|
|
14582
14964
|
var init_tracker = () => {};
|
|
14583
14965
|
|
|
14584
14966
|
// src/modules/execution/auditor.ts
|
|
14585
|
-
import { existsSync as
|
|
14586
|
-
import { resolve as
|
|
14967
|
+
import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
|
|
14968
|
+
import { resolve as resolve17, join as join21 } from "path";
|
|
14587
14969
|
function findTestFile(dir, depth = 0) {
|
|
14588
14970
|
if (depth > 5)
|
|
14589
14971
|
return null;
|
|
@@ -14673,8 +15055,8 @@ class Auditor {
|
|
|
14673
15055
|
const missingFiles = [];
|
|
14674
15056
|
const existingFiles = [];
|
|
14675
15057
|
for (const filePath of uniqueFiles) {
|
|
14676
|
-
const resolved =
|
|
14677
|
-
if (
|
|
15058
|
+
const resolved = resolve17(this.baseDir, filePath);
|
|
15059
|
+
if (existsSync27(resolved)) {
|
|
14678
15060
|
existingFiles.push(filePath);
|
|
14679
15061
|
} else {
|
|
14680
15062
|
missingFiles.push(filePath);
|
|
@@ -14753,11 +15135,11 @@ var init_auditor = __esm(() => {
|
|
|
14753
15135
|
});
|
|
14754
15136
|
|
|
14755
15137
|
// src/modules/execution/plan-store.ts
|
|
14756
|
-
import { readFileSync as
|
|
15138
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync13, existsSync as existsSync28, readdirSync as readdirSync9, rmSync } from "fs";
|
|
14757
15139
|
import { join as join22 } from "path";
|
|
14758
15140
|
function readPlanFile(path, fallbackBaseDir) {
|
|
14759
15141
|
try {
|
|
14760
|
-
const raw =
|
|
15142
|
+
const raw = readFileSync16(path, "utf-8");
|
|
14761
15143
|
if (!raw.trim())
|
|
14762
15144
|
return null;
|
|
14763
15145
|
const parsed = JSON.parse(raw);
|
|
@@ -14776,10 +15158,10 @@ function readPlanFile(path, fallbackBaseDir) {
|
|
|
14776
15158
|
}
|
|
14777
15159
|
}
|
|
14778
15160
|
function writePlanFile(path, plan) {
|
|
14779
|
-
|
|
15161
|
+
writeFileSync9(path, JSON.stringify(plan, null, 2), "utf-8");
|
|
14780
15162
|
}
|
|
14781
15163
|
function listDir(dir, baseDir) {
|
|
14782
|
-
if (!
|
|
15164
|
+
if (!existsSync28(dir))
|
|
14783
15165
|
return [];
|
|
14784
15166
|
const files = readdirSync9(dir).filter((f) => f.endsWith(".json"));
|
|
14785
15167
|
return files.map((f) => readPlanFile(join22(dir, f), baseDir)).filter((p) => p !== null);
|
|
@@ -14804,16 +15186,16 @@ class PlanStore {
|
|
|
14804
15186
|
legacyPath;
|
|
14805
15187
|
constructor(baseDir) {
|
|
14806
15188
|
const mmaDir = join22(baseDir, ".mma");
|
|
14807
|
-
if (!
|
|
14808
|
-
|
|
15189
|
+
if (!existsSync28(mmaDir))
|
|
15190
|
+
mkdirSync13(mmaDir, { recursive: true });
|
|
14809
15191
|
this.baseDir = baseDir;
|
|
14810
15192
|
this.plansDir = join22(mmaDir, "plans");
|
|
14811
15193
|
this.draftsDir = join22(this.plansDir, "drafts");
|
|
14812
15194
|
this.archiveDir = join22(this.plansDir, "archive");
|
|
14813
15195
|
this.legacyPath = join22(mmaDir, LEGACY_FILE);
|
|
14814
15196
|
for (const dir of [this.plansDir, this.draftsDir, this.archiveDir]) {
|
|
14815
|
-
if (!
|
|
14816
|
-
|
|
15197
|
+
if (!existsSync28(dir))
|
|
15198
|
+
mkdirSync13(dir, { recursive: true });
|
|
14817
15199
|
}
|
|
14818
15200
|
}
|
|
14819
15201
|
activePath() {
|
|
@@ -14824,12 +15206,12 @@ class PlanStore {
|
|
|
14824
15206
|
}
|
|
14825
15207
|
loadActive() {
|
|
14826
15208
|
const activePath = this.activePath();
|
|
14827
|
-
if (
|
|
15209
|
+
if (existsSync28(activePath)) {
|
|
14828
15210
|
const plan = readPlanFile(activePath, this.baseDir);
|
|
14829
15211
|
if (plan)
|
|
14830
15212
|
return plan;
|
|
14831
15213
|
}
|
|
14832
|
-
if (
|
|
15214
|
+
if (existsSync28(this.legacyPath)) {
|
|
14833
15215
|
const legacy = readPlanFile(this.legacyPath, this.baseDir);
|
|
14834
15216
|
if (legacy) {
|
|
14835
15217
|
this.saveActive(legacy);
|
|
@@ -14843,7 +15225,7 @@ class PlanStore {
|
|
|
14843
15225
|
}
|
|
14844
15226
|
clearActive() {
|
|
14845
15227
|
const p = this.activePath();
|
|
14846
|
-
if (
|
|
15228
|
+
if (existsSync28(p))
|
|
14847
15229
|
rmSync(p, { force: true });
|
|
14848
15230
|
}
|
|
14849
15231
|
saveDraft(plan) {
|
|
@@ -14851,11 +15233,11 @@ class PlanStore {
|
|
|
14851
15233
|
}
|
|
14852
15234
|
loadDraft(id) {
|
|
14853
15235
|
const p = join22(this.draftsDir, `${id}.json`);
|
|
14854
|
-
return
|
|
15236
|
+
return existsSync28(p) ? readPlanFile(p, this.baseDir) : null;
|
|
14855
15237
|
}
|
|
14856
15238
|
removeDraft(id) {
|
|
14857
15239
|
const p = join22(this.draftsDir, `${id}.json`);
|
|
14858
|
-
if (
|
|
15240
|
+
if (existsSync28(p))
|
|
14859
15241
|
rmSync(p, { force: true });
|
|
14860
15242
|
}
|
|
14861
15243
|
listDrafts() {
|
|
@@ -14874,7 +15256,7 @@ class PlanStore {
|
|
|
14874
15256
|
}
|
|
14875
15257
|
removeArchived(id) {
|
|
14876
15258
|
const p = join22(this.archiveDir, `${id}.json`);
|
|
14877
|
-
if (
|
|
15259
|
+
if (existsSync28(p))
|
|
14878
15260
|
rmSync(p, { force: true });
|
|
14879
15261
|
}
|
|
14880
15262
|
listAll() {
|
|
@@ -14968,8 +15350,8 @@ var init_plan_coverage = __esm(() => {
|
|
|
14968
15350
|
});
|
|
14969
15351
|
|
|
14970
15352
|
// src/modules/execution/module.ts
|
|
14971
|
-
import { existsSync as
|
|
14972
|
-
import { resolve as
|
|
15353
|
+
import { existsSync as existsSync29, readFileSync as readFileSync17 } from "fs";
|
|
15354
|
+
import { resolve as resolve18 } from "path";
|
|
14973
15355
|
|
|
14974
15356
|
class ExecutionModule {
|
|
14975
15357
|
name = "execution";
|
|
@@ -15624,7 +16006,7 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
15624
16006
|
"poetry.lock",
|
|
15625
16007
|
"requirements.txt"
|
|
15626
16008
|
];
|
|
15627
|
-
const hasLockFile = lockFiles.some((f) =>
|
|
16009
|
+
const hasLockFile = lockFiles.some((f) => existsSync29(resolve18(this.baseDir, f)));
|
|
15628
16010
|
if (!hasLockFile) {
|
|
15629
16011
|
if (contextManager) {
|
|
15630
16012
|
const hints = this.depsGateHints.get(step.id) || 0;
|
|
@@ -15644,13 +16026,13 @@ Tool "${this.stuckDetector.getLastFailedTool()}" is failing. Try "${alternative}
|
|
|
15644
16026
|
}
|
|
15645
16027
|
if (stepPaths.length === 0)
|
|
15646
16028
|
return;
|
|
15647
|
-
const allExist = stepPaths.every((p) =>
|
|
16029
|
+
const allExist = stepPaths.every((p) => existsSync29(resolve18(this.baseDir, p)));
|
|
15648
16030
|
if (!allExist)
|
|
15649
16031
|
return;
|
|
15650
16032
|
const emptyFiles = [];
|
|
15651
16033
|
for (const p of stepPaths) {
|
|
15652
16034
|
try {
|
|
15653
|
-
const content =
|
|
16035
|
+
const content = readFileSync17(resolve18(this.baseDir, p), "utf-8");
|
|
15654
16036
|
if (content.trim().length < 10) {
|
|
15655
16037
|
emptyFiles.push(p);
|
|
15656
16038
|
}
|
|
@@ -15707,9 +16089,9 @@ var init_module = __esm(() => {
|
|
|
15707
16089
|
|
|
15708
16090
|
// src/modules/security/session-encryption.ts
|
|
15709
16091
|
import {
|
|
15710
|
-
readFileSync as
|
|
15711
|
-
writeFileSync as
|
|
15712
|
-
existsSync as
|
|
16092
|
+
readFileSync as readFileSync18,
|
|
16093
|
+
writeFileSync as writeFileSync10,
|
|
16094
|
+
existsSync as existsSync30,
|
|
15713
16095
|
readdirSync as readdirSync10,
|
|
15714
16096
|
unlinkSync as unlinkSync4
|
|
15715
16097
|
} from "fs";
|
|
@@ -15767,23 +16149,23 @@ class SessionFileEncryptor {
|
|
|
15767
16149
|
return lines.map((line) => this.decryptFileContent(line));
|
|
15768
16150
|
}
|
|
15769
16151
|
readSessionFile(filePath) {
|
|
15770
|
-
const content =
|
|
16152
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15771
16153
|
return this.decryptFileContent(content);
|
|
15772
16154
|
}
|
|
15773
16155
|
writeSessionFile(filePath, content) {
|
|
15774
16156
|
const encrypted = this.encryptFileContent(content);
|
|
15775
|
-
|
|
16157
|
+
writeFileSync10(filePath, encrypted, "utf8");
|
|
15776
16158
|
}
|
|
15777
16159
|
readSessionJSON(filePath) {
|
|
15778
|
-
const content =
|
|
16160
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15779
16161
|
return this.decryptJSON(content);
|
|
15780
16162
|
}
|
|
15781
16163
|
writeSessionJSON(filePath, obj) {
|
|
15782
16164
|
const content = this.encryptJSON(obj);
|
|
15783
|
-
|
|
16165
|
+
writeFileSync10(filePath, content, "utf8");
|
|
15784
16166
|
}
|
|
15785
16167
|
readSessionJSONL(filePath) {
|
|
15786
|
-
const content =
|
|
16168
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15787
16169
|
const lines = content.split(`
|
|
15788
16170
|
`).filter((line) => line.trim());
|
|
15789
16171
|
const decryptedLines = this.decryptJSONL(lines);
|
|
@@ -15797,7 +16179,7 @@ class SessionFileEncryptor {
|
|
|
15797
16179
|
}
|
|
15798
16180
|
appendToSessionJSONL(filePath, obj) {
|
|
15799
16181
|
const encryptedLine = this.encryptFileContent(JSON.stringify(obj));
|
|
15800
|
-
|
|
16182
|
+
writeFileSync10(filePath, encryptedLine + `
|
|
15801
16183
|
`, {
|
|
15802
16184
|
flag: "a",
|
|
15803
16185
|
encoding: "utf8"
|
|
@@ -15809,11 +16191,11 @@ class SessionFileEncryptor {
|
|
|
15809
16191
|
const files = readdirSync10(sessionDir);
|
|
15810
16192
|
for (const file of files) {
|
|
15811
16193
|
const filePath = join23(sessionDir, file);
|
|
15812
|
-
if (
|
|
16194
|
+
if (existsSync30(filePath) && !file.endsWith(".enc")) {
|
|
15813
16195
|
try {
|
|
15814
|
-
const content =
|
|
16196
|
+
const content = readFileSync18(filePath, "utf8");
|
|
15815
16197
|
const encrypted = this.encryptFileContent(content);
|
|
15816
|
-
|
|
16198
|
+
writeFileSync10(filePath + ".enc", encrypted, "utf8");
|
|
15817
16199
|
unlinkSync4(filePath);
|
|
15818
16200
|
} catch {}
|
|
15819
16201
|
}
|
|
@@ -15828,9 +16210,9 @@ class SessionFileEncryptor {
|
|
|
15828
16210
|
const encFilePath = join23(sessionDir, file);
|
|
15829
16211
|
const decFilePath = encFilePath.slice(0, -4);
|
|
15830
16212
|
try {
|
|
15831
|
-
const content =
|
|
16213
|
+
const content = readFileSync18(encFilePath, "utf8");
|
|
15832
16214
|
const decrypted = this.decryptFileContent(content);
|
|
15833
|
-
|
|
16215
|
+
writeFileSync10(decFilePath, decrypted, "utf8");
|
|
15834
16216
|
unlinkSync4(encFilePath);
|
|
15835
16217
|
} catch {}
|
|
15836
16218
|
}
|
|
@@ -15850,12 +16232,12 @@ var init_session_encryption = __esm(() => {
|
|
|
15850
16232
|
|
|
15851
16233
|
// src/modules/session/store.ts
|
|
15852
16234
|
import {
|
|
15853
|
-
existsSync as
|
|
15854
|
-
mkdirSync as
|
|
16235
|
+
existsSync as existsSync31,
|
|
16236
|
+
mkdirSync as mkdirSync14,
|
|
15855
16237
|
readdirSync as readdirSync11,
|
|
15856
|
-
readFileSync as
|
|
16238
|
+
readFileSync as readFileSync19,
|
|
15857
16239
|
rmSync as rmSync2,
|
|
15858
|
-
writeFileSync as
|
|
16240
|
+
writeFileSync as writeFileSync11,
|
|
15859
16241
|
appendFileSync as appendFileSync6
|
|
15860
16242
|
} from "fs";
|
|
15861
16243
|
import { join as join24 } from "path";
|
|
@@ -15885,7 +16267,7 @@ class SessionStore {
|
|
|
15885
16267
|
return this.encryptor?.isEnabled() ?? false;
|
|
15886
16268
|
}
|
|
15887
16269
|
init() {
|
|
15888
|
-
|
|
16270
|
+
mkdirSync14(this.baseDir, { recursive: true });
|
|
15889
16271
|
}
|
|
15890
16272
|
sessionDir(id) {
|
|
15891
16273
|
return join24(this.baseDir, id);
|
|
@@ -15900,17 +16282,17 @@ class SessionStore {
|
|
|
15900
16282
|
return join24(this.sessionDir(id), "session.jsonl");
|
|
15901
16283
|
}
|
|
15902
16284
|
sessionExists(id) {
|
|
15903
|
-
return
|
|
16285
|
+
return existsSync31(this.metaPath(id));
|
|
15904
16286
|
}
|
|
15905
16287
|
saveMeta(id, meta) {
|
|
15906
16288
|
this._metaCache.set(id, meta);
|
|
15907
16289
|
const dir = this.sessionDir(id);
|
|
15908
|
-
|
|
16290
|
+
mkdirSync14(dir, { recursive: true });
|
|
15909
16291
|
const content = JSON.stringify(meta, null, 2);
|
|
15910
16292
|
if (this.encryptor) {
|
|
15911
|
-
|
|
16293
|
+
writeFileSync11(this.metaPath(id), this.encryptor.encryptFileContent(content), "utf-8");
|
|
15912
16294
|
} else {
|
|
15913
|
-
|
|
16295
|
+
writeFileSync11(this.metaPath(id), content, "utf-8");
|
|
15914
16296
|
}
|
|
15915
16297
|
}
|
|
15916
16298
|
loadMeta(id) {
|
|
@@ -15918,10 +16300,10 @@ class SessionStore {
|
|
|
15918
16300
|
if (cached)
|
|
15919
16301
|
return cached;
|
|
15920
16302
|
const path = this.metaPath(id);
|
|
15921
|
-
if (!
|
|
16303
|
+
if (!existsSync31(path))
|
|
15922
16304
|
return null;
|
|
15923
16305
|
try {
|
|
15924
|
-
const raw =
|
|
16306
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15925
16307
|
const content = this.encryptor ? this.encryptor.decryptFileContent(raw) : raw;
|
|
15926
16308
|
const meta = JSON.parse(content);
|
|
15927
16309
|
this._metaCache.set(id, meta);
|
|
@@ -15932,7 +16314,7 @@ class SessionStore {
|
|
|
15932
16314
|
}
|
|
15933
16315
|
appendMessage(id, msg) {
|
|
15934
16316
|
const dir = this.sessionDir(id);
|
|
15935
|
-
|
|
16317
|
+
mkdirSync14(dir, { recursive: true });
|
|
15936
16318
|
const line = JSON.stringify(msg);
|
|
15937
16319
|
if (this.encryptor?.isEnabled()) {
|
|
15938
16320
|
appendFileSync6(this.historyPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -15950,10 +16332,10 @@ class SessionStore {
|
|
|
15950
16332
|
}
|
|
15951
16333
|
loadHistory(id) {
|
|
15952
16334
|
const path = this.historyPath(id);
|
|
15953
|
-
if (!
|
|
16335
|
+
if (!existsSync31(path))
|
|
15954
16336
|
return [];
|
|
15955
16337
|
try {
|
|
15956
|
-
const raw =
|
|
16338
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15957
16339
|
const lines = raw.split(`
|
|
15958
16340
|
`).filter(Boolean);
|
|
15959
16341
|
const parseLine = (line) => {
|
|
@@ -15979,7 +16361,7 @@ class SessionStore {
|
|
|
15979
16361
|
}
|
|
15980
16362
|
appendSessionLog(id, entry) {
|
|
15981
16363
|
const dir = this.sessionDir(id);
|
|
15982
|
-
|
|
16364
|
+
mkdirSync14(dir, { recursive: true });
|
|
15983
16365
|
const line = JSON.stringify(entry);
|
|
15984
16366
|
if (this.encryptor?.isEnabled()) {
|
|
15985
16367
|
appendFileSync6(this.sessionLogPath(id), this.encryptor.encryptFileContent(line) + `
|
|
@@ -15991,10 +16373,10 @@ class SessionStore {
|
|
|
15991
16373
|
}
|
|
15992
16374
|
loadSessionLog(id) {
|
|
15993
16375
|
const path = this.sessionLogPath(id);
|
|
15994
|
-
if (!
|
|
16376
|
+
if (!existsSync31(path))
|
|
15995
16377
|
return [];
|
|
15996
16378
|
try {
|
|
15997
|
-
const raw =
|
|
16379
|
+
const raw = readFileSync19(path, "utf-8");
|
|
15998
16380
|
const lines = raw.split(`
|
|
15999
16381
|
`).filter(Boolean);
|
|
16000
16382
|
const parseLine = (line) => {
|
|
@@ -16019,7 +16401,7 @@ class SessionStore {
|
|
|
16019
16401
|
}
|
|
16020
16402
|
}
|
|
16021
16403
|
listSessions() {
|
|
16022
|
-
if (!
|
|
16404
|
+
if (!existsSync31(this.baseDir))
|
|
16023
16405
|
return [];
|
|
16024
16406
|
const entries = readdirSync11(this.baseDir, { withFileTypes: true });
|
|
16025
16407
|
const sessions = [];
|
|
@@ -16036,7 +16418,7 @@ class SessionStore {
|
|
|
16036
16418
|
deleteSession(id) {
|
|
16037
16419
|
this._metaCache.delete(id);
|
|
16038
16420
|
const dir = this.sessionDir(id);
|
|
16039
|
-
if (
|
|
16421
|
+
if (existsSync31(dir)) {
|
|
16040
16422
|
rmSync2(dir, { recursive: true, force: true });
|
|
16041
16423
|
}
|
|
16042
16424
|
}
|
|
@@ -16048,18 +16430,18 @@ class SessionStore {
|
|
|
16048
16430
|
const updatedAt = new Date(session2.updatedAt);
|
|
16049
16431
|
if (updatedAt < thirtyDaysAgo) {
|
|
16050
16432
|
const historyPath = this.historyPath(session2.id);
|
|
16051
|
-
if (
|
|
16052
|
-
const content =
|
|
16433
|
+
if (existsSync31(historyPath)) {
|
|
16434
|
+
const content = readFileSync19(historyPath, "utf-8");
|
|
16053
16435
|
const compressed = gzipSync(content);
|
|
16054
16436
|
const gzPath = join24(this.baseDir, `${session2.id}.jsonl.gz`);
|
|
16055
|
-
|
|
16437
|
+
writeFileSync11(gzPath, compressed);
|
|
16056
16438
|
rmSync2(historyPath);
|
|
16057
16439
|
}
|
|
16058
16440
|
}
|
|
16059
16441
|
}
|
|
16060
16442
|
}
|
|
16061
16443
|
}
|
|
16062
|
-
var
|
|
16444
|
+
var init_store3 = __esm(() => {
|
|
16063
16445
|
init_session_encryption();
|
|
16064
16446
|
});
|
|
16065
16447
|
|
|
@@ -16239,7 +16621,7 @@ var init_module2 = __esm(() => {
|
|
|
16239
16621
|
|
|
16240
16622
|
// src/modules/session/index.ts
|
|
16241
16623
|
var init_session2 = __esm(() => {
|
|
16242
|
-
|
|
16624
|
+
init_store3();
|
|
16243
16625
|
init_manager2();
|
|
16244
16626
|
init_module2();
|
|
16245
16627
|
});
|
|
@@ -16261,7 +16643,7 @@ class ProfileCompressor {
|
|
|
16261
16643
|
}
|
|
16262
16644
|
|
|
16263
16645
|
// src/modules/user-profile/profile.ts
|
|
16264
|
-
import { readFileSync as
|
|
16646
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync12, existsSync as existsSync32, mkdirSync as mkdirSync15 } from "fs";
|
|
16265
16647
|
import { join as join25 } from "path";
|
|
16266
16648
|
import { homedir as homedir9, hostname, platform as platform4, type } from "os";
|
|
16267
16649
|
import { env } from "process";
|
|
@@ -16286,17 +16668,17 @@ class UserProfile {
|
|
|
16286
16668
|
return this.info;
|
|
16287
16669
|
}
|
|
16288
16670
|
save() {
|
|
16289
|
-
if (!
|
|
16290
|
-
|
|
16671
|
+
if (!existsSync32(this.profileDir)) {
|
|
16672
|
+
mkdirSync15(this.profileDir, { recursive: true });
|
|
16291
16673
|
}
|
|
16292
|
-
|
|
16674
|
+
writeFileSync12(join25(this.profileDir, "profile.json"), JSON.stringify({ ...this.info, preferences: this.preferences }, null, 2), "utf-8");
|
|
16293
16675
|
}
|
|
16294
16676
|
load() {
|
|
16295
16677
|
const path = join25(this.profileDir, "profile.json");
|
|
16296
|
-
if (!
|
|
16678
|
+
if (!existsSync32(path))
|
|
16297
16679
|
return null;
|
|
16298
16680
|
try {
|
|
16299
|
-
const data = JSON.parse(
|
|
16681
|
+
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
16300
16682
|
this.info = {
|
|
16301
16683
|
platform: data.platform,
|
|
16302
16684
|
os: data.os,
|
|
@@ -16331,12 +16713,12 @@ class UserProfile {
|
|
|
16331
16713
|
var init_profile = () => {};
|
|
16332
16714
|
|
|
16333
16715
|
// src/modules/skills/loader.ts
|
|
16334
|
-
import { readdirSync as readdirSync12, readFileSync as
|
|
16716
|
+
import { readdirSync as readdirSync12, readFileSync as readFileSync21, existsSync as existsSync33, statSync as statSync6 } from "fs";
|
|
16335
16717
|
import { join as join26 } from "path";
|
|
16336
16718
|
|
|
16337
16719
|
class SkillsLoader {
|
|
16338
16720
|
loadFromDir(dirPath) {
|
|
16339
|
-
if (!
|
|
16721
|
+
if (!existsSync33(dirPath))
|
|
16340
16722
|
return [];
|
|
16341
16723
|
const skills = [];
|
|
16342
16724
|
this.scanDir(dirPath, skills);
|
|
@@ -16353,7 +16735,7 @@ class SkillsLoader {
|
|
|
16353
16735
|
}
|
|
16354
16736
|
if (!entry.endsWith(".md") && !entry.endsWith(".skill.md"))
|
|
16355
16737
|
continue;
|
|
16356
|
-
const content =
|
|
16738
|
+
const content = readFileSync21(fullPath, "utf-8");
|
|
16357
16739
|
const parsed = this.parseSkillFile(content, fullPath);
|
|
16358
16740
|
if (parsed)
|
|
16359
16741
|
skills.push(parsed);
|
|
@@ -16587,7 +16969,7 @@ var init_browser2 = __esm(() => {
|
|
|
16587
16969
|
|
|
16588
16970
|
// src/modules/lsp/client.ts
|
|
16589
16971
|
import { spawn as spawn5, execSync as execSync2 } from "child_process";
|
|
16590
|
-
import { resolve as
|
|
16972
|
+
import { resolve as resolve19 } from "path";
|
|
16591
16973
|
|
|
16592
16974
|
class LspClient {
|
|
16593
16975
|
process = null;
|
|
@@ -16603,7 +16985,7 @@ class LspClient {
|
|
|
16603
16985
|
const timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
16604
16986
|
try {
|
|
16605
16987
|
await this.startServer(config, baseDir);
|
|
16606
|
-
const rootUri = this.pathToUri(
|
|
16988
|
+
const rootUri = this.pathToUri(resolve19(baseDir));
|
|
16607
16989
|
const initResult = await this.sendRequest("initialize", {
|
|
16608
16990
|
processId: process.pid,
|
|
16609
16991
|
rootUri,
|
|
@@ -16612,11 +16994,11 @@ class LspClient {
|
|
|
16612
16994
|
}, timeout);
|
|
16613
16995
|
this.initialized = true;
|
|
16614
16996
|
this.sendNotification("initialized", {});
|
|
16615
|
-
const uri = this.pathToUri(
|
|
16997
|
+
const uri = this.pathToUri(resolve19(filePath));
|
|
16616
16998
|
const fs2 = await import("fs");
|
|
16617
16999
|
const content = fs2.readFileSync(filePath, "utf-8");
|
|
16618
|
-
const diagPromise = new Promise((
|
|
16619
|
-
this.diagnosticsResolve =
|
|
17000
|
+
const diagPromise = new Promise((resolve20) => {
|
|
17001
|
+
this.diagnosticsResolve = resolve20;
|
|
16620
17002
|
this.diagnostics = [];
|
|
16621
17003
|
this.diagnosticsTimer = setTimeout(() => {
|
|
16622
17004
|
if (this.diagnosticsResolve) {
|
|
@@ -16648,7 +17030,7 @@ class LspClient {
|
|
|
16648
17030
|
throw new Error(`${config.command} not found in PATH`);
|
|
16649
17031
|
}
|
|
16650
17032
|
}
|
|
16651
|
-
return new Promise((
|
|
17033
|
+
return new Promise((resolve20, reject) => {
|
|
16652
17034
|
const args = config.args ?? [];
|
|
16653
17035
|
const proc = spawn5(config.command, args, {
|
|
16654
17036
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -16661,7 +17043,7 @@ class LspClient {
|
|
|
16661
17043
|
});
|
|
16662
17044
|
proc.stderr.on("data", () => {});
|
|
16663
17045
|
proc.once("spawn", () => {
|
|
16664
|
-
|
|
17046
|
+
resolve20();
|
|
16665
17047
|
});
|
|
16666
17048
|
this.process = proc;
|
|
16667
17049
|
setTimeout(() => {
|
|
@@ -16738,9 +17120,9 @@ class LspClient {
|
|
|
16738
17120
|
}
|
|
16739
17121
|
}
|
|
16740
17122
|
sendRequest(method, params, timeout) {
|
|
16741
|
-
return new Promise((
|
|
17123
|
+
return new Promise((resolve20, reject) => {
|
|
16742
17124
|
const id = ++this.requestId;
|
|
16743
|
-
this.pending.set(id, { resolve:
|
|
17125
|
+
this.pending.set(id, { resolve: resolve20, reject });
|
|
16744
17126
|
const message = JSON.stringify({ jsonrpc: "2.0", id, method, params });
|
|
16745
17127
|
this.write(message);
|
|
16746
17128
|
setTimeout(() => {
|
|
@@ -16818,8 +17200,8 @@ var DEFAULT_TIMEOUT = 15000;
|
|
|
16818
17200
|
var init_client2 = () => {};
|
|
16819
17201
|
|
|
16820
17202
|
// src/modules/lsp/module.ts
|
|
16821
|
-
import { existsSync as
|
|
16822
|
-
import { resolve as
|
|
17203
|
+
import { existsSync as existsSync34 } from "fs";
|
|
17204
|
+
import { resolve as resolve20 } from "path";
|
|
16823
17205
|
|
|
16824
17206
|
class LspModule {
|
|
16825
17207
|
name = "lsp";
|
|
@@ -16843,8 +17225,8 @@ class LspModule {
|
|
|
16843
17225
|
const filePath = String(call.arguments.path ?? "");
|
|
16844
17226
|
if (!filePath)
|
|
16845
17227
|
return;
|
|
16846
|
-
const fullPath =
|
|
16847
|
-
if (!
|
|
17228
|
+
const fullPath = resolve20(_ctx.baseDir, filePath);
|
|
17229
|
+
if (!existsSync34(fullPath))
|
|
16848
17230
|
return;
|
|
16849
17231
|
const serverConfig = getServerForFile(fullPath, self.config);
|
|
16850
17232
|
if (!serverConfig)
|
|
@@ -16902,8 +17284,8 @@ var init_lsp = __esm(() => {
|
|
|
16902
17284
|
});
|
|
16903
17285
|
|
|
16904
17286
|
// src/modules/indexer/walker.ts
|
|
16905
|
-
import { readdirSync as readdirSync13, readFileSync as
|
|
16906
|
-
import { join as join27, relative, extname as extname5 } from "path";
|
|
17287
|
+
import { readdirSync as readdirSync13, readFileSync as readFileSync22, statSync as statSync7, existsSync as existsSync35, watch } from "fs";
|
|
17288
|
+
import { join as join27, relative as relative2, extname as extname5 } from "path";
|
|
16907
17289
|
|
|
16908
17290
|
class Indexer {
|
|
16909
17291
|
baseDir;
|
|
@@ -16930,7 +17312,7 @@ class Indexer {
|
|
|
16930
17312
|
let totalSize = 0;
|
|
16931
17313
|
let count = 0;
|
|
16932
17314
|
const walkDir = (dir) => {
|
|
16933
|
-
if (!
|
|
17315
|
+
if (!existsSync35(dir))
|
|
16934
17316
|
return;
|
|
16935
17317
|
let entries;
|
|
16936
17318
|
try {
|
|
@@ -16942,7 +17324,7 @@ class Indexer {
|
|
|
16942
17324
|
if (count >= this.MAX_FILES)
|
|
16943
17325
|
return;
|
|
16944
17326
|
const fullPath = join27(dir, entry);
|
|
16945
|
-
const relPath =
|
|
17327
|
+
const relPath = relative2(this.baseDir, fullPath);
|
|
16946
17328
|
const stat = statSync7(fullPath);
|
|
16947
17329
|
if (stat.isDirectory()) {
|
|
16948
17330
|
if (!IGNORE_DIRS.has(entry)) {
|
|
@@ -16952,7 +17334,7 @@ class Indexer {
|
|
|
16952
17334
|
const ext = extname5(entry).toLowerCase();
|
|
16953
17335
|
const language = LANGUAGES[ext];
|
|
16954
17336
|
if (language) {
|
|
16955
|
-
const content =
|
|
17337
|
+
const content = readFileSync22(fullPath, "utf-8");
|
|
16956
17338
|
const exports = this.extractExports(content, language);
|
|
16957
17339
|
files.push({ path: relPath, language, exports, size: stat.size });
|
|
16958
17340
|
totalSize += stat.size;
|
|
@@ -17004,7 +17386,7 @@ var init_walker = __esm(() => {
|
|
|
17004
17386
|
});
|
|
17005
17387
|
|
|
17006
17388
|
// src/modules/indexer/cache.ts
|
|
17007
|
-
import { readFileSync as
|
|
17389
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync13, existsSync as existsSync36, mkdirSync as mkdirSync16, rmSync as rmSync3 } from "fs";
|
|
17008
17390
|
import { join as join28 } from "path";
|
|
17009
17391
|
|
|
17010
17392
|
class IndexCache {
|
|
@@ -17016,10 +17398,10 @@ class IndexCache {
|
|
|
17016
17398
|
load() {
|
|
17017
17399
|
if (this.cache)
|
|
17018
17400
|
return this.cache;
|
|
17019
|
-
if (!
|
|
17401
|
+
if (!existsSync36(this.cachePath))
|
|
17020
17402
|
return null;
|
|
17021
17403
|
try {
|
|
17022
|
-
this.cache = JSON.parse(
|
|
17404
|
+
this.cache = JSON.parse(readFileSync23(this.cachePath, "utf-8"));
|
|
17023
17405
|
return this.cache;
|
|
17024
17406
|
} catch {
|
|
17025
17407
|
return null;
|
|
@@ -17028,13 +17410,13 @@ class IndexCache {
|
|
|
17028
17410
|
save(result) {
|
|
17029
17411
|
this.cache = result;
|
|
17030
17412
|
const dir = join28(this.cachePath, "..");
|
|
17031
|
-
if (!
|
|
17032
|
-
|
|
17033
|
-
|
|
17413
|
+
if (!existsSync36(dir))
|
|
17414
|
+
mkdirSync16(dir, { recursive: true });
|
|
17415
|
+
writeFileSync13(this.cachePath, JSON.stringify(result), "utf-8");
|
|
17034
17416
|
}
|
|
17035
17417
|
invalidate() {
|
|
17036
17418
|
this.cache = null;
|
|
17037
|
-
if (
|
|
17419
|
+
if (existsSync36(this.cachePath)) {
|
|
17038
17420
|
try {
|
|
17039
17421
|
rmSync3(this.cachePath);
|
|
17040
17422
|
} catch {}
|
|
@@ -17434,7 +17816,7 @@ class MemoryModule {
|
|
|
17434
17816
|
}
|
|
17435
17817
|
}
|
|
17436
17818
|
var init_module8 = __esm(() => {
|
|
17437
|
-
|
|
17819
|
+
init_store2();
|
|
17438
17820
|
init_remember();
|
|
17439
17821
|
init_recall();
|
|
17440
17822
|
});
|
|
@@ -17446,8 +17828,8 @@ __export(exports_bootstrap, {
|
|
|
17446
17828
|
bootstrap: () => bootstrap
|
|
17447
17829
|
});
|
|
17448
17830
|
import { homedir as homedir11 } from "os";
|
|
17449
|
-
import { join as join30, resolve as
|
|
17450
|
-
import { existsSync as
|
|
17831
|
+
import { join as join30, resolve as resolve21 } from "path";
|
|
17832
|
+
import { existsSync as existsSync37, readFileSync as readFileSync24, writeFileSync as writeFileSync14 } from "fs";
|
|
17451
17833
|
function buildSystemInfo(config, baseDir, profileCompressed) {
|
|
17452
17834
|
const now = new Date().toISOString().replace("T", " ").slice(0, 19);
|
|
17453
17835
|
const isWin = profileCompressed.toLowerCase().includes("win32");
|
|
@@ -17516,7 +17898,7 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17516
17898
|
retry: config.retry,
|
|
17517
17899
|
rateLimits: config.security?.rateLimits
|
|
17518
17900
|
});
|
|
17519
|
-
const baseDir = projectDir ?
|
|
17901
|
+
const baseDir = projectDir ? resolve21(projectDir) : process.cwd();
|
|
17520
17902
|
const projectMapCacheDir = join30(baseDir, ".mma");
|
|
17521
17903
|
const indexerModule = new IndexerModule({
|
|
17522
17904
|
baseDir,
|
|
@@ -17545,8 +17927,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17545
17927
|
estimatedTokens: Math.ceil(systemInfoContent.length / 4)
|
|
17546
17928
|
};
|
|
17547
17929
|
const agentsMdGlobal = join30(dir, "AGENTS.md");
|
|
17548
|
-
if (!
|
|
17549
|
-
|
|
17930
|
+
if (!existsSync37(agentsMdGlobal)) {
|
|
17931
|
+
writeFileSync14(agentsMdGlobal, "", "utf-8");
|
|
17550
17932
|
}
|
|
17551
17933
|
const sessionDir = join30(dir, "sessions");
|
|
17552
17934
|
const sessionStore = new SessionStore(sessionDir);
|
|
@@ -17689,8 +18071,8 @@ async function bootstrap(configDir, projectDir, noAgentsMd, exitOnComplete) {
|
|
|
17689
18071
|
join30(dir, "AGENTS.md")
|
|
17690
18072
|
];
|
|
17691
18073
|
for (const p of agentsMdCandidates) {
|
|
17692
|
-
if (
|
|
17693
|
-
const content =
|
|
18074
|
+
if (existsSync37(p)) {
|
|
18075
|
+
const content = readFileSync24(p, "utf-8").trim();
|
|
17694
18076
|
if (content) {
|
|
17695
18077
|
agentsMdBlocks.push({
|
|
17696
18078
|
content,
|
|
@@ -18317,10 +18699,10 @@ function menuList(items) {
|
|
|
18317
18699
|
console.log(l);
|
|
18318
18700
|
}
|
|
18319
18701
|
function ask(rl, question, defaultValue) {
|
|
18320
|
-
return new Promise((
|
|
18702
|
+
return new Promise((resolve22) => {
|
|
18321
18703
|
const prompt = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
|
|
18322
18704
|
rl.question(prompt, (answer) => {
|
|
18323
|
-
|
|
18705
|
+
resolve22(answer.trim() || defaultValue || "");
|
|
18324
18706
|
});
|
|
18325
18707
|
});
|
|
18326
18708
|
}
|
|
@@ -18539,21 +18921,21 @@ __export(exports_manifest, {
|
|
|
18539
18921
|
getCertMark: () => getCertMark,
|
|
18540
18922
|
MANIFEST_PATH: () => MANIFEST_PATH
|
|
18541
18923
|
});
|
|
18542
|
-
import { existsSync as
|
|
18924
|
+
import { existsSync as existsSync38, readFileSync as readFileSync25, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
18543
18925
|
import { homedir as homedir13 } from "os";
|
|
18544
18926
|
import { join as join32 } from "path";
|
|
18545
18927
|
function readManifest(path = MANIFEST_PATH) {
|
|
18546
18928
|
try {
|
|
18547
|
-
if (
|
|
18548
|
-
const raw = JSON.parse(
|
|
18929
|
+
if (existsSync38(path)) {
|
|
18930
|
+
const raw = JSON.parse(readFileSync25(path, "utf-8"));
|
|
18549
18931
|
return { version: 1, certifications: raw.certifications ?? [] };
|
|
18550
18932
|
}
|
|
18551
18933
|
} catch {}
|
|
18552
18934
|
return { version: 1, certifications: [] };
|
|
18553
18935
|
}
|
|
18554
18936
|
function saveManifest(m, path = MANIFEST_PATH) {
|
|
18555
|
-
|
|
18556
|
-
|
|
18937
|
+
mkdirSync17(join32(homedir13(), ".mma"), { recursive: true });
|
|
18938
|
+
writeFileSync15(path, JSON.stringify(m, null, 2), "utf-8");
|
|
18557
18939
|
}
|
|
18558
18940
|
function upsertCertification(entry, path = MANIFEST_PATH) {
|
|
18559
18941
|
const m = readManifest(path);
|
|
@@ -25710,7 +26092,7 @@ var init_scenarios = __esm(() => {
|
|
|
25710
26092
|
});
|
|
25711
26093
|
|
|
25712
26094
|
// src/modules/certification/loader.ts
|
|
25713
|
-
import { existsSync as
|
|
26095
|
+
import { existsSync as existsSync39, readdirSync as readdirSync14, readFileSync as readFileSync26 } from "fs";
|
|
25714
26096
|
import { join as join33 } from "path";
|
|
25715
26097
|
function validateScenario(s) {
|
|
25716
26098
|
const errors2 = [];
|
|
@@ -25760,12 +26142,12 @@ function loadScenarios(userDir) {
|
|
|
25760
26142
|
else
|
|
25761
26143
|
scenarios.push(s);
|
|
25762
26144
|
}
|
|
25763
|
-
if (userDir &&
|
|
26145
|
+
if (userDir && existsSync39(userDir)) {
|
|
25764
26146
|
for (const file of readdirSync14(userDir)) {
|
|
25765
26147
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml"))
|
|
25766
26148
|
continue;
|
|
25767
26149
|
try {
|
|
25768
|
-
const raw =
|
|
26150
|
+
const raw = readFileSync26(join33(userDir, file), "utf-8");
|
|
25769
26151
|
const data = $parse(raw);
|
|
25770
26152
|
const parsed = normalizeScenario(data, file);
|
|
25771
26153
|
const errs = validateScenario(parsed);
|
|
@@ -25818,7 +26200,7 @@ var init_loader3 = __esm(() => {
|
|
|
25818
26200
|
});
|
|
25819
26201
|
|
|
25820
26202
|
// src/modules/certification/fact-checker.ts
|
|
25821
|
-
import { existsSync as
|
|
26203
|
+
import { existsSync as existsSync40, readFileSync as readFileSync27, statSync as statSync8 } from "fs";
|
|
25822
26204
|
import { join as join34 } from "path";
|
|
25823
26205
|
function checkSandbox(sandboxDir, checks, exitCode, output) {
|
|
25824
26206
|
const failures = [];
|
|
@@ -25838,14 +26220,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25838
26220
|
case "fileExists":
|
|
25839
26221
|
return isFile(join34(sandboxDir, check.path));
|
|
25840
26222
|
case "fileNotExists":
|
|
25841
|
-
return !
|
|
26223
|
+
return !existsSync40(join34(sandboxDir, check.path));
|
|
25842
26224
|
case "dirExists":
|
|
25843
26225
|
return isDir(join34(sandboxDir, check.path));
|
|
25844
26226
|
case "fileContent": {
|
|
25845
26227
|
const abs = join34(sandboxDir, check.path);
|
|
25846
26228
|
if (!isFile(abs))
|
|
25847
26229
|
return false;
|
|
25848
|
-
const content =
|
|
26230
|
+
const content = readFileSync27(abs, "utf-8");
|
|
25849
26231
|
if (check.contains !== undefined)
|
|
25850
26232
|
return content.includes(check.contains);
|
|
25851
26233
|
if (check.equals !== undefined)
|
|
@@ -25856,7 +26238,7 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25856
26238
|
const abs = join34(sandboxDir, check.path);
|
|
25857
26239
|
if (!isFile(abs))
|
|
25858
26240
|
return false;
|
|
25859
|
-
return new RegExp(check.pattern).test(
|
|
26241
|
+
return new RegExp(check.pattern).test(readFileSync27(abs, "utf-8"));
|
|
25860
26242
|
}
|
|
25861
26243
|
default:
|
|
25862
26244
|
return false;
|
|
@@ -25864,14 +26246,14 @@ function runCheck(sandboxDir, check, exitCode, output) {
|
|
|
25864
26246
|
}
|
|
25865
26247
|
function isFile(p) {
|
|
25866
26248
|
try {
|
|
25867
|
-
return
|
|
26249
|
+
return existsSync40(p) && statSync8(p).isFile();
|
|
25868
26250
|
} catch {
|
|
25869
26251
|
return false;
|
|
25870
26252
|
}
|
|
25871
26253
|
}
|
|
25872
26254
|
function isDir(p) {
|
|
25873
26255
|
try {
|
|
25874
|
-
return
|
|
26256
|
+
return existsSync40(p) && statSync8(p).isDirectory();
|
|
25875
26257
|
} catch {
|
|
25876
26258
|
return false;
|
|
25877
26259
|
}
|
|
@@ -25902,9 +26284,9 @@ var init_fact_checker = () => {};
|
|
|
25902
26284
|
|
|
25903
26285
|
// src/modules/certification/runner.ts
|
|
25904
26286
|
import { spawn as spawn6 } from "child_process";
|
|
25905
|
-
import { existsSync as
|
|
26287
|
+
import { existsSync as existsSync41, mkdirSync as mkdirSync18, rmSync as rmSync4, cpSync as cpSync2 } from "fs";
|
|
25906
26288
|
import { platform as platform5 } from "os";
|
|
25907
|
-
import { join as join35, resolve as
|
|
26289
|
+
import { join as join35, resolve as resolve22, dirname as dirname8 } from "path";
|
|
25908
26290
|
async function runScenario(scenario, opts) {
|
|
25909
26291
|
if (scenario.mode === "skip") {
|
|
25910
26292
|
return {
|
|
@@ -25982,30 +26364,30 @@ ${res.stderr}`;
|
|
|
25982
26364
|
}
|
|
25983
26365
|
function prepareSandbox(sandbox, scenario, mmaRoot) {
|
|
25984
26366
|
rmSync4(sandbox, { recursive: true, force: true });
|
|
25985
|
-
|
|
26367
|
+
mkdirSync18(sandbox, { recursive: true });
|
|
25986
26368
|
for (const f of scenario.fixtures ?? []) {
|
|
25987
26369
|
const src = join35(mmaRoot, f.source);
|
|
25988
|
-
if (!
|
|
26370
|
+
if (!existsSync41(src)) {
|
|
25989
26371
|
throw new Error(`fixture missing: ${f.source}`);
|
|
25990
26372
|
}
|
|
25991
26373
|
const dest = join35(sandbox, f.dest);
|
|
25992
|
-
|
|
26374
|
+
mkdirSync18(dirname8(dest), { recursive: true });
|
|
25993
26375
|
cpSync2(src, dest);
|
|
25994
26376
|
}
|
|
25995
26377
|
}
|
|
25996
26378
|
function resolveMmaEntry(mmaRoot) {
|
|
25997
26379
|
const dev = join35(mmaRoot, "src", "cli", "main.ts");
|
|
25998
|
-
if (
|
|
26380
|
+
if (existsSync41(dev))
|
|
25999
26381
|
return dev;
|
|
26000
26382
|
return join35(mmaRoot, "dist", "main.js");
|
|
26001
26383
|
}
|
|
26002
26384
|
function findMmaRoot(fromDir) {
|
|
26003
26385
|
const candidates = [
|
|
26004
|
-
|
|
26005
|
-
|
|
26386
|
+
resolve22(fromDir, "..", "..", ".."),
|
|
26387
|
+
resolve22(fromDir, "..")
|
|
26006
26388
|
];
|
|
26007
26389
|
for (const c of candidates) {
|
|
26008
|
-
if (
|
|
26390
|
+
if (existsSync41(join35(c, "package.json")))
|
|
26009
26391
|
return c;
|
|
26010
26392
|
}
|
|
26011
26393
|
return process.cwd();
|
|
@@ -26075,13 +26457,13 @@ import { rmSync as rmSync5 } from "fs";
|
|
|
26075
26457
|
import { homedir as homedir14 } from "os";
|
|
26076
26458
|
import { join as join36, dirname as dirname9 } from "path";
|
|
26077
26459
|
import { fileURLToPath } from "url";
|
|
26078
|
-
import { existsSync as
|
|
26460
|
+
import { existsSync as existsSync42, readFileSync as readFileSync28 } from "fs";
|
|
26079
26461
|
function readVersion() {
|
|
26080
26462
|
const candidates = [join36(MMA_ROOT, "package.json")];
|
|
26081
26463
|
for (const p of candidates) {
|
|
26082
|
-
if (
|
|
26464
|
+
if (existsSync42(p)) {
|
|
26083
26465
|
try {
|
|
26084
|
-
const raw = JSON.parse(
|
|
26466
|
+
const raw = JSON.parse(readFileSync28(p, "utf-8"));
|
|
26085
26467
|
if (raw.version)
|
|
26086
26468
|
return raw.version;
|
|
26087
26469
|
} catch {}
|
|
@@ -26242,7 +26624,7 @@ __export(exports_repl_commands, {
|
|
|
26242
26624
|
});
|
|
26243
26625
|
import { join as join38, dirname as dirname11 } from "path";
|
|
26244
26626
|
import { homedir as homedir16 } from "os";
|
|
26245
|
-
import { existsSync as
|
|
26627
|
+
import { existsSync as existsSync44, readFileSync as readFileSync30 } from "fs";
|
|
26246
26628
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
26247
26629
|
function readVersion3() {
|
|
26248
26630
|
const here = dirname11(fileURLToPath3(import.meta.url));
|
|
@@ -26251,9 +26633,9 @@ function readVersion3() {
|
|
|
26251
26633
|
join38(here, "..", "package.json")
|
|
26252
26634
|
];
|
|
26253
26635
|
for (const p of candidates) {
|
|
26254
|
-
if (
|
|
26636
|
+
if (existsSync44(p)) {
|
|
26255
26637
|
try {
|
|
26256
|
-
const raw = JSON.parse(
|
|
26638
|
+
const raw = JSON.parse(readFileSync30(p, "utf8"));
|
|
26257
26639
|
if (raw.version)
|
|
26258
26640
|
return raw.version;
|
|
26259
26641
|
} catch {}
|
|
@@ -26317,8 +26699,8 @@ function registerMmaCommands(ctx) {
|
|
|
26317
26699
|
}
|
|
26318
26700
|
try {
|
|
26319
26701
|
const { loadFileAsDataUrl: loadFileAsDataUrl2, loadUrlAsDataUrl: loadUrlAsDataUrl2, readClipboardImage: readClipboardImage2 } = await Promise.resolve().then(() => (init_image_utils(), exports_image_utils));
|
|
26320
|
-
const { existsSync:
|
|
26321
|
-
const { resolve:
|
|
26702
|
+
const { existsSync: existsSync45 } = await import("fs");
|
|
26703
|
+
const { resolve: resolve23 } = await import("path");
|
|
26322
26704
|
let dataUrl;
|
|
26323
26705
|
let label;
|
|
26324
26706
|
if (source.toLowerCase() === "clipboard") {
|
|
@@ -26336,8 +26718,8 @@ function registerMmaCommands(ctx) {
|
|
|
26336
26718
|
dataUrl = result.dataUrl;
|
|
26337
26719
|
label = source;
|
|
26338
26720
|
} else {
|
|
26339
|
-
const absPath =
|
|
26340
|
-
if (!
|
|
26721
|
+
const absPath = resolve23(process.cwd(), source);
|
|
26722
|
+
if (!existsSync45(absPath)) {
|
|
26341
26723
|
console.log(pc2.red(t("image.not_found", { path: source })));
|
|
26342
26724
|
return;
|
|
26343
26725
|
}
|
|
@@ -26875,7 +27257,7 @@ init_setup();
|
|
|
26875
27257
|
init_i18n();
|
|
26876
27258
|
import { join as join37, dirname as dirname10 } from "path";
|
|
26877
27259
|
import { homedir as homedir15 } from "os";
|
|
26878
|
-
import { existsSync as
|
|
27260
|
+
import { existsSync as existsSync43, readFileSync as readFileSync29 } from "fs";
|
|
26879
27261
|
|
|
26880
27262
|
// src/cli/security-commands.ts
|
|
26881
27263
|
init_bootstrap();
|
|
@@ -27503,9 +27885,9 @@ function readVersion2() {
|
|
|
27503
27885
|
join37(here, "..", "package.json")
|
|
27504
27886
|
];
|
|
27505
27887
|
for (const p of candidates) {
|
|
27506
|
-
if (
|
|
27888
|
+
if (existsSync43(p)) {
|
|
27507
27889
|
try {
|
|
27508
|
-
const raw = JSON.parse(
|
|
27890
|
+
const raw = JSON.parse(readFileSync29(p, "utf8"));
|
|
27509
27891
|
if (raw.version)
|
|
27510
27892
|
return raw.version;
|
|
27511
27893
|
} catch {}
|
|
@@ -27732,7 +28114,7 @@ init_bootstrap();
|
|
|
27732
28114
|
// src/cli/repl.ts
|
|
27733
28115
|
init_colors();
|
|
27734
28116
|
import * as readline2 from "readline";
|
|
27735
|
-
import { existsSync as
|
|
28117
|
+
import { existsSync as existsSync45, readFileSync as readFileSync31, writeFileSync as writeFileSync16 } from "fs";
|
|
27736
28118
|
import { join as join39, dirname as dirname12 } from "path";
|
|
27737
28119
|
import { homedir as homedir17 } from "os";
|
|
27738
28120
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -28251,9 +28633,9 @@ function readVersion4() {
|
|
|
28251
28633
|
join39(here, "..", "package.json")
|
|
28252
28634
|
];
|
|
28253
28635
|
for (const p of candidates) {
|
|
28254
|
-
if (
|
|
28636
|
+
if (existsSync45(p)) {
|
|
28255
28637
|
try {
|
|
28256
|
-
const raw = JSON.parse(
|
|
28638
|
+
const raw = JSON.parse(readFileSync31(p, "utf8"));
|
|
28257
28639
|
if (raw.version)
|
|
28258
28640
|
return raw.version;
|
|
28259
28641
|
} catch {}
|
|
@@ -28331,9 +28713,9 @@ class Repl {
|
|
|
28331
28713
|
this.setupListeners();
|
|
28332
28714
|
}
|
|
28333
28715
|
loadHistory() {
|
|
28334
|
-
if (
|
|
28716
|
+
if (existsSync45(this.historyPath)) {
|
|
28335
28717
|
try {
|
|
28336
|
-
const raw =
|
|
28718
|
+
const raw = readFileSync31(this.historyPath, "utf-8");
|
|
28337
28719
|
this.history = raw.split(`
|
|
28338
28720
|
`).filter(Boolean).slice(-this.maxHistory);
|
|
28339
28721
|
} catch {
|
|
@@ -28343,7 +28725,7 @@ class Repl {
|
|
|
28343
28725
|
}
|
|
28344
28726
|
saveHistory() {
|
|
28345
28727
|
const allHistory = this.history.slice(-this.maxHistory);
|
|
28346
|
-
|
|
28728
|
+
writeFileSync16(this.historyPath, allHistory.join(`
|
|
28347
28729
|
`), "utf-8");
|
|
28348
28730
|
}
|
|
28349
28731
|
setupCompleter() {
|
|
@@ -28668,7 +29050,7 @@ ${t("image.clipboard_empty")}`));
|
|
|
28668
29050
|
join39(this.baseDir, ".mma", "AGENTS.md"),
|
|
28669
29051
|
join39(this.configDir, "AGENTS.md")
|
|
28670
29052
|
];
|
|
28671
|
-
const foundAgents = agentsMdCandidates.filter((p) =>
|
|
29053
|
+
const foundAgents = agentsMdCandidates.filter((p) => existsSync45(p));
|
|
28672
29054
|
if (foundAgents.length > 0) {
|
|
28673
29055
|
for (const p of foundAgents) {
|
|
28674
29056
|
row(t("repl.agents_label"), pc2.dim(p));
|
|
@@ -28705,7 +29087,7 @@ init_setup();
|
|
|
28705
29087
|
init_config2();
|
|
28706
29088
|
init_i18n();
|
|
28707
29089
|
init_colors();
|
|
28708
|
-
import { existsSync as
|
|
29090
|
+
import { existsSync as existsSync46 } from "fs";
|
|
28709
29091
|
import { join as join40 } from "path";
|
|
28710
29092
|
import { homedir as homedir18 } from "os";
|
|
28711
29093
|
async function main() {
|
|
@@ -28774,7 +29156,7 @@ async function main() {
|
|
|
28774
29156
|
agent.shutdown();
|
|
28775
29157
|
} else {
|
|
28776
29158
|
const configPath = join40(homedir18(), ".mma", "config.json");
|
|
28777
|
-
if (!
|
|
29159
|
+
if (!existsSync46(configPath)) {
|
|
28778
29160
|
console.log(pc2.yellow(`
|
|
28779
29161
|
` + t("cli.first_run") + `
|
|
28780
29162
|
`));
|